//////////////////////////////////////////////////////////////////////////////////////// // MAIN PROGRAM: move a sprite over a background // void main(void) { // One alien that will move bouncing through the screen static const TAlien sa = {0, 0, 1, 1}; TAlien* a = (TAlien*)&sa; // Initialize screen, palette and background initialization(); // // Main loop: Moves the sprite left-to-right and vice-versa // while(1) { u8* pscra; // Pointer to the screen location to draw the alien // Check if sprite is going to got out the screen and produce bouncing in its case if (a->vx < 0) { if (a->tx < -a->vx) a->vx = 1; } else if (a->tx + a->vx + ALIEN_WIDTH_TILES >= MAP_WIDTH_TILES) a->vx = -1; if (a->vy < 0) { if (a->ty < -a->vy) a->vy = 1; } else if (a->ty + a->vy + ALIEN_HEIGHT_TILES >= MAP_HEIGHT_TILES) a->vy = -1; // Wait for VSYNC before drawing to the screen to reduce flickering // We also wait for several VSYNC to make it move slow, or it will be too fast waitNVSYNCs(2); // Redraw a tilebox over the alien to erase it (redrawing background over it) cpct_etm_drawTileBox2x4(a->tx, a->ty, ALIEN_WIDTH_TILES, ALIEN_HEIGHT_TILES, MAP_WIDTH_TILES, CPCT_VMEM_START, g_background); // Move the alien and calculate it's new location on screen a->tx += a->vx; a->ty += a->vy; pscra = cpct_getScreenPtr(CPCT_VMEM_START, TILEWIDTH_BYTES*a->tx, TILEHEIGHT_BYTES*a->ty); // Draw the alien in its new location cpct_drawSpriteMaskedAlignedTable(g_alien, pscra, ALIEN_WIDTH_BYTES, ALIEN_HEIGHT_BYTES, g_masktable); } }
///////////////////////////////////////////////////////////////////////////////// // 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); }
///////////////////////////////////////////////////////////////////////////////// // Machine initialization code // void initialize_CPC() { // Initialize the application cpct_disableFirmware(); // Firmware must be disabled for this application to work cpct_setVideoMode(0); // Set Mode 0 (160x200, 16 Colours) cpct_setPalette(g_palette, 13); // Set Palette cpct_setBorder(HW_BLACK); // Set the border and background colours to black // VERY IMPORTANT: Before using EasyTileMap functions (etm), the internal // pointer to the tileset must be set. cpct_etm_setTileset2x4(g_tileset); // Clean up the screen cpct_memset(CPCT_VMEM_START, 0x00, 0x4000); // Draw the full tilemap for the first time cpct_etm_drawTileBox2x4(0, 0, // (X, Y) upper-left corner of the tilemap SCR_TILE_WIDTH, MAP_HEIGHT, // (Width, Height) of the Box to be drawn (all the screen) MAP_WIDTH, // Width of the full tilemap (which is wider than the screen) CPCT_VMEM_START, // Pointer to the start of video memory (upper-left corner of the // ...tilemap in the screen) g_tilemap); // Pointer to the first tile of the tilemap to be drawn (upper-left // ... corner of the tilemap viewport window) }
///////////////////////////////////////////////////////////////////////////////// // 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); }