mirror of
https://github.com/jummy0/sb2-decomp
synced 2025-03-15 04:24:48 +01:00
Most Engine Code
Most of the engine code (being more or less copy and paste) is done.
This commit is contained in:
parent
b0bd8090c0
commit
c79cf0e0dd
16
action.h
Normal file
16
action.h
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
extern
|
||||
BOOL Action(short action, short direct,
|
||||
short &phase, short &step,
|
||||
short &channel, short &icon, POINT &pos, short &posZ,
|
||||
short &sound);
|
||||
|
||||
extern
|
||||
BOOL Rotate (short &icon, short direct);
|
||||
|
||||
extern
|
||||
int GetIconDirect(short icon);
|
||||
|
||||
extern
|
||||
int GetAmplitude(short action);
|
155
blupi.cpp
Normal file
155
blupi.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
// blupi.cpp
|
||||
//
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <mmsystem.h>
|
||||
#include "def.h"
|
||||
#include "resource.h"
|
||||
#include "ddutil.h"
|
||||
#include "pixmap.h"
|
||||
#include "sound.h"
|
||||
#include "decor.h"
|
||||
#include "movie.h"
|
||||
#include "button.h"
|
||||
#include "menu.h"
|
||||
#include "jauge.h"
|
||||
#include "event.h"
|
||||
#include "misc.h"
|
||||
|
||||
// Define Globals
|
||||
|
||||
#define NAME "Blupi"
|
||||
#define TITLE "Eggbert"
|
||||
|
||||
|
||||
// Variables Globals
|
||||
|
||||
HWND g_hWnd; // handle <20> la fen<65>tre
|
||||
CEvent* g_pEvent = NULL;
|
||||
CPixmap* g_pPixmap = NULL; // pixmap principal
|
||||
CSound* g_pSound = NULL; // sound principal
|
||||
CMovie* g_pMovie = NULL; // movie principal
|
||||
CDecor* g_pDecor = NULL;
|
||||
char g_CDPath[MAX_PATH]; // chemin d'acc<63>s au CD-Rom
|
||||
BOOL g_bFullScreen = FALSE; // FALSE si mode de test
|
||||
int g_speedRate = 1;
|
||||
int g_timerInterval = 50; // inverval = 50ms
|
||||
int g_mouseType = MOUSETYPEGRA;
|
||||
MMRESULT g_updateTimer; // timer g<>n<EFBFBD>ral
|
||||
BOOL g_bActive = TRUE; // is application active ?
|
||||
BOOL g_bTermInit = FALSE; // initialisation en cours
|
||||
|
||||
UINT g_lastPhase = 999;
|
||||
|
||||
int GetNum(char *p)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
while ( *p >= '0' && *p <= '9' )
|
||||
{
|
||||
n *= 10;
|
||||
n += (*p++)-'0';
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
BOOL ReadConfig (LPSTR lpCmdLine)
|
||||
{
|
||||
FILE* file = NULL;
|
||||
char buffer[200];
|
||||
char* pText;
|
||||
int nb;
|
||||
|
||||
file = fopen("data\\config.def", "rb");
|
||||
if ( file == NULL ) return FALSE;
|
||||
nb = fread(buffer, sizeof(char), 200-1 file);
|
||||
buffer[nb] = 0;
|
||||
fclose(file);
|
||||
|
||||
|
||||
#if 0
|
||||
pText = strstr(buffer, "CD-Rom=");
|
||||
if ( pText == NULL )
|
||||
{
|
||||
#if _DEMO
|
||||
GetCurrentDirectory(MAX_PATH, g_CDPath);
|
||||
i = strlen (g_CDPath);
|
||||
if ( i > 0 && g_CDPath [i-1] != '\\' )
|
||||
{
|
||||
g_CDPath[i++] = '\\';
|
||||
g_CDPath[i] = 0;
|
||||
}
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
pText += 7;
|
||||
i = 0;
|
||||
while ( pText[i] != 0 && pText[i] != '\n' && pText[i] != '\r' )
|
||||
{
|
||||
g_CDPath[i] = pText[i];
|
||||
i ++;
|
||||
}
|
||||
if ( i > 0 && g_CDPath[i-1] != '\\' )
|
||||
{
|
||||
g_CDPath[i++] = '\\';
|
||||
}
|
||||
g_CDPath[i] = 0; // met le terminateur
|
||||
}
|
||||
|
||||
#if !_DEMO & !_EGAMES
|
||||
if ( strstr(lpCmdLine, "-nocd") == NULL )
|
||||
{
|
||||
char drive[10];
|
||||
|
||||
drive[0] = g_CDPath[0];
|
||||
drive[1] = ':';
|
||||
drive[2] = '\\';
|
||||
drive[3] = 0;
|
||||
nb = GetDriveType(drive);
|
||||
if ( nb != DRIVE_CDROM ) return FALSE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pText = strstr(buffer, "SpeedRate=");
|
||||
if ( pText != NULL )
|
||||
{
|
||||
g_speedRate = GetNum(pText+10);
|
||||
if ( g_speedRate < 1 ) g_speedRate = 1;
|
||||
if ( g_speedRate > 2 ) g_speedRate = 2;
|
||||
}
|
||||
|
||||
pText = strstr(buffer, "Timer=");
|
||||
if ( pText != NULL )
|
||||
{
|
||||
g_timerInterval = GetNum(pText+6);
|
||||
if ( g_timerInterval < 10 ) g_timerInterval = 10;
|
||||
if ( g_timerInterval > 1000 ) g_timerInterval = 1000;
|
||||
}
|
||||
|
||||
pText = strstr(buffer, "FullScreen=");
|
||||
if ( pText != NULL )
|
||||
{
|
||||
g_bFullScreen = GetNum(pText+11);
|
||||
if ( g_bFullScreen != 0 ) g_bFullScreen = 1;
|
||||
}
|
||||
|
||||
pText = strstr(buffer, "MouseType=");
|
||||
if ( pText != NULL )
|
||||
{
|
||||
g_mouseType = GetNum(pText+10);
|
||||
if ( g_mouseType < 1 ) g_mouseType = 1;
|
||||
if ( g_mouseType > 9 ) g_mouseType = 9;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
417
button.cpp
Normal file
417
button.cpp
Normal file
@ -0,0 +1,417 @@
|
||||
// Button.cpp
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ddraw.h>
|
||||
#include "def.h"
|
||||
#include "pixmap.h"
|
||||
#include "sound.h"
|
||||
#include "decor.h"
|
||||
#include "button.h"
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
// Constructor
|
||||
|
||||
CButton:CButton()
|
||||
{
|
||||
m_type = 0;
|
||||
m_bEnable = TRUE;
|
||||
m_bHide = FALSE;
|
||||
m_state = 0;
|
||||
m_mouseState = 0;
|
||||
m_mbMenu = 0;
|
||||
m_nbToolTips = 0;
|
||||
m_selMenu = 0;
|
||||
m_bMouseDown = FALSE;
|
||||
m_bMinimizeRedraw = FALSE;
|
||||
m_bRedraw = FALSE;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
CButton:~CButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Create a new Button
|
||||
|
||||
BOOL CButton::Create(HWND hWnd, CPixmap *pPixmap, CSound *pSound,
|
||||
POINT pos, int type, BOOL bMinimizeRedraw,
|
||||
int *pMenu, int nbMenu,
|
||||
int *pToolTips, int nbToolTips,
|
||||
int region, UINT message)
|
||||
{
|
||||
POINT iconDim;
|
||||
int i, icon;
|
||||
|
||||
static int ttypes[] =
|
||||
{
|
||||
DIMBUTTONX,DIMBUTTONY,
|
||||
};
|
||||
|
||||
if ( type < 0 || type > 0 ) return FALSE;
|
||||
|
||||
iconDim.x = ttypes[type*2+0];
|
||||
iconDim.y = ttypes[type*2+1];
|
||||
|
||||
m_hWnd = hWnd;
|
||||
m_pPixmap = pPixmap;
|
||||
m_pSound = pSound;
|
||||
m_type = type;
|
||||
m_bMinimizeRedraw = bMinimizeRedraw;
|
||||
m_bEnable = TRUE;
|
||||
m_bHide = FALSE;
|
||||
m_message = message;
|
||||
m_pos = pos;
|
||||
m_dim = iconDim;
|
||||
m_nbMenu = nbMenu;
|
||||
m_nbToolTips = nbToolTips;
|
||||
m_selMenu = 0;
|
||||
m_state = 0;
|
||||
m_mouseState = 0;
|
||||
m_bMouseDown = FALSE;
|
||||
m_bRedraw = TRUE;
|
||||
|
||||
/* Do we need this yet?
|
||||
///////////////////////////////////////////////////
|
||||
for ( i=0 ; i<nbMenu ; i++ )
|
||||
{
|
||||
icon = pMenu[i];
|
||||
|
||||
if ( region == 1 ) // palmiers ?
|
||||
{
|
||||
if ( icon == 0 ) icon = 90; // sol normal
|
||||
if ( icon == 1 ) icon = 91; // sol inflammable
|
||||
if ( icon == 2 ) icon = 92; // sol inculte
|
||||
if ( icon == 7 ) icon = 9; // plante
|
||||
if ( icon == 8 ) icon = 10; // arbre
|
||||
}
|
||||
|
||||
if ( region == 2 ) // hiver ?
|
||||
{
|
||||
if ( icon == 0 ) icon = 96; // sol normal
|
||||
if ( icon == 1 ) icon = 97; // sol inflammable
|
||||
if ( icon == 2 ) icon = 98; // sol inculte
|
||||
if ( icon == 8 ) icon = 99; // arbre
|
||||
}
|
||||
|
||||
if ( region == 3 ) // sapin ?
|
||||
{
|
||||
if ( icon == 0 ) icon = 102; // sol normal
|
||||
if ( icon == 1 ) icon = 103; // sol inflammable
|
||||
if ( icon == 2 ) icon = 104; // sol inculte
|
||||
if ( icon == 8 ) icon = 105; // arbre
|
||||
}
|
||||
|
||||
m_iconMenu[i] = icon;
|
||||
}
|
||||
|
||||
for ( i=0 ; i<nbToolTips ; i++ )
|
||||
{
|
||||
m_toolTips[i] = pToolTips[i];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
/////////////////////////////////////////////////////
|
||||
*/
|
||||
}
|
||||
|
||||
// Draw a button in its state
|
||||
|
||||
void CButton::Draw()
|
||||
{
|
||||
int i;
|
||||
POINT pos;
|
||||
RECT rect;
|
||||
|
||||
if ( m_bMinimizeRedraw && !m_bRedraw ) return;
|
||||
m_bRedraw = FALSE, m_bSomething = FALSE;
|
||||
|
||||
if ( m_bHide ) // Hidden button
|
||||
{
|
||||
pos.y = m_pos.y;
|
||||
pos.x = m_pos.x;
|
||||
m_pPixmap->DrawPart(-1, CHBACK, m_pos, rect, 1); // Draw the background
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_bEnable )
|
||||
{
|
||||
m_pPixmap->DrawIcon(-1, CHBUTTON+m_type, m_mousestatre, m_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pPixmap->DrawIcon(-1, CHBUTTON+m_type, 4, m_pos);
|
||||
}
|
||||
|
||||
if ( m_nbMenu == 0 ) return;
|
||||
|
||||
pos = m_pos;
|
||||
if ( m_nbMenu > 0 )
|
||||
{
|
||||
m_pPixmap->DrawIcon(-1, CHBUTTON+m_type,
|
||||
m_iconMenu[m_selMenu]+6, pos);
|
||||
}
|
||||
|
||||
if ( m_nbMenu == 1 || !m_bEnable || !m_bMouseDown ) return;
|
||||
|
||||
pos = m_pos;
|
||||
pos.x += m_dim.x+2;
|
||||
for ( i=0 ; i<m_nbMenu ; i++ )
|
||||
{
|
||||
m_pPixmap->DrawIcon(-1, CHBUTTON+m_type, i==m_selMenu?1:0, pos);
|
||||
m_pPixmap->DrawIcon(-1, CHBUTTON+m_type, m_iconMenu[i]+6, pos);
|
||||
pos.x += m_dim.x-1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/Needed Yet?
|
||||
//////////////////////////////////////////////
|
||||
void CButton::Redraw()
|
||||
{
|
||||
m_bRedraw = TRUE;
|
||||
}
|
||||
//////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
int CButton::GetState()
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void CButton::SetState(int state)
|
||||
{
|
||||
if ( m_state != state ||
|
||||
m_mouseState != state )
|
||||
{
|
||||
m_bRedraw = TRUE;
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
m_mouseState = state;
|
||||
}
|
||||
|
||||
int CButton::GetMenu()
|
||||
{
|
||||
return m_selMenu;
|
||||
}
|
||||
|
||||
void CButton::SetMenu(int menu)
|
||||
{
|
||||
if ( m_selMenu != menu )
|
||||
{
|
||||
m_bRedraw = TRUE;
|
||||
}
|
||||
|
||||
m_selMenu = menu;
|
||||
}
|
||||
|
||||
void CButton::SetEnable(BOOL bEnable)
|
||||
{
|
||||
if ( m_bEnable != bEnable )
|
||||
{
|
||||
m_bRedraw = TRUE;
|
||||
}
|
||||
|
||||
m_bEnable = bEnable;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Needed Yet?
|
||||
/////////////////////////////////////////
|
||||
BOOL CButton::GetHide()
|
||||
{
|
||||
return m_bHide;
|
||||
}
|
||||
/////////////////////////////////////////
|
||||
*/
|
||||
|
||||
|
||||
void CButton::SetHide(BOOL bHide)
|
||||
{
|
||||
if ( m_bHide != bHide )
|
||||
{
|
||||
m_bRedraw = TRUE;
|
||||
}
|
||||
|
||||
m_bHide = bHide;
|
||||
}
|
||||
|
||||
BOOL CButton::TreatEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
POINT pos;
|
||||
|
||||
if ( m_bHide || !m_bEnable ) return FALSE;
|
||||
|
||||
pos = ConvLongToPos(lParam);
|
||||
|
||||
switch( message )
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN;
|
||||
if ( MouseDown(pos) ) return TRUE;
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if ( MouseMove(pos) ) return TRUE;
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
if ( MouseUp(pos) ) return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// All buttons must receive the BUTTONUP event!
|
||||
|
||||
// Indicates whether the mouse is over this button.
|
||||
|
||||
BOOL CButton::MouseOnButton(POINT pos)
|
||||
{
|
||||
return Detect(pos);
|
||||
}
|
||||
|
||||
// Return the tooltips for a button, depending
|
||||
// on mouse position.
|
||||
|
||||
int CButton::GetToolTips(POINT pos)
|
||||
{
|
||||
int width = m_dim.x;
|
||||
int rank;
|
||||
|
||||
if ( m_bHide || !m_bEnable ) return -1;
|
||||
|
||||
if ( m_nbMenu > 1 && m_bMouseDown ) // Drop-down submenu?
|
||||
{
|
||||
width += 2+(m_dim.x-1)*m_nbMenu;
|
||||
}
|
||||
|
||||
if ( pos.x < m_pos.x ||
|
||||
pos.x > m_pos.x+width ||
|
||||
pos.y < m_pos.y ||
|
||||
pos.y > m_pos.y+m_dim.y ) return -1;
|
||||
|
||||
rank = (pos.x=-(m_pos.x+2+1))/(m_dim.x-1);
|
||||
if ( rank < 0 ) rank = 0;
|
||||
if ( rank > m_nbToolTips ) return -1;
|
||||
|
||||
if ( m_nbMenu > 1 )
|
||||
{
|
||||
if ( m_MouseDown && rank > 0 )
|
||||
{
|
||||
rank --;
|
||||
}
|
||||
else
|
||||
{
|
||||
rank = m_selMenu;
|
||||
}
|
||||
}
|
||||
|
||||
return m_toolTips[rank];
|
||||
}
|
||||
|
||||
BOOL CButton::Detect(POINT pos)
|
||||
{
|
||||
int width = m_dim.x;
|
||||
|
||||
if ( m_bHide || !m_bEnable ) return FALSE;
|
||||
|
||||
if ( m_nbMenu > 1 && m_bMouseDown )
|
||||
{
|
||||
width += 2+(m_dim.x-1)*m_nbMenu;
|
||||
}
|
||||
|
||||
if ( pos.x < m_pos.x ||
|
||||
pos.x > m_pos.x+width ||
|
||||
pos.y < m_pos.y ||
|
||||
pos.y > m_pos.y+m_dim.y ) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CButton::MouseDown(POINT pos)
|
||||
{
|
||||
if ( !Detect(pos) ) return FALSE;
|
||||
|
||||
m_mouseState = 1;
|
||||
m_bMouseDown = TRUE;
|
||||
m_bRedraw = TRUE;
|
||||
PostMessage(m_hWnd, WM_UPDATE, 0, 0);
|
||||
|
||||
m_pSound->PlayImage(SOUND_CLICK, pos);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CButton::MouseMove(POINT pos)
|
||||
{
|
||||
BOOL bDetect;
|
||||
int iState, iMenu;
|
||||
|
||||
iState = m_mouseState;
|
||||
iMenu = m_selMenu;
|
||||
|
||||
bDetect = Detect(pos);
|
||||
|
||||
if ( m_bMouseDown )
|
||||
{
|
||||
if ( bDetect ) m_mouseState = 1;
|
||||
else m_mouseState = m_state;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bDetect ) m_mouseState = m_state+2;
|
||||
else m_mouseState = m_state;
|
||||
}
|
||||
|
||||
if ( m_nbMenu > 1 &&
|
||||
m_bMouseDown &&
|
||||
pos.x > m_pos.x+m_dim.x+2 )
|
||||
{
|
||||
m_selMenu = (pos.x-(m_pos.x+m_dim.x+2))/(m_dim.x-1);
|
||||
if ( m_selMenu >= m_nbMenu )
|
||||
{
|
||||
m_selMenu = m_nbMenu-1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( iState != m_mouseState ||
|
||||
iMenu != m_selMenu )
|
||||
{
|
||||
m_bRedraw = TRUE;
|
||||
PostMessage(m_hWnd, WM_UPDATE, 0, 0);
|
||||
}
|
||||
|
||||
return m_bMouseDown;
|
||||
}
|
||||
|
||||
BOOL CButton::MouseUp(POINT pos)
|
||||
{
|
||||
BOOL bDetect;
|
||||
|
||||
bDetect = Detect(pos);
|
||||
|
||||
m_mouseState = m_state;
|
||||
m_bMouseDown = FALSE;
|
||||
m_bRedraw = TRUE;
|
||||
|
||||
if ( !bDetect ) return FALSE;
|
||||
|
||||
if ( m_message != -1 )
|
||||
{
|
||||
PostMessage(m_hWnd, m_message, 0, 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
61
button.h
Normal file
61
button.h
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
|
||||
class CButton
|
||||
{
|
||||
public:
|
||||
CButton();
|
||||
~CButton();
|
||||
|
||||
BOOL Create(HWND hWnd, CPixmap *pPixmap, CSound *pSound,
|
||||
POINT pos, int type, BOOL bMinimizeRedraw,
|
||||
int *pMenu, int nbMenu,
|
||||
int *pTooltips, int nbToolTips,
|
||||
int region, UINT message);
|
||||
void Draw();
|
||||
void Redraw();
|
||||
|
||||
int GetState();
|
||||
void SetState(int state);
|
||||
|
||||
int GetMenu();
|
||||
void SetMenu(int menu);
|
||||
|
||||
BOOL GetEnable();
|
||||
void SetEnable(BOOL bEnable);
|
||||
|
||||
BOOL GetHide();
|
||||
void SetHide(BOOL bHide);
|
||||
|
||||
BOOL TreatEvent(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL MouseOnButton(POINT pos);
|
||||
int GetToolTips(POINT pos);
|
||||
|
||||
|
||||
protected:
|
||||
BOOL Detect(POINT pos);
|
||||
BOOL MouseDown(POINT pos);
|
||||
BOOL MouseMove(POINT pos);
|
||||
BOOL MouseUp(POINT pos);
|
||||
|
||||
protected:
|
||||
HWND m_hWnd;
|
||||
CPixmap* m_pPixmap;
|
||||
CDecor* m_pDecor;
|
||||
CSound* m_pSound;
|
||||
int m_type; // type de bouton
|
||||
BOOL m_bEnable; // TRUE si bouton actif
|
||||
BOOL m_bHide; // TRUE si bouton cach<63>
|
||||
UINT m_message; // message envoy<6F> si bouton actionn<6E>
|
||||
POINT m_pos; // coin sup/gauche
|
||||
POINT m_dim; // dimensions
|
||||
int m_state; // 0=rel<65>ch<63>, 1=press<73>, +2=survoll<6C>
|
||||
int m_mouseState; // 0=rel<65>ch<63>, 1=press<73>, +2=survoll<6C>
|
||||
int m_iconMenu[20]; // ic<69>nes du sous-menu
|
||||
int m_toolTips[20]; // info-bulles
|
||||
int m_nbMenu; // nb de case du sous-menu
|
||||
int m_nbToolTips; // nb d'info-bulles
|
||||
int m_selMenu; // sous-menu s<>lectionn<6E>
|
||||
BOOL m_bMouseDown; // TRUE -> bouton souris press<73>
|
||||
BOOL m_bMinimizeRedraw;
|
||||
BOOL m_bRedraw; // TRUE -> doit <20>tre redessin<69>
|
||||
};
|
415
ddutil.cpp
Normal file
415
ddutil.cpp
Normal file
@ -0,0 +1,415 @@
|
||||
/*==========================================================================
|
||||
*
|
||||
* Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
|
||||
*
|
||||
* File: ddutil.cpp
|
||||
* Content: Routines for loading bitmap and palettes from resources
|
||||
*
|
||||
***************************************************************************/
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <ddraw.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "ddutil.h"
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
// Le message :
|
||||
// First-chance exception in Blupi.exe (GDI32.DLL): 0xC0000005: Access Violation.
|
||||
// appara<72>t au endroits marqu<71>s par (@) ...
|
||||
|
||||
BOOL g_bDebug = TRUE;
|
||||
|
||||
void DDSetDebug(BOOL bDebug)
|
||||
{
|
||||
g_bDebug = bDebug;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDConnectBitmap
|
||||
*
|
||||
* create a DirectDrawSurface from a bitmap resource.
|
||||
*
|
||||
*/
|
||||
extern "C" IDirectDrawSurface * DDConnectBitmap(IDirectDraw *pdd, HBITMAP hbm)
|
||||
{
|
||||
BITMAP bm;
|
||||
DDSURFACEDESC ddsd;
|
||||
IDirectDrawSurface *pdds;
|
||||
HRESULT ddrval;
|
||||
|
||||
//
|
||||
// get size of the bitmap
|
||||
//
|
||||
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
|
||||
|
||||
//
|
||||
// create a DirectDrawSurface for this bitmap
|
||||
//
|
||||
ZeroMemory(&ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
|
||||
//? ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
|
||||
ddsd.dwWidth = bm.bmWidth;
|
||||
ddsd.dwHeight = bm.bmHeight;
|
||||
|
||||
ddrval = pdd->CreateSurface(&ddsd, &pdds, NULL);
|
||||
if ( ddrval != DD_OK )
|
||||
{
|
||||
TraceErrorDD(ddrval, "", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DDCopyBitmap(pdds, hbm, 0, 0, bm.bmWidth, bm.bmHeight);
|
||||
|
||||
return pdds;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDLoadBitmap
|
||||
*
|
||||
* create a DirectDrawSurface from a bitmap resource.
|
||||
*
|
||||
*/
|
||||
extern "C" IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy)
|
||||
{
|
||||
HBITMAP hbm;
|
||||
BITMAP bm;
|
||||
DDSURFACEDESC ddsd;
|
||||
IDirectDrawSurface *pdds;
|
||||
HRESULT ddrval;
|
||||
|
||||
if ( g_bDebug ) OutputDebug("DDLoadBitmap\n");
|
||||
//
|
||||
// try to load the bitmap as a resource, if that fails, try it as a file
|
||||
//
|
||||
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);
|
||||
|
||||
if ( g_bDebug ) OutputDebug("DDLoadBitmap\n");
|
||||
if (hbm == NULL)
|
||||
{
|
||||
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION); // (@)
|
||||
}
|
||||
|
||||
if ( hbm == NULL ) return NULL;
|
||||
|
||||
//
|
||||
// get size of the bitmap
|
||||
//
|
||||
if ( g_bDebug ) OutputDebug("DDLoadBitmap: GetObject\n");
|
||||
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
|
||||
|
||||
//
|
||||
// create a DirectDrawSurface for this bitmap
|
||||
//
|
||||
ZeroMemory(&ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
|
||||
//? ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
|
||||
ddsd.dwWidth = bm.bmWidth;
|
||||
ddsd.dwHeight = bm.bmHeight;
|
||||
|
||||
if ( g_bDebug ) OutputDebug("DDLoadBitmap: CreateSurface\n");
|
||||
ddrval = pdd->CreateSurface(&ddsd, &pdds, NULL);
|
||||
if ( ddrval != DD_OK )
|
||||
{
|
||||
TraceErrorDD(ddrval, "", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
|
||||
if ( g_bDebug ) OutputDebug("DDLoadBitmap: DeleteObject\n");
|
||||
DeleteObject(hbm); // (@)
|
||||
|
||||
if ( g_bDebug ) OutputDebug("DDLoadBitmap: return\n");
|
||||
return pdds;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDReLoadBitmap
|
||||
*
|
||||
* load a bitmap from a file or resource into a directdraw surface.
|
||||
* normaly used to re-load a surface after a restore.
|
||||
*
|
||||
*/
|
||||
HRESULT DDReLoadBitmap(IDirectDrawSurface *pdds, LPCSTR szBitmap)
|
||||
{
|
||||
HBITMAP hbm;
|
||||
HRESULT hr;
|
||||
|
||||
//
|
||||
// try to load the bitmap as a resource, if that fails, try it as a file
|
||||
//
|
||||
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
|
||||
|
||||
if (hbm == NULL)
|
||||
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
|
||||
|
||||
if (hbm == NULL)
|
||||
{
|
||||
if ( g_bDebug ) OutputDebug("handle is null\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
|
||||
if (hr != DD_OK)
|
||||
{
|
||||
if ( g_bDebug ) OutputDebug("ddcopybitmap failed\n");
|
||||
}
|
||||
|
||||
|
||||
DeleteObject(hbm);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDCopyBitmap
|
||||
*
|
||||
* draw a bitmap into a DirectDrawSurface
|
||||
*
|
||||
*/
|
||||
extern "C" HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy)
|
||||
{
|
||||
HDC hdcImage;
|
||||
HDC hdc;
|
||||
BITMAP bm;
|
||||
DDSURFACEDESC ddsd;
|
||||
HRESULT hr;
|
||||
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap\n");
|
||||
if (hbm == NULL || pdds == NULL)
|
||||
return E_FAIL;
|
||||
|
||||
//
|
||||
// make sure this surface is restored.
|
||||
//
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: Restore\n");
|
||||
pdds->Restore();
|
||||
|
||||
//
|
||||
// select bitmap into a memoryDC so we can use it.
|
||||
//
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: CreateCompatibleDC\n");
|
||||
hdcImage = CreateCompatibleDC(NULL);
|
||||
if (!hdcImage)
|
||||
OutputDebug("createcompatible dc failed\n");
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: SelectObject\n");
|
||||
SelectObject(hdcImage, hbm);
|
||||
|
||||
//
|
||||
// get size of the bitmap
|
||||
//
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: GetObject\n");
|
||||
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
|
||||
dx = dx == 0 ? bm.bmWidth : dx; // use the passed size, unless zero
|
||||
dy = dy == 0 ? bm.bmHeight : dy;
|
||||
|
||||
//
|
||||
// get size of surface.
|
||||
//
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: GetSurfaceDesc\n");
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
|
||||
pdds->GetSurfaceDesc(&ddsd);
|
||||
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: StretchBlt\n");
|
||||
if ((hr = pdds->GetDC(&hdc)) == DD_OK)
|
||||
{
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: StretchBlt-go\n");
|
||||
StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: ReleaseDC\n");
|
||||
pdds->ReleaseDC(hdc); // (@)
|
||||
}
|
||||
|
||||
if ( g_bDebug ) OutputDebug("DDCopyBitmap: DeleteDC\n");
|
||||
DeleteDC(hdcImage);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// DDLoadPalette
|
||||
//
|
||||
// Create a DirectDraw palette object from a bitmap resoure
|
||||
//
|
||||
// if the resource does not exist or NULL is passed create a
|
||||
// default 332 palette.
|
||||
//
|
||||
extern "C" IDirectDrawPalette * DDLoadPalette(IDirectDraw *pdd, LPCSTR szBitmap)
|
||||
{
|
||||
IDirectDrawPalette* ddpal;
|
||||
int i;
|
||||
int n;
|
||||
int fh;
|
||||
HRSRC h;
|
||||
LPBITMAPINFOHEADER lpbi;
|
||||
PALETTEENTRY ape[256];
|
||||
RGBQUAD * prgb;
|
||||
|
||||
//
|
||||
// build a 332 palette as the default.
|
||||
//
|
||||
for (i=0; i<256; i++)
|
||||
{
|
||||
ape[i].peRed = (BYTE)(((i >> 5) & 0x07) * 255 / 7);
|
||||
ape[i].peGreen = (BYTE)(((i >> 2) & 0x07) * 255 / 7);
|
||||
ape[i].peBlue = (BYTE)(((i >> 0) & 0x03) * 255 / 3);
|
||||
ape[i].peFlags = (BYTE)0;
|
||||
}
|
||||
|
||||
//
|
||||
// get a pointer to the bitmap resource.
|
||||
//
|
||||
if (szBitmap && (h = FindResource(NULL, szBitmap, RT_BITMAP)))
|
||||
{
|
||||
if ( g_bDebug ) OutputDebug("DDLoadPalette -a\n");
|
||||
lpbi = (LPBITMAPINFOHEADER)LockResource(LoadResource(NULL, h));
|
||||
if (!lpbi)
|
||||
OutputDebug("lock resource failed\n");
|
||||
prgb = (RGBQUAD*)((BYTE*)lpbi + lpbi->biSize);
|
||||
|
||||
if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))
|
||||
n = 0;
|
||||
else if (lpbi->biBitCount > 8)
|
||||
n = 0;
|
||||
else if (lpbi->biClrUsed == 0)
|
||||
n = 1 << lpbi->biBitCount;
|
||||
else
|
||||
n = lpbi->biClrUsed;
|
||||
|
||||
//
|
||||
// a DIB color table has its colors stored BGR not RGB
|
||||
// so flip them around.
|
||||
//
|
||||
for(i=0; i<n; i++ )
|
||||
{
|
||||
ape[i].peRed = prgb[i].rgbRed;
|
||||
ape[i].peGreen = prgb[i].rgbGreen;
|
||||
ape[i].peBlue = prgb[i].rgbBlue;
|
||||
ape[i].peFlags = 0;
|
||||
}
|
||||
}
|
||||
else if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
|
||||
{
|
||||
if ( g_bDebug ) OutputDebug("DDLoadPalette -b\n");
|
||||
BITMAPFILEHEADER bf;
|
||||
BITMAPINFOHEADER bi;
|
||||
|
||||
_lread(fh, &bf, sizeof(bf));
|
||||
_lread(fh, &bi, sizeof(bi));
|
||||
_lread(fh, ape, sizeof(ape));
|
||||
_lclose(fh);
|
||||
|
||||
if (bi.biSize != sizeof(BITMAPINFOHEADER))
|
||||
n = 0;
|
||||
else if (bi.biBitCount > 8)
|
||||
n = 0;
|
||||
else if (bi.biClrUsed == 0)
|
||||
n = 1 << bi.biBitCount;
|
||||
else
|
||||
n = bi.biClrUsed;
|
||||
|
||||
//
|
||||
// a DIB color table has its colors stored BGR not RGB
|
||||
// so flip them around.
|
||||
//
|
||||
//?
|
||||
char s[50];
|
||||
sprintf(s, "DDLoadPalette n=%d\n", n);
|
||||
if ( g_bDebug ) OutputDebug(s);
|
||||
//?
|
||||
for(i=0; i<n; i++ )
|
||||
{
|
||||
BYTE r = ape[i].peRed;
|
||||
ape[i].peRed = ape[i].peBlue;
|
||||
ape[i].peBlue = r;
|
||||
}
|
||||
}
|
||||
|
||||
pdd->CreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL);
|
||||
|
||||
return ddpal;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDColorMatch
|
||||
*
|
||||
* convert a RGB color to a pysical color.
|
||||
*
|
||||
* we do this by leting GDI SetPixel() do the color matching
|
||||
* then we lock the memory and see what it got mapped to.
|
||||
*/
|
||||
extern "C" DWORD DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb)
|
||||
{
|
||||
COLORREF rgbT;
|
||||
HDC hdc;
|
||||
DWORD dw = CLR_INVALID;
|
||||
DDSURFACEDESC ddsd;
|
||||
HRESULT hres;
|
||||
|
||||
//
|
||||
// use GDI SetPixel to color match for us
|
||||
//
|
||||
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
|
||||
{
|
||||
rgbT = GetPixel(hdc, 0, 0); // save current pixel value
|
||||
SetPixel(hdc, 0, 0, rgb); // set our value
|
||||
pdds->ReleaseDC(hdc);
|
||||
}
|
||||
|
||||
//
|
||||
// now lock the surface so we can read back the converted color
|
||||
//
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
|
||||
;
|
||||
|
||||
if (hres == DD_OK)
|
||||
{
|
||||
dw = *(DWORD *)ddsd.lpSurface; // get DWORD
|
||||
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1; // mask it to bpp
|
||||
pdds->Unlock(NULL);
|
||||
}
|
||||
|
||||
//
|
||||
// now put the color that was there back.
|
||||
//
|
||||
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
|
||||
{
|
||||
SetPixel(hdc, 0, 0, rgbT);
|
||||
pdds->ReleaseDC(hdc);
|
||||
}
|
||||
|
||||
return dw;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDSetColorKey
|
||||
*
|
||||
* set a color key for a surface, given a RGB.
|
||||
* if you pass CLR_INVALID as the color key, the pixel
|
||||
* in the upper-left corner will be used.
|
||||
*/
|
||||
extern "C" HRESULT DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb)
|
||||
{
|
||||
DDCOLORKEY ddck;
|
||||
|
||||
ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);
|
||||
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
|
||||
return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
|
||||
}
|
||||
|
||||
extern "C" HRESULT DDSetColorKey2(IDirectDrawSurface *pdds, COLORREF rgb1,
|
||||
COLORREF rgb2)
|
||||
{
|
||||
DDCOLORKEY ddck;
|
||||
|
||||
ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb1);
|
||||
ddck.dwColorSpaceHighValue = DDColorMatch(pdds, rgb2);
|
||||
return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
|
||||
}
|
23
ddutil.h
Normal file
23
ddutil.h
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void DDSetDebug (BOOL bDebug);
|
||||
extern IDirectDrawSurface * DDConnectBitmap(IDirectDraw *pdd, HBITMAP hbm);
|
||||
extern IDirectDrawPalette * DDLoadPalette(IDirectDraw *pdd, LPCSTR szBitmap);
|
||||
extern IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy);
|
||||
extern HRESULT DDReLoadBitmap(IDirectDrawSurface *pdds, LPCSTR szBitmap);
|
||||
extern HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy);
|
||||
extern DWORD DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb);
|
||||
extern HRESULT DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb);
|
||||
extern HRESULT DDSetColorKey2(IDirectDrawSurface *pdds, COLORREF rgb1, COLORREF rgb2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
59
decor.cpp
Normal file
59
decor.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
// CDecor.cpp
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ddraw.h>
|
||||
#include "def.h"
|
||||
#include "resource.h"
|
||||
#include "pixmap.h"
|
||||
#include "sound.h"
|
||||
#include "decor.h"
|
||||
#include "action.h"
|
||||
#include "text.h"
|
||||
#include "misc.h"
|
||||
#include "fifo.h"
|
||||
#include "DECMOVE.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#define TEXTDELAY 10
|
||||
|
||||
// Constructor
|
||||
// Possibly incomplete
|
||||
|
||||
CDecor::CDecor()
|
||||
{
|
||||
m_hWnd = NULL;
|
||||
m_pSound = NULL;
|
||||
m_pPixmap = NULL;
|
||||
|
||||
m_time = 0;
|
||||
m_bAllMissions = FALSE;
|
||||
m_bInvincible = FALSE;
|
||||
m_bShowSecret = FALSE;
|
||||
m_bAccessBuild = FALSE;
|
||||
m_bNetPacked = FALSE;
|
||||
m_bNetMovePredict = TRUE;
|
||||
m_bNetDebug = FALSE;
|
||||
m_bMulti = FALSE;
|
||||
m_team = FALSE;
|
||||
m_netPacketsSent = 0;
|
||||
m_netPacketsSent2 = 0;
|
||||
m_netPacketsRecieved = 0;
|
||||
m_netPacketsRecieved2 = 0;
|
||||
|
||||
Init(CHFLOOR, 0);
|
||||
BlupiFlush();
|
||||
MoveFlush();
|
||||
InitDrapeau();
|
||||
}
|
||||
|
||||
CDecor::~CDecor()
|
||||
{
|
||||
UndoClose();
|
||||
}
|
220
event.h
Normal file
220
event.h
Normal file
@ -0,0 +1,220 @@
|
||||
// Event.h
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT message;
|
||||
int type;
|
||||
int iconMenu[20];
|
||||
int x, y;
|
||||
int toolTips[20];
|
||||
}
|
||||
Button;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT phase;
|
||||
char backName[20];
|
||||
BOOL bCDrom;
|
||||
Button buttons[MAXBUTTON];
|
||||
}
|
||||
Phase;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short majRev;
|
||||
short minRev;
|
||||
short bSchool;
|
||||
short bPrivate;
|
||||
short world;
|
||||
short skill;
|
||||
short reserve1[99];
|
||||
}
|
||||
DemoHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int time;
|
||||
UINT message;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
}
|
||||
DemoEvent;
|
||||
|
||||
|
||||
class CEvent
|
||||
{
|
||||
public:
|
||||
CEvent();
|
||||
~CEvent();
|
||||
|
||||
POINT GetMousePos();
|
||||
void Create(HWND hWnd, CPixmap *pPixmap, CDecor *pDecor, CSound *pSound, CMovie *pMovie);
|
||||
void SetFullScreen(BOOL bFullScreen);
|
||||
void SetMouseType(int mouseType);
|
||||
int GetWorld();
|
||||
int GetPhysicalWorld();
|
||||
int GetImageWorld();
|
||||
BOOL IsHelpHide();
|
||||
BOOL ChangePhase(UINT phase);
|
||||
void MovieToStart();
|
||||
UINT GetPhase();
|
||||
void TryInsert();
|
||||
void RestoreGame();
|
||||
|
||||
int GetButtonIndex(int button);
|
||||
int GetState(int button);
|
||||
void SetState(int button, int state);
|
||||
BOOL GetEnable(int button);
|
||||
void SetEnable(int button, BOOL bEnable);
|
||||
BOOL GetHide(int button);
|
||||
void SetHide(int button, BOOL bHide);
|
||||
int GetMenu(int button);
|
||||
void SetMenu(int button, int menu);
|
||||
|
||||
BOOL DrawButtons();
|
||||
int MousePosToSprite(POINT pos);
|
||||
void MouseSprite(POINT pos);
|
||||
void WaitMouse(BOOL bWait);
|
||||
void HideMouse(BOOL bHide);
|
||||
POINT GetLastMousePos();
|
||||
BOOL TreatEvent(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void DecorAutoShift(POINT pos);
|
||||
|
||||
BOOL StartMovie(char *pFilename);
|
||||
void StopMovie();
|
||||
BOOL IsMovie();
|
||||
|
||||
BOOL FlipObject();
|
||||
|
||||
void Read(int message);
|
||||
void Write(int message);
|
||||
|
||||
void SetSpeed(int speed);
|
||||
int GetSpeed();
|
||||
BOOL GetPause();
|
||||
BOOL IsShift();
|
||||
|
||||
void DemoStep();
|
||||
void DebugDisplay(char m);
|
||||
|
||||
void IntroStep();
|
||||
|
||||
protected:
|
||||
void DrawTextCenter(int res, int x, int y, int font=0);
|
||||
BOOL CreateButtons();
|
||||
BOOL EventButtons(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL MouseOnButton(POINT pos);
|
||||
int SearchPhase(UINT phase);
|
||||
void DecorShift(int dx, int dy);
|
||||
|
||||
BOOL PlayDown(POINT pos, int fwKeys);
|
||||
BOOL PlayMove(POINT pos, int fwKeys);
|
||||
BOOL PlayUp(POINT pos, int fwKeys);
|
||||
void ChangeButtons(int message);
|
||||
|
||||
void BuildFloor(POINT cel, int insIcon);
|
||||
void BuildWater(POINT cel, int insIcon);
|
||||
BOOL BuildDown(POINT pos, int fwKeys, BOOL bMix=TRUE);
|
||||
BOOL BuildMove(POINT pos, int fwKeys);
|
||||
BOOL BuildUp(POINT pos, int fwKeys);
|
||||
|
||||
void PrivateLibelle();
|
||||
BOOL ReadLibelle(int world, BOOL bSchool, BOOL bHelp);
|
||||
BOOL WriteInfo();
|
||||
BOOL ReadInfo();
|
||||
|
||||
void DemoRecStart();
|
||||
void DemoRecStop();
|
||||
BOOL DemoPlayStart();
|
||||
void DemoPlayStop();
|
||||
void DemoRecEvent(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
int m_speed;
|
||||
int m_exercice;
|
||||
int m_mission;
|
||||
int m_private;
|
||||
int m_maxMission;
|
||||
int m_phase;
|
||||
int m_index;
|
||||
BOOL m_bSchool;
|
||||
BOOL m_bPrivate;
|
||||
BOOL m_bAccesBuild;
|
||||
BOOL m_bFullScreen;
|
||||
int m_mouseType;
|
||||
HWND m_hWnd;
|
||||
CPixmap* m_pPixmap;
|
||||
CDecor* m_pDecor;
|
||||
CSound* m_pSound;
|
||||
CMovie* m_pMovie;
|
||||
char m_movieToStart[MAX_PATH];
|
||||
int m_phaseAfterMovie;
|
||||
CButton m_buttons[MAXBUTTON];
|
||||
int m_lastFloor[MAXBUTTON];
|
||||
int m_lastObject[MAXBUTTON];
|
||||
int m_lastHome[MAXBUTTON];
|
||||
BOOL m_bRunMovie;
|
||||
BOOL m_bBuildModify;
|
||||
CJauge m_jauges[2];
|
||||
CMenu m_menu;
|
||||
BOOL m_bMenu;
|
||||
POINT m_menuPos;
|
||||
int m_menuNb;
|
||||
int m_menuButtons[MAXBUTTON];
|
||||
int m_menuErrors[MAXBUTTON];
|
||||
int m_menuPerso;
|
||||
POINT m_menuCel;
|
||||
POINT m_oldMousePos;
|
||||
BOOL m_bMousePress;
|
||||
BOOL m_bMouseDown;
|
||||
BOOL m_bHili;
|
||||
int m_fileWorld[10];
|
||||
int m_fileTime[10];
|
||||
POINT m_posToolTips;
|
||||
char m_textToolTips[50];
|
||||
int m_mouseSprite;
|
||||
BOOL m_bFillMouse;
|
||||
BOOL m_bWaitMouse;
|
||||
BOOL m_bHideMouse;
|
||||
BOOL m_bShowMouse;
|
||||
int m_rankCheat;
|
||||
int m_posCheat;
|
||||
BOOL m_bMovie;
|
||||
BOOL m_bSpeed;
|
||||
BOOL m_bHelp;
|
||||
BOOL m_bAllMissions;
|
||||
BOOL m_bChangeCheat;
|
||||
int m_scrollSpeed;
|
||||
BOOL m_bPause;
|
||||
BOOL m_bShift;
|
||||
int m_shiftPhase;
|
||||
POINT m_shiftVector;
|
||||
POINT m_shiftOffset;
|
||||
char m_libelle[1000];
|
||||
char m_filenameBuffer[100][256];
|
||||
int m_tryPhase;
|
||||
int m_tryInsertCount;
|
||||
POINT m_posInfoButton;
|
||||
POINT m_posHelpButton;
|
||||
BOOL m_bHiliInfoButton;
|
||||
BOOL m_bHiliHelpButton;
|
||||
BOOL m_bInfoHelp;
|
||||
BOOL m_bDemoRec;
|
||||
BOOL m_bDemoPlay;
|
||||
DemoEvent* m_pDemoBuffer;
|
||||
int m_demoTime;
|
||||
int m_input;
|
||||
int m_demoIndex;
|
||||
int m_demoEnd;
|
||||
int m_demoNumber;
|
||||
BOOL m_bCtrlDown;
|
||||
POINT m_debugPos;
|
||||
int m_introTime;
|
||||
};
|
33
fifo.h
Normal file
33
fifo.h
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long pos;
|
||||
long dist;
|
||||
}
|
||||
Element;
|
||||
|
||||
|
||||
|
||||
|
||||
class CPileTriee
|
||||
{
|
||||
private:
|
||||
long m_taille;
|
||||
long m_max;
|
||||
long m_out;
|
||||
Element* m_data;
|
||||
|
||||
public:
|
||||
CPileTriee(long taille);
|
||||
~CPileLTriee();
|
||||
|
||||
void put(long pos, long dist);
|
||||
long get();
|
||||
};
|
41
jauge.h
Normal file
41
jauge.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Jauge.h
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CJauge
|
||||
{
|
||||
public:
|
||||
CJauge();
|
||||
~CJauge();
|
||||
|
||||
BOOL Create(HWND hWnd, CPixmap *pPixmap, CSound *pSound,
|
||||
POINT pos, int type, BOOL bMinimizeRedraw);
|
||||
void Draw();
|
||||
void Redraw();
|
||||
|
||||
void SetLevel(int level);
|
||||
void SetType(int type);
|
||||
|
||||
BOOL GetHide();
|
||||
void SetHide(BOOL bHide);
|
||||
|
||||
POINT GetPos();
|
||||
void SetRedraw();
|
||||
|
||||
protected:
|
||||
HWND m_hWnd;
|
||||
CPixmap* m_pPixmap;
|
||||
CDecor* m_pDecor;
|
||||
CSound* m_pSound;
|
||||
BOOL m_bHide;
|
||||
POINT m_pos;
|
||||
POINT m_dim;
|
||||
int m_type;
|
||||
int m_level;
|
||||
BOOL m_bMinimizeRedraw;
|
||||
BOOL m_bRedraw;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
48
menu.h
Normal file
48
menu.h
Normal file
@ -0,0 +1,48 @@
|
||||
// Menu.h
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CMenu
|
||||
{
|
||||
public:
|
||||
CMenu();
|
||||
~CMenu();
|
||||
|
||||
BOOL Create(HWND hWnd, CPixmap *pPixmap, CSound *pSound,
|
||||
POINT pos, int nbm, int *pButtons, int *pErrors,
|
||||
int perso);
|
||||
void Update(int nb, int *pButtons, int *pErrors);
|
||||
void Delete();
|
||||
void Draw();
|
||||
int GetSel();
|
||||
int GetRank();
|
||||
BOOL IsError();
|
||||
BOOL IsExist();
|
||||
void Message();
|
||||
|
||||
BOOL TreatEvent(UINT message, WPARAM wParam, LPARAM lPararm);
|
||||
|
||||
protected:
|
||||
int Detect(POINT pos);
|
||||
BOOL MouseDown(POINT pos);
|
||||
BOOL MouseMove(POINT pos);
|
||||
BOOL MouseUp(POINT pos);
|
||||
|
||||
protected:
|
||||
HWND m_hWnd;
|
||||
CPixmap* m_pPixmap;
|
||||
CDecor* m_pDecor;
|
||||
CSound* m_pSound;
|
||||
POINT m_pos;
|
||||
POINT m_dim;
|
||||
int m_nbButtons;
|
||||
POINT m_nbCel;
|
||||
int m_perso;
|
||||
int m_buttons[MAXBUTTON];
|
||||
int m_errors[MAXBUTTON];
|
||||
UINT m_messages[MAXBUTTON];
|
||||
int m_selRank;
|
||||
POINT m_mousePos;
|
||||
};
|
19
misc.h
Normal file
19
misc.h
Normal file
@ -0,0 +1,19 @@
|
||||
// misc.h
|
||||
//
|
||||
|
||||
extern void InitHInstance(HINSTANCE hInstance);
|
||||
extern void OutputDebug(char *pMessage);
|
||||
extern void LoadString(UINT nID, char *pBuffer, int lgBuffer);
|
||||
extern void ChangeSprite(int sprite);
|
||||
|
||||
extern POINT ConvLongToPos(LPARAM lParam);
|
||||
|
||||
extern void InitRandom();
|
||||
extern int Random(int min, int max);
|
||||
|
||||
extern void GetCurrentDir(char *pName, int lg);
|
||||
extern void AddCDPath(char *pFilename);
|
||||
extern void AddUserPath(char *pFilename);
|
||||
|
||||
extern void TraceErrorDD(HRESULT hErr, char *sFile, int nLine);
|
||||
extern void TraceErrorDS(HRESULT hErr, char *sFile, int nLine);
|
298
movie.cpp
Normal file
298
movie.cpp
Normal file
@ -0,0 +1,298 @@
|
||||
// movie.cpp
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <commdlg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#include <mmsystem.h>
|
||||
#include <digitalv.h>
|
||||
#include "def.h"
|
||||
#include "movie.h"
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define AVI_VIDEO "avivideo"
|
||||
|
||||
#define IDM_PLAY 10
|
||||
#define IDM_RPLAY 11
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize avi libraries.
|
||||
|
||||
BOOL CMovie::initAVI()
|
||||
{
|
||||
MCI_DGV_OPEN_PARMS mciOpen;
|
||||
|
||||
// set up the open parameters
|
||||
mciOpen.dwCallback = 0L;
|
||||
mciOpen.wDeviceID = 0;
|
||||
mciOpen.lpstrDeviceType = AVI_VIDEO;
|
||||
mciOpen.lpstrElementName = NULL;
|
||||
mciOpen.lpstrAlias = NULL;
|
||||
mciOpen.dwStyle = 0;
|
||||
mciOpen.hWndParent = NULL;
|
||||
|
||||
// try to open the driver
|
||||
return (mciSendCommand(0, MCI_OPEN, (DWORD)(MCI_OPEN_TYPE),
|
||||
(DWORD)(LPMCI_DGV_OPEN_PARMS)&mciOpen) == 0);
|
||||
}
|
||||
|
||||
// Closes the opened AVI file and the opened device type. |
|
||||
|
||||
void CMovie::termAVI()
|
||||
{
|
||||
MCIDEVICEID mciID;
|
||||
MCI_GENERIC_PARMS mciClose;
|
||||
|
||||
// Get the device ID for the opened device type and then close
|
||||
// the device type.
|
||||
mciID = mciGetDeviceID(AVI_VIDEO);
|
||||
mciSendCommand(mciID, MCI_CLOSE, 0L,
|
||||
(DWORD)(LPMCI_GENERIC_PARMS)&mciClose);
|
||||
}
|
||||
|
||||
|
||||
// Sets the movie rectange <rcMovie> to be
|
||||
// centered within the app's window.
|
||||
|
||||
void CMovie::positionMovie(HWND hWnd, RECT rect)
|
||||
{
|
||||
// reposition the playback (child) window
|
||||
MoveWindow(m_hwndMovie,
|
||||
rect.left, rect.top,
|
||||
rect.right, rect.bottom, TRUE);
|
||||
}
|
||||
|
||||
// Close the movie and anything associated with it. |
|
||||
// This function clears the <m_fPlaying> and <m_fMovieOpen> flags |
|
||||
|
||||
void CMovie::fileCloseMovie(HWND hWnd)
|
||||
{
|
||||
MCI_GENERIC_PARMS mciGeneric;
|
||||
|
||||
mciSendCommand(m_wMCIDeviceID, MCI_CLOSE, 0L,
|
||||
(DWORD)(LPMCI_GENERIC_PARMS)&mciGeneric);
|
||||
|
||||
m_fPlaying = FALSE; // can't be playing any longer
|
||||
m_fMovieOpen = FALSE; // no more movies open
|
||||
|
||||
// cause a total repaint to occur
|
||||
InvalidateRect(hWnd, NULL, TRUE);
|
||||
UpdateWindow(hWnd);
|
||||
}
|
||||
|
||||
|
||||
// Open an AVI movie. Use CommDlg open box to
|
||||
// open and then handle the initialization to
|
||||
// show the movie and position it properly. Keep
|
||||
// the movie paused when opened.
|
||||
// Sets <m_fMovieOpen> on success.
|
||||
|
||||
BOOL CMovie::fileOpenMovie(HWND hWnd, RECT rect, char *pFilename)
|
||||
{
|
||||
MCI_DGV_OPEN_PARMS mciOpen;
|
||||
MCI_DGV_WINDOW_PARMS mciWindow;
|
||||
MCI_DGV_STATUS_PARMS mciStatus;
|
||||
char string[MAX_PATH];
|
||||
|
||||
if ( pFilename[1] == ':' ) // nom complet "D:\REP..." ?
|
||||
{
|
||||
strcpy(string, pFilename);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCurrentDir(string, MAX_PATH-30);
|
||||
strcat(string, pFilename);
|
||||
}
|
||||
|
||||
// we got a filename, now close any old movie and open the new one. */
|
||||
if ( m_fMovieOpen ) fileCloseMovie(hWnd);
|
||||
|
||||
// we have a .AVI movie to open, use MCI
|
||||
// set up the open parameters
|
||||
mciOpen.dwCallback = 0L;
|
||||
mciOpen.wDeviceID = 0;
|
||||
mciOpen.lpstrDeviceType = NULL;
|
||||
mciOpen.lpstrElementName = string;
|
||||
mciOpen.lpstrAlias = NULL;
|
||||
mciOpen.dwStyle = WS_CHILD;
|
||||
mciOpen.hWndParent = hWnd;
|
||||
|
||||
// try to open the file
|
||||
if ( mciSendCommand(0, MCI_OPEN,
|
||||
(DWORD)(MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS),
|
||||
(DWORD)(LPMCI_DGV_OPEN_PARMS)&mciOpen) == 0 )
|
||||
{
|
||||
// we opened the file o.k., now set up to play it.
|
||||
m_wMCIDeviceID = mciOpen.wDeviceID; // save ID
|
||||
m_fMovieOpen = TRUE; // a movie was opened
|
||||
|
||||
// show the playback window
|
||||
mciWindow.dwCallback = 0L;
|
||||
mciWindow.hWnd = NULL;
|
||||
mciWindow.nCmdShow = SW_SHOW;
|
||||
mciWindow.lpstrText = (LPSTR)NULL;
|
||||
// mciSendCommand(m_wMCIDeviceID, MCI_WINDOW,
|
||||
// MCI_DGV_WINDOW_STATE,
|
||||
// (DWORD)(LPMCI_DGV_WINDOW_PARMS)&mciWindow);
|
||||
|
||||
// get the window handle
|
||||
mciStatus.dwItem = MCI_DGV_STATUS_HWND;
|
||||
mciSendCommand(m_wMCIDeviceID,
|
||||
MCI_STATUS, MCI_STATUS_ITEM,
|
||||
(DWORD)(LPMCI_STATUS_PARMS)&mciStatus);
|
||||
m_hwndMovie = (HWND)mciStatus.dwReturn;
|
||||
|
||||
// now get the movie centered
|
||||
positionMovie(hWnd, rect);
|
||||
|
||||
// cause an update to occur
|
||||
InvalidateRect(hWnd, NULL, FALSE);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// generic error for open
|
||||
m_fMovieOpen = FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Play/pause the movie depending on the state
|
||||
// of the <m_fPlaying> flag. |
|
||||
// This function sets the <m_fPlaying> flag appropriately when done|
|
||||
|
||||
void CMovie::playMovie(HWND hWnd, int nDirection)
|
||||
{
|
||||
m_fPlaying = !m_fPlaying; // swap the play flag
|
||||
|
||||
if( !nDirection )
|
||||
m_fPlaying = FALSE; // wDirection == NULL means PAUSE
|
||||
|
||||
// play/pause the AVI movie
|
||||
if ( m_fPlaying )
|
||||
{
|
||||
DWORD dwFlags;
|
||||
MCI_DGV_PLAY_PARMS mciPlay;
|
||||
|
||||
// init to play all
|
||||
mciPlay.dwCallback = MAKELONG(hWnd,0);
|
||||
mciPlay.dwFrom = mciPlay.dwTo = 0;
|
||||
dwFlags = MCI_NOTIFY;
|
||||
if ( nDirection == IDM_RPLAY )
|
||||
dwFlags |= MCI_DGV_PLAY_REVERSE;
|
||||
|
||||
mciSendCommand(m_wMCIDeviceID, MCI_PLAY, dwFlags,
|
||||
(DWORD)(LPMCI_DGV_PLAY_PARMS)&mciPlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCI_DGV_PAUSE_PARMS mciPause;
|
||||
|
||||
// tell it to pause
|
||||
mciSendCommand(m_wMCIDeviceID,MCI_PAUSE,0L,
|
||||
(DWORD)(LPMCI_DGV_PAUSE_PARMS)&mciPause);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Constructeur.
|
||||
|
||||
CMovie::CMovie()
|
||||
{
|
||||
m_bEnable = FALSE;
|
||||
m_wMCIDeviceID = 0;
|
||||
m_fPlaying = FALSE;
|
||||
m_fMovieOpen = FALSE;
|
||||
}
|
||||
|
||||
// Destructeur.
|
||||
|
||||
CMovie::~CMovie()
|
||||
{
|
||||
termAVI();
|
||||
}
|
||||
|
||||
// Ouvre la librairie avi.
|
||||
|
||||
BOOL CMovie::Create()
|
||||
{
|
||||
#if _EGAMES
|
||||
m_bEnable = FALSE;
|
||||
return FALSE;
|
||||
#else
|
||||
if ( initAVI() )
|
||||
{
|
||||
m_bEnable = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bEnable = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Retourne l'<27>tat de DirectMovie.
|
||||
|
||||
BOOL CMovie::GetEnable()
|
||||
{
|
||||
return m_bEnable;
|
||||
}
|
||||
|
||||
// Indique si un film existe.
|
||||
|
||||
BOOL CMovie::IsExist(char *pFilename)
|
||||
{
|
||||
char string[MAX_PATH];
|
||||
FILE* file;
|
||||
|
||||
if ( pFilename[1] == ':' ) // nom complet "D:\REP..." ?
|
||||
{
|
||||
strcpy(string, pFilename);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCurrentDir(string, MAX_PATH-30);
|
||||
strcat(string, pFilename);
|
||||
}
|
||||
|
||||
file = fopen(string, "rb");
|
||||
if ( file == NULL ) return FALSE;
|
||||
|
||||
fclose(file);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Montre un film avi.
|
||||
|
||||
BOOL CMovie::Play(HWND hWnd, RECT rect, char *pFilename)
|
||||
{
|
||||
if ( !m_bEnable ) return FALSE;
|
||||
if ( !fileOpenMovie(hWnd, rect, pFilename) ) return FALSE;
|
||||
playMovie(hWnd, IDM_PLAY);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Stoppe le film avi.
|
||||
|
||||
void CMovie::Stop(HWND hWnd)
|
||||
{
|
||||
if ( !m_bEnable ) return;
|
||||
fileCloseMovie(hWnd);
|
||||
}
|
30
movie.h
Normal file
30
movie.h
Normal file
@ -0,0 +1,30 @@
|
||||
// movie.h
|
||||
//
|
||||
|
||||
class CMovie
|
||||
{
|
||||
public:
|
||||
CMovie();
|
||||
~CMovie();
|
||||
|
||||
BOOL Create();
|
||||
BOOL GetEnable();
|
||||
BOOL IsExist(char *pFilename);
|
||||
BOOL Play(HWND hWnd, RECT rect, char *pFilename);
|
||||
void Stop(HWND hWnd);
|
||||
|
||||
protected:
|
||||
void playMovie(HWND hWnd, int nDirection);
|
||||
BOOL fileOpenMovie(HWND hWnd, RECT rect, char *pFilename);
|
||||
void fileCloseMovie(HWND hWnd);
|
||||
void positionMovie(HWND hWnd, RECT rect);
|
||||
void termAVI();
|
||||
BOOL initAVI();
|
||||
|
||||
protected:
|
||||
BOOL m_bEnable;
|
||||
MCIDEVICEID m_wMCIDeviceID;
|
||||
HWND m_hwndMovie;
|
||||
BOOL m_fPlaying;
|
||||
BOOL m_fMovieOpen;
|
||||
};
|
1414
pixmap.cpp
Normal file
1414
pixmap.cpp
Normal file
File diff suppressed because it is too large
Load Diff
111
pixmap.h
Normal file
111
pixmap.h
Normal file
@ -0,0 +1,111 @@
|
||||
// CPixmap.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAXIMAGE 100
|
||||
|
||||
|
||||
class CPixmap
|
||||
{
|
||||
public:
|
||||
CPixmap();
|
||||
~CPixmap();
|
||||
|
||||
void SetDebug(BOOL bDebug);
|
||||
|
||||
BOOL Create(HWND hwnd, POINT dim, BOOL bFullScreen, int mouseType);
|
||||
BOOL Flush();
|
||||
BOOL Restore();
|
||||
BOOL InitSysPalette();
|
||||
BOOL IsPalette();
|
||||
void Fill(RECT rect, COLORREF color);
|
||||
|
||||
BOOL SavePalette();
|
||||
BOOL RestorePalette();
|
||||
int SearchColor(int red, int green, int blue);
|
||||
BOOL Cache(int channel, char *pFilename, POINT totalDim, POINT iconDim, BOOL bUsePalette);
|
||||
BOOL Cache(int channel, char *pFilename, POINT totalDim, BOOL bUsePalette);
|
||||
BOOL Cache(int channel, HBITMAP hbm, POINT totalDim);
|
||||
void Flush(int channel);
|
||||
void SetTransparent(int channel, COLORREF color);
|
||||
void SetTransparent2(int channel, COLORREF color1, COLORREF color2);
|
||||
void SetClipping(RECT clip);
|
||||
RECT GetClipping();
|
||||
|
||||
BOOL IsIconPixel(int channel, int rank, POINT pos);
|
||||
|
||||
BOOL DrawIcon(int chDst, int channel, int rank, POINT pos, int mode=0, BOOL bMask=FALSE);
|
||||
BOOL DrawIconDemi(int chDst, int channel, int rank, POINT pos, int mode=0, BOOL bMask=FALSE);
|
||||
BOOL DrawIconPart(int chDst, int channel, int rank, POINT pos, int startY, int endY, int mode=0, BOOL bMask=FALSE);
|
||||
BOOL DrawPart(int chDst, int channel, POINT dest, RECT rect, int mode=0, BOOL bMask=FALSE);
|
||||
BOOL DrawImage(int chDst, int channel, RECT rect, int mode=0);
|
||||
|
||||
BOOL BuildIconMask(int channelMask, int rankMask,
|
||||
int channel, int rankSrc, int rankDst);
|
||||
|
||||
BOOL Display();
|
||||
|
||||
void SetMousePosSprite(POINT pos, int sprite, BOOL bDemoPlay);
|
||||
void SetMousePos(POINT pos, BOOL bDemoPlay);
|
||||
void SetMouseSprite(int sprite, BOOL bDemoPlay);
|
||||
void MouseShow(BOOL bShow);
|
||||
void MouseInvalidate();
|
||||
void MouseBackClear();
|
||||
void MouseBackDraw();
|
||||
|
||||
protected:
|
||||
HRESULT RestoreAll();
|
||||
HRESULT BltFast(int chDst, int channel, POINT dst, RECT rcRect, int mode);
|
||||
HRESULT BltFast(LPDIRECTDRAWSURFACE lpDD,
|
||||
int channel, POINT dst, RECT rcRect, int mode);
|
||||
|
||||
void MouseUpdate();
|
||||
BOOL MouseQuickDraw(RECT rect);
|
||||
void MouseBackSave();
|
||||
void MouseBackRestore();
|
||||
void MouseBackDebug();
|
||||
RECT MouseRectSprite();
|
||||
void MouseHotSpot();
|
||||
|
||||
protected:
|
||||
BOOL m_bFullScreen;
|
||||
BOOL m_bBenchmarkSuccess;
|
||||
BOOL m_bTrueColor;
|
||||
BOOL m_bTrueColorDecor;
|
||||
BOOL m_field5_0x14; //Need to figure out
|
||||
BOOL m_field5_0x18; //Need to figure out
|
||||
int m_mouseType;
|
||||
BOOL m_bDebug;
|
||||
BOOL m_bPalette;
|
||||
HWND m_hWnd;
|
||||
POINT m_dim;
|
||||
RECT m_clipRect;
|
||||
|
||||
POINT m_mousePos;
|
||||
int m_mouseSprite;
|
||||
POINT m_mouseHotSpot;
|
||||
POINT m_mouseBackPos;
|
||||
BOOL m_bMouseBack;
|
||||
BOOL m_bMouseShow;
|
||||
BOOL m_bBackDisplayed;
|
||||
|
||||
LPDIRECTDRAW m_lpDD;
|
||||
LPDIRECTDRAWSURFACE m_lpDDSPrimary;
|
||||
LPDIRECTDRAWSURFACE m_lpDDSBack;
|
||||
LPDIRECTDRAWSURFACE m_lpDDSMouse;
|
||||
LPDIRECTDRAWPALETTE m_lpDDPal;
|
||||
LPDIRECTDRAWSURFACE m_lpDDSurface[MAXIMAGE];
|
||||
LPDIRECTDRAWCLIPPER m_lpClipper;
|
||||
PALETTEENTRY m_pal[256];
|
||||
PALETTEENTRY m_sysPal[256];
|
||||
COLORREF m_colorSurface[2*MAXIMAGE];
|
||||
|
||||
char m_filename[MAXIMAGE][20];
|
||||
POINT m_totalDim[MAXIMAGE];
|
||||
POINT m_iconDim[MAXIMAGE];
|
||||
DDBLTFX m_DDbltfx
|
||||
}
|
648
sound.cpp
Normal file
648
sound.cpp
Normal file
@ -0,0 +1,648 @@
|
||||
// sound.cpp
|
||||
//
|
||||
|
||||
#include <dsound.h>
|
||||
#include <stdio.h>
|
||||
#include "sound.h"
|
||||
#include "misc.h"
|
||||
#include "def.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
// The following macro are used for proper error handling for DirectSound.
|
||||
#define TRY_DS(exp) { { HRESULT rval = exp; if (rval != DS_OK) { TraceErrorDS(rval, __FILE__, __LINE__); return FALSE; } } }
|
||||
|
||||
|
||||
struct WaveHeader
|
||||
{
|
||||
BYTE RIFF[4]; // "RIFF"
|
||||
DWORD dwSize; // Size of data to follow
|
||||
BYTE WAVE[4]; // "WAVE"
|
||||
BYTE fmt_[4]; // "fmt "
|
||||
DWORD dw16; // 16
|
||||
WORD wOne_0; // 1
|
||||
WORD wChnls; // Number of Channels
|
||||
DWORD dwSRate; // Sample Rate
|
||||
DWORD BytesPerSec; // Sample Rate
|
||||
WORD wBlkAlign; // 1
|
||||
WORD BitsPerSample; // Sample size
|
||||
BYTE DATA[4]; // "DATA"
|
||||
DWORD dwDSize; // Number of Samples
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Creates a DirectSound buffer.
|
||||
|
||||
BOOL CSound::CreateSoundBuffer(int dwBuf, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
|
||||
{
|
||||
PCMWAVEFORMAT pcmwf;
|
||||
DSBUFFERDESC dsbdesc;
|
||||
|
||||
// Set up wave format structure.
|
||||
memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
|
||||
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
|
||||
pcmwf.wf.nChannels = bStereo ? 2 : 1;
|
||||
pcmwf.wf.nSamplesPerSec = dwFreq;
|
||||
pcmwf.wf.nBlockAlign = (WORD)dwBlkAlign;
|
||||
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
|
||||
pcmwf.wBitsPerSample = (WORD)dwBitsPerSample;
|
||||
|
||||
// Set up DSBUFFERDESC structure.
|
||||
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
|
||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbdesc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME;
|
||||
dsbdesc.dwBufferBytes = dwBufSize;
|
||||
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
|
||||
|
||||
TRY_DS(m_lpDS->CreateSoundBuffer(&dsbdesc, &m_lpDSB[dwBuf], NULL))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Reads in data from a wave file.
|
||||
|
||||
BOOL CSound::ReadData(LPDIRECTSOUNDBUFFER lpDSB, FILE* pFile, DWORD dwSize, DWORD dwPos)
|
||||
{
|
||||
// Seek to correct position in file (if necessary)
|
||||
if ( dwPos != 0xffffffff )
|
||||
{
|
||||
if ( fseek(pFile, dwPos, SEEK_SET) != 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Lock data in buffer for writing
|
||||
LPVOID pData1;
|
||||
DWORD dwData1Size;
|
||||
LPVOID pData2;
|
||||
DWORD dwData2Size;
|
||||
HRESULT rval;
|
||||
|
||||
rval = lpDSB->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
|
||||
if ( rval != DS_OK )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Read in first chunk of data
|
||||
if ( dwData1Size > 0 )
|
||||
{
|
||||
if ( fread(pData1, dwData1Size, 1, pFile) != 1 )
|
||||
{
|
||||
char holder[256];
|
||||
wsprintf(holder,"Data1 : %d, dwdata: %d, pFile: %d",pData1,dwData1Size,pFile);
|
||||
OutputDebug(holder);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// read in second chunk if necessary
|
||||
if ( dwData2Size > 0 )
|
||||
{
|
||||
if ( fread(pData2, dwData2Size, 1, pFile) != 1 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock data in buffer
|
||||
rval = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size);
|
||||
if ( rval != DS_OK )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Creates a DirectSound buffer from a wave file.
|
||||
|
||||
BOOL CSound::CreateBufferFromWaveFile(int dwBuf, char *pFileName)
|
||||
{
|
||||
// Open the wave file
|
||||
FILE* pFile = fopen(pFileName, "rb");
|
||||
if ( pFile == NULL ) return FALSE;
|
||||
|
||||
// Read in the wave header
|
||||
WaveHeader wavHdr;
|
||||
if ( fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1 )
|
||||
{
|
||||
fclose(pFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Figure out the size of the data region
|
||||
DWORD dwSize = wavHdr.dwDSize;
|
||||
|
||||
// Is this a stereo or mono file?
|
||||
BOOL bStereo = wavHdr.wChnls > 1 ? TRUE : FALSE;
|
||||
|
||||
// Create the sound buffer for the wave file
|
||||
if ( !CreateSoundBuffer(dwBuf, dwSize, wavHdr.dwSRate,
|
||||
wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo) )
|
||||
{
|
||||
// Close the file
|
||||
fclose(pFile);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Read the data for the wave file into the sound buffer
|
||||
if ( !ReadData(m_lpDSB[dwBuf], pFile, dwSize, sizeof(wavHdr)) )
|
||||
{
|
||||
fclose(pFile);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Close out the wave file
|
||||
fclose(pFile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Stops all sounds.
|
||||
|
||||
BOOL CSound::StopAllSounds()
|
||||
{
|
||||
// Make sure we have a valid sound buffer
|
||||
for (int i = 0; i < MAXSOUND; i ++)
|
||||
{
|
||||
if ( m_lpDSB[i] )
|
||||
{
|
||||
DWORD dwStatus;
|
||||
TRY_DS(m_lpDSB[i]->GetStatus(&dwStatus));
|
||||
|
||||
if ( (dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING )
|
||||
{
|
||||
TRY_DS(m_lpDSB[i]->Stop())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Plays a sound using direct sound.
|
||||
|
||||
BOOL CSound::PlaySoundDS(DWORD dwSound, DWORD dwFlags)
|
||||
{
|
||||
// Make sure the sound is valid
|
||||
if ( dwSound >= MAXSOUND ) return FALSE;
|
||||
|
||||
// Make sure we have a valid sound buffer
|
||||
if ( m_lpDSB[dwSound] )
|
||||
{
|
||||
DWORD dwStatus;
|
||||
TRY_DS(m_lpDSB[dwSound]->GetStatus(&dwStatus));
|
||||
|
||||
if ( (dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING )
|
||||
{
|
||||
// Play the sound
|
||||
TRY_DS(m_lpDSB[dwSound]->Play(0, 0, dwFlags));
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Modifie le volume midi.
|
||||
// Le volume est compris entre 0 et 20 !
|
||||
|
||||
void InitMidiVolume(int volume)
|
||||
{
|
||||
int nb, i, n;
|
||||
MMRESULT result;
|
||||
HMIDIOUT hmo = 0;
|
||||
|
||||
static int table[21] =
|
||||
{
|
||||
0x00000000,
|
||||
0x11111111,
|
||||
0x22222222,
|
||||
0x33333333,
|
||||
0x44444444,
|
||||
0x55555555,
|
||||
0x66666666,
|
||||
0x77777777,
|
||||
0x88888888,
|
||||
0x99999999,
|
||||
0xAAAAAAAA,
|
||||
0xBBBBBBBB,
|
||||
0xCCCCCCCC,
|
||||
0xDDDDDDDD,
|
||||
0xEEEEEEEE,
|
||||
0xF222F222,
|
||||
0xF555F555,
|
||||
0xF777F777,
|
||||
0xFAAAFAAA,
|
||||
0xFDDDFDDD,
|
||||
0xFFFFFFFF,
|
||||
};
|
||||
|
||||
if ( volume < 0 ) volume = 0;
|
||||
if ( volume > MAXVOLUME ) volume = MAXVOLUME;
|
||||
|
||||
nb = midiOutGetNumDevs();
|
||||
for ( i=0 ; i<nb ; i++ )
|
||||
{
|
||||
result = midiOutOpen((LPHMIDIOUT)&hmo, i, 0L, 0L, 0L);
|
||||
if ( result != MMSYSERR_NOERROR )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result = midiOutSetVolume(hmo, table[volume]);
|
||||
if ( result != MMSYSERR_NOERROR )
|
||||
{
|
||||
n = 1;
|
||||
}
|
||||
midiOutClose(hmo);
|
||||
hmo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Constructeur.
|
||||
|
||||
CSound::CSound()
|
||||
{
|
||||
int i;
|
||||
|
||||
m_bEnable = FALSE;
|
||||
m_bState = FALSE;
|
||||
m_MidiDeviceID = 0;
|
||||
m_MIDIFilename[0] = 0;
|
||||
m_audioVolume = 20;
|
||||
m_midiVolume = 15;
|
||||
m_lastMidiVolume = 0;
|
||||
m_nbSuspendSkip = 0;
|
||||
|
||||
m_lpDS = NULL;
|
||||
|
||||
for ( i=0 ; i<MAXSOUND ; i++ )
|
||||
{
|
||||
m_lpDSB[i] = NULL;
|
||||
}
|
||||
|
||||
for ( i=0 ; i<MAXBLUPI ; i++ )
|
||||
{
|
||||
m_channelBlupi[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Destructeur.
|
||||
|
||||
CSound::~CSound()
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( m_bEnable )
|
||||
{
|
||||
InitMidiVolume(15); // remet un volume moyen !
|
||||
}
|
||||
|
||||
for ( i=0 ; i<MAXSOUND ; i++ )
|
||||
{
|
||||
if ( m_lpDSB[i] != NULL )
|
||||
{
|
||||
//? m_lpDSB[i]->Release();
|
||||
m_lpDSB[i]= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_lpDS != NULL )
|
||||
{
|
||||
m_lpDS->Release();
|
||||
m_lpDS = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialisation de DirectSound.
|
||||
|
||||
BOOL CSound::Create(HWND hWnd)
|
||||
{
|
||||
if ( !DirectSoundCreate(NULL, &m_lpDS, NULL) == DS_OK )
|
||||
{
|
||||
OutputDebug("Fatal error: DirectSoundCreate\n");
|
||||
m_bEnable = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_lpDS->SetCooperativeLevel(hWnd, DSSCL_NORMAL);
|
||||
m_bEnable = TRUE;
|
||||
m_hWnd = hWnd;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Retourne l'<27>tat de DirectSound.
|
||||
|
||||
BOOL CSound::GetEnable()
|
||||
{
|
||||
return m_bEnable;
|
||||
}
|
||||
|
||||
|
||||
// Enclenche ou d<>clenche le son.
|
||||
|
||||
void CSound::SetState(BOOL bState)
|
||||
{
|
||||
m_bState = bState;
|
||||
}
|
||||
|
||||
|
||||
// Gestion des volumes audio (.wav) et midi (.mid).
|
||||
|
||||
void CSound::SetAudioVolume(int volume)
|
||||
{
|
||||
m_audioVolume = volume;
|
||||
}
|
||||
|
||||
int CSound::GetAudioVolume()
|
||||
{
|
||||
if ( !m_bEnable ) return 0;
|
||||
return m_audioVolume;
|
||||
}
|
||||
|
||||
void CSound::SetMidiVolume(int volume)
|
||||
{
|
||||
m_midiVolume = volume;
|
||||
}
|
||||
|
||||
int CSound::GetMidiVolume()
|
||||
{
|
||||
if ( !m_bEnable ) return 0;
|
||||
return m_midiVolume;
|
||||
}
|
||||
|
||||
|
||||
// Cache tous les ficheirs son (.wav).
|
||||
|
||||
void CSound::CacheAll()
|
||||
{
|
||||
int i;
|
||||
char name[50];
|
||||
|
||||
if ( !m_bEnable ) return;
|
||||
|
||||
for ( i=0 ; i<MAXSOUND ; i++ )
|
||||
{
|
||||
sprintf(name, "sound\\sound%.3d.blp", i);
|
||||
if ( !Cache(i, name) ) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Charge un fichier son (.wav).
|
||||
|
||||
BOOL CSound::Cache(int channel, char *pFilename)
|
||||
{
|
||||
if ( !m_bEnable ) return FALSE;
|
||||
if ( channel < 0 || channel >= MAXSOUND ) return FALSE;
|
||||
|
||||
if ( m_lpDSB[channel] != NULL )
|
||||
{
|
||||
Flush(channel);
|
||||
}
|
||||
|
||||
return CreateBufferFromWaveFile(channel, pFilename);
|
||||
}
|
||||
|
||||
// D<>charge un son.
|
||||
|
||||
void CSound::Flush(int channel)
|
||||
{
|
||||
if ( !m_bEnable ) return;
|
||||
if ( channel < 0 || channel >= MAXSOUND ) return;
|
||||
|
||||
if ( m_lpDSB[channel] != NULL )
|
||||
{
|
||||
m_lpDSB[channel]->Release();
|
||||
m_lpDSB[channel]= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Fait entendre un son.
|
||||
// Le volume est compris entre 0 (max) et -10000 (silence).
|
||||
// Le panoramique est compris entre -10000 (gauche), 0 (centre)
|
||||
// et +10000 (droite).
|
||||
|
||||
BOOL CSound::Play(int channel, int volume, int pan)
|
||||
{
|
||||
if ( !m_bEnable ) return TRUE;
|
||||
if ( !m_bState || m_audioVolume == 0 ) return TRUE;
|
||||
|
||||
volume -= (MAXVOLUME-m_audioVolume)*((10000/4)/MAXVOLUME);
|
||||
|
||||
//? if ( volume == -10000 ) return TRUE;
|
||||
if ( volume <= -10000/4 ) return TRUE;
|
||||
|
||||
if ( channel < 0 || channel >= MAXSOUND ) return FALSE;
|
||||
if ( m_lpDSB[channel] == NULL ) return FALSE;
|
||||
|
||||
m_lpDSB[channel]->SetVolume(volume);
|
||||
m_lpDSB[channel]->SetPan(pan);
|
||||
m_lpDSB[channel]->Play(0, 0, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Fait entendre un son dans une image.
|
||||
// Si rank != -1, il indique le rang du blupi dont il faudra
|
||||
// <20>ventuellement stopper le dernier son en cours !
|
||||
|
||||
BOOL CSound::PlayImage(int channel, POINT pos, int rank)
|
||||
{
|
||||
int stopCh, volumex, volumey, volume, pan;
|
||||
|
||||
if ( rank >= 0 && rank < MAXBLUPI )
|
||||
{
|
||||
stopCh = m_channelBlupi[rank];
|
||||
if ( stopCh >= 0 && m_lpDSB[stopCh] != NULL )
|
||||
{
|
||||
m_lpDSB[stopCh]->Stop(); // stoppe le son pr<70>c<EFBFBD>dent
|
||||
m_lpDSB[stopCh]->SetCurrentPosition(0);
|
||||
}
|
||||
|
||||
m_channelBlupi[rank] = channel;
|
||||
}
|
||||
|
||||
//? pan = (int)(((long)pos.x*20000L)/LXIMAGE)-10000L;
|
||||
//? pan = (int)(((long)pos.x*10000L)/LXIMAGE)-5000L;
|
||||
pan = (int)(((long)pos.x*5000L)/LXIMAGE)-2500L;
|
||||
|
||||
volumex = 0; // volume maximum
|
||||
if ( pos.x < 0 )
|
||||
{
|
||||
volumex = (pos.x*2500)/LXIMAGE;
|
||||
}
|
||||
if ( pos.x > LXIMAGE )
|
||||
{
|
||||
pos.x -= LXIMAGE;
|
||||
volumex = (-pos.x*2500)/LXIMAGE;
|
||||
}
|
||||
if ( volumex < -10000 ) volumex = -10000;
|
||||
|
||||
volumey = 0; // volume maximum
|
||||
if ( pos.y < 0 )
|
||||
{
|
||||
volumey = (pos.y*2500)/LYIMAGE;
|
||||
}
|
||||
if ( pos.y > LYIMAGE )
|
||||
{
|
||||
pos.y -= LYIMAGE;
|
||||
volumey = (-pos.y*2500)/LYIMAGE;
|
||||
}
|
||||
if ( volumey < -10000 ) volumey = -10000;
|
||||
|
||||
if ( volumex < volumey ) volume = volumex;
|
||||
else volume = volumey;
|
||||
|
||||
return Play(channel, volume, pan);
|
||||
}
|
||||
|
||||
|
||||
// Uses MCI to play a MIDI file. The window procedure
|
||||
// is notified when playback is complete.
|
||||
|
||||
BOOL CSound::PlayMusic(HWND hWnd, LPSTR lpszMIDIFilename)
|
||||
{
|
||||
MCI_OPEN_PARMS mciOpenParms;
|
||||
MCI_PLAY_PARMS mciPlayParms;
|
||||
DWORD dwReturn;
|
||||
char string[MAX_PATH];
|
||||
|
||||
if ( !m_bEnable ) return TRUE;
|
||||
if ( m_midiVolume == 0 ) return TRUE;
|
||||
InitMidiVolume(m_midiVolume);
|
||||
m_lastMidiVolume = m_midiVolume;
|
||||
|
||||
if ( lpszMIDIFilename[1] == ':' ) // nom complet "D:\REP..." ?
|
||||
{
|
||||
strcpy(string, lpszMIDIFilename);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCurrentDir(string, MAX_PATH-30);
|
||||
strcat(string, lpszMIDIFilename);
|
||||
}
|
||||
|
||||
// Open the device by specifying the device and filename.
|
||||
// MCI will attempt to choose the MIDI mapper as the output port.
|
||||
mciOpenParms.lpstrDeviceType = "sequencer";
|
||||
mciOpenParms.lpstrElementName = string;
|
||||
dwReturn = mciSendCommand(NULL,
|
||||
MCI_OPEN,
|
||||
MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,
|
||||
(DWORD)(LPVOID)&mciOpenParms);
|
||||
if ( dwReturn != 0 )
|
||||
{
|
||||
OutputDebug("PlayMusic-1\n");
|
||||
mciGetErrorString(dwReturn, string, 128);
|
||||
OutputDebug(string);
|
||||
// Failed to open device. Don't close it; just return error.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// The device opened successfully; get the device ID.
|
||||
m_MidiDeviceID = mciOpenParms.wDeviceID;
|
||||
|
||||
// Begin playback.
|
||||
mciPlayParms.dwCallback = (DWORD)hWnd;
|
||||
dwReturn = mciSendCommand(m_MidiDeviceID,
|
||||
MCI_PLAY,
|
||||
MCI_NOTIFY,
|
||||
(DWORD)(LPVOID)&mciPlayParms);
|
||||
if ( dwReturn != 0 )
|
||||
{
|
||||
OutputDebug("PlayMusic-2\n");
|
||||
mciGetErrorString(dwReturn, string, 128);
|
||||
OutputDebug(string);
|
||||
StopMusic();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strcpy(m_MIDIFilename, lpszMIDIFilename);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Restart the MIDI player.
|
||||
|
||||
BOOL CSound::RestartMusic()
|
||||
{
|
||||
OutputDebug("RestartMusic\n");
|
||||
if ( !m_bEnable ) return TRUE;
|
||||
if ( m_midiVolume == 0 ) return TRUE;
|
||||
if ( m_MIDIFilename[0] == 0 ) return FALSE;
|
||||
|
||||
return PlayMusic(m_hWnd, m_MIDIFilename);
|
||||
}
|
||||
|
||||
// Shuts down the MIDI player.
|
||||
|
||||
void CSound::SuspendMusic()
|
||||
{
|
||||
if ( !m_bEnable ) return;
|
||||
|
||||
if ( m_nbSuspendSkip != 0 )
|
||||
{
|
||||
m_nbSuspendSkip --;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_MidiDeviceID && m_midiVolume != 0 )
|
||||
{
|
||||
mciSendCommand(m_MidiDeviceID, MCI_CLOSE, 0, NULL);
|
||||
}
|
||||
m_MidiDeviceID = 0;
|
||||
}
|
||||
|
||||
// Shuts down the MIDI player.
|
||||
|
||||
void CSound::StopMusic()
|
||||
{
|
||||
SuspendMusic();
|
||||
m_MIDIFilename[0] = 0;
|
||||
}
|
||||
|
||||
// Retourne TRUE si une musique est en cours.
|
||||
|
||||
BOOL CSound::IsPlayingMusic()
|
||||
{
|
||||
return (m_MIDIFilename[0] != 0);
|
||||
}
|
||||
|
||||
// Adapte le volume de la musique en cours, si n<>cessaire.
|
||||
|
||||
void CSound::AdaptVolumeMusic()
|
||||
{
|
||||
if ( m_midiVolume != m_lastMidiVolume )
|
||||
{
|
||||
InitMidiVolume(m_midiVolume);
|
||||
m_lastMidiVolume = m_midiVolume;
|
||||
RestartMusic();
|
||||
}
|
||||
}
|
||||
|
||||
// Indique le nombre de suspend <20> sauter.
|
||||
|
||||
void CSound::SetSuspendSkip(int nb)
|
||||
{
|
||||
m_nbSuspendSkip = nb;
|
||||
}
|
||||
|
65
sound.h
Normal file
65
sound.h
Normal file
@ -0,0 +1,65 @@
|
||||
// sound.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dsound.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAXSOUND 100
|
||||
#define MAXVOLUME 20
|
||||
#define MAXBLUPI 100
|
||||
|
||||
class CSound
|
||||
{
|
||||
public:
|
||||
CSound();
|
||||
~CSound();
|
||||
|
||||
BOOL Create(HWND hWnd);
|
||||
void SetState(BOOL bState);
|
||||
BOOL GetEnable();
|
||||
|
||||
void SetAudioVolume(int volume);
|
||||
int GetAudioVolume();
|
||||
void SetMidiVolume(int volume);
|
||||
int GetMidiVolume();
|
||||
|
||||
void CacheAll();
|
||||
BOOL Cache(int channel, char *pFilename);
|
||||
void Flush(int channel);
|
||||
|
||||
BOOL Play (int channel, int volume=0, int pan=0);
|
||||
BOOL PlayImage(int channel, POINT pos, int rank=-1);
|
||||
BOOL PlayMusic(HWND hWnd, LPSTR lpszMIDIFilename);
|
||||
BOOL RestartMusic();
|
||||
void SuspendMusic();
|
||||
void StopMusic();
|
||||
BOOL IsPlayingMusic();
|
||||
void AdaptVolumeMusic();
|
||||
void SetSuspendSkip(int nb);
|
||||
|
||||
protected:
|
||||
BOOL CreateSoundBuffer(int dwBuf, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo);
|
||||
BOOL ReadData(LPDIRECTSOUNDBUFFER lpDSB, FILE* pFile, DWORD dwSize, DWORD dwPos);
|
||||
BOOL CreateBufferFromWaveFile(int dwBuf, char *pFileName);
|
||||
BOOL StopAllSounds();
|
||||
BOOL PlaySoundDS(DWORD dwSound, DWORD dwFlags);
|
||||
|
||||
protected:
|
||||
HWND m_hWnd;
|
||||
BOOL m_bEnable;
|
||||
BOOL m_bState;
|
||||
LPDIRECTSOUND m_lpDS;
|
||||
LPDIRECTSOUNDBUFFER m_lpDSB[MAXSOUND];
|
||||
short m_channelBlupi[MAXBLUPI];
|
||||
UINT m_MidiDeviceID;
|
||||
char m_MIDIFilename[50];
|
||||
int m_audioVolume;
|
||||
int m_midiVolume;
|
||||
int m_lastMidiVolume;
|
||||
int m_nbSuspendSkip;
|
||||
};
|
346
text.cpp
Normal file
346
text.cpp
Normal file
@ -0,0 +1,346 @@
|
||||
// Text.cpp
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ddraw.h>
|
||||
#include "def.h"
|
||||
#include "pixmap.h"
|
||||
#include "text.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Retourne l'offset pour un caract<63>re donn<6E>.
|
||||
|
||||
int GetOffset(char c)
|
||||
{
|
||||
int i;
|
||||
|
||||
static unsigned char table_accents[15] =
|
||||
{
|
||||
0xFC, 0xE0, 0xE2, 0xE9, 0xE8, 0xEB, 0xEA, 0xEF,
|
||||
0xEE, 0xF4, 0xF9, 0xFB, 0xE4, 0xF6, 0xE7
|
||||
};
|
||||
|
||||
for ( i=0 ; i<15 ; i++ )
|
||||
{
|
||||
if ( (unsigned char)c == table_accents[i] )
|
||||
{
|
||||
return 15+i;
|
||||
}
|
||||
}
|
||||
if ( c<0 || c>128 ) return 1; // carr<72>
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
// Retourne la longueur d'un caract<63>re.
|
||||
|
||||
int GetCharWidth(char c, int font)
|
||||
{
|
||||
static unsigned char table_width[128] =
|
||||
{
|
||||
9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,8,
|
||||
9,9,8,8,8,8,5,5,8,8,8,9,8,8,10,10,
|
||||
5,6,9,13,11,12,12,6,6,6,12,12,5,9,6,9,
|
||||
8,8,9,9,8,9,8,8,9,9,6,6,8,9,10,11,
|
||||
12,8,9,9,9,8,8,8,9,4,8,9,8,10,9,9,
|
||||
8,9,8,9,10,8,9,11,9,8,10,7,10,7,13,13,
|
||||
9,9,8,8,8,8,6,8,8,4,6,8,4,12,8,8,
|
||||
8,8,7,6,7,8,8,10,8,8,7,6,6,6,10,0,
|
||||
};
|
||||
|
||||
static unsigned char table_width_little[128] =
|
||||
{
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,7,
|
||||
6,6,6,6,6,6,3,3,6,6,6,6,6,6,5,5,
|
||||
3,3,5,8,5,11,9,3,4,4,6,6,3,4,3,6,
|
||||
5,5,5,5,5,5,5,5,5,5,3,3,7,6,7,6,
|
||||
9,8,6,7,7,5,5,8,7,2,4,7,5,10,7,8,
|
||||
6,8,7,6,6,6,8,12,7,6,6,3,5,3,6,8,
|
||||
4,6,6,6,6,6,4,6,6,2,3,5,2,10,6,6,
|
||||
6,6,3,5,3,6,6,8,6,6,5,4,6,4,7,0,
|
||||
};
|
||||
|
||||
if ( font == FONTLITTLE )
|
||||
{
|
||||
return table_width_little[GetOffset(c)];
|
||||
}
|
||||
else
|
||||
{
|
||||
return table_width[GetOffset(c)]-1;
|
||||
}
|
||||
}
|
||||
|
||||
// Affiche un texte.
|
||||
|
||||
void DrawText(CPixmap *pPixmap, POINT pos, char *pText, int font)
|
||||
{
|
||||
int rank;
|
||||
|
||||
if ( font == FONTLITTLE )
|
||||
{
|
||||
while ( *pText != 0 )
|
||||
{
|
||||
rank = GetOffset(*pText);
|
||||
pPixmap->DrawIcon(-1, CHLITTLE, rank, pos);
|
||||
|
||||
pos.x += GetCharWidth(*pText++, font);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( *pText != 0 )
|
||||
{
|
||||
rank = GetOffset(*pText);
|
||||
rank += 128*font;
|
||||
pPixmap->DrawIcon(-1, CHTEXT, rank, pos);
|
||||
|
||||
pos.x += GetCharWidth(*pText++, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Affiche un texte pench<63>.
|
||||
|
||||
void DrawTextPente(CPixmap *pPixmap, POINT pos, char *pText,
|
||||
int pente, int font)
|
||||
{
|
||||
int rank, lg, rel, start;
|
||||
|
||||
start = pos.y;
|
||||
rel = 0;
|
||||
while ( *pText != 0 )
|
||||
{
|
||||
rank = GetOffset(*pText);
|
||||
rank += 128*font;
|
||||
pPixmap->DrawIcon(-1, CHTEXT, rank, pos);
|
||||
|
||||
lg = GetCharWidth(*pText++, font);
|
||||
rel += lg;
|
||||
pos.x += lg;
|
||||
pos.y = start + rel/pente;
|
||||
}
|
||||
}
|
||||
|
||||
// Affiche un pav<61> de texte.
|
||||
// Une ligne vide est affich<63>e avec un demi interligne !
|
||||
// Si part != -1, n'affiche que les lignes qui commencent
|
||||
// par "n|", avec n=part.
|
||||
|
||||
void DrawTextRect(CPixmap *pPixmap, POINT pos, char *pText,
|
||||
int pente, int font, int part)
|
||||
{
|
||||
char text[100];
|
||||
char* pDest;
|
||||
int itl;
|
||||
|
||||
if ( font == FONTLITTLE ) itl = DIMLITTLEY;
|
||||
else itl = DIMTEXTY;
|
||||
|
||||
while ( *pText != 0 )
|
||||
{
|
||||
pDest = text;
|
||||
while ( *pText != 0 && *pText != '\r' && *pText != '\n' )
|
||||
{
|
||||
*pDest++ = *pText++;
|
||||
}
|
||||
*pDest = 0;
|
||||
if ( *pText == '\r' ) pText ++; // saute '\r'
|
||||
if ( *pText == '\n' ) pText ++; // saute '\n'
|
||||
|
||||
pDest = text;
|
||||
if ( text[0] != 0 && text[1] == '|' ) // commence par "n|" ?
|
||||
{
|
||||
if ( part != -1 && part != text[0]-'0' ) continue;
|
||||
pDest += 2; // saute "n|"
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( part != -1 ) continue;
|
||||
}
|
||||
|
||||
if ( pente == 0 )
|
||||
{
|
||||
DrawText(pPixmap, pos, pDest, font);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextPente(pPixmap, pos, pDest, pente, font);
|
||||
}
|
||||
|
||||
if ( pDest[0] == 0 ) // ligne vide ?
|
||||
{
|
||||
pos.y += itl/2; // descend de 1/2 ligne
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.y += itl; // passe <20> la ligne suivante
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Affiche un texte centr<74> pouvant <20>ventuellement
|
||||
// contenir plusieurs lignes s<>par<61>es par des '\n'.
|
||||
|
||||
void DrawTextCenter(CPixmap *pPixmap, POINT pos, char *pText, int font)
|
||||
{
|
||||
char text[100];
|
||||
char* pDest;
|
||||
int itl;
|
||||
POINT start;
|
||||
|
||||
if ( font == FONTLITTLE ) itl = DIMLITTLEY;
|
||||
else itl = DIMTEXTY;
|
||||
|
||||
while ( *pText != 0 )
|
||||
{
|
||||
pDest = text;
|
||||
while ( *pText != 0 && *pText != '\r' && *pText != '\n' )
|
||||
{
|
||||
*pDest++ = *pText++;
|
||||
}
|
||||
*pDest = 0;
|
||||
if ( *pText == '\r' ) pText ++; // saute '\r'
|
||||
if ( *pText == '\n' ) pText ++; // saute '\n'
|
||||
|
||||
pDest = text;
|
||||
start.x = pos.x - GetTextWidth(pDest)/2;
|
||||
start.y = pos.y;
|
||||
DrawText(pPixmap, start, pDest, font);
|
||||
|
||||
if ( pDest[0] == 0 ) // ligne vide ?
|
||||
{
|
||||
pos.y += itl/2; // descend de 1/2 ligne
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.y += itl; // passe <20> la ligne suivante
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retourne la hauteur d'un texte.
|
||||
|
||||
int GetTextHeight(char *pText, int font, int part)
|
||||
{
|
||||
char text[100];
|
||||
char* pDest;
|
||||
int itl;
|
||||
int h=0;
|
||||
|
||||
if ( font == FONTLITTLE ) itl = DIMLITTLEY;
|
||||
else itl = DIMTEXTY;
|
||||
|
||||
while ( *pText != 0 )
|
||||
{
|
||||
pDest = text;
|
||||
while ( *pText != 0 && *pText != '\r' && *pText != '\n' )
|
||||
{
|
||||
*pDest++ = *pText++;
|
||||
}
|
||||
*pDest = 0;
|
||||
if ( *pText == '\r' ) pText ++; // saute '\r'
|
||||
if ( *pText == '\n' ) pText ++; // saute '\n'
|
||||
|
||||
pDest = text;
|
||||
if ( text[0] != 0 && text[1] == '|' ) // commence par "n|" ?
|
||||
{
|
||||
if ( part != -1 && part != text[0]-'0' ) continue;
|
||||
pDest += 2; // saute "n|"
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( part != -1 ) continue;
|
||||
}
|
||||
|
||||
if ( pDest[0] == 0 ) // ligne vide ?
|
||||
{
|
||||
h += itl/2; // descend de 1/2 ligne
|
||||
}
|
||||
else
|
||||
{
|
||||
h += itl; // passe <20> la ligne suivante
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
// Retourne la longueur d'un texte.
|
||||
|
||||
int GetTextWidth(char *pText, int font)
|
||||
{
|
||||
int width = 0;
|
||||
|
||||
while ( *pText != 0 )
|
||||
{
|
||||
width += GetCharWidth(*pText++, font);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
// Retourne la longueur d'un grand chiffre.
|
||||
|
||||
void GetBignumInfo(int num, int &start, int &lg)
|
||||
{
|
||||
static int table[11] =
|
||||
{
|
||||
0,53,87,133,164,217,253,297,340,382,426
|
||||
};
|
||||
|
||||
start = table[num];
|
||||
lg = table[num+1]-table[num];
|
||||
}
|
||||
|
||||
// Affiche un grand nombre.
|
||||
|
||||
void DrawBignum(CPixmap *pPixmap, POINT pos, int num)
|
||||
{
|
||||
char string[10];
|
||||
int i = 0;
|
||||
int start, lg;
|
||||
RECT rect;
|
||||
|
||||
sprintf(string, "%d", num);
|
||||
|
||||
rect.top = 0;
|
||||
rect.bottom = 52;
|
||||
while ( string[i] != 0 )
|
||||
{
|
||||
GetBignumInfo(string[i]-'0', start, lg);
|
||||
|
||||
rect.left = start;
|
||||
rect.right = start+lg;
|
||||
pPixmap->DrawPart(-1, CHBIGNUM, pos, rect);
|
||||
pos.x += lg+4;
|
||||
|
||||
i ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Retourne la longueur d'un grand nombre.
|
||||
|
||||
int GetBignumWidth(int num)
|
||||
{
|
||||
char string[10];
|
||||
int i = 0;
|
||||
int start, lg;
|
||||
int width = -4;
|
||||
|
||||
sprintf(string, "%d", num);
|
||||
|
||||
while ( string[i] != 0 )
|
||||
{
|
||||
GetBignumInfo(string[i]-'0', start, lg);
|
||||
width += lg+4;
|
||||
i ++;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
35
text.h
Normal file
35
text.h
Normal file
@ -0,0 +1,35 @@
|
||||
// Text.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#define FONTWHITE 0
|
||||
#define FONTRED 1
|
||||
#define FONTSLIM 2
|
||||
#define FONTLITTLE 10
|
||||
|
||||
extern
|
||||
void DrawText(CPixmap *pPixmap, POINT pos, char *pText, int font=0);
|
||||
|
||||
extern
|
||||
void DrawTextPente(CPixmap *pPixmap, POINT pos, char *pText,
|
||||
int pente, int font=0);
|
||||
|
||||
extern
|
||||
void DrawTextRect(CPixmap *pPixmap, POINT pos, char *pText,
|
||||
int pente, int font=0, int part=-1);
|
||||
|
||||
extern
|
||||
void DrawTextCenter(CPixmap *pPixmap, POINT pos, char *pText, int font=0);
|
||||
|
||||
extern
|
||||
int GetTextHeight(char *pText, int font=0, int part=-1);
|
||||
|
||||
extern
|
||||
int GetTextWidth(char *pText, int font=0);
|
||||
|
||||
extern
|
||||
void DrawBignum(CPixmap *pPixmap, POINT pos, int num);
|
||||
|
||||
extern
|
||||
int GetBignumWidth(int num);
|
||||
|
270
wave.cpp
Normal file
270
wave.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Copyright (c) 1996 Microsoft Corporation
|
||||
*
|
||||
* File: wave.cpp
|
||||
* Content: Routines for getting waves from resources
|
||||
* Author: Dave Edson; modified by Peter Donnelly
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include "wave.h"
|
||||
|
||||
typedef struct tagWAVEFILE
|
||||
{
|
||||
DWORD cbSize; // Size of file
|
||||
LPWAVEFORMATEX pwfxInfo; // Wave Header
|
||||
LPBYTE pbData; // Wave Bits
|
||||
}
|
||||
WAVEFILE, *LPWAVEFILE;
|
||||
|
||||
|
||||
// Function Prototypes
|
||||
BOOL wave_ParseWaveMemory(void *pvRes,
|
||||
WAVEFORMATEX **ppWaveHeader,
|
||||
BYTE **ppbWaveData,
|
||||
DWORD *pcbWaveSize);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WAVE_LoadResource: Gets a wave file into the memory pointed
|
||||
// to by pWaveFile from a resource.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
LPVOID WAVE_LoadResource
|
||||
(int ID, // ID of resource
|
||||
HMODULE hModule, // hInst of app with WAVE
|
||||
LPWAVEFILE pWaveFile) // Points to the struct to fill
|
||||
{
|
||||
HRSRC hResInfo;
|
||||
HGLOBAL hResData;
|
||||
void *pvRes;
|
||||
DWORD dwSize;
|
||||
LPVOID lpMemory;
|
||||
|
||||
// Find the resource and load into memory
|
||||
if (((hResInfo = FindResource(hModule, MAKEINTRESOURCE(ID), "WAVE")) != NULL) &&
|
||||
((hResData = LoadResource(hModule, hResInfo)) != NULL) &&
|
||||
((pvRes = LockResource(hResData)) != NULL))
|
||||
{
|
||||
// If we found it, copy the bits from the resource into
|
||||
// our own chunk of memory
|
||||
dwSize = SizeofResource(hModule, hResInfo);
|
||||
lpMemory = malloc (dwSize);
|
||||
memcpy (lpMemory, pvRes, dwSize);
|
||||
UnlockResource(hResData);
|
||||
FreeResource(hResData);
|
||||
|
||||
// Parse it out
|
||||
if (wave_ParseWaveMemory(lpMemory,
|
||||
&(pWaveFile->pwfxInfo),
|
||||
&(pWaveFile->pbData),
|
||||
&(pWaveFile->cbSize)))
|
||||
{
|
||||
return lpMemory; // OK
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wave_ParseWaveMemory
|
||||
// Parses a chunk of memory into the header and samples.
|
||||
// This is done by looking for the "fmt " and "data"
|
||||
// fields in the memory.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL wave_ParseWaveMemory
|
||||
|
||||
(LPVOID lpChunkOfMemory, // Points to raw ram
|
||||
LPWAVEFORMATEX *lplpWaveHeader, // Points to pointer to header
|
||||
LPBYTE *lplpWaveSamples,// Points to pointer to samples
|
||||
LPDWORD lpcbWaveSize) // Points to size
|
||||
{
|
||||
LPDWORD pdw;
|
||||
LPDWORD pdwEnd;
|
||||
DWORD dwRiff;
|
||||
DWORD dwType;
|
||||
DWORD dwLength;
|
||||
|
||||
// Set defaults to NULL or zero
|
||||
if (lplpWaveHeader)
|
||||
*lplpWaveHeader = NULL;
|
||||
|
||||
if (lplpWaveSamples)
|
||||
*lplpWaveSamples = NULL;
|
||||
|
||||
if (lpcbWaveSize)
|
||||
*lpcbWaveSize = 0;
|
||||
|
||||
// Set up DWORD pointers to the start of the chunk
|
||||
// of memory.
|
||||
pdw = (DWORD *)lpChunkOfMemory;
|
||||
|
||||
// Get the type and length of the chunk of memory
|
||||
dwRiff = *pdw++;
|
||||
dwLength = *pdw++;
|
||||
dwType = *pdw++;
|
||||
|
||||
// Using the mmioFOURCC macro (part of Windows SDK), ensure
|
||||
// that this is a RIFF WAVE chunk of memory
|
||||
if (dwRiff != mmioFOURCC('R', 'I', 'F', 'F'))
|
||||
return FALSE; // not even RIFF
|
||||
|
||||
if (dwType != mmioFOURCC('W', 'A', 'V', 'E'))
|
||||
return FALSE; // not a WAV
|
||||
|
||||
// Find the pointer to the end of the chunk of memory
|
||||
pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);
|
||||
|
||||
// Run through the bytes looking for the tags
|
||||
while (pdw < pdwEnd)
|
||||
{
|
||||
dwType = *pdw++;
|
||||
dwLength = *pdw++;
|
||||
|
||||
switch (dwType)
|
||||
{
|
||||
// Found the format part
|
||||
case mmioFOURCC('f', 'm', 't', ' '):
|
||||
|
||||
if (lplpWaveHeader && !*lplpWaveHeader)
|
||||
{
|
||||
if (dwLength < sizeof(WAVEFORMAT))
|
||||
return FALSE; // something's wrong! Not a WAV
|
||||
|
||||
// Set the lplpWaveHeader to point to this part of
|
||||
// the memory chunk
|
||||
*lplpWaveHeader = (LPWAVEFORMATEX)pdw;
|
||||
|
||||
// Check to see if the other two items have been
|
||||
// filled out yet (the bits and the size of the
|
||||
// bits). If so, then this chunk of memory has
|
||||
// been parsed out and we can exit
|
||||
if ((!lplpWaveSamples || *lplpWaveSamples) &&
|
||||
(!lpcbWaveSize || *lpcbWaveSize))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Found the samples
|
||||
case mmioFOURCC('d', 'a', 't', 'a'):
|
||||
|
||||
if ((lplpWaveSamples && !*lplpWaveSamples) ||
|
||||
(lpcbWaveSize && !*lpcbWaveSize))
|
||||
{
|
||||
// Point the samples pointer to this part of the
|
||||
// chunk of memory.
|
||||
if (lplpWaveSamples) *lplpWaveSamples = (LPBYTE)pdw;
|
||||
|
||||
// Set the size of the wave
|
||||
if (lpcbWaveSize) *lpcbWaveSize = dwLength;
|
||||
|
||||
// Make sure we have our header pointer set up.
|
||||
// If we do, we can exit
|
||||
if (!lplpWaveHeader || *lplpWaveHeader)
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
} // End case
|
||||
|
||||
// Move the pointer through the chunk of memory
|
||||
pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
|
||||
}
|
||||
|
||||
// Failed! If we made it here, we did not get all the pieces
|
||||
// of the wave
|
||||
return FALSE;
|
||||
} // wave_ParseWaveMemory
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LoadWave
|
||||
// Gets the sound data and loads it into a DirectSound
|
||||
// secondary buffer.
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
void LoadWave(HINSTANCE hinst, int ResourceID,
|
||||
LPDIRECTSOUND lpds,
|
||||
LPDIRECTSOUNDBUFFER &lpDSB)
|
||||
{
|
||||
// These variables are used in Steps 1 and 2
|
||||
LPVOID lpWaveData;
|
||||
WAVEFILE WaveFile;
|
||||
DSBUFFERDESC dsbd;
|
||||
|
||||
// These variables are used in step 3, further down below
|
||||
LPVOID pbData = NULL;
|
||||
LPVOID pbData2 = NULL;
|
||||
DWORD dwLength;
|
||||
DWORD dwLength2;
|
||||
|
||||
|
||||
lpWaveData = WAVE_LoadResource (ResourceID, hinst, &WaveFile );
|
||||
|
||||
// Step 1: Set up the direct sound buffer.
|
||||
memset(&dsbd, 0, sizeof(DSBUFFERDESC));
|
||||
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
// We want a buffer that lives on the sound card's memory
|
||||
// (DSBCAPS_STATIC) and can have the pan, volume, and
|
||||
// frequency adjusted (DSBCAPS_CTRLDEFAULT)
|
||||
dsbd.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_STATIC ;
|
||||
|
||||
// Set up the size and format
|
||||
dsbd.dwBufferBytes = WaveFile.cbSize;
|
||||
dsbd.lpwfxFormat = WaveFile.pwfxInfo; // Must be a PCM format!
|
||||
|
||||
// Step 2: Create the buffer
|
||||
if (DS_OK != lpds->CreateSoundBuffer(&dsbd, &lpDSB, NULL))
|
||||
{
|
||||
OutputDebugString("Failed to create sound buffer\n");
|
||||
return;
|
||||
}
|
||||
// Once this code succeeds, lpDSB will point to a DirectSoundBuffer.
|
||||
// At this point, you can copy blocks of sound data into the buffer,
|
||||
// using the Lock and Unlock interfaces on the DirectSoundBuffer:
|
||||
|
||||
// Lock down the DirectSound buffer
|
||||
if (DS_OK == lpDSB->Lock
|
||||
(0, // Offset into buffer to start writing
|
||||
WaveFile.cbSize, // Size of wave file to copy in
|
||||
&pbData, // Points to first block of sound data
|
||||
&dwLength, // Length of first block of data
|
||||
&pbData2, // Points to second block of sound data
|
||||
&dwLength2, // Length of second block of data
|
||||
0L)) // Flags
|
||||
{
|
||||
// Copy first chunk
|
||||
memcpy(pbData, WaveFile.pbData, dwLength);
|
||||
|
||||
// Copy second chunk
|
||||
if (dwLength2)
|
||||
memcpy(pbData2, WaveFile.pbData+dwLength , dwLength2);
|
||||
|
||||
// Free up the memory allocated in the WAVE_LoadFile function, since we
|
||||
// have copied it to the buffer
|
||||
free (lpWaveData);
|
||||
|
||||
// Unlock the buffer
|
||||
if (DS_OK != lpDSB->Unlock(pbData, dwLength, pbData2, dwLength2))
|
||||
OutputDebugString("Unlock failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDebugString("Lock failed");
|
||||
}
|
||||
} // LoadWave
|
Loading…
x
Reference in New Issue
Block a user