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); }
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.*/ }
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; }
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(); } }
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; }
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; }