|
to return to the last page click here
#include <stdlib.h> #include <stdio.h> #include "font.h"
//some useful colors #define BLACK 0x0000 #define WHITE 0xFFFF #define BLUE 0xEE00 #define CYAN 0xFF00 #define GREEN 0x0EE0 #define RED 0x00FF #define MAGENTA 0xF00F #define BROWN 0x0D0D
//defines for the video system unsigned short* videoBuffer = (unsigned short*)0x6000000; #define DISPLAY_CONTROLLER *(unsigned long*)0x4000000 #define VIDC_BASE_HALF ((volatile unsigned short int*) 0x04000000) #define VCOUNT (VIDC_BASE_HALF[3])
#define VIDEO_MODE_3 0x3 #define BACKGROUND2 0x400 #define SCREEN_W 240 #define SCREEN_H 160
//game constants #define BALL_SIZE 6 #define PADDLE_WIDTH 8 #define PADDLE_HEIGHT 28 #define PADDLE_SPEED 2
//global variables int paddleX[3]; int paddleY[3]; int ballX, ballY; int velX = 2, velY = 1; int score1=0,score2=0;
void setMode(int mode) { DISPLAY_CONTROLLER = mode | BACKGROUND2; }
inline void drawpixel(int x, int y, unsigned short color) { videoBuffer[y * 240 + x] = color; }
inline unsigned short getpixel(int x, int y) { return videoBuffer[y * 240 + x]; }
void drawbox(int left, int top, int right, int bottom, unsigned short color) { int x, y; for(y = top; y < bottom; y++) for(x = left; x < right; x++) drawpixel(x, y, color); }
int buttonPressed(int button) { //pointer to the button interface volatile unsigned int *BUTTONS = (volatile unsigned int *)0x04000130; //see if UP button is pressed if (!((*BUTTONS) & button)) return 1; else return 0; }
//draw text using characters contained in font.h void print(int left, int top, char *str, unsigned short color) { int x, y, draw; int pos = 0; char letter; //look at all characters in this string while (*str) { //get current character ASCII code letter = (*str++) - 32; //draw the character for(y = 0; y < 8; y++) for(x = 0; x < 8; x++) { //grab a pixel from the font character draw = font[letter * 64 + y * 8 + x]; //if pixel = 1, then draw it if (draw) drawpixel(left + pos + x, top + y, color); }
//jump over 8 pixels pos += 8; } }
void printScores() { char s[5];
//erase scores drawbox(0,0,20,10,BLACK); drawbox(220,0,239,10,BLACK);
//display scores sprintf(s,"%i",score1); print(5,0,s,WHITE); sprintf(s,"%i",score2); print(220,0,s,WHITE); }
void eraseBall() { drawbox(ballX, ballY, ballX+BALL_SIZE, ballY+BALL_SIZE, BLACK); }
void updateBall() { ballX += velX; ballY += velY;
//did ball hit right wall? if (ballX > SCREEN_W - BALL_SIZE - 1) { velX *= -1; score1++; }
//did ball hit left wall? if (ballX < 1) { velX *= -1; score2++; }
//did ball hit top or bottom walls? if (ballY < 12 || ballY > SCREEN_H - BALL_SIZE - 1) velY *= -1;
}
void drawBall() { drawbox(ballX, ballY, ballX+BALL_SIZE, ballY+BALL_SIZE, MAGENTA); }
void erasePaddle1() { drawbox(paddleX[1], paddleY[1], paddleX[1] + PADDLE_WIDTH, paddleY[1] + PADDLE_HEIGHT, BLACK); }
void updatePaddle1() { int py = paddleY[1] + PADDLE_HEIGHT/2;
//only move computer paddle if ball is moving toward left if (velX < 0 && ballX < 120) { if (py > ballY) { paddleY[1] -= 1; if (paddleY[1] < 12) paddleY[1] = 12; }
if (py < ballY) { paddleY[1] += 1; if (paddleY[1] > 160-PADDLE_HEIGHT) paddleY[1] = 160-PADDLE_HEIGHT; } }
}
void drawPaddle1() { drawbox(paddleX[1], paddleY[1], paddleX[1] + PADDLE_WIDTH, paddleY[1] + PADDLE_HEIGHT, CYAN); }
void erasePaddle2() { drawbox(paddleX[2], paddleY[2], paddleX[2] + PADDLE_WIDTH, paddleY[2] + PADDLE_HEIGHT, BLACK); }
void updatePaddle2() { //check for UP button press if (buttonPressed(64)) { if (paddleY[2] > 10) paddleY[2] -= PADDLE_SPEED; } //check for DOWN button press if (buttonPressed(128)) { if (paddleY[2] < SCREEN_H - PADDLE_HEIGHT - 1) paddleY[2] += PADDLE_SPEED; } }
void drawPaddle2() { drawbox(paddleX[2], paddleY[2], paddleX[2] + PADDLE_WIDTH, paddleY[2] + PADDLE_HEIGHT, CYAN); }
void checkCollisions() { int x,y; //see if ball hit a paddle x = ballX + BALL_SIZE/2; y = ballY + BALL_SIZE/2; if (getpixel(x,y) != BLACK) { //we have a hit! velX *= -1; ballX += velX; } }
void waitRetrace() { while (VCOUNT != 160); while (VCOUNT == 160); }
int main(void) { //init video mode 3 (240x160) setMode(VIDEO_MODE_3); //init the ball ballX = SCREEN_W / 2 - BALL_SIZE / 2; ballY = 40; //init the left paddle paddleX[1] = 10; paddleY[1] = SCREEN_H / 2 - PADDLE_HEIGHT / 2; //init the right paddle paddleX[2] = SCREEN_W - 20; paddleY[2] = SCREEN_H / 2 - PADDLE_HEIGHT / 2;
//clear the screen drawbox(0, 0, 239, 159, BLACK); //display title print(120-16,1,"PONG",BLUE);
//game loop while(1) { waitRetrace(); eraseBall(); erasePaddle1(); erasePaddle2();
updatePaddle1(); updatePaddle2(); updateBall();
drawPaddle1(); drawPaddle2();
checkCollisions(); drawBall();
printScores(); }
return 0; }
|