////////////////////////////////////////////////////////////////////////////// // 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(); } }
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); }
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; }
//////////////////////////////////////////////////////////////////////////////////////// // Wait for n VSYNCs // void waitNVSYNCs(u8 n) { do { cpct_waitVSYNC(); if (--n) { __asm__ ("halt"); __asm__ ("halt"); } } while (n); }
///////////////////////////////////////////////////////////////// //#############################################################// ///////////////////////////////////////////////////////////////// // 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(); } }
// // 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; } } }
////////////////////////////////////////////////////////////////// // 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(); }
///////////////////////////////////////////////////////////////////////////////// // 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); }
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; }
//////////////////////////////////////////////////////////////////////////////// // 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(); }
///////////////////////////////////////////////////////////////////////////////// // 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 } }
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); }
/*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; } } }
//////////////////////////////////////////////////////////////////////// // 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); } }