/************************************************* * NEXT LEVEL * DESCRIPTION: Advance the game to the next level. **************************************************/ uint8_t NextLevel(struct MovingSolid* ball, struct Solid* paddle, struct Solid* solids, uint8_t* balls, uint16_t* num_blocks, uint16_t *ballSpeed, uint8_t level) { display_solid(paddle, 1); display_moving_solid(ball, 1); *balls = 4; *ballSpeed = BALL_SPEED; printf_setFont_location(5, 300); _printf("Ball %d", *balls); build_solid(paddle, 200, 160, 5, 25, COLOR_RED); build_moving_solid(ball, 200, 167, 7, 7, COLOR_DRKGREY, SOLID_AUTOUP | SOLID_AUTOLEFT, 4); if (level < LEVELS) { level++; } else { level = 1; } #if READ_EEPROMLEVEL == 1 SetClockSpeed(0); //Clock Speed must be < 10Mhz to support EEProm __disable_interrupt(); EEProm_Write(BRICK_BREAKER_LEVEL, level); //Save the current level __enable_interrupt(); SetClockSpeed(5); //Clock Speed must be < 10Mhz to support EEProm #endif *num_blocks = loadLevel(solids, level); StartTimer(0, PADDLE_SPEED); StartTimer(1, *ballSpeed); StartTimer(2, SCORE_UPDATE); return level; }
// The Window Procedure LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; unsigned int x,y; unsigned char kb_char; kb_char=(unsigned char)wParam; static unsigned char OEMscan=0; static char ascii=0; static RECT ClientSize; static unsigned long Width,Height; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: // Added for Dynamic menu system if ( (wmId >=ID_SDYNAMENU) & (wmId <=ID_EDYNAMENU) ) { DynamicMenuActivated (wmId - ID_SDYNAMENU); //Calls to the loaded DLL so it can do the right thing break; } switch (wmId) { case IDM_HELP_ABOUT: DialogBox(EmuState.WindowInstance, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case ID_CONFIGURE_OPTIONS: if (EmuState.ConfigDialog==NULL) { EmuState.ConfigDialog = CreateDialog (NULL,(LPCTSTR)IDD_TCONFIG,EmuState.WindowHandle,(DLGPROC) Config) ; ShowWindow (EmuState.ConfigDialog, SW_SHOWNORMAL) ; } // DialogBox(EmuState.WindowInstance, (LPCTSTR)IDD_TCONFIG, hWnd, (DLGPROC)Config); break; case IDOK: SendMessage (hWnd, WM_CLOSE, 0, 0); break; case ID_FILE_EXIT: BinaryRunning=0; break; case ID_FILE_RESET: if (EmuState.EmulationRunning) EmuState.ResetPending=2; break; case ID_FILE_RUN: EmuState.EmulationRunning=TRUE; InvalidateBoarder(); break; case ID_FILE_RESET_SFT: if (EmuState.EmulationRunning) EmuState.ResetPending=1; break; case ID_FILE_LOAD: LoadIniFile(); EmuState.ResetPending=2; SetClockSpeed(1); //Default clock speed .89 MHZ break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; // case WM_CREATE: // // break; // case WM_SETFOCUS: // Set8BitPalette(); // break; case WM_CLOSE: BinaryRunning=0; break; case WM_CHAR: // OEMscan=(unsigned char)((lParam & 0xFF0000)>>16); // ascii=kb_char; // sprintf(ttbuff,"Getting REAL CHAR %i",ascii); // WriteLine ( ttbuff); // KeyboardEvent(kb_char,OEMscan,1); //Capture ascii value for scancode return 0; break; case WM_KEYUP: case WM_SYSKEYUP: OEMscan=(unsigned char)((lParam & 0xFF0000)>>16); KeyboardEvent(kb_char,OEMscan,0); return 0; break; case WM_KEYDOWN: case WM_SYSKEYDOWN: OEMscan=(unsigned char)((lParam & 0xFF0000)>>16); switch (OEMscan) { case 61: //F3 break; case 62: //F4 break; case 63: //F5 if (EmuState.EmulationRunning) EmuState.ResetPending=1; break; case 64: //F6 SetMonitorType(!SetMonitorType(QUERY)); break; // case 65: //F7 // SetArtifacts(!SetArtifacts(QUERY)); // break; case 66: //F8 SetSpeedThrottle(!SetSpeedThrottle(QUERY)); break; case 67: //F9 EmuState.EmulationRunning=!EmuState.EmulationRunning; if (EmuState.EmulationRunning) EmuState.ResetPending=2; else SetStatusBarText("",&EmuState); break; case 68: //F10 SetInfoBand(!SetInfoBand(QUERY)); InvalidateBoarder(); break; case 87: //F11 if (FlagEmuStop==TH_RUNNING) { FlagEmuStop=TH_REQWAIT; EmuState.FullScreen=!EmuState.FullScreen; } break; // case 88: //F12 // CpuDump(); // break; default: if (EmuState.EmulationRunning) KeyboardEvent(kb_char,OEMscan,2); break; } return 0; break; case WM_LBUTTONDOWN: //0 = Left 1=right SetButtonStatus(0,1); break; case WM_LBUTTONUP: SetButtonStatus(0,0); break; case WM_RBUTTONDOWN: SetButtonStatus(1,1); break; case WM_RBUTTONUP: SetButtonStatus(1,0); break; case WM_MOUSEMOVE: if (EmuState.EmulationRunning) { x = LOWORD( lParam ) ; y = HIWORD( lParam ) ; GetClientRect(EmuState.WindowHandle,&ClientSize); x/=((ClientSize.right-ClientSize.left)>>6); y/=(((ClientSize.bottom-ClientSize.top)-20)>>6); joystick(x,y); } return(0); break; // default: // return DefWindowProc(hWnd, message, wParam, lParam); }
/*--------------------------------------------------------------------------*/ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG Msg; EmuState.WindowInstance = hInstance; char temp1[MAX_PATH]=""; char temp2[MAX_PATH]=" Running on "; unsigned threadID; HANDLE hEvent, // SetPriorityClass(GetCurrentProcess(),ABOVE_NORMAL_PRIORITY_CLASS ); // SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL); // CoInitializeEx(NULL,COINIT_MULTITHREADED); // CoInitialize(NULL); // InitializeCriticalSection(); OleInitialize(NULL); //Work around fixs app crashing in "Open file" system dialogs (related to Adobe acrobat 7+ LoadString(hInstance, IDS_APP_TITLE,g_szAppName, MAX_LOADSTRING); if ( strlen(lpCmdLine) !=0) { strcpy(QuickLoadFile,lpCmdLine); strcpy(temp1,lpCmdLine); PathStripPath(temp1); strlwr(temp1); temp1[0]=toupper(temp1[0]); strcat (temp1,temp2); strcat(temp1,g_szAppName); strcpy(g_szAppName,temp1); } EmuState.WindowSize.x=640; EmuState.WindowSize.y=480; InitInstance (hInstance, nCmdShow); if (!CreateDDWindow(&EmuState)) { MessageBox(0,"Can't create primary Window","Error",0); exit(0); } Cls(0,&EmuState); DynamicMenuCallback( "",0, 0); DynamicMenuCallback( "",1, 0); LoadConfig(&EmuState); //Loads the default config file Vcc.ini from the exec directory EmuState.ResetPending=2; SetClockSpeed(1); //Default clock speed .89 MHZ BinaryRunning = true; EmuState.EmulationRunning=AutoStart; if (strlen(lpCmdLine)!=0) { Qflag=255; EmuState.EmulationRunning=1; } hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ) ; if (hEvent==NULL) { MessageBox(0,"Can't create Thread!!","Error",0); return(0); } hEMUThread = (HANDLE)_beginthreadex( NULL, 0, &EmuLoop, hEvent, 0, &threadID ); if (hEMUThread==NULL) { MessageBox(0,"Can't Start main Emulation Thread!","Ok",0); return(0); } WaitForSingleObject( hEvent, INFINITE ); SetThreadPriority(hEMUThread,THREAD_PRIORITY_NORMAL); // InitializeCriticalSection(&FrameRender); while (BinaryRunning) { if (FlagEmuStop==TH_WAITING) //Need to stop the EMU thread for screen mode change { //As it holds the Secondary screen buffer open while running FullScreenToggle(); FlagEmuStop=TH_RUNNING; } GetMessage(&Msg,NULL,0,0); //Seems if the main loop stops polling for Messages the child threads stall TranslateMessage(&Msg); DispatchMessage(&Msg) ; } CloseHandle( hEvent ) ; CloseHandle( hEMUThread ) ; timeEndPeriod(1); UnloadDll(); SoundDeInit(); WriteIniFile(); //Save Any changes to ini File return Msg.wParam; }
void BrickBreaker(void) { uint8_t temp; uint16_t i = 0; uint16_t j = 0; uint8_t level = 4; uint8_t random = 0; uint16_t non_paddle_hits = 0; uint16_t num_blocks = 0; struct Solid solids[NUM_BRICKS]; uint16_t ballSpeed = BALL_SPEED; uint32_t score = 0; uint8_t balls = 4; uint16_t blocks_destroyed = 0; char vertical = 0; char horizontal = 0; char item_flame = 0; char item_long_paddle = 0; char item_short_paddle = 0; char ball_speed_fast = 0; char ball_speed_slow = 0; char item_bullets = 0; uint16_t bullet_index = 0; uint16_t paddle_width = 25; uint16_t item_buffer[200]; struct DropItem items[10]; //Items that get dropped struct MovingSolid bullets[15]; struct Solid paddle; struct MovingSolid ball; setBgColor(COLOR_GREEN); printf_setFont_properties(2, 0, COLOR_BLUE, COLOR_GREEN); printf_setFont_location(5, 300); _printf("Ball %d", balls); printf_setFont_location(5, 200); _printf("Score 0"); for (i = 0; i < NUM_BRICKS; i++) { solids[i].status = 0; } //Initialize the items for (i = 0; i < 10; i++) { items[i].sprite.status = 0; items[i].sprite.type = 0; } for (i = 0; i < 15; i++) { bullets[i].solid.status = 0; } #if READ_EEPROMLEVEL == 1 //Load the last level from memory SetClockSpeed(0); //Clock Speed must be < 10Mhz to support EEProm __disable_interrupt(); level = EEProm_Read(BRICK_BREAKER_LEVEL); if (level == 0 || level > 4) { level = 1; EEProm_Write(BRICK_BREAKER_LEVEL, level); } __enable_interrupt(); SetClockSpeed(5); //Clock Speed must be < 10Mhz to support EEProm #endif num_blocks = loadLevel(solids, level); build_solid(&paddle, 200, 160, 5, paddle_width, COLOR_DRKGREY); build_moving_solid(&ball, 200, 167, 7, 7, COLOR_DRKGREY, SOLID_AUTOUP | SOLID_AUTOLEFT, 4); solid_setScreenBounds(0x0f); StartTimer(0, PADDLE_SPEED + 21); StartTimer(1, ballSpeed + 31); StartTimer(2, PAUSE_CHECK); StartTimer(4, ITEM_DROP_SPEED); StartTimer(5, ITEM_RANDOM_DROP); for (;;) { //Check the joystick if (CheckTimer(0)) { if (GetLeft()) { solid_fastMoveLeft(&paddle, GetJoystickXMag() + 5, 0); } else if (GetRight()) { solid_fastMoveRight(&paddle, GetJoystickXMag() + 5, 0); } StartTimer(0, PADDLE_SPEED); } //Auto-move the ball, check if it has hit any bricks. if (CheckTimer(1)) { temp = solid_autoMove(&ball); if (temp != 0) { play_sound(0); } if (temp == 3) { balls--; printf_setFont_location(5, 300); _printf("Ball %d", balls); display_moving_solid(&ball, 1); ballSpeed = BALL_SPEED;// Reset the ball speed build_moving_solid(&ball, 200, 167, 7, 7, COLOR_DRKGREY, SOLID_AUTOUP | SOLID_AUTOLEFT, 4); if (balls == 0) { AddHighScore(score, BRICK_BREAKER_SCORE_ADDR); setBgColor(COLOR_GREEN); display_solid(&paddle, 1); display_moving_solid(&ball, 1); balls = 4; score = 0; printf_setFont_location(5, 300); _printf("Ball %d", balls); printf_setFont_location(5, 200); _printf("Score 0"); build_solid(&paddle, 200, 160, 5, 25, COLOR_DRKGREY); build_moving_solid(&ball, 200, 167, 7, 7, COLOR_DRKGREY, SOLID_AUTOUP | SOLID_AUTOLEFT, 4); num_blocks = loadLevel(solids, level); StartTimer(0, PADDLE_SPEED); StartTimer(1, ballSpeed); StartTimer(2, SCORE_UPDATE); } } if (solid_checkIntersectionPaddle(&ball, &paddle) != 0) { non_paddle_hits = 0; play_sound(0); } for (i = 0; i < NUM_BRICKS; i++) { if (solid_checkIntersectionBrick(&ball, &solids[i], &vertical, &horizontal, random) != 0) { if (solids[i].color == 0x0000 || item_flame == 0) { solid_verticalBounce(&ball, vertical, random); solid_horizontalBounce(&ball, horizontal, random); } StartTimer(3, 1011);//A block was hit, schedule a block redraw if (random == 1) { random = 0; } if (solids[i].color == 0x0000) { non_paddle_hits++; if (non_paddle_hits == 5) { random = 1; non_paddle_hits = 0; } break;//Only allow one brick to be hit at once } else { blocks_destroyed = DropRandomItem(items, item_buffer, solids, blocks_destroyed, i); blocks_destroyed++; display_solid(&solids[i], 1); solids[i].status = 0; score++; printf_setFont_location(5, 128); _printf("%d", score); num_blocks--; play_sound(0); if (ballSpeed > 20) { ballSpeed--; } //This game has been finished, reset for the next if (num_blocks == 0) { level = NextLevel(&ball, &paddle, solids, &balls, &num_blocks, &ballSpeed, level); } break; //Only allow one brick to be hit at once } } } StartTimer(1, ballSpeed); } //Auto-move the bullets and check if bullets have intersected any bricks if (CheckTimer(7)) { for (i = 0; i < 15; i++) { if (bullets[i].solid.status > 0) { if (solid_autoMove(&bullets[i]) == 2) { bullets[i].solid.status = 0; display_moving_solid(&bullets[i], 0); } else { for (j = 0; j < NUM_BRICKS; j++) { if (solid_checkIntersectionSolid(&bullets[i].solid, &solids[j]) != 0) { bullets[i].solid.status = 0; //Black brick, do nothing if (solids[j].color == 0x0000) { } else { blocks_destroyed = DropRandomItem(items, item_buffer, solids, blocks_destroyed, i); blocks_destroyed++; display_solid(&solids[j], 1); solids[j].status = 0; score++; printf_setFont_location(5, 128); _printf("%d", score); num_blocks--; play_sound(0); if (ballSpeed > 20) { ballSpeed--; } //This game has been finished, reset for the next if (num_blocks == 0) { level = NextLevel(&ball, &paddle, solids, &balls, &num_blocks, &ballSpeed, level); } break; //Only allow one brick to be hit at once } } } } } //Re-display the bullet if it is still moving if (bullets[i].solid.status == 1) { display_moving_solid(&bullets[i], 0); } } StartTimer(7, 40); } //Launch a new bullet (if the bullet item is currently in use if (CheckTimer(6)) { build_moving_solid(&bullets[bullet_index], paddle.y_pos - 5, paddle.x_pos + 5, 4, 4, COLOR_BLACK, SOLID_AUTOUP, 4); bullet_index++; if (bullet_index == 15) { bullet_index = 0; } StartTimer(6, 400); } //Check for pause (center joystick) button if (CheckTimer(2)) { if (GetJoystickBtn()) { if (Pause(BRICK_BREAKER_SCORE_ADDR) == 1) { AddHighScore(score, BRICK_BREAKER_SCORE_ADDR); break; } printf_setFont_location(5, 300); _printf("Ball %d", balls); printf_setFont_location(5, 200); _printf("Score %d", score); StartTimer(3, 100); //Redraw the screen } StartTimer(2, PAUSE_CHECK); } //Redraw blocks timer if (CheckTimer(3)) { for (i = 0; i < NUM_BRICKS; i++) { if (solids[i].status == 1) { display_solid(&solids[i], 0); } } StopTimer(3); } //Auto-move items and check to see if the user has obtained one. if (CheckTimer(4)) { for (i = 0; i < 10; i++) { //Item was captured, enabled it if (drop_item_autoMove(&items[i], &paddle) == 2) { if (items[i].sprite.type == 0) { //Easy break condition to prevent a lot of work on this } else if (items[i].sprite.type == SPRITE_ITEMFLAMEBALL) { item_flame = 1; ball.solid.color = COLOR_RED; } else if (items[i].sprite.type == SPRITE_ITEMBULLET) { item_bullets = 1; StartTimer(6, 300); StartTimer(7, 40); bullet_index = 0; } else if (items[i].sprite.type == SPRITE_ITEMSHORTPADDLE) { item_short_paddle = 1; display_solid(&paddle, 1); //Clear the old paddle paddle_width = 15; build_solid(&paddle, paddle.y_pos, paddle.x_pos, 5, paddle_width, COLOR_DRKGREY); } else if (items[i].sprite.type == SPRITE_ITEMLONGPADDLE) { item_long_paddle = 1; display_solid(&paddle, 1); //Clear the old paddle paddle_width = 40; build_solid(&paddle, paddle.y_pos, paddle.x_pos, 5, paddle_width, COLOR_DRKGREY); } else if (items[i].sprite.type == SPRITE_ITEMFASTBALL) { ball_speed_fast = 1; ballSpeed = 50; //(50ms per move) StartTimer(1, ballSpeed + 31); } else if (items[i].sprite.type == SPRITE_ITEMSLOWBALL) { ball_speed_slow = 1; ballSpeed = 200; //(50ms per move) StartTimer(1, ballSpeed + 31); } } //Item is not active, if it is, disable it else if (items[i].sprite.status == 0) { if (items[i].sprite.type == 0) { //Easy break condition to prevent a lot of work on this } else if (item_flame == 1 && items[i].sprite.type == SPRITE_ITEMFLAMEBALL) { item_flame = 0; items[i].sprite.type = 0; ball.solid.color = COLOR_DRKGREY; } else if (items[i].sprite.type == SPRITE_ITEMBULLET && item_bullets) { item_bullets = 0; items[i].sprite.type = 0; StopTimer(6); //StopTimer(7); } else if (items[i].sprite.type == SPRITE_ITEMSHORTPADDLE && item_short_paddle) { item_short_paddle = 0; items[i].sprite.type = 0; display_solid(&paddle, 1); //Clear the old paddle paddle_width = 25; build_solid(&paddle, paddle.y_pos, paddle.x_pos, 5, paddle_width, COLOR_DRKGREY); } else if (items[i].sprite.type == SPRITE_ITEMLONGPADDLE && item_long_paddle) { item_long_paddle = 0; items[i].sprite.type = 0; display_solid(&paddle, 1); //Clear the old paddle paddle_width = 25; build_solid(&paddle, paddle.y_pos, paddle.x_pos, 5, paddle_width, COLOR_DRKGREY); } else if (items[i].sprite.type == SPRITE_ITEMFASTBALL && ball_speed_fast) { ball_speed_fast = 0; items[i].sprite.type = 0; ballSpeed = BALL_SPEED; StartTimer(1, ballSpeed + 31); } else if (items[i].sprite.type == SPRITE_ITEMSLOWBALL && ball_speed_slow) { ball_speed_slow = 0; items[i].sprite.type = 0; ballSpeed = BALL_SPEED; StartTimer(1, ballSpeed + 31); } } } StartTimer(4, ITEM_DROP_SPEED); } } }