mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-24 17:49:52 +01:00
experimental 16bit color support (Dune 2000)
This commit is contained in:
parent
a9ce4ac13c
commit
806746d364
@ -23,6 +23,17 @@ const char PaletteFragShader110Src[] =
|
|||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
|
const char PassthroughFragShader110Src[] =
|
||||||
|
"#version 110\n"
|
||||||
|
"uniform sampler2D SurfaceTex; \n"
|
||||||
|
"varying vec2 TEX0; \n"
|
||||||
|
"\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 texel = texture2D(SurfaceTex, TEX0); \n"
|
||||||
|
" gl_FragColor = texel; \n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
// new
|
// new
|
||||||
|
|
||||||
const char PassthroughVertShaderSrc[] =
|
const char PassthroughVertShaderSrc[] =
|
||||||
@ -55,3 +66,15 @@ const char PaletteFragShaderSrc[] =
|
|||||||
" FragColor = texture(PaletteTex, vec2(pIndex.r * (255.0/256.0) + (0.5/256.0), 0));\n"
|
" FragColor = texture(PaletteTex, vec2(pIndex.r * (255.0/256.0) + (0.5/256.0), 0));\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
|
const char PassthroughFragShaderSrc[] =
|
||||||
|
"#version 130\n"
|
||||||
|
"out vec4 FragColor;\n"
|
||||||
|
"uniform sampler2D SurfaceTex;\n"
|
||||||
|
"in vec4 TEX0;\n"
|
||||||
|
"\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 texel = texture(SurfaceTex, TEX0.xy);\n"
|
||||||
|
" FragColor = texel;\n"
|
||||||
|
"}\n";
|
||||||
|
@ -42,9 +42,9 @@ void DrawFrameInfoStart()
|
|||||||
|
|
||||||
RECT debugrc = { 0, 0, ddraw->width, ddraw->height };
|
RECT debugrc = { 0, 0, ddraw->width, ddraw->height };
|
||||||
|
|
||||||
if (ddraw->primary && ddraw->primary->palette)
|
if (ddraw->primary)
|
||||||
{
|
{
|
||||||
if (ddraw->primary->palette->data_rgb)
|
if (ddraw->primary->palette && ddraw->primary->palette->data_rgb)
|
||||||
SetDIBColorTable(ddraw->primary->hDC, 0, 256, ddraw->primary->palette->data_rgb);
|
SetDIBColorTable(ddraw->primary->hDC, 0, 256, ddraw->primary->palette->data_rgb);
|
||||||
|
|
||||||
DrawText(ddraw->primary->hDC, debugText, -1, &debugrc, DT_NOCLIP);
|
DrawText(ddraw->primary->hDC, debugText, -1, &debugrc, DT_NOCLIP);
|
||||||
|
18
src/main.c
18
src/main.c
@ -215,6 +215,18 @@ HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD dwFlags, L
|
|||||||
printf(" DDENUMRET_CANCEL returned, stopping\n");
|
printf(" DDENUMRET_CANCEL returned, stopping\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||||
|
s.ddpfPixelFormat.dwRGBBitCount = 16;
|
||||||
|
s.ddpfPixelFormat.dwRBitMask = 0xF800;
|
||||||
|
s.ddpfPixelFormat.dwGBitMask = 0x07E0;
|
||||||
|
s.ddpfPixelFormat.dwBBitMask = 0x001F;
|
||||||
|
|
||||||
|
if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
|
||||||
|
{
|
||||||
|
printf(" DDENUMRET_CANCEL returned, stopping\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some games crash when you feed them with too many resolutions...
|
/* Some games crash when you feed them with too many resolutions...
|
||||||
@ -384,7 +396,7 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD
|
|||||||
{
|
{
|
||||||
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
||||||
|
|
||||||
if (bpp != 8)
|
if (bpp != 8 && bpp != 16)
|
||||||
return DDERR_INVALIDMODE;
|
return DDERR_INVALIDMODE;
|
||||||
|
|
||||||
if (This->render.thread)
|
if (This->render.thread)
|
||||||
@ -660,7 +672,7 @@ void ToggleFullscreen()
|
|||||||
WindowState = ddraw->windowed = FALSE;
|
WindowState = ddraw->windowed = FALSE;
|
||||||
SetWindowLong(ddraw->hWnd, GWL_STYLE, GetWindowLong(ddraw->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
|
SetWindowLong(ddraw->hWnd, GWL_STYLE, GetWindowLong(ddraw->hWnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU));
|
||||||
ddraw->altenter = TRUE;
|
ddraw->altenter = TRUE;
|
||||||
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, 8);
|
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
|
||||||
mouse_lock();
|
mouse_lock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -673,7 +685,7 @@ void ToggleFullscreen()
|
|||||||
else
|
else
|
||||||
ChangeDisplaySettings(&ddraw->mode, 0);
|
ChangeDisplaySettings(&ddraw->mode, 0);
|
||||||
|
|
||||||
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, 8);
|
ddraw_SetDisplayMode(ddraw, ddraw->width, ddraw->height, ddraw->bpp);
|
||||||
mouse_lock();
|
mouse_lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
223
src/render.c
223
src/render.c
@ -27,13 +27,14 @@
|
|||||||
static HGLRC OpenGLContext;
|
static HGLRC OpenGLContext;
|
||||||
static int MaxFPS;
|
static int MaxFPS;
|
||||||
static DWORD FrameLength;
|
static DWORD FrameLength;
|
||||||
static GLuint PaletteProgram;
|
static GLuint MainProgram;
|
||||||
static GLuint ScaleProgram;
|
static GLuint ScaleProgram;
|
||||||
static BOOL GotError;
|
static BOOL GotError;
|
||||||
static int SurfaceTexWidth;
|
static int SurfaceTexWidth;
|
||||||
static int SurfaceTexHeight;
|
static int SurfaceTexHeight;
|
||||||
static int *SurfaceTex;
|
static int *SurfaceTex;
|
||||||
static GLenum SurfaceFormat = GL_LUMINANCE;
|
static GLenum SurfaceFormat = GL_LUMINANCE;
|
||||||
|
static GLenum SurfaceType = GL_UNSIGNED_BYTE;
|
||||||
static GLuint SurfaceTexIds[TEXTURE_COUNT];
|
static GLuint SurfaceTexIds[TEXTURE_COUNT];
|
||||||
static GLuint PaletteTexIds[TEXTURE_COUNT];
|
static GLuint PaletteTexIds[TEXTURE_COUNT];
|
||||||
static float ScaleW;
|
static float ScaleW;
|
||||||
@ -52,7 +53,7 @@ static HGLRC CreateContext(HDC hdc);
|
|||||||
static void SetMaxFPS(int baseMaxFPS);
|
static void SetMaxFPS(int baseMaxFPS);
|
||||||
static void BuildPrograms();
|
static void BuildPrograms();
|
||||||
static void CreateTextures(int width, int height);
|
static void CreateTextures(int width, int height);
|
||||||
static void InitPaletteProgram();
|
static void InitMainProgram();
|
||||||
static void InitScaleProgram();
|
static void InitScaleProgram();
|
||||||
static void Render();
|
static void Render();
|
||||||
static void DeleteContext(HGLRC context);
|
static void DeleteContext(HGLRC context);
|
||||||
@ -71,13 +72,13 @@ DWORD WINAPI render_main(void)
|
|||||||
SetMaxFPS(ddraw->render.maxfps);
|
SetMaxFPS(ddraw->render.maxfps);
|
||||||
BuildPrograms();
|
BuildPrograms();
|
||||||
CreateTextures(ddraw->width, ddraw->height);
|
CreateTextures(ddraw->width, ddraw->height);
|
||||||
InitPaletteProgram();
|
InitMainProgram();
|
||||||
InitScaleProgram();
|
InitScaleProgram();
|
||||||
|
|
||||||
GotError = GotError || !TextureUploadTest();
|
GotError = GotError || !TextureUploadTest();
|
||||||
GotError = GotError || !ShaderTest();
|
GotError = GotError || !ShaderTest();
|
||||||
GotError = GotError || glGetError() != GL_NO_ERROR;
|
GotError = GotError || glGetError() != GL_NO_ERROR;
|
||||||
UseOpenGL = PaletteProgram && !GotError;
|
UseOpenGL = MainProgram && !GotError;
|
||||||
|
|
||||||
Render();
|
Render();
|
||||||
|
|
||||||
@ -156,21 +157,27 @@ static void SetMaxFPS(int baseMaxFPS)
|
|||||||
|
|
||||||
static void BuildPrograms()
|
static void BuildPrograms()
|
||||||
{
|
{
|
||||||
PaletteProgram = ScaleProgram = 0;
|
MainProgram = ScaleProgram = 0;
|
||||||
|
|
||||||
if (OpenGL_GotVersion3)
|
if (OpenGL_GotVersion3)
|
||||||
{
|
{
|
||||||
PaletteProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PaletteFragShaderSrc);
|
if (ddraw->bpp == 8)
|
||||||
|
MainProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PaletteFragShaderSrc);
|
||||||
|
else if (ddraw->bpp == 16)
|
||||||
|
MainProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PassthroughFragShaderSrc);
|
||||||
|
|
||||||
if (PaletteProgram)
|
if (MainProgram)
|
||||||
ScaleProgram = OpenGL_BuildProgramFromFile(ddraw->shader);
|
ScaleProgram = OpenGL_BuildProgramFromFile(ddraw->shader);
|
||||||
else
|
else
|
||||||
OpenGL_GotVersion3 = FALSE;
|
OpenGL_GotVersion3 = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OpenGL_GotVersion2 && !PaletteProgram)
|
if (OpenGL_GotVersion2 && !MainProgram)
|
||||||
{
|
{
|
||||||
PaletteProgram = OpenGL_BuildProgram(PassthroughVertShader110Src, PaletteFragShader110Src);
|
if (ddraw->bpp == 8)
|
||||||
|
MainProgram = OpenGL_BuildProgram(PassthroughVertShader110Src, PaletteFragShader110Src);
|
||||||
|
else if (ddraw->bpp == 16)
|
||||||
|
MainProgram = OpenGL_BuildProgram(PassthroughVertShader110Src, PassthroughFragShader110Src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,74 +209,110 @@ static void CreateTextures(int width, int height)
|
|||||||
|
|
||||||
while (glGetError() != GL_NO_ERROR);
|
while (glGetError() != GL_NO_ERROR);
|
||||||
|
|
||||||
glTexImage2D(
|
if (ddraw->bpp == 16)
|
||||||
GL_TEXTURE_2D,
|
|
||||||
0,
|
|
||||||
GL_LUMINANCE8,
|
|
||||||
SurfaceTexWidth,
|
|
||||||
SurfaceTexHeight,
|
|
||||||
0,
|
|
||||||
SurfaceFormat = GL_LUMINANCE,
|
|
||||||
GL_UNSIGNED_BYTE,
|
|
||||||
0);
|
|
||||||
|
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR)
|
|
||||||
{
|
{
|
||||||
glTexImage2D(
|
glTexImage2D(
|
||||||
GL_TEXTURE_2D,
|
GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
GL_R8,
|
GL_RGB565,
|
||||||
SurfaceTexWidth,
|
SurfaceTexWidth,
|
||||||
SurfaceTexHeight,
|
SurfaceTexHeight,
|
||||||
0,
|
0,
|
||||||
SurfaceFormat = GL_RED,
|
SurfaceFormat = GL_RGB,
|
||||||
GL_UNSIGNED_BYTE,
|
SurfaceType = GL_UNSIGNED_SHORT_5_6_5,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
|
||||||
|
if (glGetError() != GL_NO_ERROR)
|
||||||
|
{
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_RGB5,
|
||||||
|
SurfaceTexWidth,
|
||||||
|
SurfaceTexHeight,
|
||||||
|
0,
|
||||||
|
SurfaceFormat = GL_RGB,
|
||||||
|
SurfaceType = GL_UNSIGNED_SHORT_5_6_5,
|
||||||
|
0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (ddraw->bpp == 8)
|
||||||
if (glGetError() != GL_NO_ERROR)
|
|
||||||
{
|
{
|
||||||
glTexImage2D(
|
glTexImage2D(
|
||||||
GL_TEXTURE_2D,
|
GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
GL_RED,
|
GL_LUMINANCE8,
|
||||||
SurfaceTexWidth,
|
SurfaceTexWidth,
|
||||||
SurfaceTexHeight,
|
SurfaceTexHeight,
|
||||||
0,
|
0,
|
||||||
SurfaceFormat = GL_RED,
|
SurfaceFormat = GL_LUMINANCE,
|
||||||
GL_UNSIGNED_BYTE,
|
SurfaceType = GL_UNSIGNED_BYTE,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
|
||||||
|
if (glGetError() != GL_NO_ERROR)
|
||||||
|
{
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_R8,
|
||||||
|
SurfaceTexWidth,
|
||||||
|
SurfaceTexHeight,
|
||||||
|
0,
|
||||||
|
SurfaceFormat = GL_RED,
|
||||||
|
SurfaceType = GL_UNSIGNED_BYTE,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glGetError() != GL_NO_ERROR)
|
||||||
|
{
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_RED,
|
||||||
|
SurfaceTexWidth,
|
||||||
|
SurfaceTexHeight,
|
||||||
|
0,
|
||||||
|
SurfaceFormat = GL_RED,
|
||||||
|
SurfaceType = GL_UNSIGNED_BYTE,
|
||||||
|
0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenTextures(TEXTURE_COUNT, PaletteTexIds);
|
if (ddraw->bpp == 8)
|
||||||
|
|
||||||
for (i = 0; i < TEXTURE_COUNT; i++)
|
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[i]);
|
glGenTextures(TEXTURE_COUNT, PaletteTexIds);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
for (i = 0; i < TEXTURE_COUNT; i++)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[i]);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InitPaletteProgram()
|
static void InitMainProgram()
|
||||||
{
|
{
|
||||||
if (!PaletteProgram)
|
if (!MainProgram)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glUseProgram(PaletteProgram);
|
glUseProgram(MainProgram);
|
||||||
|
|
||||||
glUniform1i(glGetUniformLocation(PaletteProgram, "SurfaceTex"), 0);
|
glUniform1i(glGetUniformLocation(MainProgram, "SurfaceTex"), 0);
|
||||||
glUniform1i(glGetUniformLocation(PaletteProgram, "PaletteTex"), 1);
|
|
||||||
|
if (ddraw->bpp == 8)
|
||||||
|
glUniform1i(glGetUniformLocation(MainProgram, "PaletteTex"), 1);
|
||||||
|
|
||||||
if (OpenGL_GotVersion3)
|
if (OpenGL_GotVersion3)
|
||||||
{
|
{
|
||||||
MainVertexCoordAttrLoc = glGetAttribLocation(PaletteProgram, "VertexCoord");
|
MainVertexCoordAttrLoc = glGetAttribLocation(MainProgram, "VertexCoord");
|
||||||
MainTexCoordAttrLoc = glGetAttribLocation(PaletteProgram, "TexCoord");
|
MainTexCoordAttrLoc = glGetAttribLocation(MainProgram, "TexCoord");
|
||||||
|
|
||||||
glGenBuffers(3, MainVBOs);
|
glGenBuffers(3, MainVBOs);
|
||||||
|
|
||||||
@ -347,7 +390,7 @@ static void InitPaletteProgram()
|
|||||||
0,0,1,0,
|
0,0,1,0,
|
||||||
0,0,0,1,
|
0,0,0,1,
|
||||||
};
|
};
|
||||||
glUniformMatrix4fv(glGetUniformLocation(PaletteProgram, "MVPMatrix"), 1, GL_FALSE, mvpMatrix);
|
glUniformMatrix4fv(glGetUniformLocation(MainProgram, "MVPMatrix"), 1, GL_FALSE, mvpMatrix);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,7 +506,7 @@ static void InitScaleProgram()
|
|||||||
if (glDeleteVertexArrays)
|
if (glDeleteVertexArrays)
|
||||||
glDeleteVertexArrays(1, &ScaleVAO);
|
glDeleteVertexArrays(1, &ScaleVAO);
|
||||||
|
|
||||||
if (PaletteProgram)
|
if (MainProgram)
|
||||||
{
|
{
|
||||||
glBindVertexArray(MainVAO);
|
glBindVertexArray(MainVAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[0]);
|
glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[0]);
|
||||||
@ -507,8 +550,8 @@ static void Render()
|
|||||||
ddraw->render.viewport.x, ddraw->render.viewport.y,
|
ddraw->render.viewport.x, ddraw->render.viewport.y,
|
||||||
ddraw->render.viewport.width, ddraw->render.viewport.height);
|
ddraw->render.viewport.width, ddraw->render.viewport.height);
|
||||||
|
|
||||||
if (PaletteProgram)
|
if (MainProgram)
|
||||||
glUseProgram(PaletteProgram);
|
glUseProgram(MainProgram);
|
||||||
|
|
||||||
while (UseOpenGL && ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
|
while (UseOpenGL && ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED)
|
||||||
{
|
{
|
||||||
@ -528,7 +571,7 @@ static void Render()
|
|||||||
|
|
||||||
EnterCriticalSection(&ddraw->cs);
|
EnterCriticalSection(&ddraw->cs);
|
||||||
|
|
||||||
if (ddraw->primary && ddraw->primary->palette)
|
if (ddraw->primary && (ddraw->bpp == 16 || ddraw->primary->palette))
|
||||||
{
|
{
|
||||||
if (ddraw->vhack)
|
if (ddraw->vhack)
|
||||||
{
|
{
|
||||||
@ -547,7 +590,7 @@ static void Render()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InterlockedExchange(&ddraw->render.paletteUpdated, FALSE))
|
if (ddraw->bpp == 8 && InterlockedExchange(&ddraw->render.paletteUpdated, FALSE))
|
||||||
{
|
{
|
||||||
if (++palIndex >= TEXTURE_COUNT)
|
if (++palIndex >= TEXTURE_COUNT)
|
||||||
palIndex = 0;
|
palIndex = 0;
|
||||||
@ -584,7 +627,7 @@ static void Render()
|
|||||||
ddraw->width,
|
ddraw->width,
|
||||||
ddraw->height,
|
ddraw->height,
|
||||||
SurfaceFormat,
|
SurfaceFormat,
|
||||||
GL_UNSIGNED_BYTE,
|
SurfaceType,
|
||||||
ddraw->primary->surface);
|
ddraw->primary->surface);
|
||||||
|
|
||||||
if (AdjustAlignment)
|
if (AdjustAlignment)
|
||||||
@ -605,7 +648,7 @@ static void Render()
|
|||||||
|
|
||||||
if (scaleChanged)
|
if (scaleChanged)
|
||||||
{
|
{
|
||||||
if (ScaleProgram && PaletteProgram)
|
if (ScaleProgram && MainProgram)
|
||||||
{
|
{
|
||||||
glBindVertexArray(MainVAO);
|
glBindVertexArray(MainVAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
|
glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
|
||||||
@ -621,7 +664,7 @@ static void Render()
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
else if (OpenGL_GotVersion3 && PaletteProgram)
|
else if (OpenGL_GotVersion3 && MainProgram)
|
||||||
{
|
{
|
||||||
glBindVertexArray(MainVAO);
|
glBindVertexArray(MainVAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
|
glBindBuffer(GL_ARRAY_BUFFER, MainVBOs[1]);
|
||||||
@ -642,15 +685,18 @@ static void Render()
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, SurfaceTexIds[texIndex]);
|
glBindTexture(GL_TEXTURE_2D, SurfaceTexIds[texIndex]);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
if (ddraw->bpp == 8)
|
||||||
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[palIndex]);
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[palIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
if (ScaleProgram && PaletteProgram)
|
if (ScaleProgram && MainProgram)
|
||||||
{
|
{
|
||||||
// draw surface into framebuffer
|
// draw surface into framebuffer
|
||||||
glUseProgram(PaletteProgram);
|
glUseProgram(MainProgram);
|
||||||
|
|
||||||
glViewport(0, 0, ddraw->width, ddraw->height);
|
glViewport(0, 0, ddraw->width, ddraw->height);
|
||||||
|
|
||||||
@ -683,7 +729,7 @@ static void Render()
|
|||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
else if (OpenGL_GotVersion3 && PaletteProgram)
|
else if (OpenGL_GotVersion3 && MainProgram)
|
||||||
{
|
{
|
||||||
glBindVertexArray(MainVAO);
|
glBindVertexArray(MainVAO);
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
||||||
@ -719,7 +765,9 @@ static void DeleteContext(HGLRC context)
|
|||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, SurfaceTex);
|
HeapFree(GetProcessHeap(), 0, SurfaceTex);
|
||||||
glDeleteTextures(TEXTURE_COUNT, SurfaceTexIds);
|
glDeleteTextures(TEXTURE_COUNT, SurfaceTexIds);
|
||||||
glDeleteTextures(TEXTURE_COUNT, PaletteTexIds);
|
|
||||||
|
if (ddraw->bpp == 8)
|
||||||
|
glDeleteTextures(TEXTURE_COUNT, PaletteTexIds);
|
||||||
|
|
||||||
if (glUseProgram)
|
if (glUseProgram)
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
@ -740,8 +788,8 @@ static void DeleteContext(HGLRC context)
|
|||||||
|
|
||||||
if (glDeleteProgram)
|
if (glDeleteProgram)
|
||||||
{
|
{
|
||||||
if (PaletteProgram)
|
if (MainProgram)
|
||||||
glDeleteProgram(PaletteProgram);
|
glDeleteProgram(MainProgram);
|
||||||
|
|
||||||
if (ScaleProgram)
|
if (ScaleProgram)
|
||||||
glDeleteProgram(ScaleProgram);
|
glDeleteProgram(ScaleProgram);
|
||||||
@ -749,7 +797,7 @@ static void DeleteContext(HGLRC context)
|
|||||||
|
|
||||||
if (OpenGL_GotVersion3)
|
if (OpenGL_GotVersion3)
|
||||||
{
|
{
|
||||||
if (PaletteProgram)
|
if (MainProgram)
|
||||||
{
|
{
|
||||||
if (glDeleteBuffers)
|
if (glDeleteBuffers)
|
||||||
glDeleteBuffers(3, MainVBOs);
|
glDeleteBuffers(3, MainVBOs);
|
||||||
@ -782,40 +830,42 @@ static BOOL TextureUploadTest()
|
|||||||
ddraw->width,
|
ddraw->width,
|
||||||
ddraw->height,
|
ddraw->height,
|
||||||
SurfaceFormat,
|
SurfaceFormat,
|
||||||
GL_UNSIGNED_BYTE,
|
SurfaceType,
|
||||||
SurfaceTex);
|
SurfaceTex);
|
||||||
|
|
||||||
memset(SurfaceTex, 0, sizeof(testData));
|
memset(SurfaceTex, 0, sizeof(testData));
|
||||||
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, SurfaceFormat, GL_UNSIGNED_BYTE, SurfaceTex);
|
glGetTexImage(GL_TEXTURE_2D, 0, SurfaceFormat, SurfaceType, SurfaceTex);
|
||||||
|
|
||||||
if (memcmp(SurfaceTex, testData, sizeof(testData)) != 0)
|
if (memcmp(SurfaceTex, testData, sizeof(testData)) != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < TEXTURE_COUNT; i++)
|
if (ddraw->bpp == 8)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[i]);
|
for (i = 0; i < TEXTURE_COUNT; i++)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[i]);
|
||||||
|
|
||||||
glTexSubImage2D(
|
glTexSubImage2D(
|
||||||
GL_TEXTURE_2D,
|
GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
256,
|
256,
|
||||||
1,
|
1,
|
||||||
GL_RGBA,
|
GL_RGBA,
|
||||||
GL_UNSIGNED_BYTE,
|
GL_UNSIGNED_BYTE,
|
||||||
SurfaceTex);
|
SurfaceTex);
|
||||||
|
|
||||||
memset(SurfaceTex, 0, sizeof(testData));
|
memset(SurfaceTex, 0, sizeof(testData));
|
||||||
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, SurfaceTex);
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, SurfaceTex);
|
||||||
|
|
||||||
if (memcmp(SurfaceTex, testData, sizeof(testData)) != 0)
|
if (memcmp(SurfaceTex, testData, sizeof(testData)) != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +873,10 @@ static BOOL ShaderTest()
|
|||||||
{
|
{
|
||||||
BOOL result = TRUE;
|
BOOL result = TRUE;
|
||||||
|
|
||||||
if (OpenGL_GotVersion3 && PaletteProgram)
|
if (ddraw->bpp != 8)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (OpenGL_GotVersion3 && MainProgram)
|
||||||
{
|
{
|
||||||
memset(SurfaceTex, 0, SurfaceTexHeight * SurfaceTexWidth * sizeof(int));
|
memset(SurfaceTex, 0, SurfaceTexHeight * SurfaceTexWidth * sizeof(int));
|
||||||
|
|
||||||
@ -876,7 +929,7 @@ static BOOL ShaderTest()
|
|||||||
|
|
||||||
glViewport(0, 0, SurfaceTexWidth, SurfaceTexHeight);
|
glViewport(0, 0, SurfaceTexWidth, SurfaceTexHeight);
|
||||||
|
|
||||||
glUseProgram(PaletteProgram);
|
glUseProgram(MainProgram);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[0]);
|
glBindTexture(GL_TEXTURE_2D, PaletteTexIds[0]);
|
||||||
|
@ -176,20 +176,44 @@ static BOOL CreateResources()
|
|||||||
for (i = 0; i < TEXTURE_COUNT; i++)
|
for (i = 0; i < TEXTURE_COUNT; i++)
|
||||||
{
|
{
|
||||||
err = err || FAILED(
|
err = err || FAILED(
|
||||||
IDirect3DDevice9_CreateTexture(D3dDev, texWidth, texHeight, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &SurfaceTex[i], 0));
|
IDirect3DDevice9_CreateTexture(
|
||||||
|
D3dDev,
|
||||||
|
texWidth,
|
||||||
|
texHeight,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8,
|
||||||
|
D3DPOOL_MANAGED,
|
||||||
|
&SurfaceTex[i],
|
||||||
|
0));
|
||||||
|
|
||||||
err = err || !SurfaceTex[i];
|
err = err || !SurfaceTex[i];
|
||||||
|
|
||||||
err = err || FAILED(
|
if (ddraw->bpp == 8)
|
||||||
IDirect3DDevice9_CreateTexture(D3dDev, 256, 256, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &PaletteTex[i], 0));
|
{
|
||||||
|
err = err || FAILED(
|
||||||
err = err || !PaletteTex[i];
|
IDirect3DDevice9_CreateTexture(
|
||||||
|
D3dDev,
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
D3DFMT_X8R8G8B8,
|
||||||
|
D3DPOOL_MANAGED,
|
||||||
|
&PaletteTex[i],
|
||||||
|
0));
|
||||||
|
|
||||||
|
err = err || !PaletteTex[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = err || FAILED(
|
if (ddraw->bpp == 8)
|
||||||
IDirect3DDevice9_CreatePixelShader(D3dDev, (DWORD *)PalettePixelShaderSrc, &PixelShader));
|
{
|
||||||
|
err = err || FAILED(
|
||||||
|
IDirect3DDevice9_CreatePixelShader(D3dDev, (DWORD *)PalettePixelShaderSrc, &PixelShader));
|
||||||
|
}
|
||||||
|
|
||||||
return VertexBuf && PixelShader && !err;
|
return VertexBuf && (PixelShader || ddraw->bpp == 16) && !err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL SetStates()
|
static BOOL SetStates()
|
||||||
@ -199,8 +223,12 @@ static BOOL SetStates()
|
|||||||
err = err || FAILED(IDirect3DDevice9_SetFVF(D3dDev, D3DFVF_XYZRHW | D3DFVF_TEX1));
|
err = err || FAILED(IDirect3DDevice9_SetFVF(D3dDev, D3DFVF_XYZRHW | D3DFVF_TEX1));
|
||||||
err = err || FAILED(IDirect3DDevice9_SetStreamSource(D3dDev, 0, VertexBuf, 0, sizeof(CUSTOMVERTEX)));
|
err = err || FAILED(IDirect3DDevice9_SetStreamSource(D3dDev, 0, VertexBuf, 0, sizeof(CUSTOMVERTEX)));
|
||||||
err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 0, (IDirect3DBaseTexture9 *)SurfaceTex[0]));
|
err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 0, (IDirect3DBaseTexture9 *)SurfaceTex[0]));
|
||||||
err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 1, (IDirect3DBaseTexture9 *)PaletteTex[0]));
|
|
||||||
err = err || FAILED(IDirect3DDevice9_SetPixelShader(D3dDev, PixelShader));
|
if (ddraw->bpp == 8)
|
||||||
|
{
|
||||||
|
err = err || FAILED(IDirect3DDevice9_SetTexture(D3dDev, 1, (IDirect3DBaseTexture9 *)PaletteTex[0]));
|
||||||
|
err = err || FAILED(IDirect3DDevice9_SetPixelShader(D3dDev, PixelShader));
|
||||||
|
}
|
||||||
|
|
||||||
D3DVIEWPORT9 viewData = {
|
D3DVIEWPORT9 viewData = {
|
||||||
ddraw->render.viewport.x,
|
ddraw->render.viewport.x,
|
||||||
@ -288,7 +316,7 @@ DWORD WINAPI render_d3d9_main(void)
|
|||||||
|
|
||||||
EnterCriticalSection(&ddraw->cs);
|
EnterCriticalSection(&ddraw->cs);
|
||||||
|
|
||||||
if (ddraw->primary && ddraw->primary->palette && ddraw->primary->palette->data_rgb)
|
if (ddraw->primary && (ddraw->bpp == 16 || (ddraw->primary->palette && ddraw->primary->palette->data_rgb)))
|
||||||
{
|
{
|
||||||
if (ddraw->vhack)
|
if (ddraw->vhack)
|
||||||
{
|
{
|
||||||
@ -322,9 +350,9 @@ DWORD WINAPI render_d3d9_main(void)
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ddraw->height; i++)
|
for (i = 0; i < ddraw->height; i++)
|
||||||
{
|
{
|
||||||
memcpy(dst, src, ddraw->width);
|
memcpy(dst, src, ddraw->width * ddraw->primary->lXPitch);
|
||||||
|
|
||||||
src += ddraw->width;
|
src += ddraw->primary->lPitch;
|
||||||
dst += lock_rc.Pitch;
|
dst += lock_rc.Pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +360,7 @@ DWORD WINAPI render_d3d9_main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InterlockedExchange(&ddraw->render.paletteUpdated, FALSE))
|
if (ddraw->bpp == 8 && InterlockedExchange(&ddraw->render.paletteUpdated, FALSE))
|
||||||
{
|
{
|
||||||
if (++palIndex >= TEXTURE_COUNT)
|
if (++palIndex >= TEXTURE_COUNT)
|
||||||
palIndex = 0;
|
palIndex = 0;
|
||||||
|
@ -48,7 +48,7 @@ DWORD WINAPI render_soft_main(void)
|
|||||||
|
|
||||||
EnterCriticalSection(&ddraw->cs);
|
EnterCriticalSection(&ddraw->cs);
|
||||||
|
|
||||||
if (ddraw->primary && ddraw->primary->palette && ddraw->primary->palette->data_rgb)
|
if (ddraw->primary && (ddraw->bpp == 16 || (ddraw->primary->palette && ddraw->primary->palette->data_rgb)))
|
||||||
{
|
{
|
||||||
if (warningText[0])
|
if (warningText[0])
|
||||||
{
|
{
|
||||||
|
325
src/surface.c
325
src/surface.c
@ -109,21 +109,68 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RECT srcRect = { 0, 0, Source ? Source->width : 0, Source ? Source->height : 0 };
|
||||||
|
RECT dstRect = { 0, 0, This->width, This->height };
|
||||||
|
|
||||||
|
if (lpSrcRect && Source)
|
||||||
|
{
|
||||||
|
memcpy(&srcRect, lpSrcRect, sizeof(srcRect));
|
||||||
|
|
||||||
|
if (srcRect.right > Source->width)
|
||||||
|
srcRect.right = Source->width;
|
||||||
|
|
||||||
|
if (srcRect.bottom > Source->height)
|
||||||
|
srcRect.bottom = Source->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpDestRect)
|
||||||
|
{
|
||||||
|
memcpy(&dstRect, lpDestRect, sizeof(dstRect));
|
||||||
|
|
||||||
|
if (dstRect.right > This->width)
|
||||||
|
dstRect.right = This->width;
|
||||||
|
|
||||||
|
if (dstRect.bottom > This->height)
|
||||||
|
dstRect.bottom = This->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int src_w = srcRect.right - srcRect.left;
|
||||||
|
int src_h = srcRect.bottom - srcRect.top;
|
||||||
|
int src_x = srcRect.left;
|
||||||
|
int src_y = srcRect.top;
|
||||||
|
|
||||||
|
int dst_w = dstRect.right - dstRect.left;
|
||||||
|
int dst_h = dstRect.bottom - dstRect.top;
|
||||||
|
int dst_x = dstRect.left;
|
||||||
|
int dst_y = dstRect.top;
|
||||||
|
|
||||||
|
|
||||||
if (This->surface && (dwFlags & DDBLT_COLORFILL))
|
if (This->surface && (dwFlags & DDBLT_COLORFILL))
|
||||||
{
|
{
|
||||||
int dst_w = lpDestRect ? lpDestRect->right - lpDestRect->left : This->width;
|
if (This->bpp == 8)
|
||||||
int dst_h = lpDestRect ? lpDestRect->bottom - lpDestRect->top : This->height;
|
|
||||||
int dst_x = lpDestRect ? lpDestRect->left : 0;
|
|
||||||
int dst_y = lpDestRect ? lpDestRect->top : 0;
|
|
||||||
|
|
||||||
int y, x;
|
|
||||||
for (y = 0; y < dst_h; y++)
|
|
||||||
{
|
{
|
||||||
int ydst = This->width * (y + dst_y);
|
int y, x;
|
||||||
|
for (y = 0; y < dst_h; y++)
|
||||||
for (x = 0; x < dst_w; x++)
|
|
||||||
{
|
{
|
||||||
((unsigned char *)This->surface)[x + dst_x + ydst] = lpDDBltFx->dwFillColor;
|
int ydst = This->width * (y + dst_y);
|
||||||
|
|
||||||
|
for (x = 0; x < dst_w; x++)
|
||||||
|
{
|
||||||
|
((unsigned char *)This->surface)[x + dst_x + ydst] = lpDDBltFx->dwFillColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (This->bpp == 16)
|
||||||
|
{
|
||||||
|
int y, x;
|
||||||
|
for (y = 0; y < dst_h; y++)
|
||||||
|
{
|
||||||
|
int ydst = This->width * (y + dst_y);
|
||||||
|
|
||||||
|
for (x = 0; x < dst_w; x++)
|
||||||
|
{
|
||||||
|
((unsigned short *)This->surface)[x + dst_x + ydst] = lpDDBltFx->dwFillColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,56 +179,74 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR
|
|||||||
{
|
{
|
||||||
if (dwFlags & DDBLT_KEYSRC)
|
if (dwFlags & DDBLT_KEYSRC)
|
||||||
{
|
{
|
||||||
int src_w = lpSrcRect ? lpSrcRect->right - lpSrcRect->left : Source->width;
|
if (dst_w == src_w && dst_h == src_h)
|
||||||
int src_h = lpSrcRect ? lpSrcRect->bottom - lpSrcRect->top : Source->height;
|
|
||||||
int src_x = lpSrcRect ? lpSrcRect->left : 0;
|
|
||||||
int src_y = lpSrcRect ? lpSrcRect->top : 0;
|
|
||||||
int dst_x = lpDestRect ? lpDestRect->left : 0;
|
|
||||||
int dst_y = lpDestRect ? lpDestRect->top : 0;
|
|
||||||
|
|
||||||
unsigned char* dstSurface = (unsigned char *)This->surface;
|
|
||||||
unsigned char* srcSurface = (unsigned char *)Source->surface;
|
|
||||||
|
|
||||||
int y1, x1;
|
|
||||||
for (y1 = 0; y1 < src_h; y1++)
|
|
||||||
{
|
{
|
||||||
int ydst = This->width * (y1 + dst_y);
|
if (This->bpp == 8)
|
||||||
int ysrc = Source->width * (y1 + src_y);
|
|
||||||
|
|
||||||
for (x1 = 0; x1 < src_w; x1++)
|
|
||||||
{
|
{
|
||||||
unsigned char index = srcSurface[x1 + src_x + ysrc];
|
int y1, x1;
|
||||||
|
for (y1 = 0; y1 < dst_h; y1++)
|
||||||
|
{
|
||||||
|
int ydst = This->width * (y1 + dst_y);
|
||||||
|
int ysrc = Source->width * (y1 + src_y);
|
||||||
|
|
||||||
if (index != Source->colorKey.dwColorSpaceLowValue)
|
for (x1 = 0; x1 < dst_w; x1++)
|
||||||
dstSurface[x1 + dst_x + ydst] = index;
|
{
|
||||||
|
unsigned char c = ((unsigned char *)Source->surface)[x1 + src_x + ysrc];
|
||||||
|
|
||||||
|
if (c != Source->colorKey.dwColorSpaceLowValue)
|
||||||
|
{
|
||||||
|
((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (This->bpp == 16)
|
||||||
|
{
|
||||||
|
int y1, x1;
|
||||||
|
for (y1 = 0; y1 < dst_h; y1++)
|
||||||
|
{
|
||||||
|
int ydst = This->width * (y1 + dst_y);
|
||||||
|
int ysrc = Source->width * (y1 + src_y);
|
||||||
|
|
||||||
|
for (x1 = 0; x1 < dst_w; x1++)
|
||||||
|
{
|
||||||
|
unsigned short c = ((unsigned short *)Source->surface)[x1 + src_x + ysrc];
|
||||||
|
|
||||||
|
if (c != Source->colorKey.dwColorSpaceLowValue)
|
||||||
|
{
|
||||||
|
((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" DDBLT_KEYSRC does not support stretching");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int dx = 0, dy = 0;
|
if (dst_w == src_w && dst_h == src_h)
|
||||||
if (lpDestRect)
|
|
||||||
{
|
{
|
||||||
dx = lpDestRect->left;
|
unsigned char *src =
|
||||||
dy = lpDestRect->top;
|
(unsigned char *)Source->surface + ((src_x + (Source->width * src_y)) * Source->lXPitch);
|
||||||
}
|
|
||||||
int x0 = 0, y0 = 0, x1 = Source->width, y1 = Source->height;
|
|
||||||
if (lpSrcRect)
|
|
||||||
{
|
|
||||||
x0 = max(x0, lpSrcRect->left);
|
|
||||||
x1 = min(x1, lpSrcRect->right);
|
|
||||||
y0 = max(y0, lpSrcRect->top);
|
|
||||||
y1 = min(y1, lpSrcRect->bottom);
|
|
||||||
}
|
|
||||||
unsigned char* to = (unsigned char *)This->surface + dy*This->width + dx;
|
|
||||||
unsigned char* from = (unsigned char *)Source->surface + y0*Source->width + x0;
|
|
||||||
int s = x1 - x0;
|
|
||||||
|
|
||||||
int y;
|
unsigned char *dst =
|
||||||
for (y = y0; y < y1; ++y, to += This->width, from += Source->width)
|
(unsigned char *)This->surface + ((dst_x + (This->width * dst_y)) * This->lXPitch);
|
||||||
{
|
|
||||||
memcpy(to, from, s);
|
int i;
|
||||||
|
for (i = 0; i < dst_h; i++)
|
||||||
|
{
|
||||||
|
memcpy(dst, src, dst_w * This->lXPitch);
|
||||||
|
|
||||||
|
src += Source->lPitch;
|
||||||
|
dst += This->lPitch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
StretchBlt(This->hDC, dst_x, dst_y, dst_w, dst_h, Source->hDC, src_x, src_y, src_w, src_h, SRCCOPY);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,51 +300,93 @@ HRESULT __stdcall ddraw_surface_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RECT srcRect = { 0, 0, Source ? Source->width : 0, Source ? Source->height : 0 };
|
||||||
|
|
||||||
|
if (lpSrcRect && Source)
|
||||||
|
{
|
||||||
|
memcpy(&srcRect, lpSrcRect, sizeof(srcRect));
|
||||||
|
|
||||||
|
if (srcRect.right > Source->width)
|
||||||
|
srcRect.right = Source->width;
|
||||||
|
|
||||||
|
if (srcRect.bottom > Source->height)
|
||||||
|
srcRect.bottom = Source->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int src_w = srcRect.right - srcRect.left;
|
||||||
|
int src_h = srcRect.bottom - srcRect.top;
|
||||||
|
int src_x = srcRect.left;
|
||||||
|
int src_y = srcRect.top;
|
||||||
|
|
||||||
|
RECT dstRect = { dst_x, dst_y, src_w + dst_x, src_h + dst_y };
|
||||||
|
|
||||||
|
if (dstRect.right > This->width)
|
||||||
|
dstRect.right = This->width;
|
||||||
|
|
||||||
|
if (dstRect.bottom > This->height)
|
||||||
|
dstRect.bottom = This->height;
|
||||||
|
|
||||||
|
int dst_w = dstRect.right - dstRect.left;
|
||||||
|
int dst_h = dstRect.bottom - dstRect.top;
|
||||||
|
|
||||||
if (Source)
|
if (Source)
|
||||||
{
|
{
|
||||||
if (flags & DDBLTFAST_SRCCOLORKEY)
|
if (flags & DDBLTFAST_SRCCOLORKEY)
|
||||||
{
|
{
|
||||||
int src_w = lpSrcRect ? lpSrcRect->right - lpSrcRect->left : Source->width;
|
if (This->bpp == 8)
|
||||||
int src_h = lpSrcRect ? lpSrcRect->bottom - lpSrcRect->top : Source->height;
|
|
||||||
int src_x = lpSrcRect ? lpSrcRect->left : 0;
|
|
||||||
int src_y = lpSrcRect ? lpSrcRect->top : 0;
|
|
||||||
|
|
||||||
unsigned char* dstSurface = (unsigned char *)This->surface;
|
|
||||||
unsigned char* srcSurface = (unsigned char *)Source->surface;
|
|
||||||
|
|
||||||
int y1, x1;
|
|
||||||
for (y1 = 0; y1 < src_h; y1++)
|
|
||||||
{
|
{
|
||||||
int ydst = This->width * (y1 + dst_y);
|
int y1, x1;
|
||||||
int ysrc = Source->width * (y1 + src_y);
|
for (y1 = 0; y1 < dst_h; y1++)
|
||||||
|
|
||||||
for (x1 = 0; x1 < src_w; x1++)
|
|
||||||
{
|
{
|
||||||
unsigned char index = srcSurface[x1 + src_x + ysrc];
|
int ydst = This->width * (y1 + dst_y);
|
||||||
|
int ysrc = Source->width * (y1 + src_y);
|
||||||
|
|
||||||
if (index != Source->colorKey.dwColorSpaceLowValue)
|
for (x1 = 0; x1 < dst_w; x1++)
|
||||||
dstSurface[x1 + dst_x + ydst] = index;
|
{
|
||||||
|
unsigned char c = ((unsigned char *)Source->surface)[x1 + src_x + ysrc];
|
||||||
|
|
||||||
|
if (c != Source->colorKey.dwColorSpaceLowValue)
|
||||||
|
{
|
||||||
|
((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (This->bpp == 16)
|
||||||
|
{
|
||||||
|
int y1, x1;
|
||||||
|
for (y1 = 0; y1 < dst_h; y1++)
|
||||||
|
{
|
||||||
|
int ydst = This->width * (y1 + dst_y);
|
||||||
|
int ysrc = Source->width * (y1 + src_y);
|
||||||
|
|
||||||
|
for (x1 = 0; x1 < dst_w; x1++)
|
||||||
|
{
|
||||||
|
unsigned short c = ((unsigned short *)Source->surface)[x1 + src_x + ysrc];
|
||||||
|
|
||||||
|
if (c != Source->colorKey.dwColorSpaceLowValue)
|
||||||
|
{
|
||||||
|
((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int x0 = 0, y0 = 0, x1 = Source->width, y1 = Source->height;
|
unsigned char *src =
|
||||||
if (lpSrcRect)
|
(unsigned char *)Source->surface + ((src_x + (Source->width * src_y)) * Source->lXPitch);
|
||||||
{
|
|
||||||
x0 = max(x0, lpSrcRect->left);
|
|
||||||
x1 = min(x1, lpSrcRect->right);
|
|
||||||
y0 = max(y0, lpSrcRect->top);
|
|
||||||
y1 = min(y1, lpSrcRect->bottom);
|
|
||||||
}
|
|
||||||
unsigned char* to = (unsigned char *)This->surface + dst_y*This->width + dst_x;
|
|
||||||
unsigned char* from = (unsigned char *)Source->surface + y0*Source->width + x0;
|
|
||||||
int s = x1 - x0;
|
|
||||||
|
|
||||||
int y;
|
unsigned char *dst =
|
||||||
for (y = y0; y < y1; ++y, to += This->width, from += Source->width)
|
(unsigned char *)This->surface + ((dst_x + (This->width * dst_y)) * This->lXPitch);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < dst_h; i++)
|
||||||
{
|
{
|
||||||
memcpy(to, from, s);
|
memcpy(dst, src, dst_w * This->lXPitch);
|
||||||
|
|
||||||
|
src += Source->lPitch;
|
||||||
|
dst += This->lPitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,14 +419,18 @@ HRESULT __stdcall ddraw_surface_GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPD
|
|||||||
lpDDSurfaceDesc->dwHeight = This->height;
|
lpDDSurfaceDesc->dwHeight = This->height;
|
||||||
lpDDSurfaceDesc->lPitch = This->lPitch;
|
lpDDSurfaceDesc->lPitch = This->lPitch;
|
||||||
lpDDSurfaceDesc->lpSurface = This->surface;
|
lpDDSurfaceDesc->lpSurface = This->surface;
|
||||||
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
|
lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||||
|
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||||
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
|
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
|
||||||
|
|
||||||
if (This->bpp == 16)
|
if (This->bpp == 8)
|
||||||
{
|
{
|
||||||
/* RGB 555 */
|
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
|
||||||
lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x7C00;
|
}
|
||||||
lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x03E0;
|
else if (This->bpp == 16)
|
||||||
|
{
|
||||||
|
lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0xF800;
|
||||||
|
lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x07E0;
|
||||||
lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x001F;
|
lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x001F;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,8 +578,19 @@ HRESULT __stdcall ddraw_surface_GetPixelFormat(IDirectDrawSurfaceImpl *This, LPD
|
|||||||
memset(ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT));
|
memset(ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT));
|
||||||
|
|
||||||
ddpfPixelFormat->dwSize = size;
|
ddpfPixelFormat->dwSize = size;
|
||||||
ddpfPixelFormat->dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
|
ddpfPixelFormat->dwFlags = DDPF_RGB;
|
||||||
ddpfPixelFormat->dwRGBBitCount = 8;
|
ddpfPixelFormat->dwRGBBitCount = This->bpp;
|
||||||
|
|
||||||
|
if (This->bpp == 8)
|
||||||
|
{
|
||||||
|
ddpfPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
|
||||||
|
}
|
||||||
|
else if (This->bpp == 16)
|
||||||
|
{
|
||||||
|
ddpfPixelFormat->dwRBitMask = 0xF800;
|
||||||
|
ddpfPixelFormat->dwGBitMask = 0x07E0;
|
||||||
|
ddpfPixelFormat->dwBBitMask = 0x001F;
|
||||||
|
}
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
@ -530,7 +652,9 @@ HRESULT __stdcall ddraw_surface_ReleaseDC(IDirectDrawSurfaceImpl *This, HDC a)
|
|||||||
|
|
||||||
HRESULT __stdcall ddraw_surface_Restore(IDirectDrawSurfaceImpl *This)
|
HRESULT __stdcall ddraw_surface_Restore(IDirectDrawSurfaceImpl *This)
|
||||||
{
|
{
|
||||||
|
#if _DEBUG_X
|
||||||
printf("DirectDrawSurface::Restore(This=%p) ???\n", This);
|
printf("DirectDrawSurface::Restore(This=%p) ???\n", This);
|
||||||
|
#endif
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,6 +806,8 @@ HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC lpD
|
|||||||
|
|
||||||
Surface->lpVtbl = &siface;
|
Surface->lpVtbl = &siface;
|
||||||
|
|
||||||
|
lpDDSurfaceDesc->dwFlags |= DDSD_CAPS;
|
||||||
|
|
||||||
/* private stuff */
|
/* private stuff */
|
||||||
Surface->bpp = This->bpp;
|
Surface->bpp = This->bpp;
|
||||||
Surface->flags = lpDDSurfaceDesc->dwFlags;
|
Surface->flags = lpDDSurfaceDesc->dwFlags;
|
||||||
@ -716,7 +842,7 @@ HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC lpD
|
|||||||
Surface->bmi->bmiHeader.biHeight = -Surface->height;
|
Surface->bmi->bmiHeader.biHeight = -Surface->height;
|
||||||
Surface->bmi->bmiHeader.biPlanes = 1;
|
Surface->bmi->bmiHeader.biPlanes = 1;
|
||||||
Surface->bmi->bmiHeader.biBitCount = Surface->bpp;
|
Surface->bmi->bmiHeader.biBitCount = Surface->bpp;
|
||||||
Surface->bmi->bmiHeader.biCompression = BI_RGB;
|
Surface->bmi->bmiHeader.biCompression = Surface->bpp == 16 ? BI_BITFIELDS : BI_RGB;
|
||||||
|
|
||||||
WORD cClrBits = (WORD)(Surface->bmi->bmiHeader.biPlanes * Surface->bmi->bmiHeader.biBitCount);
|
WORD cClrBits = (WORD)(Surface->bmi->bmiHeader.biPlanes * Surface->bmi->bmiHeader.biBitCount);
|
||||||
if (cClrBits < 24)
|
if (cClrBits < 24)
|
||||||
@ -724,13 +850,22 @@ HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC lpD
|
|||||||
|
|
||||||
Surface->bmi->bmiHeader.biSizeImage = ((Surface->width * cClrBits + 31) & ~31) / 8 * Surface->height;
|
Surface->bmi->bmiHeader.biSizeImage = ((Surface->width * cClrBits + 31) & ~31) / 8 * Surface->height;
|
||||||
|
|
||||||
int i;
|
if (Surface->bpp == 8)
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
{
|
||||||
Surface->bmi->bmiColors[i].rgbRed = i;
|
int i;
|
||||||
Surface->bmi->bmiColors[i].rgbGreen = i;
|
for (i = 0; i < 256; i++)
|
||||||
Surface->bmi->bmiColors[i].rgbBlue = i;
|
{
|
||||||
Surface->bmi->bmiColors[i].rgbReserved = 0;
|
Surface->bmi->bmiColors[i].rgbRed = i;
|
||||||
|
Surface->bmi->bmiColors[i].rgbGreen = i;
|
||||||
|
Surface->bmi->bmiColors[i].rgbBlue = i;
|
||||||
|
Surface->bmi->bmiColors[i].rgbReserved = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Surface->bpp == 16)
|
||||||
|
{
|
||||||
|
((DWORD *)Surface->bmi->bmiColors)[0] = 0xF800;
|
||||||
|
((DWORD *)Surface->bmi->bmiColors)[1] = 0x07E0;
|
||||||
|
((DWORD *)Surface->bmi->bmiColors)[2] = 0x001F;
|
||||||
}
|
}
|
||||||
|
|
||||||
Surface->lXPitch = Surface->bpp / 8;
|
Surface->lXPitch = Surface->bpp / 8;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user