Пример #1
0
void movePaddle(gint direction) {
    DrawPaddle(false);
    paddle->x += paddle->speed * direction;
    while (paddle->x < 0) //Keep 0 < paddle->x < DISPLAY_WIDTH
        paddle->x += DISPLAY_WIDTH;
    while (paddle->x > DISPLAY_WIDTH)
        paddle->x -= DISPLAY_WIDTH;
    DrawPaddle(true);
}
Пример #2
0
static void ProcessGameOver(struct BALL *Ball, struct PADDLE *Paddle)
{
	char OutBuf[255];
	
	snprintf(OutBuf, sizeof OutBuf, "GAME OVER! Score is %d. Hit ESC to exit or space to play again.", Score);

	Lives = 0;
	
	DrawStats();
	
	Lives = 3;
	Score = 0;
	
	DrawMessage(OutBuf);
	
	cbreak();
	
AskAgain:
	switch (getch())
	{
		case 27: /*27 is ESC.*/
			endwin();
			exit(0);
			break;
		case ' ':
			break;
		default:
			goto AskAgain;
	}
	
	halfdelay(1);
	DeleteMessage();
	
	DeleteBall(Ball);
	DeletePaddle(Paddle);
	DeleteAllBricks();
	DeleteAllCharms();
	SetLevel(1); /*Set back to the default level again.*/
	
	ResetPaddle(Paddle);
	ResetBricks();
	
	DrawPaddle(Paddle);
	DrawAllBricks();
	
	DrawStats();
	
	/*Assume they want to play again.*/
	WaitForUserLaunch();
	ResetBall(Ball);
	DrawBall(Ball);
	DrawAllBricks(); /*Redraw to fix WaitForUserLaunch() goofing.*/

}
Пример #3
0
int video_thread(SceSize args, void *argp) {
	// Pixel coordinates: first = first luminant pixel to breach threshhold, last = ..., mid = ...
	Coord first, last, mid;
	int bufsize; int threshold = 200; // Luminance threshold.
	int showvideo = 0; // Show the actual video input? 0: No, 1: Yes

	// Camera buffers.
	PspUsbCamSetupVideoParam videoparam;
	static u8  buffer[MAX_STILL_IMAGE_SIZE] __attribute__((aligned(64)));
	static u8  work[68*1024] __attribute__((aligned(64)));
	static u32 framebuffer[480*272] __attribute__((aligned(64)));

	// Startup cursor position.
	cursor.x = 237, cursor.y = 50; old.x = 237, old.y = 50;

	// Setup the screenmap size and position.
	screenmap.x = 20; screenmap.y = 200;
	screenmap.w = 60; screenmap.h = 60;
	screenmap.gridcolor = 0xFFC09090;
	screenmap.fillcolor = 0xFFF0F0F0;
	screenmap.selcolor = 0xFFC0FFFF;

	// Create a start button.
	Button btnStart;
	btnStart.x = 420; btnStart.y = 250;
	btnStart.w = 50; btnStart.h = 12;
	btnStart.fillcolor = 0xFF00FFFF;
	btnStart.textcolor = 0xFF000000;
	btnStart.bordercolor = 0xFF000000;
	btnStart.shadowcolor = 0xFF888888;
	btnStart.bordersize = 1;
	btnStart.borderbevel = 0;
	btnStart.shadowsize = 0;
	btnStart.shadowdistance = 0;
	strcpy(btnStart.text, "Start");
	strcpy(btnStart.name, "btnStart");

	// Wait for camera to be connected.
	while (!connected) {
		clearScreen(0xFFF0F0F0);
		printTextScreenCenter(132, "Please connect the camera and press any button.", 0xFF009900);
		flipScreen(); sceDisplayWaitVblankStart();
		sceKernelDelayThread(20000);
	}

	// Load the camera modules and start the decoder.
	if (LoadModules() < 0) sceKernelSleepThread();
	if (StartUsb() < 0) sceKernelSleepThread();
	if (sceUsbActivate(PSP_USBCAM_PID) < 0) sceKernelSleepThread();
	if (InitJpegDecoder() < 0) sceKernelSleepThread();
	while (1) {
		if ((sceUsbGetState() & 0xF) == PSP_USB_CONNECTION_ESTABLISHED) break;
		sceKernelDelayThread(50000);
	}

	//Setup video parameters and start video capture.
	memset(&videoparam, 0, sizeof(videoparam));
	videoparam.size = sizeof(videoparam);
	videoparam.resolution = PSP_USBCAM_RESOLUTION_480_272;
	videoparam.framerate = PSP_USBCAM_FRAMERATE_30_FPS;
	videoparam.wb = PSP_USBCAM_WB_INCANDESCENT;
	videoparam.saturation = 125;
	videoparam.brightness = 100;
	videoparam.contrast = 64;
	videoparam.sharpness = 0;
	videoparam.effectmode = PSP_USBCAM_EFFECTMODE_NORMAL;
	videoparam.framesize = MAX_VIDEO_FRAME_SIZE;
	videoparam.evlevel = PSP_USBCAM_EVLEVEL_0_0;	
	if (sceUsbCamSetupVideo(&videoparam, work, sizeof(work)) < 0) sceKernelExitDeleteThread(0);
	sceUsbCamAutoImageReverseSW(1);
	if (sceUsbCamStartVideo() < 0) sceKernelExitDeleteThread(0);

	while (running) {
		int i, j, lum = 0, tracking = 0;
		first.x = 0; first.y = 0; last.x = 0; last.y = 0; mid.x = old.x; mid.y = old.y;
		clearScreen(0xFFFFFFFF);

		// Capture the camera image into the framebuffer.
		bufsize = sceUsbCamReadVideoFrameBlocking(buffer, MAX_VIDEO_FRAME_SIZE);
		if (bufsize > 0) sceJpegDecodeMJpeg(buffer, bufsize, framebuffer, 0);

		// Analyze the camera image.
		for (i = 0; i < 272; i++) {
			for (j = 0; j < 480; j++) {
				if (showvideo) putPixelScreen(framebuffer[i * CAM_LINE_SIZE + j], j, i); // Show video input.
				// Calculate luminance (brightness as perceived by the eye) and compare versus threshhold. 
				lum = (299 * R(framebuffer[i * CAM_LINE_SIZE + j]) + 587 * G(framebuffer[i * CAM_LINE_SIZE + j]) + 114 * B(framebuffer[i * CAM_LINE_SIZE + j])) / 1000;
				if (lum > threshold) {
					tracking = 1; if (aligned) putPixelScreen(0xFF0000FF, j, i);
					if ((first.x == 0) || (j < first.x)) first.x = j;
					if ((first.y == 0) || (i < first.y)) first.y = i;
					if ((last.x == 0) || (j > last.x)) last.x = j;
					if ((last.y == 0) || (i > last.y)) last.y = i;
				}
			}
		}

		if (tracking) {
			// Calculate directional movement and determine cursor position.
			mid.x = first.x + (abs((last.x - first.x)) / 2); mid.y = first.y + (abs((last.y - first.y)) / 2);
			checkDirection(mid, old);
			switch (direction) {
				case 0: cursor.x = old.x; cursor.y = old.y; break;
				case 1: cursor.x = first.x; cursor.y = first.y + (abs((last.y - first.y)) / 2); break;
				case 2: cursor.x = first.x; cursor.y = first.y; break;
				case 3: cursor.x = first.x + (abs((last.x - first.x)) / 2); cursor.y = first.y; break;
				case 4: cursor.x = last.x; cursor.y = first.y; break;
				case 5: cursor.x = last.x; cursor.y = first.y + (abs((last.y - first.y)) / 2); break;
				case 6: cursor.x = last.x; cursor.y = last.y; break;
				case 7: cursor.x = first.x + (abs((last.x - first.x)) / 2); cursor.y = last.y; break;
				case 8: cursor.x = first.x; cursor.y = last.y; break;		
			};
			
			//Uncomment the following lines to draw 'directional' markers on screen.
			/*if ((abs(last.x - first.x) > 15) || (abs(last.y - first.y) > 15)) {
				if ((direction > 0) && (direction <= 4)) {
					drawLineScreen(first.x, first.y, last.x, last.y, 0xFFC0C0C0);
				} else {
					drawLineScreen(last.x, last.y, first.x, first.y, 0xFFC0C0C0);
				}
				switch (direction) {
					case 0: break;
					case 1: drawLineScreen(last.x, last.y + ((last.y - first.y) / 2), first.x, first.y + ((last.y - first.y) / 2), 0xFFC0C0C0); break; // W
					case 2: drawLineScreen(last.x, last.y, first.x, first.y, 0xFFC0C0C0); break; // NW
					case 3: drawLineScreen(first.x + ((last.x - first.x) / 2), last.y, first.x + ((last.x - first.x) / 2), first.y, 0xFFC0C0C0); break; // N
					case 4: drawLineScreen(first.x, last.y, last.x, first.y, 0xFFC0C0C0); break; // NE
					case 5: drawLineScreen(first.x, first.y + ((last.y - first.y) / 2), last.x, first.y + ((last.y - first.y) / 2), 0xFFC0C0C0); break; // E
					case 6: drawLineScreen(first.x, first.y, last.x, last.y, 0xFFC0C0C0); break; // SE
					case 7: drawLineScreen(first.x + ((last.x - first.x) / 2), first.y, first.x + ((last.x - first.x) / 2), last.y, 0xFFC0C0C0); break; // S
					case 8: drawLineScreen(last.x, first.y, first.x, last.y, 0xFFC0C0C0); break; // SW
				};
				drawLineScreen((first.x > last.x) ? last.x : first.x, (first.y > last.y) ? last.y : first.y, (first.x < last.x) ? last.x : first.x, (first.y < last.y) ? last.y : first.y, 0xFFC0C0C0);
			} else {
				drawRectScreen(0xFFC0C0C0, first.x, first.y, last.x - first.x, last.y - first.y);
			}*/
		} else {
			printTextScreenCenter(10, "Please return to the playing area.", 0xFF0000FF);
			if (lastdirection == 0) { cursor.x = old.x; cursor.y = old.y; }
			//if ((aligned) && (!menu) && (_gameState = GAME_RUNNING)) HandlePauseGame();
		}

		if (!aligned) {
			showvideo = 1;
			// Alignment Screen: wait for camera to be aligned to the playing area.
			printTextScreenCenter(126, "Please align the camera to the playing area.", 0xFFFFFFFF);
			printTextScreenCenter(136, "Drag the cursor to the \"Start\" button to continue.", 0xFFFFFFFF);

			if (checkCoordButton(cursor, btnStart)) { btnStart.fillcolor = 0xFF00FF00; aligned = 1; menu = 1; }
			drawButtonScreen(btnStart);
			if (aligned) { btnStart.fillcolor = 0xFF00FFFF; btnStart.x = 240 - (btnStart.w / 2); btnStart.y = 200; }
		} else if (menu) {
			showvideo = 0;
			// Menu Screen: show a splash, logo, menu, etc.
			printTextScreenCenter(126, "eyePSP Pong", 0xFF009900);
			printTextScreenCenter(136, "Please press the \"Start\" button to continue.", 0xFFFF0000);

			if (checkCoordButton(cursor, btnStart)) { btnStart.fillcolor = 0xFFC0FFC0; menu = 0; }
			drawButtonScreen(btnStart);
		} else {
			// Draw any game objects here.
			if (_gameState == GAME_PAUSED) {
				printTextScreenCenter(100, "Game Paused", COLOR_RED);
				if (tracking) _gameState = GAME_RUNNING;
			} else if (_gameState == GAME_RUNNING) {
				DrawMainText(); // Draw main graphics and supporting text to the screen.
				DrawPaddle(&_paddle); // Draws the paddle to the screen
			} else if (_gameState == GAME_CONTINUE) {
				char sbuffer[50];
				sprintf(sbuffer, "%d Ball%s Remaining...", _resBalls, (_resBalls == 1) ? "" : "s");
				printTextScreenCenter(100, sbuffer, 0xFF000088);

				if (checkCoordButton(cursor, btnStart)) { btnStart.fillcolor = 0xFFC0FFC0; _gameState = GAME_RUNNING; }
				drawButtonScreen(btnStart);
			} else if (_gameState == GAME_OVER) {
				// Draws game over graphics and waits for user to continue
				DrawGameOverMenu();

				if (checkCoordButton(cursor, btnStart)) { btnStart.fillcolor = 0xFFC0FFC0; _gameState = GAME_RUNNING; }
				drawButtonScreen(btnStart);
			}
		}

		// Draw cursor (within boundaries) .
		if (tracking) {
			for (i = cursor.y - 5; i <= cursor.y + 5; i++) { if ((i > 0) && (i < 272)) putPixelScreen(!tracking ? 0xFF0000FF : 0xFF009900, cursor.x, i); } // y-axis
			for (j = cursor.x - 5; j <= cursor.x + 5; j++) { if ((j > 0) && (j < 480)) putPixelScreen(!tracking ? 0xFF0000FF : 0xFF009900, j, cursor.y); } // x-axis
		}

		old.x = cursor.x; old.y = cursor.y; lastdirection = direction;
		flipScreen(); sceDisplayWaitVblankStart();
		sceKernelDelayThread(2000);
	}
	sceKernelExitDeleteThread(0);
	return 0;	
}
Пример #4
0
static void GameLoop(struct BALL *const Ball, struct PADDLE *const Paddle)
{ /*Primary loop where most events get processed.*/
	
	struct BRICKSTRIKE Strike;
	int Key = 0;
	int SecTick = 0;
	Bool PaddleMovedLastTick;
	DirectionX PaddleMoveDir;
	int Inc = 0;
	Bool Flip = false;
	int SlowBallTicks = 0, BallNukeTicks = 0;
	
	while ((Key = getch()) != 27) /*27 is ESC*/
	{		
		if (SecTick == 10)
		{ /*We get score every second for just surviving.*/
			Score += 2;
			DrawStats();
			SecTick = 0;
		}
		++SecTick;

		if (Ball->Y == 1)
		{ /*We hit the ceiling.*/
			BounceBallY(Ball, DOWN);
		}
		else if (Ball->Y >= BRICKTICK_MAX_Y - 2)
		{ /*More happens when we hit the floor.*/
			if (!CheckBallHitPaddle(Ball, Paddle))
			{
				DeleteBall(Ball);
				Ball->Y = BRICKTICK_MAX_Y - 1;
				DrawBall(Ball);
				
				if (Lives == 1)
				{ /*We ran out of lives.*/
					ProcessGameOver(Ball, Paddle);
				}
				else
				{
					--Lives;
					DrawStats();
					
					WaitForUserLaunch();
							
					DeleteBall(Ball);
					DeletePaddle(Paddle);
					
					ResetBall(Ball);
					ResetPaddle(Paddle);
					
					DrawPaddle(Paddle);
					DrawBall(Ball);
					
					/*Redraw but don't reset.*/
					DrawAllBricks();
				}
			}
			else
			{
				BounceBallY(Ball, UP);
				
				if (PaddleMovedLastTick)
				{ /*We can "whack" the ball with our Paddle->*/
					Ball->DirX = PaddleMoveDir;
				}
				else
				{ /*We cut the paddle into thirds for the X direction after bounce.*/
#define PADDLE_THIRD (Paddle->Length / 3)
					if (Ball->X <= Paddle->X + PADDLE_THIRD)
					{
						Ball->DirX = LEFT;
					}
					else if (Ball->X  > Paddle->X + PADDLE_THIRD && Ball->X <= Paddle->X + (PADDLE_THIRD * 2))
					{
						/*Make whether we hit up or not as a chance.*/
						Bool StraightUp = rand() & 1;
						if (StraightUp) Ball->DirX = X_NEUTRAL;
					}
					else
					{
						Ball->DirX = RIGHT;
					}
				}
			}
		}
		PaddleMovedLastTick = false;
		/*Bounce off left and right walls.*/
		if (Ball->X >= BRICKTICK_MAX_X - 1)
		{
			Ball->X = BRICKTICK_MAX_X - 1;
			BounceBallX(Ball, LEFT);
		}
		else if (Ball->X <= 0)
		{
			Ball->X = 0;
			BounceBallX(Ball, RIGHT);
		}
			
	
		/*Check if a charm hit the paddle.*/
		for (Inc = 0; Inc < BRICK_MAX_NUMLINES * BRICK_MAX_PERLINE; ++Inc)
		{
			if (Charms[Inc].Type == CHARM_NONE || !Charms[Inc].Dropped || Charms[Inc].Y != BRICKTICK_MAX_Y - 2) continue;
			
			if (CheckCharmHitPaddle(Paddle, Charms + Inc))
			{
				void *Ptr = NULL;
				const char *const Strings[] = { "+1,000 Score", "+1 Lives",
											"10 Second Slow Ball", "3 second nuke mode" };
					
				switch (Charms[Inc].Type)
				{
					case CHARM_SCORE:
						Ptr = &Score;
						break;
					case CHARM_LIFE:
						Ptr = &Lives;
						break;
					case CHARM_SLOW:
						Ptr = &SlowBallTicks;
						break;
					case CHARM_NUKE:
						Ptr = &BallNukeTicks;
						break;
					default:
						break;
				}
				
				if (Charms[Inc].Type != CHARM_NONE)
				{ /*Show a message on what type of charm we have here.*/
					DrawMessage(Strings[Charms[Inc].Type - 1]); fflush(NULL);
					usleep(500000);
					DeleteMessage();
					DrawAllBricks();
					DrawStats();
				}
				
				/*Do the thing the charm does.*/
				ProcessCharmAction(Charms + Inc, Ptr);
			}
			
			/*In any case, we're done with it.*/
			DeleteCharm(Charms + Inc);
			Charms[Inc].Type = CHARM_NONE;
		}
		
		/*We hit a brick.*/
		if (BallStruckBrick(Ball, &Strike))
		{
			
			if (BallNukeTicks == 0) /*Nuclear ball passes through.*/
			{
				switch (Strike.StrikeV)
				{
					case STRIKE_TOP:
						Ball->DirY = UP;
						break;
					case STRIKE_BOTTOM:
						Ball->DirY = DOWN;
						break;
					default:
						break;
				}
				
				switch (Strike.StrikeH)
				{
					case STRIKE_LEFT:
						Ball->DirX = LEFT;
						break;
					case STRIKE_RIGHT:
						Ball->DirX = RIGHT;
						break;
					default:
					{
						if (Ball->DirX != X_NEUTRAL) break;
						else
						{
							Bool Dir = rand() & 1;
							Ball->DirX = (DirectionX)Dir;
						}
						break;
					}
				}
			}
			
			DeleteBrick(Strike.Brick);
			Score += 100;
			DrawStats();
			
			if (!BricksLeft())
			{ /*Move to next level.*/

				if (SetLevel(Level + 1))
				{ /*We have more levels to go before we win.*/
					DeleteAllBricks();
					DeleteAllCharms();
					DeleteBall(Ball);
					DeletePaddle(Paddle);
					DrawStats();
					
					Score += 1000; /*Reward for making it this far.*/
					Lives = BRICKTICK_NUMLIVES;
					
					ResetBall(Ball);
					ResetPaddle(Paddle);
					ResetBricks();
					
					DrawAllBricks();
					DrawPaddle(Paddle);
					WaitForUserLaunch();
					DrawBall(Ball);
					DrawAllBricks(); /*Redraw to fix WaitForUserLaunch() goofing.*/
				}
				else
				{ /*WE WON!!!!*/
					char WonBuf[256];
					
					snprintf(WonBuf, sizeof WonBuf, "You Won! Score is %d! Hit ESC to exit or space to play again.", Score);
					DrawMessage(WonBuf);
					
				WinRegetch:
					switch (getch())
					{
						case 27: /*27 is ESC*/
							endwin();
							exit(0);
							break;
						case ' ':
						{
							DeleteMessage();
							
							SetLevel(1);
							
							Lives = BRICKTICK_NUMLIVES;
							Score = 0;
							
							DeleteAllBricks();
							DeleteAllCharms();
							DeleteBall(Ball);
							DeletePaddle(Paddle);
							DrawStats();
							
							ResetBall(Ball);
							ResetPaddle(Paddle);
							ResetBricks();
							
							DrawAllBricks();
							DrawPaddle(Paddle);
							WaitForUserLaunch();
							DrawBall(Ball);
							DrawAllBricks(); /*Redraw to fix WaitForUserLaunch() goofing.*/

							continue; /*For the loop we are in.*/
						}
						default:
							goto WinRegetch;
					}
				}

				continue;
			}
			else
			{ /*Charm drops.*/
				struct CHARM *Charm = GetCharmByBrick(Strike.Brick);
				
				if (Charm)
				{ /*We DO have a charm for this brick.*/
					PerformCharmDrop(Charm); /*Mark it dropped.*/

					/*Now draw the charm.*/
					DrawCharm(Charm);
				}
			}
		}
		
		switch (Key)
		{ /*Paddle movement.*/
			case KEY_LEFT:
				MovePaddle(Paddle, LEFT);
				PaddleMovedLastTick = true;
				PaddleMoveDir = LEFT;
				break;
			case KEY_RIGHT:
				MovePaddle(Paddle, RIGHT);
				PaddleMovedLastTick = true;
				PaddleMoveDir = RIGHT;
				break;
			case 's': /*They want to save the game.*/
				if (SaveGame(Ball, Paddle))
				{
					DrawMessage("Game saved.");
				}
				else
				{
					DrawMessage("Failed to save game.");
				}
				fflush(NULL);
				usleep(500000);
				
				DeleteMessage();
				DrawAllBricks(); /*Redraw bricks if damaged.*/
				
				break;
			case 'o': /*They want us to load a game.*/
			{
				const Bool LoadedOk = LoadGame(Ball, Paddle);
				
				if (LoadedOk)
				{
					/*Restore the state.*/
					clear();
					DrawBorders(); /*Need to redraw these after clearing the screen.*/
					
					DrawBall(Ball);
					DrawPaddle(Paddle);
					DrawStats();
					DrawAllBricks();
					
					DrawMessage("Game loaded.");
				}
				else
				{
					DrawMessage("Failed to load game.");
				}

				fflush(NULL);
				usleep(500000);
				
				DeleteMessage();
				DrawAllBricks();
				break;
			}
			case ' ':
			{
				DrawMessage("PAUSED");
				cbreak();
				
			PauseRegetch:
				switch (getch())
				{
					case ' ':
						DeleteMessage();
						DrawAllBricks(); /*Redraw to fix what deleting the message messed up.*/
						halfdelay(1);
						break;
					case 27: /*27 is ESC*/
						endwin();
						exit(0);
						break;
					default:
						goto PauseRegetch;
				}
			}
			default:
				break;
		}
		
		Flip = !Flip;

		/*Ball movement, obviously. Flip is used to keep it at half speed if we got a 'slow' charm.*/
		if (Flip || SlowBallTicks == 0) MoveBall(Ball);
		
		/*Decrement slow ball ticks until zero, then the ball goes fast again.*/
		if (SlowBallTicks > 0) --SlowBallTicks;
		
		/*Decrement nuclear ball until ticks hit zero.*/
		if (BallNukeTicks > 0) --BallNukeTicks;
		
		/*Charm movement.*/		
		for (Inc = 0; Inc < BRICK_MAX_NUMLINES * BRICK_MAX_PERLINE; ++Inc)
		{
			if (Charms[Inc].Type == CHARM_NONE || !Charms[Inc].Dropped) continue;
			
			if (Flip) MoveCharm(Charms + Inc);
		}
		
		/*Redraw borders in case of terminal resize.*/
		DrawBorders();
	}
}
Пример #5
0
int main(int argc, char **argv)
{
	int Inc = 1;
	struct BALL Ball = { 0 };
	struct PADDLE Paddle = { 0 };
	Bool DoLoadGame = false;
	int GotoLevel = 0;
	
	for (; Inc < argc; ++Inc)
	{ /*Argument parsing.*/
		if (!strcmp("--nocolor", argv[Inc]))
		{
			UseColor = false;
		}
		else if (!strcmp("--version", argv[Inc]))
		{
			printf("Bricktick brick breaker v" BRICKTICK_VERSION "\n"
					"By Subsentient.\n");
			fflush(NULL);
			exit(0);
		}
		else if (!strcmp("--help", argv[Inc]))
		{
			printf("Command line options:\n\t"
					"--help: Show this help.\n\t"
					"--nocolor: Run Bricktick with no color.\n\t"
					"--version: Display version and exit.\n");
			fflush(NULL);
			exit(0);
		}
		else if (!strncmp("--level=", argv[Inc], sizeof "--level=" - 1))
		{
			GotoLevel = atoi(argv[Inc] + sizeof "--level=" - 1);
			
			if (GotoLevel > sizeof Levels / sizeof *Levels)
			{
				fprintf(stderr, "The maximum level is %d.\n", sizeof Levels / sizeof *Levels); fflush(NULL);
				exit(1);
			}
		}
		else
		{
			fprintf(stderr, "Bad command line argument \"%s\".\n"
					"Use --help for command line options.\n", argv[Inc]);
			exit(1);
		}
	}
	
	
	initscr(); /*Fire up ncurses.*/
	
	if (COLS < BRICKTICK_MAX_X || LINES < BRICKTICK_MAX_Y)
	{
		endwin();
		fprintf(stderr, "Please use a console with a resolution of at least %dx%d.\n", BRICKTICK_MAX_X, BRICKTICK_MAX_Y);
		exit(1);
		
	}
	
	/*Color not supported.*/
	if (!has_colors()) UseColor = false;
	
	/*Various ncurses things.*/
	noecho();
	
	if (UseColor)
	{ /*Color fireup.*/
		start_color();
		init_pair(1, COLOR_CYAN, COLOR_BLACK);
		init_pair(2, COLOR_GREEN, COLOR_BLACK);
		init_pair(3, COLOR_BLACK, COLOR_WHITE);
		init_pair(4, COLOR_BLUE, COLOR_BLACK);
		init_pair(5, COLOR_GREEN, COLOR_BLACK);
		init_pair(6, COLOR_YELLOW, COLOR_BLACK);
		init_pair(7, COLOR_RED, COLOR_BLACK);
		
		
		/*Fire up colors for the bricks.*/
		init_pair(BRICK_COLORS_START, COLOR_GREEN, COLOR_BLACK);
		init_pair(BRICK_COLORS_START + 1, COLOR_BLUE, COLOR_BLACK);
		init_pair(BRICK_COLORS_START + 2, COLOR_YELLOW, COLOR_BLACK);
		init_pair(BRICK_COLORS_START + 3, COLOR_MAGENTA, COLOR_BLACK);
		init_pair(BRICK_COLORS_START + 4, COLOR_CYAN, COLOR_BLACK);
		init_pair(BRICK_COLORS_END, COLOR_RED, COLOR_BLACK);
	}
	
	/*Draw borders for consoles bigger than our 80x24 playing area.*/
	DrawBorders();
	
	/*Greeting.*/
GreetAsk:

	if (!GotoLevel)
	{ /*If they specified a level let them go straigth to game start.*/
		DrawGreeting();
		switch (getch())
		{
			case 27: /*27 is ESC key*/
				endwin();
				exit(0);
				break;
			case ' ':
				clear(); /*Wipe the message from the screen.*/
				DrawBorders(); /*Redraw borders.*/
				break;
			case 'o':
				clear();
				DrawBorders();
				DoLoadGame = true;
				LoadGame(&Ball, &Paddle);
				break;
			default:
				goto GreetAsk;
		}
	}
	else
	{
		clear();
		DrawBorders();
	}
	
	halfdelay(1);
	keypad(stdscr, true);
#if NCURSES_VERSION_MAJOR >= 5 && NCURSES_VERSION_MINOR >=4
	set_escdelay(25);
#endif
	curs_set(0);
	

	if (DoLoadGame)
	{
		DrawStats();
		DrawBall(&Ball);
		DrawPaddle(&Paddle);
		DrawAllBricks();
	}
	else
	{
		/*Show our initial lives count.*/
		DrawStats();
	
		/*Reset to level 1 if we haven't specified a level.*/
		SetLevel(GotoLevel ? GotoLevel : 1);
		
		ResetBall(&Ball);
		ResetPaddle(&Paddle);
		
		DrawBall(&Ball);
		DrawPaddle(&Paddle);
		ResetBricks();
		DrawAllBricks();
	}
	
	/*Wait for L key.*/
	WaitForUserLaunch();
	DrawAllBricks(); /*Redraw to fix goofing by WaitForUserLaunch().*/
	
	/*Set up the number generator.*/
	srand(time(NULL));

	/**
	 * Main loop for the game!
	 **/
Reloop:
	GameLoop(&Ball, &Paddle);
	
	DrawMessage("Really quit Bricktick? y/n");
	cbreak();
	
	/*When the game loop exits.*/
	switch (getch())
	{
		case 'y':
		case 'Y':
			break;
		default:
			DeleteMessage();
			refresh();
			halfdelay(1);
			DrawAllBricks(); /*Fix damage to brick display resulting from the message.*/
			goto Reloop;
			break;
	}
	DeleteBall(&Ball);
	DeletePaddle(&Paddle);
	
	endwin();
	
	return 0;
}
Пример #6
0
gint main(gint argc, char** argv) {
    gtk_init(&argc, &argv);
    ball = g_slice_new(balls);
    paddle = g_slice_new(paddles);
    white = g_slice_new(GdkGC);
    black = g_slice_new(GdkGC);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(window, DISPLAY_WIDTH, DISPLAY_HEIGHT);
    gtk_window_set_resizable(GTK_WINDOW(window), false);
    gtk_window_set_title(GTK_WINDOW(window), "GTK Pong");

    draw = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(window), draw);
    InitCallback();
    gtk_widget_show_all(window);

    pixmap = gdk_pixmap_new(draw->window, draw->allocation.width,
                            draw->allocation.height, -1);

    black = draw->style->black_gc;
    white = draw->style->white_gc;

    GtkWidget *ballimagetmp = gtk_image_new_from_file("data/chromium.png");
    ballimage = gtk_image_get_pixbuf(GTK_IMAGE(ballimagetmp));
    BallInfo();

    paddle->width = 100;
    paddle->height = 10;
    paddle->y = DISPLAY_HEIGHT - paddle->height;
    paddle->x = (DISPLAY_WIDTH / 2) - (paddle->width / 2);
    paddle->speed = paddle->width / 2;

    if (DISPLAY_WIDTH < paddle->width) {
        printf("Paddle too big");
        return 2;
    }
    if (DISPLAY_WIDTH < ball->width) {
        printf("Ball too big");
        return 2;
    }
    if (DISPLAY_HEIGHT < paddle->height + ball->height) {
        printf("Height of paddle and ball too big");
        return 2;
    }

    ball->x = UniformRandom(0, DISPLAY_WIDTH - ball->width); //Initial position
    ball->y = UniformRandom(0, (DISPLAY_HEIGHT - ball->height - paddle->height)
                            / 2);
    ball->dx = UniformRandom(3, 7); //Initial speed/direction of travel
    ball->dy = UniformRandom(3, 7);
    if (UniformRandom(1, 2) == 1)//Allow negative values initially
        ball->dx *= -1;
    if (UniformRandom(1, 2) == 1)
        ball->dy *= -1;

    Fill(white, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
    DrawPaddle(true);
    DrawBall(true);

#ifdef DEBUG
    ball->dx = 0;
    ball->dy = 0;
#else
    for (g_usleep(2 * G_USEC_PER_SEC); g_main_context_iteration(NULL, 0);)
        ;
#endif
    while (true) {
        DrawBall(false);
        gint i;
        for (i = 0; i < ABS(ball->dx) || i < ABS(ball->dy); ++i) {//Move ball
            if (i < ABS(ball->dx)) {
                ball->x += ABS(ball->dx) / ball->dx;
                if (!checkPos()) {
                    ball->dx *= -1;
                    ball->x += 2 * ABS(ball->dx) / ball->dx;
                }
            }
            if (i < ABS(ball->dy)) {
                ball->y += ABS(ball->dy) / ball->dy;
                if (!checkPos()) {
                    ball->dy *= -1;
                    ball->y += 2 * ABS(ball->dy) / ball->dy;
                }
            }
        }
        DrawBall(true);
        for (g_usleep(20000); g_main_context_iteration(NULL, 0);)
            ;
    }
    return 0;
}