# include # include # include # include # include "ddutil.h" # include "dsutil.h" # include "resource.h" const int ultris_nettobreite = 360; // Breite des Inneren des Haupfensters const int ultris_nettohoehe = 520; // Hoehe des Inneren des Hauptfensters int ultris_bruttobreite; // Breite des gesamten Haupfensters (incl. Rahmen) int ultris_bruttohoehe; // Hoehe des gesamten Haupfensters (incl. Rahmen) HINSTANCE ultris_instance; // Instanz der Ultris Applikation HWND ultris_window; // Das Hauptfenster von Ultris HMENU ultris_menu; // Das Menu von Ultris const int sound_start = 0; // Sound fuer neues Spiel const int sound_dreh = 1; // Sound bei Drehung const int sound_move = 2; // Sound bei rechts/links Bewegung const int sound_down = 3; // Sound bei Aufprall const int sound_row1 = 4; // Sound bei Abraeumen einer Reihe const int sound_row2 = 5; // Sound bei Abraeumen von mehreren Reihen const int sound_ende = 6; // Sound bei Spielende const int sound_win = 7; // Sound bei Eintrag in Highscore Tabelle const int anzahl_sounds = 8; // Anzahl Sounds char *soundfiles[anzahl_sounds] = { "ul_start.wav", "ul_dreh.wav", "ul_move.wav", "ul_down.wav", "ul_row1.wav", "ul_row2.wav", "ul_ende.wav", "ul_win.wav" }; class sounds { private: CSoundManager smgr; CSound *snd[anzahl_sounds]; public: int on; sounds(); int init( HWND wnd); void play( int snr); ~sounds(); }; sounds::sounds() { int i; for( i = 0; i < anzahl_sounds; i++) snd[i] = 0; on = 1; } int sounds::init( HWND wnd) { HRESULT ret; int i; ret = smgr.Initialize( wnd, DSSCL_PRIORITY, 2, 22050, 16); if( ret < 0) return ret; for( i = 0; i < anzahl_sounds; i++) { ret = smgr.Create( snd+i, soundfiles[i]); if( ret < 0) return ret; } return S_OK; } sounds::~sounds() { int i; for( i = 0; i < anzahl_sounds; i++) { if( snd[i]) delete snd[i]; } } void sounds::play( int i) { if( !on) return; if( snd[i]->IsSoundPlaying()) { snd[i]->Stop(); snd[i]->Reset(); } snd[i]->Play(0,0); } sounds ultris_sounds; // V3 Beginn class display { private: CDisplay dsply; CSurface *hgrnd; CSurface *fldst; CSurface *fllst; CSurface *prvst; CSurface *deckel; CSurface *ziff[10]; public: display(); void free_all(); ~display() {free_all();} HRESULT init( HWND wnd); void hintergrund() { dsply.Blt( 0, 0, hgrnd);} void abdeckung() { dsply.Blt( 60, 0, deckel);} void ziffer( int pos, int val) { dsply.Blt( 120+pos*20, 50, ziff[val]);} void feldstein( int z, int s) { dsply.Blt( 80+s*20, 100+z*20, fldst);} void fallstein( int z, int s, int offset) { dsply.Blt( 80+s*20, 100+z*20+offset, fllst);} void prevstein( int p, int z, int s, int b, int h){ dsply.Blt( 290+s*15+(4-b)*15/2, 410-p*70+z*15+(4-h)*15/2, prvst);} void update(){ dsply.UpdateBounds();} HRESULT cooperative(){return dsply.GetDirectDraw()->TestCooperativeLevel();} HRESULT restore(); HRESULT present(); }; display::display() { int i; hgrnd = 0; fldst = 0; fllst = 0; prvst = 0; deckel = 0; for( i = 0; i < 10; i++) ziff[i] = 0; } void display::free_all() { int i; if( hgrnd) delete hgrnd; if( fldst) delete fldst; if( fllst) delete fllst; if( prvst) delete prvst; if( deckel) delete deckel; for( i = 0; i < 10; i++) { if( ziff[i]) delete ziff[i]; } } HRESULT display::init( HWND wnd) { HRESULT hr; int i; char fname[20]; hr = dsply.CreateWindowedDisplay( wnd, ultris_nettobreite, ultris_nettohoehe ); if( hr < 0) return hr; hr = dsply.CreateSurfaceFromBitmap( &hgrnd, "ul_hgrnd.bmp", ultris_nettobreite, ultris_nettohoehe); if( hr < 0) return hr; hr = dsply.CreateSurfaceFromBitmap( &fldst, "ul_feld.bmp", 20, 20); if( hr < 0) return hr; hr = dsply.CreateSurfaceFromBitmap( &fllst, "ul_stein.bmp", 20, 20); if( hr < 0) return hr; hr = dsply.CreateSurfaceFromBitmap( &prvst, "ul_prev.bmp", 15, 15); if( hr < 0) return hr; hr = dsply.CreateSurfaceFromBitmap( &deckel, "ul_adeck.bmp", 240, 100); if( hr < 0) return hr; for( i = 0; i < 10; i++) { sprintf( fname, "ul_z%d.bmp", i); hr = dsply.CreateSurfaceFromBitmap( &ziff[i], fname, 20, 40); if( hr < 0) return hr; } return S_OK; } HRESULT display::restore() { HRESULT hr; int i; char fname[20]; LPDIRECTDRAWPALETTE pal = 0; hr = dsply.GetDirectDraw()->RestoreAllSurfaces(); if( hr < 0) return hr; hr = hgrnd->DrawBitmap( "ul_hgrnd.bmp", ultris_nettobreite, ultris_nettohoehe); if( hr < 0) return hr; hr = fldst->DrawBitmap( "ul_feld.bmp", 20, 20); if( hr < 0) return hr; hr = fllst->DrawBitmap( "ul_stein.bmp", 20, 20); if( hr < 0) return hr; hr = prvst->DrawBitmap( "ul_prev.bmp", 15, 15); if( hr < 0) return hr; hr = deckel->DrawBitmap( "ul_adeck.bmp", 240, 100); if( hr < 0) return hr; for( i = 0; i < 10; i++) { sprintf( fname, "ul_z%d.bmp", i); hr = ziff[i]->DrawBitmap( fname, 20, 40); if( hr < 0) return hr; } return S_OK; } HRESULT display::present() { HRESULT hr; hr = dsply.Present(); if( hr == DDERR_SURFACELOST ) return restore(); return hr; } display ultris_display; // V3 Ende /* ** ultris_windowhandler */ LRESULT CALLBACK ultris_windowhandler( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_COMMAND: switch( LOWORD( wParam)) { case IDM_EXIT: PostMessage( hWnd, WM_CLOSE, 0, 0); return 0; case ID_ULTRIS_SOUND: ultris_sounds.on = !ultris_sounds.on; CheckMenuItem( ultris_menu, ID_ULTRIS_SOUND, ultris_sounds.on ? MF_CHECKED:MF_UNCHECKED); return 0; case IDM_TEST: // Testcode return 0; } break; case WM_GETMINMAXINFO: ((MINMAXINFO *)lParam)->ptMinTrackSize.x = ((MINMAXINFO *)lParam)->ptMaxTrackSize.x = ultris_bruttobreite; ((MINMAXINFO *)lParam)->ptMinTrackSize.y = ((MINMAXINFO *)lParam)->ptMaxTrackSize.y = ultris_bruttohoehe; return 0; case WM_DESTROY: PostQuitMessage( 0); return 0; // V3 Beginn case WM_MOVE: ultris_display.update(); return 0; case WM_PAINT: int i; ultris_display.hintergrund(); ultris_display.abdeckung(); for( i = 0; i < 6; i++) ultris_display.ziffer( i, i+1); for( i = 0; i < 10; i++) ultris_display.feldstein( 19-i, i); for( i = 0; i < 10; i++) ultris_display.fallstein( 1, i, 2*i); for( i = 0; i < 4; i++) ultris_display.prevstein( 3, 0, i, 4, 1); ultris_display.present(); break; // V3 Ende } return DefWindowProc(hWnd, msg, wParam, lParam); } /* ** WinMain */ int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow) { MSG msg; HACCEL acc; WNDCLASSEX wcx; ultris_instance = hInst; wcx.cbSize = sizeof( wcx); wcx.lpszClassName = TEXT( "Ultris"); wcx.lpfnWndProc = ultris_windowhandler; wcx.style = CS_VREDRAW | CS_HREDRAW; wcx.hInstance = hInst; wcx.hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDI_MAIN)); wcx.hIconSm = LoadIcon( hInst, MAKEINTRESOURCE( IDI_MAIN)); wcx.hCursor = LoadCursor( NULL, IDC_ARROW); wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcx.lpszMenuName = MAKEINTRESOURCE( IDR_MENU); wcx.cbClsExtra = 0; wcx.cbWndExtra = 0; if( !RegisterClassEx( &wcx)) return 0; acc = LoadAccelerators( hInst, MAKEINTRESOURCE(IDR_ACCEL)); ultris_bruttohoehe = ultris_nettohoehe + 2*GetSystemMetrics( SM_CYSIZEFRAME) + GetSystemMetrics( SM_CYMENU) + GetSystemMetrics( SM_CYCAPTION); ultris_bruttobreite = ultris_nettobreite + 2*GetSystemMetrics( SM_CXSIZEFRAME); ultris_window = CreateWindowEx( 0, TEXT( "Ultris"), TEXT( "Ultris"), WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, ultris_bruttobreite, ultris_bruttohoehe, NULL, NULL, hInst, NULL); if( !ultris_window) return 0; ultris_menu = GetMenu( ultris_window); if( ultris_sounds.init( ultris_window) < 0) { MessageBox( ultris_window, "Fehler beim Initialisieren der Sounds", "Ultris-Fehlermeldung", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); return 0; } CheckMenuItem( ultris_menu, ID_ULTRIS_SOUND, ultris_sounds.on ? MF_CHECKED:MF_UNCHECKED); // V3 Beginn if( ultris_display.init( ultris_window) < 0) { MessageBox( ultris_window, "Fehler beim Initialisieren der Grafik", "Ultris-Fehlermeldung", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); return 0; } // V3 Ende MoveWindow( ultris_window, (GetSystemMetrics(SM_CXSCREEN)-ultris_bruttobreite)/2, (GetSystemMetrics(SM_CYSCREEN)-ultris_bruttohoehe)/2, ultris_bruttobreite, ultris_bruttohoehe, TRUE); ShowWindow( ultris_window, nCmdShow); while( TRUE) { if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)) { if( GetMessage( &msg, NULL, 0, 0 ) == 0) return 0; // Message ist WM_QUIT if( TranslateAccelerator( ultris_window, acc, &msg) == 0) { TranslateMessage( &msg); DispatchMessage( &msg); } } else { // V3 Beginn HRESULT hr; hr = ultris_display.cooperative(); if( hr < 0) { switch( hr ) { case DDERR_EXCLUSIVEMODEALREADYSET: Sleep(10); break; case DDERR_WRONGMODE: ultris_display.free_all(); ultris_display.init( ultris_window); PostMessage( ultris_window, WM_PAINT, 0, 0); break; } } else { // Hier koennen wir uns um das Spiel kuemmern } // V3 Ende } } }