示例#1
0
文件: main.c 项目: lronaldo/cpctelera
//////////////////////////////////////////////////////////////////////////////
// MAIN: code execution starts here
//    Initializes buffers at 0x4000 and 0xC000 and goes switching between
// both of them on keypresses
//
void main(void) {
   u8  scr = 0;      // Video buffer selector: selects what is to be shown on the screen
   u16 pattern;      // Will contain a 4 pixel-colour pattern 
   
   // First, Initialize the CPC
   initializeCPC();

   // Construct a color pattern with 4 consecutive pixels of 4 different
   // colours in mode 0, that will be used to fill up the second buffer
   pattern = ( cpct_px2byteM0(4, 6) << 8 ) | cpct_px2byteM0(8, 9);

   // Second, Set up the 0x4000 video buffer. This set up will erase 
   // all code placed in the 0x4000 area that has already been used
   // for initializing the CPC. Therefore, this code will have been 
   // used one and then replaced to gain some space.
   setUpVideoBuffer(VMEM_1, pattern, "0x4000 Screen Buffer", 0, 6);

   // Main Loop
   while (1) {
      // Wait for VSYNC and show pressently 
      // selected video buffer in the screen
      cpct_waitVSYNC();
      cpct_setVideoMemoryPage(g_buffers[scr]);  // Sets the memory page that will be shown on screen
      
      // Select the alternate video buffer and wait
      // for a keypress to change what is being shown on screen
      scr = scr ^ 0x01;    // Does operation scr XOR 1, which alternates the value of the last bit of scr, 
                           // ... so that it alternates between 0 and 1.
      wait4KeyPress();
   }
}
示例#2
0
文件: game.c 项目: johnlobo/Amsthrees
void drawScoreBoard() {
    u8 i;
    u32 c = 0;

    cpct_waitVSYNC();

    cpct_memset(CPCT_VMEM_START, cpct_px2byteM0(0, 0), 0x4000);

    drawText("AMSTHREES SCOREBOARD", 13, 2, 1);

    for (i = 0; i < 8; i++) {
        drawNumber(i + 1, 2, 5, 30 + (i * 15));
        drawText(nameHallOfFame[i], 14, 30 + (i * 15), 0);
        drawNumber(scoreHallOfFame[i], 1, 69, 30 + (i * 15));
    }

    drawText("JOHN LOBO", 25, 170, 1);
    drawText("@ GLASNOST CORP 2016", 11, 185, 1);

    c = 40000;     // Number of loops passed if not keypressed
    // Wait 'till the user presses a key, counting loop iterations
    do {
        c--;                       // One more cycle
        cpct_scanKeyboard_f();     // Scan the keyboard
    } while (( ! cpct_isAnyKeyPressed_f() ) && c > 0);
    //delay(2000);
}
示例#3
0
void credits() {
	cpct_memset(SCR_VMEM, 0, 0x4000);
	cpct_drawStringM0 ("CREDITS", getScreenPosition(6, 0), 15, 0);

	cpct_drawStringM0 ("DEVELOPERS", getScreenPosition(5, 3), 15, 0);
	cpct_drawStringM0 ("Cesar Ivorra Oliver", getScreenPosition(1, 5), 15, 0);
	cpct_drawStringM0 ("Alex Almira Molla", getScreenPosition(1, 7), 15, 0);

	cpct_drawStringM0 ("GAME POWERED BY", getScreenPosition(2, 11), 15, 0);
	cpct_drawStringM0 ("CPCtelera", getScreenPosition(5, 13), 15, 0);

	cpct_drawStringM0 ("SPECIAL THANKS", getScreenPosition(3, 18), 15, 0);
	cpct_drawStringM0 ("Francisco Gallego", getScreenPosition(1, 20), 15, 0);

	cpct_drawStringM0 ("Press Space", getScreenPosition(4, 23), 15, 0);
	cpct_drawStringM0 ("to go main menu", getScreenPosition(2, 24), 15, 0);
	cpct_scanKeyboard_f ();
	while (!cpct_isKeyPressed(Key_Space)) {
		cpct_waitVSYNC();
		cpct_akp_musicPlay();

		cpct_scanKeyboard_f ();
	}
	gameScene=MENUSCREEN;
}
示例#4
0
////////////////////////////////////////////////////////////////////////////////////////
// Wait for n VSYNCs
//
void waitNVSYNCs(u8 n) {
   do {
      cpct_waitVSYNC();
      if (--n) {
         __asm__ ("halt");
         __asm__ ("halt");
      }
   } while (n);
}
示例#5
0
/////////////////////////////////////////////////////////////////
//#############################################################//
/////////////////////////////////////////////////////////////////
// Main entry point of the application
//
void main (void) {
   // First of all, initialize the application
   initialize();

   // Main loop (repeat forever)
   while(1) {
      // Wait for VSYNC to limit actions to 60 per second
      cpct_waitVSYNC();
      
      // Check input and perform user actions
      checkUserInputAndPerformActions();
   }
}
示例#6
0
文件: main.c 项目: mattl/cpctelera
//
// EXAMPLE: Measuring free cycles after moving an sprite
//
void main(void) {
   u8  i;                        // Loop index
   u8  x=0, y=0;                 // Sprite coordinates (in bytes)
   u8* pvideomem = (u8*)0xC000;  // Sprite initial video memory byte location (where it will be drawn)
   u16 avc = 0;                  // Available cycles until next VSYNC, after all main loop calculations

   // First, disable firmware to prevent it from intercepting our palette and video mode settings (and,
   // at the same time, winning some speed not having to process firmware code at every interrupt)
   cpct_disableFirmware();
   // Set palette and Screen Border (transform firmware to hardware colours and then set them)
   cpct_fw2hw     (G_palette, 4);
   cpct_setPalette(G_palette, 4);
   cpct_setBorder (G_palette[1]);
   // Ensure MODE 1 is set
   cpct_setVideoMode(1);

   // Main Loop
   while(1) {
      // First, wait VSYNC monitor signal to synchronize the loop with it. We'll start doing
      // calculations always at the same time (when VSYNC is first detected)
      cpct_waitVSYNC();

      // Scan Keyboard and change sprite location if cursor keys are pressed
      cpct_scanKeyboard_f();
      if      (cpct_isKeyPressed(Key_CursorRight) && x <  80 - SPR_W) { x++; pvideomem++; }
      else if (cpct_isKeyPressed(Key_CursorLeft)  && x >   0        ) { x--; pvideomem--; }
      if      (cpct_isKeyPressed(Key_CursorUp)    && y >   0        ) { pvideomem -= (y-- & 7) ? 0x0800 : 0xC850; }
      else if (cpct_isKeyPressed(Key_CursorDown)  && y < 200 - SPR_H) { pvideomem += (++y & 7) ? 0x0800 : 0xC850; }

      // Draw the sprite at its new location on screen. 
      // Sprite automatically erases previous copy of itself on the screen because it moves 
      // 1 byte at a time and has a 0x00 border that overwrites previous colours on that place
      cpct_drawSprite(G_death, pvideomem, SPR_W, SPR_H);
      
      // Wait to next VSYNC signal, calculating the amount of free cycles (time we wait for VSYNC)
      // As documented on <cpct_count2VSYNC>, function returns number of loop iterations (L), and 
      // cycles shall be calculated doing 22 + 34*L
      avc = 22 + 34 * cpct_count2VSYNC();

      // Print 5 digits on the upper right corner of the screen, 
      // with the amount of free cycles calculated in previous step. 
      // Digits will be printed at screen locations (0xC046, 0xC048, 0xC04A, 0xC04C, 0xC04E)
      for(i=0; i<5; i++) {
         u8 digit = '0' + (avc % 10);
         cpct_drawCharM1_f((void*)(0xC04E - 2*i), 3, 0, digit);
         avc /= 10;
      }
   }
}
示例#7
0
文件: game.c 项目: johnlobo/Amsthrees
//////////////////////////////////////////////////////////////////
// drawMenu
//
//
//
// Returns:
//    void
//
void drawMenu() {
    u8* pvmem;

    cpct_waitVSYNC();

    cpct_memset(CPCT_VMEM_START, cpct_px2byteM0(0, 0), 0x4000);

    //Small Logo
    pvmem = cpct_getScreenPtr(CPCT_VMEM_START, 23, 0);
    cpct_drawSprite(logo_micro, pvmem, 5, 18);

    drawText("AMSTHREES", 30, 4, 0);

    // Session Highest Card
    drawText("SESSION", 1, 57, 0);
    drawText("HIGH", 5, 72, 0);
    pvmem = cpct_getScreenPtr(CPCT_VMEM_START, 7, 92);
    cpct_drawSprite(cards[highestCardAll], pvmem, CARD_W, CARD_H);

    drawFrame(23, 43, 76, 151);

    //Camelot Mode Badgae
    if (camelotMode) {
        pvmem = cpct_getScreenPtr(CPCT_VMEM_START, 80 - G_CAMELOTBADGE_W, 8);
        cpct_drawSpriteMaskedAlignedTable(g_camelotBadge, pvmem, G_CAMELOTBADGE_W, G_CAMELOTBADGE_H, am_tablatrans);
    }

    drawText("REDEFINE", 38, 60, 0);
    drawText("MUSIC", 38, 80, 0);
    if (playing)
        drawText("OFF", 56, 80, 0);
    else
        drawText("ON", 56, 80, 0);
    drawText("HELP", 38, 100, 0);
    drawText("PLAY", 38, 120, 0);

    drawNumber(1, 1, 31, 60);
    drawNumber(2, 1, 31, 80);
    drawNumber(3, 1, 31, 100);
    drawNumber(4, 1, 31, 120);


    drawText("JOHN LOBO", 25, 170, 1);
    drawText("@ GLASNOST CORP 2016", 11, 185, 1);

    drawMarker();
}
示例#8
0
/////////////////////////////////////////////////////////////////////////////////
// Draws the tilemap in a new location or with a change in its viewport.
//  The drawing is done in the backbuffer and then shown in the screen when it's
//  done, switching screen buffers just after the VSYNC
//
void drawScreenTilemap(TScreenTilemap *scr) {
   u8* ptmscr;    // Backbuffer pointer where the tilemap is to be drawn
   
   // Clear the backbuffer
   cpct_memset_f64(g_scrbuffers[1], 0x00, 0x4000);

   // Calculate the new location where the tilemap is to be drawn in
   // the backbuffer, using x, y coordinates of the tilemap
   ptmscr = cpct_getScreenPtr(g_scrbuffers[1], scr->x, scr->y);

   // Draw the viewport of the tilemap in the backbuffer (pointed by ptmscr)
   cpct_etm_drawTileBox2x4(scr->viewport.x, scr->viewport.y, 
                           scr->viewport.w, scr->viewport.h, 
                           MAP_WIDTH, ptmscr, g_tilemap);
   
   // Wait for VSYNC and change screen buffers just afterwards, 
   // to make the backbuffer show on the screen
   cpct_waitVSYNC();
   swapBuffers(g_scrbuffers);
}
示例#9
0
void controls() {
	cpct_memset(SCR_VMEM, 0, 0x4000);
	cpct_drawStringM0 ("CONTROLS", getScreenPosition(5, 3), 15, 0);

	cpct_drawStringM0 ("W: Move Up", getScreenPosition(4, 7), 15, 0);
	cpct_drawStringM0 ("S: Move Down", getScreenPosition(4, 9), 15, 0);
	cpct_drawStringM0 ("A: Move Left", getScreenPosition(4, 11), 15, 0);
	cpct_drawStringM0 ("D: Move Right", getScreenPosition(4, 13), 15, 0);

	cpct_drawStringM0 ("Press Space", getScreenPosition(4, 23), 15, 0);
	cpct_drawStringM0 ("to go main menu", getScreenPosition(2, 24), 15, 0);

	cpct_scanKeyboard_f ();
	while (!cpct_isKeyPressed(Key_Space)) {
		cpct_waitVSYNC();
		cpct_akp_musicPlay();
		cpct_scanKeyboard_f ();
	}
	// gameScene=MENUSCREEN;
	gameScene=MENUSCREEN;
}
示例#10
0
////////////////////////////////////////////////////////////////////////////////
// Plays a complete game, until the death of the main character
//
u16 game(u16 hiscore) {
   u8 alive = 1;        // Main character still alive?
   TCharacter* c;       // Pointer to main character

   // Initialize game
   initializeGameScreen(hiscore);   // Set up Game Screen
   initializeEntities();            // Set up initial entities
   c = getCharacter();              // Get the main character

   /////
   // Main Game Loop (while character is alive)
   /////
   while(alive) {
      updateUser(c);                // Update user status (depending on keypresses)
      scrollWorld();                // Update world scrolling
      alive = updateCharacter(c);   // Update character status     
      cpct_waitVSYNC();             // Wait for VSYNC and...
      drawAll();                    // ..draw everything
   }

   // Return final score, at the end of the game
   return getScore();
}
示例#11
0
文件: main.c 项目: Trewdbal/cpctelera
/////////////////////////////////////////////////////////////////////////////////
// Scrolls the tilemap, relocates pointers and draws left and right columns 
// with their new content after scrolling
//
void scrollScreenTilemap(TScreenTilemap *scr, i16 scroll) { 
   // Select leftmost or rightmost column of the tilemap to be redrawn 
   // depending on the direction of the scrolling movement made
   u8 column = (scroll > 0) ? (SCR_TILE_WIDTH-1) : (0);

   // Update pointers to tilemap drawable window, tilemap upper-left corner in video memory
   // and scroll offset
   scr->pVideo   += 2*scroll; // Video memory starts now 2 bytes to the left or to the right
   scr->pTilemap += scroll;   // Move the start pointer to the tilemap 1 tile (1 byte) to point to the drawable zone (viewport)
   scr->scroll   += scroll;   // Update scroll offset to produce scrolling

   // Wait for VSYNC before redrawing,
   cpct_waitVSYNC();
     
   // Do hardware scrolling to the present offset
   cpct_setVideoMemoryOffset(scr->scroll);    
   
   // Redraw newly appearing column (either it is left or right)
   cpct_etm_drawTileBox2x4(column, 0,         // (X, Y) Upper-left Location of the Box (column in this case) to be redrawn
                           1, MAP_HEIGHT,     // (Width, Height) of the Box (column) to be redrawn
                           MAP_WIDTH,         // Width of the full tilemap (which is wider than the screen in this case)
                           scr->pVideo,       // Pointer to the upper-left corner of the tilemap in video memory
                           scr->pTilemap);    // Pointer to the first tile of the tilemap to be drawn (upper-left corner
                                              // ... of the tilemap viewport window)

   // When scrolling to the right, erase the character (2x8) bytes that scrolls-out
   // through the top-left corner of the screen. Othewise, this pixel values will 
   // loop and appear through the bottom-down corner later on.
   // When scrolling to the left, erase the character that appears on the left, just
   // below the visible tilemap
   if (scroll > 0) 
      cpct_drawSolidBox(scr->pVideo - 2, 0, 2, 8);  // top-left scrolled-out char
   else {
      u8* br_char = cpct_getScreenPtr(scr->pVideo, 0, 4*MAP_HEIGHT);
      cpct_drawSolidBox(br_char, 0, 2, 8);  // bottom-right scrolled-out char
   }
}
示例#12
0
文件: game.c 项目: johnlobo/Amsthrees
void animate(u8 dir)
{
    u8 i, j;
    u8 *pvmem;
    u8 tempx, tempy;
    i8 shiftx = 0;
    i8 shifty = 0;
    u8 *pStartTable;  // Pointer to video memory

    pStartTable = cpct_getScreenPtr(CPCT_VMEM_START, 2, 0);

    switch (dir)    {
    case LEFT:
        shiftx = -1;
        break;
    case RIGHT:
        shiftx = 1;
        break;
    case UP:
        shifty = -1;
        break;
    case DOWN:
        shifty = 1;
        break;
    }
    //Step 1
    //Erase changed slots and print the moved card

//    for (i = 0; i < changedCards.number; i++) {
    i = 0;
    j = changedCards.number;
    cpct_waitVSYNC();
    while (i < j) {
        if ((changedCards.cards[i].x <= 3) && (changedCards.cards[i].y <= 3)) {
            tempx = changedCards.cards[i].x;
            tempy = changedCards.cards[i].y;
            cpct_waitVSYNC();
            cpct_etm_drawTileBox2x4 (2 + (tempx * 6), 1 + (tempy * 12), (CARD_W / 2), (CARD_H / 4), MAP_WIDTH, pStartTable, tmx);

            //multiply by 6 and 22 to reuse shift in next step
            pvmem = cpct_getScreenPtr(CPCT_VMEM_START, 6 + (tempx * 12) + (shiftx * 6), 4 + (tempy * 48) + (shifty * 24));
            cpct_drawSpriteMaskedAlignedTable(cards[changedCards.cards[i].prev], pvmem, CARD_W, CARD_H, am_tablatrans);
        }
        i++;
    }
    //Step 2
    //Erase moved card and print animation end for sigle movements

//  for (i = 0; i < changedCards.number; i++){
    i = 0;
    j = changedCards.number;
    cpct_waitVSYNC();
    while (i < j) {
        tempx = changedCards.cards[i].x;
        tempy = changedCards.cards[i].y;
        if ((changedCards.cards[i].x <= 3) && (changedCards.cards[i].y <= 3)) {
            cpct_waitVSYNC();
            //Restore touched tiles
            switch (dir)
            {
            case LEFT:
                cpct_etm_drawTileBox2x4 (2 + ((tempx - 1) * 6), 1 + (tempy * 12), (CARD_W), (CARD_H / 4), MAP_WIDTH, pStartTable, tmx);
                break;
            case RIGHT:
                cpct_etm_drawTileBox2x4 (2 + (tempx * 6), 1 + (tempy * 12), (CARD_W), (CARD_H / 4), MAP_WIDTH, pStartTable, tmx);
                break;
            case UP:
                cpct_etm_drawTileBox2x4 (2 + (tempx * 6), 1 + ((tempy - 1) * 12), (CARD_W / 2), (CARD_H / 2), MAP_WIDTH, pStartTable, tmx);
                break;
            case DOWN:
                cpct_etm_drawTileBox2x4 (2 + (tempx * 6), 1 + (tempy * 12), (CARD_W / 2), (CARD_H / 2), MAP_WIDTH, pStartTable, tmx);
                break;
            }
        }
        cpct_waitVSYNC();
        //If no upgrade is necessary, print card in final position
        //if (changedCards.cards[i].prev == changedCards.cards[i].post) {
        pvmem = cpct_getScreenPtr(CPCT_VMEM_START, 6 + (tempx * 12) + (shiftx * 12), 4 + (tempy * 48) + (shifty * 48));
        cpct_drawSpriteMaskedAlignedTable(cards[changedCards.cards[i].post], pvmem, CARD_W, CARD_H, am_tablatrans);
        //}
        i++;

    }
    //Print next card
    pvmem = cpct_getScreenPtr(CPCT_VMEM_START, 63, 18);
    cpct_drawSprite(cards[cardBag[currentCard]], pvmem, CARD_W, CARD_H);

}
示例#13
0
文件: main.c 项目: amm297/amstrad
/*JUEGO*/
void game(){
  u8 atkObj = 0;

  initVariables(1);
  initPlayer(map);
  initNivel();
  initEnemies(map);

   cpct_clearScreen(0);
   drawMap(map);
   while (1){
    if(finish == 1) return;
    //Esperar el retrazado
    cpct_waitVSYNC();

    //Desdibujar personajes
    erases();

    //Dibujar pickups
    if(temp == 10)
        drawPickUps(n.corazon,n.bullet);

    //Dibujar personajes
    draws();

    //Dibujar fatiga
    if(temp == 10){
        if(player.atk < 20) drawFatiga(player.atk,2);
        else if(player.atk > 20) drawFatiga(player.atk,1);
        else drawFatiga(player.atk,0);
    }
    //guardar datos anteriores
    if(temp%2 == 0){
        player.lx = player.x;
        player.ly = player.y;
    }

    if(enemy.life > 0){
        if(temp%2 == 1){
            enemy.lx = enemy.x;
            enemy.ly = enemy.y;
        }

       move();
        switch(checkCollisions(player.x, player.y, enemy.x, enemy.y, player.atk)){
          case 1:
            erase(enemy.lx,enemy.ly,0);
            enemy.x = enemy.ox;
            enemy.y = enemy.oy;
            enemy.lx = enemy.x;
            enemy.ly = enemy.y;
            enemy.ox = originse[map-1][4];
            enemy.oy = originse[map-1][5];
            enemy.life -= 1;
            player.atk = 20;
            enemy.pursue = 0;
            break;
          case 2:
            erase(player.lx,player.ly,0);
            player.x =originsp[map-1][0];
            player.y = originsp[map-1][1];
            player.lx =originsp[map-1][0];
            player.ly = originsp[map-1][1];
            player.life -= 1;
            player.atk = 20;
            enemy.pursue = 0;
            break;
        }
    }
    if(temp > 10)
        temp = 0;
    temp += 1;
    player.latk = player.atk;
      //Comprobar teclado
      cpct_scanKeyboard_f();
      player.sprite = checkKeyboard();
      checkBoundsCollisions(&n.corazon,&n.bullet);

      if(arrow == 1){
        moveObject();
        bound = checkArrowCollisions();
        if(object.dir == 2 || object.dir == 8)
            atkObj = 21;
        else
            atkObj = 22;
       if(enemy.life > 0 && checkCollisions(object.x, object.y, enemy.x, enemy.y, atkObj) == 1 && bound == 0){
         enemy.life -= 1;
         erase(enemy.lx,enemy.ly,0);
         enemy.x = enemy.ox;
         enemy.y = enemy.oy;
         enemy.lx = enemy.x;
         enemy.ly = enemy.y;
         enemy.pursue = 0;
         object.vivo = 0;
         bound = 1;
       }
      }
      
      if(player.life == 0){
        gameOver();
        finish = 1;
      } 
      

   }
}
示例#14
0
////////////////////////////////////////////////////////////////////////
// MAIN: Arkos Tracker Music Example
//    Keys:
//       * SPACE - Start / Stop Music
//       *   1   - Play a sound effect on Channel A
//       *   2   - Play a sound effect on Channel C
//
void main(void) {
   TKeyStatus k_space, k_0, k_1;    // Status of the 3 Keys for this example (Space, 1, 2)
   u8  playing   = 1;               // Flag to know if music is playing or not
   u8  color     = 1;               // Color to draw charactes (normal / inverse)
   u8* pvideomem = CPCT_VMEM_START; // Pointer to video memory where next character will be drawn

   // All 3 keys are considered to be released at the start of the program
   k_space = k_0 = k_1 = K_RELEASED;

   // Initialize CPC
   cpct_disableFirmware(); // Disable firmware to prevent interaction
   cpct_setVideoMode(2);   // Set Mode 2 (640x200, 2 colours)

   // Initialize the song to be played
   cpct_akp_musicInit(molusk_song);    // Initialize the music
   cpct_akp_SFXInit(molusk_song);      // Initialize instruments to be used for SFX (Same as music song)

   while (1) {
      // We have to call the play function 50 times per second (because the song is 
      // designed at 50Hz). We only have to wait for VSYNC and call the play function
      // when the song is not stopped (still playing)
      cpct_waitVSYNC();

      // Check if the music is playing. When it is, do all the things the music
      // requires to be done every 1/50 secs.
      if (playing) {
         cpct_akp_musicPlay();   // Play next music 1/50 step.

         // Write a new number to the screen to see something while playing. 
         // The number will be 0 when music is playing, and 1 when it finishes.
         //  -> If some SFX is playing write the channel where it is playing
         
         // Check if there is an instrument plaing on channel A
         if (cpct_akp_SFXGetInstrument(AY_CHANNEL_A))
            cpct_drawCharM2(pvideomem, color, 'A'); // Write an 'A' because channel A is playing
         
         // Check if there is an instrument plaing on channel C
         else if (cpct_akp_SFXGetInstrument(AY_CHANNEL_C))
            cpct_drawCharM2(pvideomem, color, 'C'); // Write an 'C' because channel A is playing 
         
         // No SFX is playing on Channels A or C, write the number of times
         // this song has looped.
         else
            cpct_drawCharM2(pvideomem, color, '0' + cpct_akp_songLoopTimes);

         // Point to the start of the next character in video memory
         if (++pvideomem >= (u8*)0xC7D0) {
            pvideomem = CPCT_VMEM_START; // When we reach the end of the screen, we return..
            color ^= 1;                  // .. to the start, and change the colour
         }

         // Check if music has already ended (when looptimes is > 0)
         if (cpct_akp_songLoopTimes > 0)
            cpct_akp_musicInit(molusk_song); // Song has ended, start it again and set loop to 0
      }

      // Check keyboard to let the user play/stop the song with de Space Bar
      // and reproduce some sound effects with keys 1 and 0
      cpct_scanKeyboard_f();

      // When Space is released, stop / continue music
      if ( checkKeyEvent(Key_Space, &k_space) == K_RELEASED ) {
         // Only stop it when it was playing previously
         // No need to call "play" again when continuing, as the
         // change in "playing" status will make the program call "play"
         // again from the next cycle on
         if (playing)
            cpct_akp_stop();
         
         // Change it from playing to not playing and viceversa (0 to 1, 1 to 0)
         playing ^= 1;

      // Check if Key 0 has been released to reproduce a Sound effect on channel A
      } else if ( checkKeyEvent(Key_0, &k_0) == K_RELEASED ) {
         cpct_akp_SFXPlay(13, 15, 36, 20, 0, AY_CHANNEL_A);

      // Check if Key 1 has been released to reproduce a Sound effect on channel C
      } else if ( checkKeyEvent(Key_1, &k_1) == K_RELEASED ) 
         cpct_akp_SFXPlay(3, 15, 60, 0, 40, AY_CHANNEL_C);
   }
}