📄 game.cpp
字号:
/*************************************************************************** game.cpp - description ------------------- begin : Tue Feb 29 2000 copyright : (C) 2000 by Michael Speck email : ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include <sys/timeb.h>#include <stdlib.h>#include <string.h>#include "game.h"#include "breakout.h"#include "menumanager.h"#include "level.h"#ifdef SOUNDextern SndSrv sndsrv;#endifextern Sdl sdl;extern int fast_quit;extern DrawRgn dr_src, dr_dst;Game::Game(){ //video mode#ifdef SOUND Sdl_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK );#else Sdl_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK);#endif if (Sdl_SetVideoMode(450, 325, 16, SDL_HWSURFACE)) exit(1); printf( "1\n" ); SDL_WM_SetCaption("LBreakout", 0); printf( "2\n" ); //load title title = SSur_Load("title.bmp", SDL_HWSURFACE); printf( "3\n" ); SDL_SetColorKey(title, 0, 0); printf( "4\n" ); if (title == 0) { title = SSur_Create(sdl.scr->w, sdl.scr->h, SDL_HWSURFACE); DR_SETFULLDST(title); SSur_Fill(0x0); } f_copy = SFnt_Load("font_s.sdlfnt"); f_copy->algn = TA_X_RIGHT | TA_Y_BOTTOM; SFnt_Write(f_copy, title, title->w-3, title->h-1, "(C) 2000 Michael Speck", 0); f_copy->algn = TA_X_LEFT | TA_Y_BOTTOM; SFnt_Write(f_copy, title, 0, title->h-1, "http://lgames.sourceforge.net", 0); SFnt_Free(f_copy); printf( "5\n" ); //load logo logo = SSur_Load("logo.bmp", SDL_HWSURFACE);// SDL_SetAlpha(logo, SDL_SRCALPHA, 16); if (logo == 0) exit(1); logo_x = (sdl.scr->w - logo->w) / 2; logo_y = 40; //load fonts f_menu_w = SFnt_LoadFixed("f_yellow.bmp", 32, 96, 10); f_menu_w->algn = TA_X_CENTER | TA_Y_CENTER; f_menu_b = SFnt_LoadFixed("f_white.bmp", 32, 96, 10); f_menu_b->algn = TA_X_CENTER | TA_Y_CENTER; f_hiscore = SFnt_LoadFixed("f_yellow.bmp", 32, 96, 10); f_hiscore->algn = TA_X_LEFT | TA_Y_TOP; f_enlgt_hiscore = SFnt_LoadFixed("f_white.bmp", 32, 96, 10); f_enlgt_hiscore->algn = TA_X_LEFT | TA_Y_TOP; //restricted keys memset(val_ctrl_keys, 0, sizeof(val_ctrl_keys)); for (int i = 32; i < 128; i++) val_ctrl_keys[i] = 1; val_ctrl_keys[SDLK_RETURN] = 0; val_ctrl_keys[SDLK_ESCAPE] = 0; val_ctrl_keys[SDLK_q] = 0; val_ctrl_keys[SDLK_r] = 0; val_ctrl_keys[SDLK_f] = 0; val_ctrl_keys[SDLK_p] = 0; val_ctrl_keys[SDLK_UP] = 1; val_ctrl_keys[SDLK_DOWN] = 1; val_ctrl_keys[SDLK_RIGHT] = 1; val_ctrl_keys[SDLK_LEFT] = 1; //breakout breakout = new BreakOut(); //create menumanager char *str_gfx[] = { "Off", "Low", "High" }; char *str_ctrls[] = { "Only Keyboard", "Only Mouse", "Keyboard&Mouse" }; char *str_diff[] = { "Easy", "Medium", "Hard" }; mm = new MenuManager(title, sdl.scr->w / 2, 240, f_menu_w, f_menu_b, 9, val_ctrl_keys); //create menus Menu *menu[9]; menu[0] = new Menu("main", 4); menu[1] = new Menu("newgame", 4); menu[2] = new Menu("options", 6); menu[3] = new Menu("graphics", 8); menu[4] = new Menu("audio", 4); menu[5] = new Menu("controls", 8); menu[6] = new Menu("game", 10); menu[7] = new Menu("level", 4); menu[8] = new Menu("mouse", 5); menu[0]->InsertItem(0, new MenuItem("New Game", AT_NEWGAME )); menu[0]->InsertItem(1, new MenuItem()); menu[0]->InsertItem(2, new MenuItem()); menu[0]->InsertItem(3, new MenuItem("Quit", AT_QUIT)); menu[1]->InsertItem(0, new MenuItem("New Game", AT_NEWGAME)); menu[1]->InsertItem(1, new MenuItem("Name", breakout->Setup()->name, 10)); menu[1]->InsertItem(2, new MenuItem()); menu[1]->InsertItem(3, new MenuItem("Back", menu[0])); menu[2]->InsertItem(0, new MenuItem("Game", menu[6])); menu[2]->InsertItem(1, new MenuItem("Controls", menu[5])); menu[2]->InsertItem(2, new MenuItem("Graphics", menu[3]));#ifdef SOUND menu[2]->InsertItem(3, new MenuItem("Audio", menu[4]));#else menu[2]->InsertItem(3, new MenuItem("Audio"));#endif menu[2]->InsertItem(4, new MenuItem()); menu[2]->InsertItem(5, new MenuItem("Back", menu[0])); menu[3]->InsertItem(0, new MenuItem("Transparency:", &breakout->Setup()->trp, "Off", "On")); menu[3]->InsertItem(1, new MenuItem("Animations:", &breakout->Setup()->anim, str_gfx, 3)); menu[3]->InsertItem(2, new MenuItem("Bonus Information:", &breakout->Setup()->no_exdisp, "On", "Off")); menu[3]->InsertItem(3, new MenuItem()); menu[3]->InsertItem(4, new MenuItem("Background:", &breakout->Setup()->bkgnd, "Off", "On")); menu[3]->InsertItem(5, new MenuItem("Display:", &breakout->Setup()->fullscreen, "Window", "Fullscreen")); menu[3]->InsertItem(6, new MenuItem()); menu[3]->InsertItem(7, new MenuItem("Back", menu[2])); menu[4]->InsertItem(0, new MenuItem("Sound:", &breakout->Setup()->snd_on, "Off", "On")); menu[4]->InsertItem(1, new MenuItem("Volume:", &breakout->Setup()->snd_vol, 1, 8)); menu[4]->InsertItem(2, new MenuItem()); menu[4]->InsertItem(3, new MenuItem("Back", menu[2])); menu[5]->InsertItem(0, new MenuItem("Left", &breakout->Setup()->k_left, 0)); menu[5]->InsertItem(1, new MenuItem("Right", &breakout->Setup()->k_right, 0)); menu[5]->InsertItem(2, new MenuItem("Fire", &breakout->Setup()->k_fire, 0)); menu[5]->InsertItem(3, new MenuItem()); menu[5]->InsertItem(4, new MenuItem("Mouse", menu[8])); menu[5]->InsertItem(5, new MenuItem("Use:", &breakout->Setup()->control, str_ctrls, 3)); menu[5]->InsertItem(6, new MenuItem()); menu[5]->InsertItem(7, new MenuItem("Back", menu[2])); menu[6]->InsertItem(0, new MenuItem("Difficulty:", &breakout->Setup()->diff, str_diff, 3)); menu[6]->InsertItem(1, new MenuItem("Starting Level:", &breakout->Setup()->startlevel, 0, LEVEL_NUM-1, 5)); menu[6]->InsertItem(2, new MenuItem("Paddle:", &breakout->Setup()->convex, "Flat Surface", "Convex Surface")); menu[6]->InsertItem(3, new MenuItem("Ball's Starting Angle:", &breakout->Setup()->rnd_start, "50 Degree", "Random")); menu[6]->InsertItem(4, new MenuItem()); menu[6]->InsertItem(5, new MenuItem("", &breakout->Setup()->lvls_frm_file, "Play Original Levels", "Play Own Levels")); menu[6]->InsertItem(6, new MenuItem("Level File", menu[7])); menu[6]->InsertItem(7, new MenuItem("(not selected)")); menu[6]->InsertItem(8, new MenuItem()); menu[6]->InsertItem(9, new MenuItem("Back", menu[2])); menu[7]->InsertItem(0, new MenuItem("Path", breakout->Setup()->lvl_path, 31)); menu[7]->InsertItem(1, new MenuItem("File", breakout->Setup()->lvl_file, 19)); menu[7]->InsertItem(2, new MenuItem()); menu[7]->InsertItem(3, new MenuItem("Back", menu[6])); menu[8]->InsertItem(0, new MenuItem("Warp Mouse:", &breakout->Setup()->warp, "Off", "On")); menu[8]->InsertItem(1, new MenuItem("Invert Mouse:", &breakout->Setup()->invert, "Off", "On")); menu[8]->InsertItem(2, new MenuItem("Motion Modifier:", &breakout->Setup()->motion_mod, 40, 100, 10)); menu[8]->InsertItem(3, new MenuItem()); menu[8]->InsertItem(4, new MenuItem("Back", menu[5])); //add to manager mm->InsertMenu(0, menu[0]); mm->InsertMenu(1, menu[1]); mm->InsertMenu(2, menu[2]); mm->InsertMenu(3, menu[3]); mm->InsertMenu(4, menu[4]); mm->InsertMenu(5, menu[5]); mm->InsertMenu(6, menu[6]); mm->InsertMenu(7, menu[7]); mm->InsertMenu(8, menu[8]); mm->Activate(); level_sw = menu[6]->Item(5); level_menu = menu[7]->Item(3); level_menu->SetUsed(1); level_sw->SetUsed(1); CheckLevelFile(); //randomize timeb t; ftime(&t); srand((unsigned int)t.time); #ifdef SOUND //load waves snd_menu = Wave_Load("click.wav");#endif }Game::~Game(){ if (breakout) delete breakout; if (title) SDL_FreeSurface(title); if (logo) SDL_FreeSurface(logo); if (mm) delete mm; if (f_menu_w) SFnt_Free(f_menu_w); if (f_menu_b) SFnt_Free(f_menu_b); if (f_hiscore) SFnt_Free(f_hiscore); if (f_enlgt_hiscore) SFnt_Free(f_enlgt_hiscore);#ifdef SOUND if (snd_menu) Wave_Free(snd_menu);#endif Sdl_Quit();}void Game::Run(){#ifdef SOUND sndsrv.spec.freq = 22050; sndsrv.spec.format = AUDIO_U8; sndsrv.spec.samples = 128; sndsrv.spec.channels = 1; SndSrv_Open(snd_menu->spec);#endif mm->Prepare(); DR_SETFULLDST(sdl.scr); DR_SETFULLSRC(title); SSur_Blit(); DR_SETDST(sdl.scr, logo_x, logo_y, logo->w, logo->h); DR_SETSRC(logo, 0, 0); SSur_Blit(); SDL_UNDIM(); mm->CurMenu()->Show(1); //loop SDL_Event event; int go_on = 1; int rank; int ret; while (go_on && !fast_quit) { ret = MR_CONTINUE; if (SDL_PollEvent(&event)) { switch (event.type) { case SDL_MOUSEMOTION: mm->CurMenu()->MouseMotion(event.motion.x, event.motion.y); break; case SDL_MOUSEBUTTONUP:#ifdef SOUND SndSrv_Play(snd_menu, 0);#endif ret = mm->ButtonEvent(event.button); break; case SDL_KEYUP:#ifdef SOUND SndSrv_Play(snd_menu, 0);#endif if (event.key.keysym.sym == SDLK_ESCAPE) { go_on = 0; break; } ret = mm->KeyEvent(&event.key); break; case SDL_QUIT: fast_quit = 1; break; default: break; } switch (ret) { case MR_CONTINUE: break; case AT_HISCORE: SDL_DIM(); ShowHiScore(0); DR_SETFULLDST(sdl.scr); DR_SETFULLSRC(title); SSur_Blit(); DR_SETDST(sdl.scr, logo_x, logo_y, logo->w, logo->h); DR_SETSRC(logo, 0, 0); SSur_Blit(); SDL_UNDIM(); mm->CurMenu()->Show(1); break; case AT_QUIT: go_on = 0; break; case AT_NEWGAME: SDL_DIM(); rank = breakout->Run(); //game if (!fast_quit) { if (rank != 0) ShowHiScore(rank); DR_SETFULLDST(sdl.scr); DR_SETFULLSRC(title); SSur_Blit(); DR_SETDST(sdl.scr, logo_x, logo_y, logo->w, logo->h); DR_SETSRC(logo, 0, 0); SSur_Blit(); SDL_UNDIM(); mm->CurMenu()->ClearState(); mm->SetCurMenu(0); mm->CurMenu()->Prepare(0); mm->CurMenu()->Show(1); } break; } } if (fast_quit) break; CheckLevelFile(); //compute mm->CurMenu()->Compute(); mm->CurMenu()->Update(1); SDL_Delay(8); #ifdef SOUND SndSrv_SetActive(breakout->Setup()->snd_on); SndSrv_SetVolume(breakout->Setup()->snd_vol);#endif } SDL_DIM();#ifdef SOUND SndSrv_Close();#endif}void Game::ShowHiScore(int r){ int i; int a_y = 100; int off = 50; int entry_h = f_hiscore->lh + 2; char buffer[12]; HiScoreEntry entry; SFnt *font; for (int page = 0; page<2; page++) { DR_SETFULLDST(sdl.scr); DR_SETFULLSRC(title); SSur_Blit(); SDL_UNDIM(); f_hiscore->algn = TA_X_CENTER | TA_Y_CENTER; const char* txt; if (0==page) txt="Highest Scores"; else txt="Highest Levels"; SFnt_Write(f_hiscore, sdl.scr, sdl.scr->w / 2, 50, const_cast<char*>(txt), 0); f_hiscore->algn = 0; for (i = 0; i < 10; i++) { if ((0==page && r%10 == i+1) || (1==page && r/10 == i+1)) font = f_enlgt_hiscore; else font = f_hiscore; entry = breakout->GetHiScore()->Entry(i,page); font->algn = TA_X_LEFT | TA_Y_TOP; SFnt_Write(font, sdl.scr, off, a_y + i * entry_h, entry.name, 0); font->algn = TA_X_CENTER | TA_Y_TOP; sprintf(buffer, "%i", entry.level); SFnt_Write(font, sdl.scr, sdl.scr->w / 2, a_y + i * entry_h, buffer, 0); font->algn = TA_X_RIGHT | TA_Y_TOP; sprintf(buffer, "%i", entry.score); SFnt_Write(font, sdl.scr, sdl.scr->w - off, a_y + i * entry_h, buffer, 0); } Sdl_FullUpdate(); Sdl_WaitForClick(); SDL_DIM(); }}void Game::CheckLevelFile(){ // strange and bad code, I know... // if (!level_sw->Used() && !level_menu->Used()) return; level_menu->Used(); int rep = mm->GetMenu(6) == mm->CurMenu() ? 1 : 0; if (!breakout->Setup()->lvls_frm_file) { mm->GetMenu(6)->Item(7)->SetString("(not selected)", rep); mm->GetMenu(6)->Item(1)->SetRange(0, LEVEL_NUM - 1, 5, rep); return; } char str[256]; FILE *f; if ((f = breakout->Levels_OpenFile(str)) == 0) { mm->GetMenu(6)->Item(7)->SetString("(not found)", rep); mm->GetMenu(6)->Item(1)->SetRange(0, LEVEL_NUM - 1, 5, rep); return; } else mm->GetMenu(6)->Item(7)->SetString("(found)", rep); int lev_num = 0; char *cur_pos; // load file into mem // fseek(f, 0, SEEK_END); int fsize = ftell(f); char *fbuf = new char[fsize]; fseek(f, 0, SEEK_SET); fread(fbuf, fsize, 1, f); cur_pos = fbuf; fclose(f); // count while (cur_pos < fbuf + fsize) { if (!strncmp(cur_pos, "[LEV", 4)) lev_num++; cur_pos = breakout->NextLine(0, cur_pos, fbuf + fsize); } if (lev_num > 0) mm->GetMenu(6)->Item(1)->SetRange(0, lev_num - 1, 5, rep); delete fbuf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -