diff --git a/harbour/contrib/directx/HB_DDraw.cpp b/harbour/contrib/directx/HB_DDraw.cpp new file mode 100644 index 0000000000..547c406eb2 --- /dev/null +++ b/harbour/contrib/directx/HB_DDraw.cpp @@ -0,0 +1,910 @@ +/* + * Copyright(C) 1999 by Jesus Salas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to: + * + * The Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * You can contact me at: jsalas@gruposp.com jsalas@sp-editores.es + * + */ + +#define INITGUID +#include "HB_DDraw.h" + + + BOOL hb_dd_g_handling_events=FALSE; // painting? + + #define HB_DD_TIMER_ID 1 + #define HB_DD_TIMER_RATE 100 + + // DDRAW MANAGEMENT + // Global Data + + LPDIRECTDRAW4 hb_dd_g_pDD = NULL; // DirectDraw object + HWND hb_dd_g_DDHwnd; // Our hWnd + + long hb_dd_g_xWindow=0; + long hb_dd_g_yWindow=0; + +//------------------------------------------------------------------------------// +// Management Structs for surfaces... + + #define MAX_DDSURFACES 255 + + LPDIRECTDRAWSURFACE4 hb_dd_g_DDSFaces[ MAX_DDSURFACES + 1 ]; + + long hb_dd_g_DDSFaceCount=0; + +//------------------------------------------------------------------------------// +// Sprites Management + + #define MAX_SPRITES 256 + + struct st_Sprites + { + short int Type; // Type of Data + long Surface; // Surface index for loaded Image(s) + char * cName; // Sprite friendly Name + // 2D Engine data + long Width; // width of one frame + long Height; // height of one frame + long Images; // Number of frames in Surface + short int Visible; // Render it and do Hit detect? + long Frame; // Actual Frame to Render + long zOrder; // For painting + long x; // x in Virtual Screen + long y; // y in Virtual Screen + long VisibleX; // "real" y in Visible Screen + long VisibleY; // "real" x in Visible Screen + long FrameSpeed; // Render frame time ratio + long DrawInverted; // Draw Inverted + long Direction; // Clock wise code 1-2-3-4-5-6-7-8-9 + long xIncrement; // x Increment Increment; + long yIncrement; // y Increment + long Solid; // is Solid object ( collision on ) + long Masked; // is Masked? + short int lCollision; // Collision Detect On/Off + + // Sprite Event Handlers... + + char * OnRender; // Render event Handler + char * OnCollision; // Collision Event Handler + char * OnFirstFrame; // First Frame handler + char * OnOutScreen; // Out of Bounds... + + }hb_dd_Sprites[MAX_SPRITES]; + + long hb_dd_g_SpritesCount=0; + +//------------------------------------------------------------------// +// Multi-Key control array. + + short int hb_dd_g_KeyDown[256]; + + HARBOUR HB_DD_ISKEYPRESSED( void ) + { + long nKey = hb_parnl( 1 ); + if ( hb_dd_g_KeyDown[ nKey ] ) + hb_retl( 1 ); + else + hb_retl( 0 ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPGETXY( void ) + { + + // This function is Broken ( hb_stornl fail ); + + long n =hb_parnl( 1 ); + + hb_reta( 2 ); + + hb_stornl( hb_dd_Sprites[ n ].x, -1, 0 ); + hb_stornl( hb_dd_Sprites[ n ].y, -1, 1 ); + } + + HARBOUR HB_DD_SPGETX( void ) + { + + long n =hb_parnl( 1 ); + hb_retnl( hb_dd_Sprites[ n ].x ); + } + + HARBOUR HB_DD_SPGETY( void ) + { + + long n =hb_parnl( 1 ); + hb_retnl( hb_dd_Sprites[ n ].y ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPGETVISIBLE( void ) + { + hb_retl( hb_dd_Sprites[ hb_parnl( 1 ) ].Visible ); + } + +//------------------------------------------------------------------// + + void HB_DD_SPSETVISIBLE( void ) + { + long n = hb_parnl( 1 ); + hb_dd_Sprites[ n ].Visible = hb_parl( 2 ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPONRENDER( void ) + { + long n = hb_parnl( 1 ); + hb_dd_Sprites[ n ].OnRender = strdup( hb_parc(1) ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPCLEARDIRECTION( void ) + { + long n = hb_parnl( 1 ); + hb_dd_Sprites[ n ].xIncrement = 0; + hb_dd_Sprites[ n ].yIncrement = 0; + hb_dd_Sprites[ n ].Direction = -1; + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPSETSOLID( void ) + { + long n =hb_parnl( 1 ); + hb_dd_Sprites[hb_parnl( 1 ) ].Solid = hb_parl( 2 ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPSETMASKED( void ) + { + long n =hb_parnl( 1 ); + hb_dd_Sprites[hb_parnl( 1 ) ].Masked = hb_parl( 2 ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPSETDIRECTION( void ) + { + long n =hb_parnl( 1 ); + + hb_dd_Sprites[ n ].Direction =hb_parnl( 2 ); + hb_dd_Sprites[ n ].xIncrement +=hb_parnl( 3 ); + hb_dd_Sprites[ n ].yIncrement +=hb_parnl( 4 ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPONFIRSTFRAME( void ) + { + long n =hb_parnl( 1 ); + hb_dd_Sprites[ n ].OnFirstFrame = strdup( hb_parc(2) ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPONOUTSCREEN( void ) + { + long n =hb_parnl( 1 ); + hb_dd_Sprites[ n ].OnOutScreen = strdup( hb_parc(2) ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPONCOLLISION( void ) + { + long n =hb_parnl( 1 ); + hb_dd_Sprites[ n ].OnCollision = strdup( hb_parc(2) ); + hb_dd_Sprites[ n ].lCollision = 1; + } + +//------------------------------------------------------------------// + + + HARBOUR HB_DD_CREATESPRITE( void ) + { + long n = hb_dd_g_SpritesCount; + + ZeroMemory( &hb_dd_Sprites[ n ], sizeof( struct st_Sprites ) ); + + hb_dd_Sprites[ n ].Surface = hb_parnl(1); + hb_dd_Sprites[ n ].cName = strdup( hb_parc(2) ); + hb_dd_Sprites[ n ].Width = hb_parnl(3); + hb_dd_Sprites[ n ].Height = hb_parnl(4); + hb_dd_Sprites[ n ].Images = hb_parnl(5); + hb_dd_Sprites[ n ].zOrder = hb_parnl(6); + hb_dd_Sprites[ n ].Visible = hb_parl(7); + hb_dd_Sprites[ n ].FrameSpeed =hb_parnl(8); + + hb_dd_g_SpritesCount++; + + hb_retnl( n ); + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_SPSETXY( void ) + { + long n =hb_parnl( 1 ); + long x =hb_parnl( 2 ); + long y =hb_parnl( 3 ); + hb_dd_Sprites[ n ].x = x; + hb_dd_Sprites[ n ].y = y; + } + +//------------------------------------------------------------------// + + HARBOUR DD_SPSETINVERTED( void ) + { + LPDIRECTDRAWSURFACE4 pdds; + long n =hb_parnl(1); + RECT rt; + DDBLTFX todo; + + long dir =hb_parnl( 2 ); + if ( dir != hb_dd_Sprites[ n ].DrawInverted ) + { + rt.top = 0; + rt.left = 0; + rt.bottom= hb_dd_Sprites[ n ].Height; + rt.right = hb_dd_Sprites[ n ].Width * hb_dd_Sprites[ n ].Images; + ZeroMemory( &todo, sizeof( DDBLTFX ) ); + + hb_dd_Sprites[ n ].DrawInverted = dir; + todo.dwSize = sizeof( DDBLTFX ); + todo.dwDDFX = DDBLTFX_MIRRORLEFTRIGHT; + pdds = hb_dd_g_DDSFaces[ hb_dd_Sprites[ n ].Surface ]; + pdds->Blt(&rt, pdds, &rt, DDBLT_DDFX ,&todo ); + } + } + + +//------------------------------------------------------------------// + + HARBOUR HB_DD_MSGBOX( void ) + { + char buff[20]=""; + long dwVal=0; + + char *m1; + char *m2; + char deftitle [100] = ""; + char defmsg [2] = ""; + + if ( hb_pcount() > 0 ) + m1 = hb_parc( 1 ); + else + m1 = defmsg; + + if ( hb_pcount() > 1 ) + m2 = hb_parc( 2 ); + else + m2 = deftitle; + + MessageBox( hb_dd_g_DDHwnd, m1, m2, NULL); + + } + +//------------------------------------------------------------------// + + void hb_dd_WinError( void ) + { + LPVOID lpMsgBuf;FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, 0, NULL );// Process any inserts in lpMsgBuf. + // ...// Display the string. + MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); + // Free the buffer. + LocalFree( lpMsgBuf ); + + } + +//------------------------------------------------------------------// + + extern "C" DWORD hb_dd_DDColorMatch(IDirectDrawSurface4 * pdds, COLORREF rgb) + { + COLORREF rgbT; + HDC hdc; + DWORD dw = CLR_INVALID; + DDSURFACEDESC2 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 + if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32) + 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; + } + + +//------------------------------------------------------------------// + + void hb_dd_RenderSprites( long control ) + { + + HRESULT hRet; + long cont,cont2; + RECT rcRect; + LPDIRECTDRAWSURFACE4 pdds; + long o =0 ; + PSYMBOL pVMCall; + PDYNSYM pDynSym; + + pDynSym = hb_FindDynSym( "DDONRENDER" ); + + if( pDynSym ) + { + pVMCall = pDynSym->pSymbol; + PushSymbol( pVMCall ); + PushNil(); + Do( 0 ); + } + + + for( cont=0; contpSymbol; + PushSymbol( pVMCall ); + PushNil(); + PushLong( cont ); + PushLong( cont2 ); + Do( 2 ); + } + } + + } + } + + } + + // Sequencer + + if ( hb_dd_Sprites[ cont ].Frame > hb_dd_Sprites[ cont ].Images ) + { + + if ( hb_dd_Sprites[ cont ].OnFirstFrame != NULL ) + { + pDynSym = hb_FindDynSym( hb_dd_Sprites[ cont ].OnFirstFrame ); + if( pDynSym ) + { + pVMCall = pDynSym->pSymbol; + PushSymbol( pVMCall ); + PushNil(); + Do( 0 ); + } + } + hb_dd_Sprites[ cont ].Frame = 1; + } + + + rcRect.left = ( hb_dd_Sprites[ cont ].Frame - 1 ) * hb_dd_Sprites[ cont ].Width; + rcRect.top = 0; + rcRect.right = ( hb_dd_Sprites[ cont ].Frame - 1 ) * hb_dd_Sprites[ cont ].Width + hb_dd_Sprites[ cont ].Width; + rcRect.bottom = hb_dd_Sprites[ cont ].Height; + + if ( control == 1 ) + hb_dd_Sprites[ cont ].Frame++; + + pdds = hb_dd_g_DDSFaces[ hb_dd_Sprites[ cont ].Surface ]; + + while (TRUE) + { + + if ( ! hb_dd_Sprites[ cont ].Masked ) + hRet = hb_dd_g_DDSFaces[1]->BltFast(hb_dd_Sprites[ cont ].x, hb_dd_Sprites[ cont ].y, pdds, &rcRect, FALSE ); + else + { + DDCOLORKEY ddck; + + ddck.dwColorSpaceLowValue = hb_dd_DDColorMatch( pdds, CLR_INVALID ); + ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue; + + pdds->SetColorKey( DDCKEY_SRCBLT ,&ddck ); + + hb_dd_g_DDSFaces[1]->SetColorKey( DDCKEY_DESTBLT ,&ddck ); + + hRet = hb_dd_g_DDSFaces[1]->BltFast(hb_dd_Sprites[ cont ].x, hb_dd_Sprites[ cont ].y, pdds, &rcRect, DDBLTFAST_SRCCOLORKEY ); + } + hb_dd_checkError( hRet ); + if (hRet == DD_OK) + break; + if (hRet == DDERR_SURFACELOST) + { + hRet = hb_dd_g_DDSFaces[1]->Restore(); + if (hRet != DD_OK) + break; + } + if (hRet != DDERR_WASSTILLDRAWING) + break; + } + + if ( hb_dd_Sprites[ cont ].OnOutScreen != NULL ) + { + if ( hb_dd_Sprites[ cont ].x < 0 || hb_dd_Sprites[ cont ].y < 0 || hb_dd_Sprites[ cont ].x > 640 || hb_dd_Sprites[ cont ].y > 480 ) + { + if ( hb_dd_Sprites[ cont ].OnOutScreen != NULL ) + { + pDynSym = hb_FindDynSym( hb_dd_Sprites[ cont ].OnOutScreen ); + + if( pDynSym ) + { + pVMCall = pDynSym->pSymbol; + PushSymbol( pVMCall ); + PushNil(); + PushLong( cont ); + Do( 1 ); + } + } + + + //SetParam( ( void * ) &cont , TSI_DWORD ); + //VMCall( hb_dd_Sprites[ cont ].OnOutScreen ); + } + } + + } + } +} + +//------------------------------------------------------------------// + + + + long _stdcall hb_dd_DDWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) + { + HRESULT hRet; + int nVirtKey; + + switch( uMsg ) + { + case WM_DESTROY: + hb_dd_ReleaseAllObjects(); + break; + case WM_KEYUP: + { + nVirtKey= (int) wParam; // virtual-key code + hb_dd_g_KeyDown[ nVirtKey ] = 0; + break; + } + case WM_KEYDOWN: + { + nVirtKey = (int) wParam; // virtual-key code + hb_dd_g_KeyDown[ nVirtKey ] = 1; + + if ( ( int ) wParam == 27 ) + { + PostMessage( hWnd, WM_CLOSE,0,0); + PostMessage( hWnd, WM_DESTROY,0,0); + } + break; + } + case WM_TIMER: + if ( HB_DD_TIMER_ID == wParam) + { + if ( ! hb_dd_g_handling_events ) + { + + hb_dd_g_handling_events = TRUE; + hb_dd_RenderSprites(1); + while (TRUE) + { + hRet = hb_dd_g_DDSFaces[0]->Flip(NULL, 0); + if (hRet == DD_OK) + break; + if (hRet == DDERR_SURFACELOST) + { + hRet = hb_dd_g_DDSFaces[0]->Restore(); + if (hRet != DD_OK) + break; + } + if (hRet != DDERR_WASSTILLDRAWING) + break; + } + hb_dd_g_handling_events = FALSE; + } + } + break; + } + + return DefWindowProc( hWnd, uMsg, wParam , lParam ); + } + +//------------------------------------------------------------------// + + + HARBOUR HB_DD_CREATEWINDOW( void ) + { + + HWND m_hWnd = NULL; + HINSTANCE m_hInstance = GetModuleHandle(NULL); + long x,y; + + x= hb_pcount() > 10 ?hb_parnl( 1 ) : GetSystemMetrics(SM_CXSCREEN); + y= hb_pcount() > 11 ?hb_parnl( 2 ) : GetSystemMetrics(SM_CYSCREEN); + + hb_dd_g_xWindow = x; + hb_dd_g_yWindow = y; + + + WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, hb_dd_DDWndProc, 0, 0, m_hInstance, + NULL, + LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), + NULL, + TEXT("4dNow") }; + + RegisterClass( &wndClass ); + + m_hWnd = CreateWindow( TEXT("4dNow"), TEXT("4dNow"), + WS_POPUP, 0, + 0, x,y, NULL, NULL, m_hInstance, 0L ); + + if ( !m_hWnd ) + hb_dd_WinError(); + + ShowWindow( m_hWnd,SW_SHOWMAXIMIZED ); + + HB_DD_DDRAWSTARTUP( m_hWnd ); + hb_retnl( ( long ) m_hWnd ); + } + +//------------------------------------------------------------------// + + hb_dd_InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...) + { + char szBuff[128]; + va_list vl; + va_start(vl, szError); + vsprintf(szBuff, szError, vl); + MessageBox(hWnd, szBuff, "4dNow extend sys.", MB_OK); + DestroyWindow(hWnd); + va_end(vl); + exit(1); + return hRet; + } + + +//------------------------------------------------------------------// + + HARBOUR HB_DD_LOADBMPINTOSURFACE( void ) + { + long nSurface = hb_parnl( 1 ); + char * cBitmap = hb_parc ( 2 ); + long x = hb_parnl( 3 ); + long y = hb_parnl( 4 ); + long dx = hb_parnl( 5 ); + long dy = hb_parnl( 6 ); + + + HBITMAP hbm; + + // Load our bitmap resource. + + + hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), cBitmap, IMAGE_BITMAP, 0, + 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); + + if (hbm == NULL) + hb_dd_g_Error( "Can't load Bitmap.",100,cBitmap ); + + if ( hb_dd_g_DDSFaces[ nSurface ] == NULL ) + hb_dd_g_Error( "Invalid Surface",nSurface,"LoadBmpIntoSurface"); + + if ( DD_OK != hb_dd_DDCopyBitmap( hb_dd_g_DDSFaces[ nSurface ], hbm, x,y, dx, dy ) ) + hb_dd_g_Error( "DDCopyBitmap",nSurface,"LoadBmpIntoSurface"); + + + DeleteObject(hbm); + + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_CREATEOFFSCREENBITMAP( void ) + { + DDSURFACEDESC2 ddsd; + HRESULT hRet; + + if ( ! hb_dd_g_pDD ) + hb_dd_g_Error("No DDraw Initialized",1000,""); + + if ( hb_dd_g_DDSFaceCount >= MAX_DDSURFACES ) + hb_dd_g_Error( "No more DDSurfaces -> Limit reached -> CreateDDSurface()",1000,"DDraw extend sys"); + else + { + ZeroMemory(&ddsd, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH ; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + ddsd.dwHeight = hb_dd_g_yWindow; + ddsd.dwWidth = hb_dd_g_xWindow; + hRet = hb_dd_g_pDD->CreateSurface(&ddsd, &hb_dd_g_DDSFaces[ hb_dd_g_DDSFaceCount ], NULL); + if (hRet != DD_OK) + hb_dd_InitFail(hb_dd_g_DDHwnd, hRet, "CreateSurface FAILED"); + } + + hb_retnl( hb_dd_g_DDSFaceCount ); + hb_dd_g_DDSFaceCount++; + + } + + +//------------------------------------------------------------------// + + void hb_RestoreAll(void) + { + HRESULT hRet; + long t; + + hRet = hb_dd_g_DDSFaces[0]->Restore(); + if (hRet == DD_OK) + { + for( t=2;tRestore(); + } + } + } + +//------------------------------------------------------------------// + + void hb_dd_ReleaseAllObjects(void) + { + long t; + if (hb_dd_g_pDD != NULL) + { + if (hb_dd_g_DDSFaces[0] != NULL) + { + hb_dd_g_DDSFaces[0]->Release(); + hb_dd_g_DDSFaces[0] = NULL; + } + for( t=2;tRelease(); + hb_dd_g_DDSFaces[t] = NULL; + } + } + hb_dd_g_pDD->Release(); + hb_dd_g_pDD = NULL; + } + } + + +//------------------------------------------------------------------// + + HARBOUR HB_DD_DDRAWSTARTUP( HWND hWnd ) + { + + + DDSURFACEDESC2 ddsd; + DDSCAPS2 ddscaps; + HRESULT hRet; + LPDIRECTDRAW pDD; + long t; + + hb_dd_g_DDHwnd = hWnd; + + + hRet = DirectDrawCreate(NULL, &pDD, NULL); + if (hRet != DD_OK) + hb_dd_InitFail(hWnd, hRet, "DirectDrawCreate FAILED"); + + + hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID *) &hb_dd_g_pDD ); + + if (hRet != DD_OK) + hb_dd_InitFail(hWnd, hRet, "QueryInterface FAILED"); + + hRet = pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT | DDSCL_ALLOWMODEX ); + + if (hRet != DD_OK) + hb_dd_InitFail(hWnd, hRet, "SetCooperativeLevel FAILED"); + + hRet = hb_dd_g_pDD->SetDisplayMode(hb_dd_g_xWindow , hb_dd_g_yWindow , 16, 0, 0); + if (hRet != DD_OK) + hb_dd_InitFail(hWnd, hRet, "SetDisplayMode FAILED"); + + for( t=0;t<= MAX_DDSURFACES;t++ ) + hb_dd_g_DDSFaces[t] = NULL; + for( t=0;t< MAX_SPRITES;t++) + hb_dd_Sprites[t].Surface = -1; + for( t=0;t<256;t++) + hb_dd_g_KeyDown[t] = 0; + ZeroMemory(&ddsd, sizeof(ddsd)); + + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT | DDSD_CKSRCBLT; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + DDSCAPS_FLIP | + DDSCAPS_COMPLEX ; + ddsd.dwBackBufferCount = 1; + hRet = hb_dd_g_pDD->CreateSurface(&ddsd, &hb_dd_g_DDSFaces[0] , NULL); + if (hRet != DD_OK) + hb_dd_InitFail(hWnd, hRet, "CreateSurface FAILED"); + + ddscaps.dwCaps = DDSCAPS_BACKBUFFER; + + hRet = hb_dd_g_DDSFaces[0]->GetAttachedSurface(&ddscaps,&hb_dd_g_DDSFaces[1] ); + + if (hRet != DD_OK) + hb_dd_InitFail(hWnd, hRet, "GetAttachedSurface FAILED"); + + if (HB_DD_TIMER_ID != SetTimer(hWnd, HB_DD_TIMER_ID, HB_DD_TIMER_RATE, NULL)) + hb_dd_InitFail( hWnd, hRet, "SetTimer FAILED" ); + + hb_dd_g_DDSFaceCount = 2; + } + +//------------------------------------------------------------------// + + HARBOUR HB_DD_STARTWINDOW( void ) + { + HWND m_hWnd = ( HWND ) hb_parnl(1); + MSG msg; + BOOL loop = TRUE; + + while( loop ) + { + if ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + if ( WM_CLOSE == msg.message ) + loop = FALSE; + + } + } + +//------------------------------------------------------------------// +HRESULT hb_dd_DDCopyBitmap(IDirectDrawSurface4 * pdds, HBITMAP hbm, int x, int y, + int dx, int dy) +{ + HDC hdcImage; + HDC hdc; + BITMAP bm; + DDSURFACEDESC2 ddsd; + HRESULT hr; + + if (hbm == NULL || pdds == NULL) + return E_FAIL; + + pdds->Restore(); + + hdcImage = CreateCompatibleDC(NULL); + if (!hdcImage) + OutputDebugString("createcompatible dc failed\n"); + SelectObject(hdcImage, hbm); + + GetObject(hbm, sizeof(bm), &bm); + dx = dx == 0 ? bm.bmWidth : dx; // Use the passed size, unless zero + dy = dy == 0 ? bm.bmHeight : dy; + + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; + + pdds->GetSurfaceDesc(&ddsd); + + if ((hr = pdds->GetDC(&hdc)) == DD_OK) + { + StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, + dx, dy, SRCCOPY); + pdds->ReleaseDC(hdc); + } + DeleteDC(hdcImage); + return hr; +} + +void hb_dd_checkError( HRESULT hr ) +{ + long p=0; + switch( hr ) + { + case DDERR_EXCEPTION : p++;break; + case DDERR_GENERIC : p++;;break; + case DDERR_INVALIDOBJECT : p++;;break; + case DDERR_INVALIDPARAMS : p++;;break; + case DDERR_INVALIDRECT : p++;;break; + case DDERR_NOBLTHW : p++;;break; + case DDERR_SURFACEBUSY : p++;;break; + case DDERR_SURFACELOST : p++;;break; + case DDERR_UNSUPPORTED : p++;;break; + case DDERR_WASSTILLDRAWING : p++;;break; + case DDERR_NOOVERLAYHW :p++;;break; + case DDERR_NOTAOVERLAYSURFACE :p++;;break; + case DDERR_INVALIDSURFACETYPE :p++;;break; + + } +} + + + +void hb_dd_g_Error( char *, long , char *) +{ +} \ No newline at end of file diff --git a/harbour/contrib/directx/HB_DDraw.h b/harbour/contrib/directx/HB_DDraw.h new file mode 100644 index 0000000000..c2ae7d8ad2 --- /dev/null +++ b/harbour/contrib/directx/HB_DDraw.h @@ -0,0 +1,67 @@ +/* + * Copyright(C) 1999 by Jesus Salas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to: + * + * The Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * You can contact me at: jsalas@gruposp.com jsalas@sp-editores.es + * + */ + +#define INITGUID +#include "windows.h" +#include "winuser.h" +#include "extend.h" +#include "ctoharb.h" +#include "errno.h" +#include "objbase.h" +#include "tchar.h" +#include "stdio.h" +#include "math.h" +#include "string.h" +#include "stdlib.h" +#include ".\include\ddraw.h" +#include ".\include\ddutil.h" + + + + // Main Message Loop + + long _stdcall hb_dd_DDWndProc ( HWND , UINT , WPARAM , LPARAM ); + void hb_dd_g_Error ( char *, long , char *); + void hb_dd_CreateWindow ( void ); + + // DDraw initialize + + void HB_DD_DDRAWSTARTUP ( HWND ); + void hb_dd_StartWindow ( void ); + void hb_dd_CreateOffScreenBitmap ( void ); + void hb_dd_ReleaseAllObjects ( void ); + void hb_dd_RestoreAll ( void ); + void hb_dd_checkError ( HRESULT ); + + HRESULT hb_dd_DDCopyBitmap ( IDirectDrawSurface4 * pdds, HBITMAP hbm, int x, int y, int dx, int dy); + void hb_dd_RenderSprites ( long ); + +extern "C" DWORD hb_dd_DDColorMatch ( IDirectDrawSurface4 * pdds, COLORREF rgb ); + +//-------------------------------------------------------// +// API Functions +//-------------------------------------------------------// + + void DD_MsgBox ( void ); + void WinError ( void ); + diff --git a/harbour/contrib/directx/readme.1st b/harbour/contrib/directx/readme.1st index 1cda0fc59b..a1d77bea86 100644 --- a/harbour/contrib/directx/readme.1st +++ b/harbour/contrib/directx/readme.1st @@ -16,6 +16,47 @@ Well, this is the first implementation of Graphics Animation Library for Windows/DirectX 6.1 and Harbour + INDEX + ----------------------------------------------------------------------------------- + 0)._ What are supported, what coming soon + 1)._ What do you need for make/run the samples. + 2)._ Files in this distribution. ( HDx01.zip ) + 3)._ Building the sample + 4)._ Reminder + ----------------------------------------------------------------------------------- + 0)._ What are supported, what coming soon + + Supported / translated to harbour: + + - DirectDraw Startup + - Masked Sprites Drawing + - Solid Sprites Controls + - Basic Animation Sequencer + - Up to 90 active animations in 133-MMX ( 166 clocked-down ;) ) + - Basic Collision Detect / Hit Collision + - Event handlers for sprites ( OnFirstFrame, OnOutOfBound, OnRenderSprite... ) + - Load animations + - KeyDown/KeyUp Detection + + (W) Waiting for implementation / (NT) not translated to Harbour: + + (NT) - OpenGL Wrapper ( For those that no want DirectX ) + (W) - GDI Wrapper ( For those that no want DirectX / OpenGL ) + (NT) - Advanced Sequencer ( Automations ) + (NT) - Blocking Animations + (NT) - Timers / Intervals Support + (NT) - 2D Shadows & Light control + (NT) - FX Particles support ( Plasma Explosions ) + (NT) - FX Star Fields Support ( 2D, 3D ) + (NT) - FX Fire Support + (NT) - Font Support + (NT) - Basic drawing functions support ( Circles, lines, putpixel, getpixel, bar ) + (W) - Support for 8 / 16 / 24 / 32 ( palettized, 5-6-5 RGB ,8-8-8 RGB, 8-8-8-8 RGBA bpps ) + (W) - Support for 800x600 video modes + (W) - Wav player/Mixer ( DirectSound, MMSystem , 3D Sound ) + (W) - Midi Player/Mixer ( DirecMusic, MMSystem ) + (NT) - Direct 3D Inmediate Mode ( Startup ) + (W) - Suppor for JPG / GIF 1)._ What do you need for make/run the samples. @@ -26,7 +67,12 @@ - Set your resolution to 640x480 before running the sample. - 2)._ Files in this distribution. ( HDx01.zip ) + 2)._ Files in this distribution. + + + /DirectX/HB_DDraw.h -> header file + + /DirectX/HB_DDraw.cpp -> Source file for DDraw /DirectX/DirectX.lib -> Lib for Harbour @@ -56,13 +102,10 @@ Cursor Right -> Bunny go to right. Shift hold down -> Bunny Turbo mode on. - 4)._ Considerations. + 4)._ Reminder. You need to have the media files into the same directory of final .exe file - The source file for DirectX for harbour is not released for now, but in a short time - it will be released. ;) ( i'm cleaning the code ) - Please if you test/use it... send to me feedback for continue supporting it! @@ -77,4 +120,3 @@ -