#include #include #include "ships.h" // Ship Bitmaps #include "display.h" // Display Tools. #include "global.h" // Global Game Specification #include "ports.h" // Port Specifications #pragma regalloc- int lineCount; // The current scanline number to be outputed. char syncOn; // The output for video out when sync is ON. char syncOff; // The output for video out when sync is OFF. char _flags; // Flags for Display.c int zoomXIndex; // Zoom X Index. int zoomYIndex; // Zoom Y Index. /** Bit Mask for rendering ships across 2 registers **/ flash char _shipBitMask[8] = {0xFE,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01}; flash char _shipBitMask2[8] = {0x0,0x0,0x80,0xC0,0xE0,0xF0,0xF8,0xFC}; flash char _bulletBitMask[8] = {0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01}; flash char _bulletBitMask2[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0}; // Store the vertical coordinates of the bitmap - bits: minX, minY signed char shipCoords[NUM_PLAYERS][4]; // Store bullet information. signed char bulletCoords[NUM_PLAYERS * MAX_BULLETS][4]; // Store explosion information. signed char explodeCoords[NUM_PLAYERS * MAX_BULLETS][3]; // Store the total number of bullets. char numBullets1, numBullets2; // Store the total number of explosions. char numExplosions; // Screen Buffer char screen[1600]; // Zoom Flag as to whether we are zooming. char zoom; #pragma regalloc+ // Interrupt 1 Handler - draws one line of the raster and syncs. // It MUST be entered from sleep mode to get accurate timing of the sync pulses. interrupt [TIM1_COMPA] void drawRaster(void) { // Start the horizontal sync pulse. VIDEO_PORT = syncOn; // Update current scanline number. lineCount++; // Start generating vertical (inverted) sync after line 247 for 3 lines. if (lineCount == 248) { syncOn = _DISP_LOW; syncOff = _DISP_SYNC; } // Return to regular sync after line 250.bgg if (lineCount == 251) { syncOn = _DISP_SYNC; syncOff = _DISP_LOW; } // Start a new frame after line 262. if (lineCount == 263) lineCount = 1; delay_us(2); // End the horizontal sync pulse. VIDEO_PORT = syncOff; // Output a line onto the screen if (lineCount < _DISP_SCREEN_BOTTOM && lineCount >= _DISP_SCREEN_TOP) { if (zoom) { //compute byte idex for beginning of the next line //left-shift 4 would be individual lines // <<3 means line-double the pixels //The 0xfff8 truncates the odd line bit //i=(LineCount-ScreenTop + Zoom)<<3 & 0xfff0; // #asm push r12 push r13 push r14 push r15 push r16 push r17 push r18 push r19 lds r12, _lineCount lds r13, _lineCount+1 ldi r16, 30 sub r12, r16 ldi r16,0 sbc r13, r16 ; + Zoom lds r18, _zoomYIndex lds r19, _zoomYIndex+1 lsl r18 rol r19 lsl r18 rol r19 add r12, r18 adc r13, r19 lsl r12 rol r13 lsl r12 rol r13 mov r16,r12 andi r16,0xf0 mov r12,r16 ; + Zoom lds r18, _zoomXIndex lds r19, _zoomXIndex+1 add r12, r18 adc r13, r19 ; load 8 registers with screen info push r26 push r27 ldi r26,low(_screen) ;base address of the current line ldi r27,high(_screen) add r26,r12 ;offset into screen (add i) adc r27,r13 ld r4,x+ ;load 16 registers and inc pointer ld r5,x+ ld r6,x+ ld r7,x+ ld r8,x+ ld r9,x+ ld r10,x+ ld r11,x pop r27 pop r26 #endasm delay_us(4); //blast 16 bytes to the screen #asm ;but first a macro to make the code shorter ;the macro takes a register number as a parameter ;and dumps its bits serially to portD.6 ;the nop can be eliminated to make the display narrower .macro videobitsZoom ;regnum BST @0,7 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,7 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,6 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,6 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,5 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,5 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,4 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,4 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,3 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,3 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,2 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,2 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,1 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,1 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,0 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,0 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 .endm videobitsZoom r4 ;video line -- byte 1 videobitsZoom r5 ;byte 2 videobitsZoom r6 ;byte 3 videobitsZoom r7 ;byte 4 videobitsZoom r8 ;byte 5 videobitsZoom r9 ;byte 6 videobitsZoom r10 ;byte 7 videobitsZoom r11 ;byte 8 clt ;clear video after the last pixel on the line IN R30,0x12 BLD R30,6 OUT 0x12,R30 pop r19 pop r18 pop r17 pop r16 pop r15 pop r14 pop r13 pop r12 #endasm } else { //compute byte idex for beginning of the next line //left-shift 4 would be individual lines // <<3 means line-double the pixels //The 0xfff8 truncates the odd line bit //i=(LineCount-ScreenTop)<<3 & 0xfff8; // #asm push r16 lds r12, _LineCount lds r13, _Linecount+1 ldi r16, 30 sub r12, r16 ldi r16,0 sbc r13, r16 lsl r12 rol r13 lsl r12 rol r13 lsl r12 rol r13 mov r16,r12 andi r16,0xf0 mov r12,r16 pop r16 #endasm //load 16 registers with screen info #asm push r14 push r15 push r16 push r17 push r18 push r19 push r26 push r27 ldi r26,low(_screen) ;base address of the current line ldi r27,high(_screen) add r26,r12 ;offset into screen (add i) adc r27,r13 ld r4,x+ ;load 16 registers and inc pointer ld r5,x+ ld r6,x+ ld r7,x+ ld r8,x+ ld r9,x+ ld r10,x+ ld r11,x+ ld r12,x+ ld r13,x+ ld r14,x+ ld r15,x+ ld r16,x+ ld r17,x+ ld r18,x+ ld r19,x pop r27 pop r26 #endasm delay_us(4); //blast 16 bytes to the screen #asm ;but first a macro to make the code shorter ;the macro takes a register number as a parameter ;and dumps its bits serially to portD.6 ;the nop can be eliminated to make the display narrower .macro videobits ;regnum BST @0,7 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,6 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,5 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,4 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,3 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,2 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,1 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 BST @0,0 IN R30,0x12 BLD R30,6 nop OUT 0x12,R30 .endm videobits r4 ;video line -- byte 1 videobits r5 ;byte 2 videobits r6 ;byte 3 videobits r7 ;byte 4 videobits r8 ;byte 5 videobits r9 ;byte 6 videobits r10 ;byte 7 videobits r11 ;byte 8 videobits r12 ;byte 9 videobits r13 ;byte 10 videobits r14 ;byte 11 videobits r15 ;byte 12 videobits r16 ;byte 13 videobits r17 ;byte 14 videobits r18 ;byte 15 videobits r19 ;byte 16 clt ;clear video after the last pixel on the line IN R30,0x12 BLD R30,6 OUT 0x12,R30 pop r19 pop r18 pop r17 pop r16 pop r15 pop r14 #endasm } } } /** * Zoom Mode Enable. * @param x The horizontal coordinate for top left corner of zoom. * @param y The vertical coordinate for top left corner of zoom. * @returns Whether zoom was successful. (0 if unsuccessful). */ char zoomEnable (char x, char y) { // We zoom by a factor of 2, which means that to left corner must be // 64 and y must be less than 50 if (x <= 64 && y <= 50) { zoom = 42; zoomXIndex = x >> 3; zoomYIndex = y; } return zoom; } /** * returns whether we are in zoom mode. */ char isZoomed() { return zoom; } /** * Zoom Mode Disable. */ void zoomDisable () { zoom = 0; } /** * Draws ship for player on screen. * @param x The horizontal coordinate for the center of the ship. * @param y The vertical coordinate for the center of the ship. * @param theta The angle of ship's orientation (0 to NUM_ANGLES - 1) * @param type The ship type. * @param player The player number 0 or 1. */ void drawShip(char x, char y, char theta, char type, char player) { #ifdef _DEBUG_ // Check to make sure ship is correct. if ( (signed char) x < 0 || (signed char)x >= 128 || (signed char)y < 0 || (signed char)y >= 100) { x = 50; y = 50; _flags |= RENDER_ERROR; } #endif // Change player to 0 or 1. eraseShip(player); // Store the coordinates shipCoords[player][0] = x - NUM_SHIP_LINES * 0.5; shipCoords[player][1] = y - NUM_SHIP_LINES * 0.5; shipCoords[player][2] = type; shipCoords[player][3] = theta >> 5; // Enforce that we draw the ship. _flags |= (player)?RENDER_SHIP_2:RENDER_SHIP_1; } /** * Erases the ship from screen. * @param player The player number 0 or 1. */ void eraseShip(char player) { // Temporary Variables register int index; // Index of screen buffer to which we are drawing register char mask,mask2; // Mask of first and second char in drawing of ship register signed char xCoord,yCoord; // X of the top left corner. register int minIndex,maxIndex; // Draw Ship 0. xCoord = shipCoords[player][0]; yCoord = shipCoords[player][1]; // Patch for negative coordinates - since xCoord>>3 should be 0, if x is negative. // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + ((xCoord) >> 3); // Calculate the minimum index. minIndex = (yCoord >= 0)?index:xCoord >> 3; maxIndex = ((int)yCoord + NUM_SHIP_LINES < _DISP_HEIGHT)?index + 96:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of ship. // In order to get pixel accuracy, we might have to map to 2 chars. mask = ~_shipBitMask[xCoord]; mask2 = ~_shipBitMask2[xCoord]; // Check for boundary conditions. if (shipCoords[player][0] < 0) { // Left edge of the screen for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. screen[index + 1] &= mask2; } } else if (shipCoords[player][0] > 127 - NUM_SHIP_LINES) { for (index = minIndex; index <= maxIndex; index += 16) { // Right edge of the screen. screen[index] &= mask; } } else { for (index = minIndex; index <= maxIndex; index += 16) { screen[index] &= mask; screen[index+1] &= mask2; } } } /** * Renders the ships on the screen. Must be called every frame. */ void renderShip() { // Temporary Variables register int index; // Index of screen buffer to which we are drawing register char mask,mask2; // Mask of first and second char in drawing of ship register signed char xCoord, yCoord; // X Coord of the top left corner. register char draw; // Bit map we're drawing. register char type,orientation; // Store the type of ship and orientation. register int minIndex,maxIndex; // min and max index for drawing register char i; // Temporary Variable if (_flags & RENDER_SHIP_1) { // Draw Ship 0. // Get the coordinates of top left corner of ship. xCoord = shipCoords[0][0]; yCoord = shipCoords[0][1]; // Get orientation and type of ship. type = shipCoords[0][2]; orientation = shipCoords[0][3]; // Patch for negative coordinates - since xCoord>>3 should be 0, if x is negative. // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + (xCoord >> 3); // Calculate the minimum index. minIndex = (yCoord >= 0)?index:(xCoord >> 3); maxIndex = ((int)yCoord + NUM_SHIP_LINES < _DISP_HEIGHT)?index + 96:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of ship. // In order to get pixel accuracy, we might have to map to 2 chars. mask = _shipBitMask[xCoord & 7]; mask2 = _shipBitMask2[xCoord & 7]; // Starting bitmap index for ship i = (minIndex - index) >> 4; // Check for boundary conditions. if (shipCoords[0][0] < 0) { // Left edge of the screen for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = shipBitmaps[type][orientation][i]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index +1] = screen[index + 1] & ~mask2 | draw & mask2; i++; } } else if (shipCoords[0][0] > 127 - NUM_SHIP_LINES) { for (index = minIndex; index <= maxIndex; index += 16) { // Right edge of the screen. // Get bitmap from flash, rotate it and apply it to our screen. draw = shipBitmaps[type][orientation][i]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = screen[index] & ~mask | draw & mask; i++; } } else { for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = shipBitmaps[type][orientation][i]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = screen[index] & ~mask | draw & mask; screen[index+1] = screen[index + 1] & ~mask2 |draw & mask2; i++; } } // Clear the Render Flag. _flags &= ~(RENDER_SHIP_1); } if (_flags & RENDER_SHIP_2) { // Draw Ship 1. // Get the coordinates of top left corner of ship. xCoord = shipCoords[1][0]; yCoord = shipCoords[1][1]; // Get orientation and type of ship. type = shipCoords[1][2]; orientation = shipCoords[1][3]; // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + ((xCoord) >> 3); // Calculate the minimum index. minIndex = (yCoord >= 0)?index:xCoord >> 3; maxIndex = ((int)yCoord + NUM_SHIP_LINES < _DISP_HEIGHT)?index + 96:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of ship. // In order to get pixel accuracy, we might have to map to 2 chars. mask = _shipBitMask[xCoord]; mask2 = _shipBitMask2[xCoord]; // Starting bitmap index for ship i = (minIndex - index) >> 4; // Check for boundary conditions. if (shipCoords[1][0] < 0) { // Left edge of the screen for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = shipBitmaps[type][orientation][i]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index+1] = screen[index + 1] & ~mask2 | draw & mask2; i++; } } else if (shipCoords[1][0] > 128 - NUM_SHIP_LINES) { for (index = minIndex; index <= maxIndex; index += 16) { // Right edge of the screen. // Get bitmap from flash, rotate it and apply it to our screen. draw = shipBitmaps[type][orientation][i]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = screen[index] & ~mask | draw & mask; i++; } } else { for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = shipBitmaps[type][orientation][i]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = screen[index] & ~mask | draw & mask; screen[index+1] = screen[index + 1] & ~mask2 |draw & mask2; i++; } } // Clear the Render Flag. _flags &= ~(RENDER_SHIP_2); } } /** * Draw Bullet on screen * @param x The horizontal coordinate for the center of the bullet. * @param y The vertical coordinate for the center of the bullet. * @param theta The angle of bullet's orientation. * @param type The type of bullet. * @param player The player who fired the bullet. */ void drawBullet(char x, char y, char theta, char type, char player) { // Check for valid coords. #ifdef _DEBUG_ if (x >= 128 || y >= 100) { x = 50; y = 50; _flags |= RENDER_ERROR; } #endif // Player 1 bullets are stored from index 0 -> MAX_BULLETS - 1. // Player 2 bullets are stored from index MAX_BULLETS - 1 -> MAX_BULLETS * 2 - 1 if (player == 0) { // Store the coordinates bulletCoords[numBullets1][0] = x - NUM_BULLET_LINES * 0.5; bulletCoords[numBullets1][1] = y - NUM_BULLET_LINES * 0.5; bulletCoords[numBullets1][2] = type; bulletCoords[numBullets1][3] = theta >> 5; numBullets1++; } else if (player == 1) { bulletCoords[(char)(numBullets2 + MAX_BULLETS)][0] = x - NUM_BULLET_LINES * 0.5; bulletCoords[(char)(numBullets2 + MAX_BULLETS)][1] = y - NUM_BULLET_LINES * 0.5; bulletCoords[(char)(numBullets2 + MAX_BULLETS)][2] = type; bulletCoords[(char)(numBullets2 + MAX_BULLETS)][3] = theta >> 5; numBullets2++; } // Enforce that we draw the ship. _flags |= RENDER_BULLET; } /** * Erase the bullets from screen of the given player. * @param player The player who fired the bullets. */ void eraseBullets(char player) { char i; // Temporary Variables register int index; // Index of screen buffer to which we are drawing register char mask,mask2; // Mask of first and second char in drawing of ship register signed char xCoord, yCoord; // X and Y Coord of the top left corner. register int minIndex,maxIndex; // min and max index for drawing register char maxBullets; // Max index of bullets // Calculate index and offset maxBullets = (player)?MAX_BULLETS + numBullets2:numBullets1; i = (player)?MAX_BULLETS:0; // Erase each bullet. for (; i < maxBullets; i++) { // X, Y Coordinate for bullet to be erased. xCoord = bulletCoords[i][0]; yCoord = bulletCoords[i][1]; // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + ((xCoord) >> 3); // Calculate the minimum index. minIndex = (yCoord >= 0)?index:xCoord >> 3; maxIndex = ((int)yCoord + NUM_BULLET_LINES < _DISP_HEIGHT)?index + 32:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of ship. // In order to get pixel accuracy, we might have to map to 2 chars. mask = ~_bulletBitMask[xCoord]; mask2 = ~_bulletBitMask2[xCoord]; // Check for boundary conditions. if (bulletCoords[i][0] < 0) { // Left edge of the screen for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. screen[index+1] &= mask2; } } else if (bulletCoords[i][0] > 127 - NUM_SHIP_LINES) { for (index = minIndex; index <= maxIndex; index += 16) { // Right edge of the screen. screen[index] &= mask; } } else { for (index = minIndex; index <= maxIndex; index += 16) { screen[index] &= mask; screen[index+1] &= mask2; } } } // Clear numBullets. if (player) numBullets2 = 0; else numBullets1 = 0; } /** * Render all the bullets. * @param player The player to render bullets */ void renderBullets(char player) { // Temporary Variables char i,j; // for-loop index register int index; // Index of screen buffer to which we are drawing register char mask,mask2; // Mask of first and second char in drawing of ship register signed char xCoord, yCoord; // X and Y coord of the top left corner. register char draw; // Bit map we're drawing. register char type,orientation; // Store the type of ship and orientation. register int minIndex,maxIndex; // min and max index for drawing register char maxBullets; // Calculate index and offset maxBullets = (player)?MAX_BULLETS + numBullets2:numBullets1; i = (player)?MAX_BULLETS:0; // If we have bullets to draw. if (_flags & RENDER_BULLET) { // Render each bullet. for (; i < maxBullets; i++) { // Get the coordinates of top left corner of bullet. xCoord = bulletCoords[i][0]; yCoord = bulletCoords[i][1]; // Get orientation and type of ship. type = bulletCoords[i][2]; orientation = bulletCoords[i][3]; // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + ((xCoord) >> 3); // Calculate the minimum and maximum index. minIndex = (yCoord >= 0)?index:xCoord >> 3; maxIndex = ((int)yCoord + NUM_BULLET_LINES < _DISP_HEIGHT)?index + 32:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of bullet. // In order to get pixel accuracy, we might have to map to 2 chars. mask = _bulletBitMask[xCoord]; mask2 = _bulletBitMask2[xCoord]; // Starting bitmap index for ship j = (minIndex - index) >> 4; // Check for boundary conditions. if (bulletCoords[i][0] < 0) { // Left edge of the screen for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = bulletBitmaps[type][orientation][j]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index+1] = draw & mask2; j++; } } else if (bulletCoords[i][0] > 128 - NUM_SHIP_LINES) { for (index = minIndex; index <= maxIndex; index += 16) { // Right edge of the screen. // Get bitmap from flash, rotate it and apply it to our screen. draw = bulletBitmaps[type][orientation][j]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = draw & mask; j++; } } else { for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = bulletBitmaps[type][orientation][j]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = draw & mask; screen[index+1] = draw & mask2; j++; } } } // Clear the Render Flag. _flags &= ~(RENDER_BULLET); } } /** * Draw Explosion on screen * @param x The horizontal coordinate for the center of the explosion. * @param y The vertical coordinate for the center of the explosion. * @param type The type of explosion effect (Frame #). */ void drawExplosion(char x, char y, char type) { #ifdef _DEBUG_ // Check to see we're getting valid coordinates if (x >= 128 || y >= 100) { x = 50; y = 50; _flags |= RENDER_ERROR; } #endif // Store the coordinates explodeCoords[numExplosions][0] = x - NUM_EXPLODE_LINES * 0.5; explodeCoords[numExplosions][1] = y - NUM_EXPLODE_LINES * 0.5; explodeCoords[numExplosions][2] = type; numExplosions++; // Enforce that we draw the ship. _flags |= RENDER_EXPLODE; } /** * Erase the all the explosions from screen. */ void eraseExplosions() { char i; // Temporary Variables register int index; // Index of screen buffer to which we are drawing register char mask,mask2; // Mask of first and second char in drawing of exp. register signed char xCoord, yCoord; // X and Y Coord of the top left corner. register int minIndex,maxIndex; // min and max index for drawing // Erase each bullet. for (i = 0; i < numExplosions; i++) { // X, Y Coordinate for bullet to be erased. xCoord = explodeCoords[i][0]; yCoord = explodeCoords[i][1]; // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + ((xCoord) >> 3); // Calculate the minimum index. minIndex = (yCoord >= 0)?index:(xCoord >> 3); maxIndex = ((int)yCoord + NUM_SHIP_LINES < _DISP_HEIGHT)?index + 96:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of ship. // In order to get pixel accuracy, we might have to map to 2 chars. mask = ~_shipBitMask[xCoord]; mask2 = ~_shipBitMask2[xCoord]; // Check for boundary conditions. if (explodeCoords[i][0] < 0) { // Left edge of the screen for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. screen[index+1] &= mask2; } } else if (explodeCoords[i][0] > 127 - NUM_SHIP_LINES) { for (index = minIndex; index <= maxIndex; index += 16) { // Right edge of the screen. screen[index] &= mask; } } else { for (index = minIndex; index <= maxIndex; index += 16) { screen[index] &= mask; screen[index+1] &= mask2; } } } numExplosions = 0; } /** * Render all the explosions. */ void renderExplosions() { // Temporary Variables char i,j; // for-loop index register int index; // Index of screen buffer to which we are drawing register char mask,mask2; // Mask of first and second char in drawing of ship register signed char xCoord, yCoord; // X and Y coord of the top left corner. register char draw; // Bit map we're drawing. register char type; // Store the type of ship and orientation. register int minIndex,maxIndex; // min and max index for drawing // If we have bullets to draw. if (_flags & RENDER_EXPLODE) { // Render each bullet. for (i = 0; i < numExplosions; i++) { // Get the coordinates of top left corner of bullet. xCoord = explodeCoords[i][0]; yCoord = explodeCoords[i][1]; // Get orientation and type of ship. type = explodeCoords[i][2]; // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + ((xCoord) >> 3); // Calculate the minimum and maximum index. minIndex = (yCoord >= 0)?index:xCoord >> 3; maxIndex = ((int)yCoord + NUM_SHIP_LINES < _DISP_HEIGHT)?index + 96:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of bullet. // In order to get pixel accuracy, we might have to map to 2 chars. mask = _shipBitMask[xCoord]; mask2 = _shipBitMask2[xCoord]; // Starting bitmap index for ship j = (minIndex - index) >> 4; // Check for boundary conditions. if (explodeCoords[i][0] < 0) { // Left edge of the screen for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = explodeBitmaps[type][j]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index+1] = draw & mask2; j++; } } else if (explodeCoords[i][0] > 128 - NUM_SHIP_LINES) { for (index = minIndex; index <= maxIndex; index += 16) { // Right edge of the screen. // Get bitmap from flash, rotate it and apply it to our screen. draw = explodeBitmaps[type][j]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = draw & mask; j++; } } else { for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = explodeBitmaps[type][j]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = draw & mask; screen[index+1] = draw & mask2; j++; } } } // Clear the Render Flag. _flags &= ~(RENDER_EXPLODE); } } /** * Draw Planet on Screen. */ void drawPlanet() { _flags &= RENDER_PLANET; } /** * Render the Planet. drawPlanet call is required. */ void renderPlanet() { // Temporary index variable. char i; int index; // Index of screen unsigned char draw; // Bitmap of current line being drawn. if (1){//_flags & RENDER_PLANET) { /** Planet is at center of screen. => @ X:60-68 Y:46-54*/ index = 46 * 16 + 7; for (i = 0; i < NUM_PLANET_LINES; i++) { draw = planetBitmap[i]; // Since center scales over 2 registers, we have to rotate it. screen[index] = draw; index += 16; } // Clear the Render Flag. _flags &= ~(RENDER_PLANET); } } /** * Initalize Display Parameters */ void initializeDisplay() { // Turn off all flags _flags = 0; // Initialize Zoom zoom = 0; // Initialzie Bullet Counters numBullets1 = 0; numBullets2 = 0; } /** * Clears the screen. - Might be slow. */ void clearScreen() { int i; for (i = 0; i < 1600; i++) screen[i] = 0; } /** * Draw a Big Ship @ (x,y) - Top Left Corner. * @param xCoord Top Left x-coordinates * @param yCoord Top Left y-coordinates. * @param type The ship type */ void drawBigShips(signed char x, signed char y, char type) { char orientation = 1; // Default Orientation char i; // for-loop index register int index; // Index of screen buffer to which we are drawing register char mask,mask2; // Mask of first and second char in drawing of ship register signed char xCoord, yCoord; // X and Y Coordinates register char draw; // Bit map we're drawing. register int minIndex,maxIndex; // min and max index for drawing xCoord = x; yCoord = y; // Get the index of screen buffer to which we are drawing index = (((int)yCoord) << 4) + ((xCoord) >> 3); // Calculate the minimum index. minIndex = (yCoord >= 0)?index:xCoord >> 3; maxIndex = ((int)yCoord + NUM_SHIP_LINES < _DISP_HEIGHT)?index + 96:MAX_SCREEN_LINE|(xCoord >> 3); // Get the x offset within one char of the buffer. xCoord = xCoord & 7; // Get Mask of first char and second char in drawing of ship. // In order to get pixel accuracy, we might have to map to 2 chars. mask = _shipBitMask[xCoord]; mask2 = _shipBitMask2[xCoord]; // Starting bitmap index for ship i = (minIndex - index) >> 4; // Check for boundary conditions. for (index = minIndex; index <= maxIndex; index += 16) { // Get bitmap from flash, rotate it and apply it to our screen. draw = shipBitmaps[type][orientation][i]; draw = (draw >> (xCoord)) | (draw << (8 - xCoord)); screen[index] = draw & mask; screen[index+1] = draw & mask2; i++; } }