You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

410 lines
10 KiB
C++

# include <stdio.h>
# include <windows.h>
# include <ddraw.h>
# include <dsound.h>
# 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
}
}
}