📄 driver.c
字号:
#pragma warning(disable : 4201 4214 4115)
#include <windows.h>
#pragma warning(default : 4201 4214 4115; disable : 4514 4244)
#include <stdio.h>
#include <Assert.h>
#include "driver.h"
#include "Display.h"
#include "errorlog.h"
#include "drawutil.h"
#define SOFTDriver_DESCRIPTION_LENGTH 256
typedef struct
{
char Description[SOFTDriver_DESCRIPTION_LENGTH];
Display_Type DisplayType;
DisplayModeInfo *Info;
} SoftDriver_DisplayInfo;
typedef struct SoftDriver
{
int RefCount;
int DisplayCount;
int CurrentDisplayIndex;
SoftDriver_DisplayInfo Display[DISPLAY_COUNT];
} SoftDriver;
static SoftDriver SoftDriver_Internals={false};
Display *SD_Display = NULL;
bool SD_DIBDisplayMode = false;
bool SD_Active = FALSE;
Driver_Window ClientWindow = { 0 };
int LastError;
char LastErrorStr[200];
static void SoftDriver_DisplayInfoTable_Destroy( SoftDriver *S )
{
int i;
S->RefCount--;
if (S->RefCount>0)
return;
for (i=0; i<S->DisplayCount; i++)
{
if (S->Display[i].Info != NULL)
{
DisplayModeInfo_Destroy( &(S->Display[i].Info) );
S->Display[i].Info=NULL;
}
}
S->DisplayCount = 0;
}
static bool SoftDriver_DisplayInfoTable_Create( SoftDriver *S, bool FillOutModes)
{
int i;
FillOutModes; // avoid unreference parameter warning
assert( S != NULL );
if (S->RefCount>0)
{
S->RefCount++;
return true;
}
else
S->RefCount=1;
S->DisplayCount = 0;
for (i=0; i<DISPLAY_COUNT; i++)
{
S->Display[i].Info = DisplayModeInfo_Create();
if (S->Display[i].Info == NULL)
{
SoftDriver_DisplayInfoTable_Destroy( S );
geErrorLog_AddString(GE_ERR_MEMORY_RESOURCE,"SoftDriver_DisplayInfoTableCreate: unable to create table",NULL);
return false;
}
if (Display_GetDisplayInfo( i,
S->Display[i].Description,
SOFTDriver_DESCRIPTION_LENGTH,
S->Display[i].Info) == false)
{
DisplayModeInfo_Destroy( &(S->Display[i].Info) );
geErrorLog_AddString(GE_ERR_MEMORY_RESOURCE,"SoftDriver_DisplayInfoTableCreate: problem filling table. (continuing)",NULL);
geErrorLog_Clear(); // is this ok?
S->Display[i].Info=NULL;
//return false;
}
else
{
S->Display[i].DisplayType = i;
S->DisplayCount++;
}
}
return true;
}
bool SoftDriver_SetActive(bool Active)
{
SD_Active = Active;
Display_SetActive(SD_Display,Active);
return TRUE;
}
bool SoftDriver_Init(
int HookDriver,
int HookMode,
HWND HookhWnd)
{
int PixelBits;
// all the _Startup paths come through here eventually
DrawUtil_Init();
if (SoftDriver_DisplayInfoTable_Create(&(SoftDriver_Internals), true)==false)
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"SoftDriver_Init: failed to get mode info",NULL);
return FALSE;
}
if ((HookDriver<0) || (HookDriver>=SoftDriver_Internals.DisplayCount))
{
geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"SoftDriver_Init: bad driver index",NULL);
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
return FALSE;
}
{
int Height, Width, BitsPerPixel;
uint Flags;
if (DisplayModeInfo_GetNth( SoftDriver_Internals.Display[HookDriver].Info,
HookMode,
&Width,
&Height,
&BitsPerPixel,
&Flags ) == false)
{
geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"SoftDriver_Init: unable to get mode info: bad mode index",NULL);
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
return FALSE;
}
SD_Display = Display_Create( HookhWnd,
SoftDriver_Internals.Display[HookDriver].DisplayType,
Width,
Height,
BitsPerPixel,
Flags);
if (SD_Display == NULL)
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDriver_Init: Could not initialize display",NULL);
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
return FALSE;
}
if( 1 )
{
int BitsPerPixel;
Display_Type DisplayType;
uint Flags;
Display_GetDisplayFormat( SD_Display,
&DisplayType,
&(ClientWindow.Width),
&(ClientWindow.Height),
&BitsPerPixel,
&Flags);
}
}
if (Display_GetPixelFormat( SD_Display,
&ClientWindow.BytesPerPixel,
&ClientWindow.R_shift,
&ClientWindow.R_mask,
&ClientWindow.R_width,
&ClientWindow.G_shift,
&ClientWindow.G_mask,
&ClientWindow.G_width,
&ClientWindow.B_shift,
&ClientWindow.B_mask,
&ClientWindow.B_width)==false)
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDriver_Init: Could not get display pixel format",NULL);
Display_Destroy(&SD_Display);
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
return FALSE;
}
if ( ClientWindow.BytesPerPixel != 2 )
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDriver_Init: Display format not 16 bit!",NULL);
Display_Destroy(&SD_Display);
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
return FALSE;
}
PixelBits = ClientWindow.R_width + ClientWindow.G_width + ClientWindow.B_width;
switch(PixelBits)
{
case 15:
ClientWindow.Mode = DRIVER_MODE_555;
break;
case 16:
ClientWindow.Mode = DRIVER_MODE_565;
break;
default:
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDriver_Init: Display format not 555 or 565!",NULL);
Display_Destroy(&SD_Display);
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
return FALSE;
}
assert(ClientWindow.R_width == 5);
assert(ClientWindow.B_width == 5);
// assume the window is active:
SoftDriver_SetActive(true);
return TRUE;
}
bool DrawDriver_Shutdown(void)
{
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
if (SD_Display)
Display_Destroy(&SD_Display);
SD_Display = NULL;
return TRUE;
}
bool DrawDriver_UpdateWindow(void)
{
int BitsPerPixel;
Display_Type DisplayType;
uint Flags;
if (Display_UpdateWindow(SD_Display)==false)
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE, "SoftDriver_UpdateWindow: Could not create new window buffer",NULL);
Display_Destroy(&SD_Display);
return FALSE;
}
Display_GetDisplayFormat( SD_Display,
&DisplayType,
&(ClientWindow.Width),
&(ClientWindow.Height),
&BitsPerPixel,
&Flags);
return true;
}
bool SoftDriver_BeginScene(bool Clear)
{
if(!Display_Lock(SD_Display,&(ClientWindow.Buffer), &(ClientWindow.Stride)))
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE ,"SoftDriver_BeginScene: failed to lock display buffer",NULL );
return FALSE;
}
if (Clear)
{
if (!Display_Wipe(SD_Display,0))
{
geErrorLog_AddString( GE_ERR_SUBSYSTEM_FAILURE,"SoftDriver_BeginScene: failed to wipe display buffer",NULL );
return FALSE;
}
}
return TRUE;
}
bool DrawDriver_UnLock(void)
{
if (!Display_Unlock(SD_Display))
{
geErrorLog_AddString( GE_ERR_SUBSYSTEM_FAILURE,"SoftDriver_EndScene: failed to unlock display buffer",NULL );
return FALSE;
}
if (!Display_Blit(SD_Display))
{
geErrorLog_AddString( GE_ERR_SUBSYSTEM_FAILURE,"SoftDriver_EndScene: failed to blit display buffer",NULL );
return FALSE;
}
return TRUE;
}
bool SoftDriver_EnumSubDrivers(Driver_ENUM_Driver_CB *Cb, void *Context)
{
int i;
if (SoftDriver_DisplayInfoTable_Create(&(SoftDriver_Internals), false)==false)
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"SoftDriver_EnumSubDrivers: failed to get mode info",NULL);
return FALSE;
}
for (i=0; i<SoftDriver_Internals.DisplayCount; i++)
{
if(!Cb(i, SoftDriver_Internals.Display[i].Description, Context))
{
break;
}
}
SoftDriver_DisplayInfoTable_Destroy(&SoftDriver_Internals);
return TRUE;
}
bool SoftDriver_EnumModes(int Driver, char *DriverName, Driver_ENUM_MODES_CB *Cb, void *Context)
{
int i,Count;
DriverName; // avoid unused parameter;
if (SoftDriver_DisplayInfoTable_Create(&(SoftDriver_Internals), true)==false)
{
geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"SoftDriver_EnumModes: failed to get mode info",NULL);
return FALSE;
}
if ((Driver < 0) || (Driver>=SoftDriver_Internals.DisplayCount))
{
geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"SoftDriver_EnumModes: bad driver index",NULL);
SoftDriver_DisplayInfoTable_Destroy(&(SoftDriver_Internals));
return FALSE;
}
Count = DisplayModeInfo_GetModeCount( SoftDriver_Internals.Display[Driver].Info );
for (i=0; i<Count; i++)
{
int Width,Height,BitsPerPixel;
uint Flags;
if (DisplayModeInfo_GetNth(SoftDriver_Internals.Display[Driver].Info,i,
&Width,&Height,&BitsPerPixel,&Flags) != false)
{
char Description[256];
if (Width<0 && Height<0)
{
sprintf(Description,"Window Mode");
}
else
{
sprintf(Description,"%dx%dx%d",Width, Height, BitsPerPixel);
}
if(Flags & MODEXMODE)
strcat(Description," ModeX");
Cb(i,Description,Width,Height,BitsPerPixel,Context);
}
}
SoftDriver_DisplayInfoTable_Destroy(&SoftDriver_Internals);
return TRUE;
}
#include "Drvlist.h"
//-----------------------------------------------------------------------------
bool DrawDriver_Startup_Closest(HANDLE hInstance, HWND hwnd, int SeekW, int SeekH )
{
return drvlist_PickDriver_Closest(hInstance,hwnd,SeekW,SeekH);
}
bool DrawDriver_Startup_Dialog(HANDLE hInstance, HWND hwnd, int MinW, int MinH, int MaxW, int MaxH )
{
return drvlist_PickDriver_Range(hInstance,hwnd,MinW,MinH,MaxW,MaxH);
}
bool DrawDriver_Startup_WindowMode(HANDLE hInstance, HWND hwnd)
{
return drvlist_PickDriver_Closest(hInstance,hwnd,-1,-1);
}
Driver_Window * DrawDriver_Lock(bool Clear)
{
if ( ! SoftDriver_BeginScene(Clear) )
return NULL;
ClientWindow.UserY = 0;
return &ClientWindow;
}
//-----------------------------------------------------------------------------
HWND DrawDriver_CreateStandardWindow(HANDLE instance,int w,int h)
{
WNDCLASS wc;
HWND windowH;
wc.style = CS_BYTEALIGNCLIENT; //CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNCLIENT | CS_SAVEBITS;
wc.lpfnWndProc = (LPVOID) DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof( DWORD );
wc.hInstance = instance;
wc.hIcon = 0;
wc.hCursor = 0; //LoadCursor(instance,IDC_ARROW);
wc.hbrBackground = GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "DrawDriver_Viewer";
if ( !RegisterClass( &wc ) )
{
return 0;
}
windowH = CreateWindow(
"DrawDriver_Viewer", /* class */
NULL, /* caption */
WS_DLGFRAME, /* style */
0,0,w,h,
NULL, /* parent window */
NULL, /* menu handle */
instance, /* program handle */
NULL /* create parms */
);
if ( ! windowH )
{
return 0;
}
{
RECT ClientRect;
int zWindowWidth,zWindowHeight;
// Set render window to proper size and position.
// Initialize the engine in the render window
// Size the render window.
// When done, ClientRect will contain the required width of
// the main window's client rect.
// compute window size for client rect
ClientRect.left = 0;
ClientRect.top = 0;
ClientRect.right = w - 1;
ClientRect.bottom = h - 1;
AdjustWindowRect (&ClientRect, GetWindowLong (windowH, GWL_STYLE)|GetWindowLong (windowH, GWL_EXSTYLE), FALSE); // FALSE == No menu
zWindowWidth = ClientRect.right - ClientRect.left + 1;
zWindowHeight = ClientRect.bottom - ClientRect.top + 1;
SetWindowPos
(
windowH, 0,
0,0,
zWindowWidth, zWindowHeight,
SWP_NOCOPYBITS | SWP_NOZORDER
);
}
ShowWindow( windowH, SW_SHOW );
UpdateWindow( windowH );
return windowH;
}
//------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -