static void draw_star(struct star * star, int z_move) { int x_draw, y_draw; x_draw = star->x / star->z + SCREEN_WIDTH / 2; if(x_draw < 1 || x_draw >= SCREEN_WIDTH) { init_star(star, z_move); return; } y_draw = star->y / star->z + SCREEN_HEIGHT/2; if(y_draw < 1 || y_draw >= SCREEN_HEIGHT) { init_star(star, z_move); return; } putPixelScreen(RGB(255, 255, 255), x_draw, y_draw); if(star->z < 5*Z_MAX_DIST/6) { putPixelScreen(RGB(255, 255, 255), x_draw, y_draw-1); putPixelScreen(RGB(255, 255, 255), x_draw-1, y_draw); if(star->z < Z_MAX_DIST/2) { putPixelScreen(RGB(255, 255, 255), x_draw+1, y_draw); putPixelScreen(RGB(255, 255, 255), x_draw, y_draw+1); } } }
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; }