2025-04-27 07:49:33 -04:00

680 lines
26 KiB
C

/*----------------------------------------------------------------------------*\
| qa.c - A template for a Windows application |
| |
\*----------------------------------------------------------------------------*/
#include <windows.h>
#include <mmsystem.h>
#include "qa.h"
#include "dva.h"
#include "lockbm.h"
#include "dibeng.inc"
#define DI_TYPE 0x4944 // 'DI'
#define DE_TYPE 0x4544 // 'DE'
#define RP_TYPE 0x5250 // 'RP'
#define M4_TYPE 0x344D // 'M4'
/*----------------------------------------------------------------------------*\
| |
| g e n e r a l c o n s t a n t s |
| |
\*----------------------------------------------------------------------------*/
#define MAXSTR 80
#define EXPORT FAR PASCAL _export // exported function
#define PRIVATE NEAR PASCAL // function local to this segment
#define PUBLIC FAR PASCAL // function external to this segment
/*----------------------------------------------------------------------------*\
| |
| g l o b a l v a r i a b l e s |
| |
\*----------------------------------------------------------------------------*/
static char szAppName[]="Quick App";
static HANDLE hInstApp;
static HWND hwndApp;
LPVOID lpScreen;
BITMAPINFOHEADER biScreen;
/*----------------------------------------------------------------------------*\
| |
| f u n c t i o n d e f i n i t i o n s |
| |
\*----------------------------------------------------------------------------*/
LONG EXPORT AppWndProc (HWND hwnd, unsigned uiMessage, WORD wParam, LONG lParam);
int ErrMsg (LPSTR sz,...);
BOOL fDialog(int id,HWND hwnd,FARPROC fpfn);
LONG NEAR PASCAL AppCommand(HWND hwnd, unsigned msg, WORD wParam, LONG lParam);
/*----------------------------------------------------------------------------*\
| AppAbout( hDlg, uiMessage, wParam, lParam ) |
| |
| Description: |
| This function handles messages belonging to the "About" dialog box. |
| The only message that it looks for is WM_COMMAND, indicating the use |
| has pressed the "OK" button. When this happens, it takes down |
| the dialog box. |
| |
| Arguments: |
| hDlg window handle of about dialog window |
| uiMessage message number |
| wParam message-dependent |
| lParam message-dependent |
| |
| Returns: |
| TRUE if message has been processed, else FALSE |
| |
\*----------------------------------------------------------------------------*/
BOOL EXPORT AppAbout( hDlg, uiMessage, wParam, lParam )
HWND hDlg;
unsigned uiMessage;
WORD wParam;
long lParam;
{
switch (uiMessage) {
case WM_COMMAND:
if (wParam == IDOK)
{
EndDialog(hDlg,TRUE);
}
break;
case WM_INITDIALOG:
return TRUE;
}
return FALSE;
}
/*----------------------------------------------------------------------------*\
| AppInit( hInst, hPrev) |
| |
| Description: |
| This is called when the application is first loaded into |
| memory. It performs all initialization that doesn't need to be done |
| once per instance. |
| |
| Arguments: |
| hInstance instance handle of current instance |
| hPrev instance handle of previous instance |
| |
| Returns: |
| TRUE if successful, FALSE if not |
| |
\*----------------------------------------------------------------------------*/
BOOL AppInit(HANDLE hInst,HANDLE hPrev,WORD sw,LPSTR szCmdLine)
{
WNDCLASS cls;
int dx,dy;
/* Save instance handle for DialogBoxs */
hInstApp = hInst;
if (!hPrev) {
/*
* Register a class for the main application window
*/
cls.hCursor = LoadCursor(NULL,IDC_ARROW);
cls.hIcon = LoadIcon(hInst,"AppIcon");
cls.lpszMenuName = "AppMenu";
cls.lpszClassName = szAppName;
cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
cls.hInstance = hInst;
cls.style = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
cls.lpfnWndProc = (WNDPROC)AppWndProc;
cls.cbWndExtra = 0;
cls.cbClsExtra = 0;
if (!RegisterClass(&cls))
return FALSE;
}
dx = GetSystemMetrics (SM_CXSCREEN);
dy = GetSystemMetrics (SM_CYSCREEN);
hwndApp = CreateWindow (szAppName, // Class name
szAppName, // Caption
WS_OVERLAPPEDWINDOW, // Style bits
CW_USEDEFAULT, 0, // Position
dx/2,dy/2, // Size
(HWND)NULL, // Parent window (no parent)
(HMENU)NULL, // use class menu
(HANDLE)hInst, // handle to window instance
(LPSTR)NULL // no params to pass on
);
ShowWindow(hwndApp,sw);
return TRUE;
}
void AppExit()
{
}
/*----------------------------------------------------------------------------*\
| WinMain( hInst, hPrev, lpszCmdLine, cmdShow ) |
| |
| Description: |
| The main procedure for the App. After initializing, it just goes |
| into a message-processing loop until it gets a WM_QUIT message |
| (meaning the app was closed). |
| |
| Arguments: |
| hInst instance handle of this instance of the app |
| hPrev instance handle of previous instance, NULL if first |
| szCmdLine ->null-terminated command line |
| cmdShow specifies how the window is initially displayed |
| |
| Returns: |
| The exit code as specified in the WM_QUIT message. |
| |
\*----------------------------------------------------------------------------*/
int PASCAL WinMain(HANDLE hInst, HANDLE hPrev, LPSTR szCmdLine, WORD sw)
{
MSG msg;
/* Call initialization procedure */
if (!AppInit(hInst,hPrev,sw,szCmdLine))
return FALSE;
/*
* Polling messages from event queue
*/
while (GetMessage(&msg,NULL,0,0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
AppExit();
return msg.wParam;
}
UINT BiosMode()
{
UINT Mode;
_asm
{
mov ax, 6F04h ;Get V7 mode
int 10h
cmp al,04h
jne short v7
mov ax,0F00h ;Call BIOS to get mode back.
int 10h ;al = mode we are in.
v7: xor ah,ah
mov Mode,ax
}
return Mode;
}
#if 0
LONG GetSelBase(short sel)
{
_asm
{
}
}
#endif
/*----------------------------------------------------------------------------*\
| AppPaint(hwnd, hdc) |
| |
| Description: |
| The paint function. Right now this does nothing. |
| |
| Arguments: |
| hwnd window painting into |
| hdc display context to paint to |
| |
| Returns: |
| nothing |
| |
\*----------------------------------------------------------------------------*/
AppPaint (HWND hwnd, HDC hdc)
{
RECT rc;
int x,y;
char ach[128];
char achDisplay[80];
UINT wType;
TEXTMETRIC tm;
IBITMAP FAR *pbm;
DWORD off;
WORD sel;
SetPixel(hdc, 0, 0, RGB(0,0,0));
#define TEXT(sz) \
(TextOut(hdc, x, y, sz, lstrlen(sz)), y += tm.tmHeight+1)
#define PF1(sz, a) PF3(sz, a, 0, 0)
#define PF2(sz, a, b) PF3(sz, a, b, 0)
#define PF3(sz, a, b, c) (wsprintf(ach, sz, a, b, c), TEXT(ach))
#define FLAG(w, f, s) if ((w) & (f)) TEXT(s)
SelectObject(hdc, GetStockObject(ANSI_FIXED_FONT));
GetTextMetrics(hdc, &tm);
GetClientRect(hwnd,&rc);
x = 4; y = 4;
SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT));
SetBkColor(hdc,GetSysColor(COLOR_WINDOW));
GetPrivateProfileString("boot", "display.drv","",achDisplay,sizeof(achDisplay),"system.ini");
wsprintf(ach, "Device: %dx%dx%d (%s)",
GetDeviceCaps(hdc, HORZRES),
GetDeviceCaps(hdc, VERTRES),
GetDeviceCaps(hdc, BITSPIXEL) *
GetDeviceCaps(hdc, PLANES),
(LPSTR)achDisplay);
TEXT(ach);
PF1("Bios Mode = %04X",BiosMode());
if (GetDeviceCaps(hdc, RASTERCAPS) & RC_DEVBITS)
TEXT(" Device bitmap support");
if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
TEXT(" Palette device");
else
TEXT(" RGB device (non-palette)");
if (lpScreen != NULL)
{
TEXT("Direct Screen access");
}
if (pbm = (IBITMAP FAR *)GetPDevice(hdc))
{
PF1("lpPDevice = %08lX",pbm);
if (pbm->bmType == DI_TYPE ||
pbm->bmType == DE_TYPE ||
pbm->bmType == RP_TYPE ||
pbm->bmType == M4_TYPE)
{
DIBENGINE FAR *pde = (DIBENGINE FAR *)pbm;
PF2(" deType = %c%c", LOBYTE(pde->deType), HIBYTE(pde->deType));
PF1(" deWidth = %d", pde->deWidth);
PF1(" deHeight = %d", pde->deHeight);
PF1(" deWidthBytes = %d", pde->deWidthBytes);
PF1(" dePlanes = %d", pde->dePlanes);
PF1(" deBitsPixel = %d", pde->deBitsPixel);
PF1(" deReserved1 = %08lX", pde->deReserved1);
PF1(" deDeltaScan = %ld", pde->deDeltaScan);
PF1(" delpPDevice = %08lX", pde->delpPDevice);
PF2(" deBits = %04X:%08lX",pde->deBitsSelector,pde->deBitsOffset);
PF1(" base = %08lX",GetSelectorBase(pde->deBitsSelector));
PF1(" limit = %08lX",GetSelectorLimit(pde->deBitsSelector));
PF1(" deFlags = %04X", pde->deFlags);
FLAG(pde->deFlags, MINIDRIVER , " MINIDRIVER ");
FLAG(pde->deFlags, PALETTIZED , " PALETTIZED ");
FLAG(pde->deFlags, SELECTEDDIB , " SELECTEDDIB ");
FLAG(pde->deFlags, CURSOREXCLUDE , " CURSOREXCLUDE");
FLAG(pde->deFlags, DISABLED , " DISABLED ");
FLAG(pde->deFlags, VRAM , " VRAM ");
FLAG(pde->deFlags, BANKEDVRAM , " BANKEDVRAM ");
FLAG(pde->deFlags, BANKEDSCAN , " BANKEDSCAN ");
PF1(" deVersion = %04X", pde->deVersion);
PF1(" deBitmapInfo = %08lX", pde->deBitmapInfo);
}
else
{
PF1(" bmType = %04X",pbm->bmType);
PF1(" bmWidth = %d",pbm->bmWidth);
PF1(" bmHeight = %d",pbm->bmHeight);
PF1(" bmWidthBytes = %d",pbm->bmWidthBytes);
PF1(" bmPlanes = %d",pbm->bmPlanes);
PF1(" bmBitsPixel = %d",pbm->bmBitsPixel);
sel = ((WORD FAR *)&pbm->bmBits)[1];
off = ((WORD FAR *)&pbm->bmBits)[0];
PF2(" bmBits = %04X:%04X",sel,(WORD)off);
PF1(" base = %08lX",GetSelectorBase(sel));
PF1(" limit = %08lX",GetSelectorLimit(sel));
sel = ((WORD FAR *)&pbm->bmBits)[2];
off = ((DWORD FAR *)&pbm->bmBits)[0];
PF2(" bmBits48 = %04X:%08lX",sel,off);
PF1(" base = %08lX",GetSelectorBase(sel));
PF1(" limit = %08lX",GetSelectorLimit(sel));
PF1(" bmWidthPlanes = %d",pbm->bmWidthPlanes);
PF1(" bmlpPDevice = %08lX",pbm->bmlpPDevice);
PF1(" bmSegmentIndex = %04X",pbm->bmSegmentIndex);
PF1(" bmScanSegment = %d",pbm->bmScanSegment);
PF1(" bmFillBytes = %d",pbm->bmFillBytes);
PF1(" reserved1 = %d",pbm->reserved1);
PF1(" reserved2 = %d",pbm->reserved2);
}
}
if (CanLockBitmaps() && GetBitmapType())
{
wType = GetBitmapType();
TEXT("Can Lock Bitmaps");
if (wType & BM_HUGE)
TEXT(" Huge Bitmaps");
else
TEXT(" Flat Bitmaps");
if (wType & BM_BOTTOMTOTOP)
TEXT(" Bottom to top Bitmaps");
else
TEXT(" Top to bottom Bitmaps");
switch (wType & BM_TYPE)
{
case BM_VGA: TEXT(" Bitmap type: VGA"); break;
case BM_1BIT: TEXT(" Bitmap type: 1 BIT"); break;
case BM_4BIT: TEXT(" Bitmap type: 4 BIT"); break;
case BM_8BIT: TEXT(" Bitmap type: 8 BIT"); break;
case BM_16555: TEXT(" Bitmap type: 16 BIT RGB 555"); break;
case BM_16565: TEXT(" Bitmap type: 16 BIT RGB 565"); break;
case BM_24BGR: TEXT(" Bitmap type: 24 BIT BGR"); break;
case BM_24RGB: TEXT(" Bitmap type: 24 BIT RGB"); break;
case BM_32BGR: TEXT(" Bitmap type: 32 BIT BGR"); break;
case BM_32RGB: TEXT(" Bitmap type: 32 BIT RGB"); break;
default: TEXT(" Bitmap type: Unknown"); break;
}
}
return TRUE;
}
/*----------------------------------------------------------------------------*\
| |
| w i n d o w p r o c s |
| |
\*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*\
| AppWndProc( hwnd, uiMessage, wParam, lParam ) |
| |
| Description: |
| The window proc for the app's main (tiled) window. This processes all |
| of the parent window's messages. |
| |
| Arguments: |
| hwnd window handle for the window |
| uiMessage message number |
| wParam message-dependent |
| lParam message-dependent |
| |
| Returns: |
| 0 if processed, nonzero if ignored |
| |
\*----------------------------------------------------------------------------*/
LONG EXPORT AppWndProc(hwnd, msg, wParam, lParam)
HWND hwnd;
unsigned msg;
WORD wParam;
long lParam;
{
PAINTSTRUCT ps;
HDC hdc;
switch (msg) {
case WM_CREATE:
hdc = GetDC(hwnd);
lpScreen = DVAGetSurface(hdc, &biScreen);
ReleaseDC(hwnd, hdc);
break;
case WM_SYSCOLORCHANGE:
break;
case WM_TIMER:
break;
case WM_ERASEBKGND:
break;
case WM_INITMENU:
EnableMenuItem((HMENU)wParam, MENU_TEST, lpScreen == NULL ? MF_GRAYED : MF_ENABLED);
EnableMenuItem((HMENU)wParam, MENU_TEST1, lpScreen == NULL ? MF_GRAYED : MF_ENABLED);
break;
case WM_COMMAND:
return AppCommand(hwnd,msg,wParam,lParam);
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CLOSE:
break;
case WM_PAINT:
BeginPaint(hwnd,&ps);
AppPaint (hwnd,ps.hdc);
EndPaint(hwnd,&ps);
return 0L;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
void NEAR PASCAL AlignPlaybackWindow(HWND hwnd, BOOL fAlign)
{
DWORD dw;
int x,y;
RECT rc;
HDC hdc;
#define X_ALIGN 4
#define Y_ALIGN 4
hdc = GetDC(hwnd);
dw = GetDCOrg(hdc);
x = LOWORD(dw);
y = HIWORD(dw);
ReleaseDC(hwnd, hdc);
if (!fAlign)
{
x++;
y++;
}
if ((x & (X_ALIGN-1)) || (y & (Y_ALIGN-1)))
{
//
// dont move the window if it does not want to be moved.
//
if (IsWindowVisible(hwnd) &&
!IsZoomed(hwnd) &&
!IsIconic(hwnd) &&
IsWindowEnabled(hwnd))
{
GetWindowRect(hwnd, &rc);
OffsetRect(&rc, -(x & (X_ALIGN-1)), -(y & (Y_ALIGN-1)));
if (GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD)
ScreenToClient(GetParent(hwnd), (LPPOINT)&rc);
SetWindowPos(hwnd,NULL,rc.left,rc.top,0,0,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
}
}
}
LONG NEAR PASCAL AppCommand (hwnd, msg, wParam, lParam)
HWND hwnd;
unsigned msg;
WORD wParam;
long lParam;
{
HDC hdc;
LPVOID lpScreen;
BITMAPINFOHEADER bi;
switch(wParam)
{
case MENU_ABOUT:
fDialog(ABOUTBOX,hwnd,(FARPROC)AppAbout);
break;
case MENU_OPEN:
break;
case MENU_EXIT:
PostMessage(hwnd,WM_CLOSE,0,0L);
break;
case MENU_XALIGN:
AlignPlaybackWindow(hwnd, FALSE);
break;
case MENU_ALIGN:
AlignPlaybackWindow(hwnd, TRUE);
break;
case MENU_TEST1:
hdc = GetDC(hwnd);
lpScreen = DVAGetSurface(hdc, &bi);
if (lpScreen)
{
UINT u;
RECT rc;
DWORD dw;
int x,y,dx,dy,w;
DWORD time;
extern void FAR PASCAL DIBRect(LPVOID, LONG, int, int, int, int, UINT);
GetClientRect(hwnd, &rc);
dw = GetDCOrg(hdc);
x = LOWORD(dw) * (int)bi.biBitCount / 8;
y = HIWORD(dw);
dx = rc.right * (int)bi.biBitCount / 8;
dy = rc.bottom;
w = bi.biWidth * (int)bi.biBitCount / 8;
time = timeGetTime();
for (u=0; u<256; u++)
{
DVABeginAccess(hdc,x,y,dx,dy);
DIBRect(lpScreen,w,x,y,dx,dy,u);
DVAEndAccess(hdc);
}
time = timeGetTime() - time;
ErrMsg("DVA %d.%03d fps",
(UINT)(1000l * 256 / time),
(UINT)((1000000l * 256 / time) % 1000));
}
ReleaseDC(hwnd, hdc);
break;
case MENU_TEST:
hdc = GetDC(hwnd);
lpScreen = DVAGetSurface(hdc, &bi);
if (lpScreen)
{
UINT u;
RECT rc;
DWORD dw;
int x,y,dx,dy,w;
DWORD time;
extern void FAR PASCAL DIBRect(LPVOID, LONG, int, int, int, int, UINT);
GetClientRect(hwnd, &rc);
dw = GetDCOrg(hdc);
x = LOWORD(dw) * (int)bi.biBitCount / 8;
y = HIWORD(dw);
dx = rc.right * (int)bi.biBitCount / 8;
dy = rc.bottom;
w = bi.biWidth * (int)bi.biBitCount / 8;
DVABeginAccess(hdc, x, y, dx, dy);
time = timeGetTime();
for (u=0; u<256; u++)
{
DIBRect(lpScreen,w,x,y,dx,dy,u);
}
time = timeGetTime() - time;
DVAEndAccess(hdc);
ErrMsg("DVA %d.%03d fps",
(UINT)(1000l * 256 / time),
(UINT)((1000000l * 256 / time) % 1000));
}
ReleaseDC(hwnd, hdc);
break;
}
return 0L;
}
/*----------------------------------------------------------------------------*\
| ErrMsg - Opens a Message box with a error message in it. The user can |
| select the OK button to continue |
\*----------------------------------------------------------------------------*/
int ErrMsg (LPSTR sz,...)
{
char ach[128];
wvsprintf (ach,sz,(LPSTR)(&sz+1)); /* Format the string */
MessageBox(NULL,ach,NULL,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
return FALSE;
}
/*----------------------------------------------------------------------------*\
| fDialog(id,hwnd,fpfn) |
| |
| Description: |
| This function displays a dialog box and returns the exit code. |
| the function passed will have a proc instance made for it. |
| |
| Arguments: |
| id resource id of dialog to display |
| hwnd parent window of dialog |
| fpfn dialog message function |
| |
| Returns: |
| exit code of dialog (what was passed to EndDialog) |
| |
\*----------------------------------------------------------------------------*/
BOOL fDialog(int id,HWND hwnd,FARPROC fpfn)
{
BOOL f;
HANDLE hInst;
hInst = GetWindowWord(hwnd,GWW_HINSTANCE);
fpfn = MakeProcInstance(fpfn,hInst);
f = DialogBox(hInst,MAKEINTRESOURCE(id),hwnd,fpfn);
FreeProcInstance (fpfn);
return f;
}