diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj index 32ced64..a60eba6 100644 --- a/cnc-ddraw.vcxproj +++ b/cnc-ddraw.vcxproj @@ -69,6 +69,7 @@ + diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters index e250556..125b22d 100644 --- a/cnc-ddraw.vcxproj.filters +++ b/cnc-ddraw.vcxproj.filters @@ -254,6 +254,9 @@ Header Files + + Header Files + diff --git a/src/config.c b/src/config.c index f7351c9..6ebfa74 100644 --- a/src/config.c +++ b/src/config.c @@ -565,7 +565,7 @@ static void cfg_create_ini() "[Tzar]\n" "handlemouse=false\n" "\n" - "; Jagged Alliance 2 1.13\n" + "; Jagged Alliance 2\n" "[ja2]\n" "hook=0\n" "\n" diff --git a/src/dd.c b/src/dd.c index 649df8f..6637f34 100644 --- a/src/dd.c +++ b/src/dd.c @@ -92,6 +92,16 @@ HRESULT dd_EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVO s.ddpfPixelFormat.dwBBitMask = 0x001F; } + if (g_ddraw->bpp == 32) + { + s.lPitch = s.dwWidth * 4; + s.ddpfPixelFormat.dwFlags = DDPF_RGB; + s.ddpfPixelFormat.dwRGBBitCount = 32; + s.ddpfPixelFormat.dwRBitMask = 0xFF0000; + s.ddpfPixelFormat.dwGBitMask = 0x00FF00; + s.ddpfPixelFormat.dwBBitMask = 0x0000FF; + } + if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL) { dprintf(" DDENUMRET_CANCEL returned, stopping\n"); @@ -151,6 +161,19 @@ HRESULT dd_EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVO dprintf(" DDENUMRET_CANCEL returned, stopping\n"); break; } + + s.lPitch = s.dwWidth * 4; + s.ddpfPixelFormat.dwFlags = DDPF_RGB; + s.ddpfPixelFormat.dwRGBBitCount = 32; + s.ddpfPixelFormat.dwRBitMask = 0xFF0000; + s.ddpfPixelFormat.dwGBitMask = 0x00FF00; + s.ddpfPixelFormat.dwBBitMask = 0x0000FF; + + if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL) + { + dprintf(" DDENUMRET_CANCEL returned, stopping\n"); + break; + } } } @@ -202,7 +225,16 @@ HRESULT dd_GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB; lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 8; - if (g_ddraw->bpp != 8) + if (g_ddraw->bpp == 32) + { + lpDDSurfaceDesc->lPitch = lpDDSurfaceDesc->dwWidth * 4; + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 32; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0xFF0000; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x00FF00; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000FF; + } + else if (g_ddraw->bpp != 8) { lpDDSurfaceDesc->lPitch = lpDDSurfaceDesc->dwWidth * 2; lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; @@ -262,7 +294,7 @@ HRESULT dd_RestoreDisplayMode() HRESULT dd_SetDisplayMode(DWORD width, DWORD height, DWORD bpp) { - if (bpp != 8 && bpp != 16) + if (bpp != 8 && bpp != 16 && bpp != 32) return DDERR_INVALIDMODE; if (g_ddraw->render.thread) diff --git a/src/ddsurface.c b/src/ddsurface.c index 09eaddb..a1d812d 100644 --- a/src/ddsurface.c +++ b/src/ddsurface.c @@ -149,6 +149,35 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR } } } + else if (This->bpp == 32) + { + unsigned int* row1 = (unsigned int*)dst; + unsigned int color = lpDDBltFx->dwFillColor; + + if ((color & 0xFF) == ((color >> 8) & 0xFF) && + (color & 0xFF) == ((color >> 16) & 0xFF) && + (color & 0xFF) == ((color >> 24) & 0xFF)) + { + unsigned char c8 = (unsigned char)(color & 0xFF); + + for (i = 0; i < dst_h; i++) + { + memset(dst, c8, dst_pitch); + dst += This->l_pitch; + } + } + else + { + for (x = 0; x < dst_w; x++) + row1[x] = color; + + for (i = 1; i < dst_h; i++) + { + dst += This->l_pitch; + memcpy(dst, first_row, dst_pitch); + } + } + } } if (src_surface && src_w > 0 && src_h > 0 && dst_w > 0 && dst_h > 0) @@ -181,8 +210,8 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR if (mirror_up_down) scaled_y = src_h - 1 - scaled_y; - int rc_src_y = src_surface->width * (scaled_y + src_y); - int rc_dst_y = This->width * (y + dst_y); + int src_row = src_surface->width * (scaled_y + src_y); + int dst_row = This->width * (y + dst_y); for (int x = 0; x < dst_w; x++) { @@ -191,11 +220,11 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR if (mirror_left_right) scaled_x = src_w - 1 - scaled_x; - unsigned char c = ((unsigned char*)src_buf)[scaled_x + src_x + rc_src_y]; + unsigned char c = ((unsigned char*)src_buf)[scaled_x + src_x + src_row]; if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue) { - ((unsigned char*)dst_buf)[x + dst_x + rc_dst_y] = c; + ((unsigned char*)dst_buf)[x + dst_x + dst_row] = c; } } } @@ -209,8 +238,8 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR if (mirror_up_down) scaled_y = src_h - 1 - scaled_y; - int rc_src_y = src_surface->width * (scaled_y + src_y); - int rc_dst_y = This->width * (y + dst_y); + int src_row = src_surface->width * (scaled_y + src_y); + int dst_row = This->width * (y + dst_y); for (int x = 0; x < dst_w; x++) { @@ -219,11 +248,39 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR if (mirror_left_right) scaled_x = src_w - 1 - scaled_x; - unsigned short c = ((unsigned short*)src_buf)[scaled_x + src_x + rc_src_y]; + unsigned short c = ((unsigned short*)src_buf)[scaled_x + src_x + src_row]; if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue) { - ((unsigned short*)dst_buf)[x + dst_x + rc_dst_y] = c; + ((unsigned short*)dst_buf)[x + dst_x + dst_row] = c; + } + } + } + } + else if (This->bpp == 32) + { + for (int y = 0; y < dst_h; y++) + { + int scaled_y = (int)(y * scale_h); + + if (mirror_up_down) + scaled_y = src_h - 1 - scaled_y; + + int src_row = src_surface->width * (scaled_y + src_y); + int dst_row = This->width * (y + dst_y); + + for (int x = 0; x < dst_w; x++) + { + int scaled_x = (int)(x * scale_w); + + if (mirror_left_right) + scaled_x = src_w - 1 - scaled_x; + + unsigned int c = ((unsigned int*)src_buf)[scaled_x + src_x + src_row]; + + if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue) + { + ((unsigned int*)dst_buf)[x + dst_x + dst_row] = c; } } } @@ -432,6 +489,45 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR break; } + current = &pattern[++pattern_idx]; + } while (current->type != END); + } + else if (This->bpp == 32) + { + unsigned int* d, * s, v; + unsigned int* src = (unsigned int*)src_buf; + unsigned int* dst = (unsigned int*)dst_buf; + + do { + switch (current->type) + { + case ONCE: + dst[dest_base + current->dst_index] = + src[source_base + current->src_index]; + break; + + case REPEAT: + d = (dst + dest_base + current->dst_index); + v = src[source_base + current->src_index]; + + count = current->count; + while (count-- > 0) + *d++ = v; + + break; + + case SEQUENCE: + d = dst + dest_base + current->dst_index; + s = src + source_base + current->src_index; + + memcpy((void*)d, (void*)s, current->count * This->lx_pitch); + break; + + case END: + default: + break; + } + current = &pattern[++pattern_idx]; } while (current->type != END); } @@ -535,16 +631,16 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI { for (int y = 0; y < dst_h; y++) { - int rc_dst_y = This->width * (y + dst_y); - int rc_src_y = src_surface->width * (y + src_y); + int dst_row = This->width * (y + dst_y); + int src_row = src_surface->width * (y + src_y); for (int x = 0; x < dst_w; x++) { - unsigned char c = ((unsigned char *)src_buf)[x + src_x + rc_src_y]; + unsigned char c = ((unsigned char *)src_buf)[x + src_x + src_row]; if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue) { - ((unsigned char *)dst_buf)[x + dst_x + rc_dst_y] = c; + ((unsigned char *)dst_buf)[x + dst_x + dst_row] = c; } } } @@ -553,16 +649,34 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI { for (int y = 0; y < dst_h; y++) { - int rc_dst_y = This->width * (y + dst_y); - int rc_src_y = src_surface->width * (y + src_y); + int dst_row = This->width * (y + dst_y); + int src_row = src_surface->width * (y + src_y); for (int x = 0; x < dst_w; x++) { - unsigned short c = ((unsigned short *)src_buf)[x + src_x + rc_src_y]; + unsigned short c = ((unsigned short *)src_buf)[x + src_x + src_row]; if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue) { - ((unsigned short *)dst_buf)[x + dst_x + rc_dst_y] = c; + ((unsigned short *)dst_buf)[x + dst_x + dst_row] = c; + } + } + } + } + else if (This->bpp == 32) + { + for (int y = 0; y < dst_h; y++) + { + int dst_row = This->width * (y + dst_y); + int src_row = src_surface->width * (y + src_y); + + for (int x = 0; x < dst_w; x++) + { + unsigned int c = ((unsigned int*)src_buf)[x + src_x + src_row]; + + if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue) + { + ((unsigned int*)dst_buf)[x + dst_x + dst_row] = c; } } } @@ -676,6 +790,12 @@ HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPDDSURFACEDESC lpDDSur lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x07E0; lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x001F; } + else if (This->bpp == 32) + { + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0xFF0000; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x00FF00; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000FF; + } } return DD_OK; @@ -889,6 +1009,12 @@ HRESULT dds_GetPixelFormat(IDirectDrawSurfaceImpl *This, LPDDPIXELFORMAT ddpfPix ddpfPixelFormat->dwGBitMask = 0x07E0; ddpfPixelFormat->dwBBitMask = 0x001F; } + else if (This->bpp == 32) + { + ddpfPixelFormat->dwRBitMask = 0xFF0000; + ddpfPixelFormat->dwGBitMask = 0x00FF00; + ddpfPixelFormat->dwBBitMask = 0x0000FF; + } return DD_OK; } @@ -1121,7 +1247,7 @@ HRESULT dd_CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, dst_surface->bmi->bmiHeader.biHeight = -((int)dst_surface->height + 200); dst_surface->bmi->bmiHeader.biPlanes = 1; dst_surface->bmi->bmiHeader.biBitCount = dst_surface->bpp; - dst_surface->bmi->bmiHeader.biCompression = dst_surface->bpp == 16 ? BI_BITFIELDS : BI_RGB; + dst_surface->bmi->bmiHeader.biCompression = dst_surface->bpp == 8 ? BI_RGB : BI_BITFIELDS; WORD clr_bits = (WORD)(dst_surface->bmi->bmiHeader.biPlanes * dst_surface->bmi->bmiHeader.biBitCount); @@ -1144,9 +1270,15 @@ HRESULT dd_CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, } else if (dst_surface->bpp == 16) { - ((DWORD *)dst_surface->bmi->bmiColors)[0] = 0xF800; - ((DWORD *)dst_surface->bmi->bmiColors)[1] = 0x07E0; - ((DWORD *)dst_surface->bmi->bmiColors)[2] = 0x001F; + ((DWORD*)dst_surface->bmi->bmiColors)[0] = 0xF800; + ((DWORD*)dst_surface->bmi->bmiColors)[1] = 0x07E0; + ((DWORD*)dst_surface->bmi->bmiColors)[2] = 0x001F; + } + else if (dst_surface->bpp == 32) + { + ((DWORD*)dst_surface->bmi->bmiColors)[0] = 0xFF0000; + ((DWORD*)dst_surface->bmi->bmiColors)[1] = 0x00FF00; + ((DWORD*)dst_surface->bmi->bmiColors)[2] = 0x0000FF; } dst_surface->hdc = CreateCompatibleDC(g_ddraw->render.hdc); diff --git a/src/render_d3d9.c b/src/render_d3d9.c index 71b7572..b259b81 100644 --- a/src/render_d3d9.c +++ b/src/render_d3d9.c @@ -207,7 +207,7 @@ static BOOL d3d9_create_resouces() tex_height, 1, 0, - g_ddraw->bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_L8, + g_ddraw->bpp == 16 ? D3DFMT_R5G6B5 : g_ddraw->bpp == 32 ? D3DFMT_X8B8G8R8 : D3DFMT_L8, D3DPOOL_MANAGED, &g_d3d9.surface_tex[i], 0)); @@ -238,7 +238,7 @@ static BOOL d3d9_create_resouces() IDirect3DDevice9_CreatePixelShader(g_d3d9.device, (DWORD *)D3D9_PALETTE_SHADER, &g_d3d9.pixel_shader)); } - return g_d3d9.vertex_buf && (g_d3d9.pixel_shader || g_ddraw->bpp == 16) && !err; + return g_d3d9.vertex_buf && (g_d3d9.pixel_shader || g_ddraw->bpp == 16 || g_ddraw->bpp == 32) && !err; } static BOOL d3d9_set_states() @@ -330,7 +330,7 @@ DWORD WINAPI d3d9_render_main(void) EnterCriticalSection(&g_ddraw->cs); - if (g_ddraw->primary && (g_ddraw->bpp == 16 || g_ddraw->primary->palette)) + if (g_ddraw->primary && (g_ddraw->bpp == 16 || g_ddraw->bpp == 32 || g_ddraw->primary->palette)) { if (g_ddraw->vhack) { diff --git a/src/render_gdi.c b/src/render_gdi.c index 3c0c0ad..c3334c7 100644 --- a/src/render_gdi.c +++ b/src/render_gdi.c @@ -46,7 +46,7 @@ DWORD WINAPI gdi_render_main(void) EnterCriticalSection(&g_ddraw->cs); - if (g_ddraw->primary && (g_ddraw->bpp == 16 || g_ddraw->primary->palette)) + if (g_ddraw->primary && (g_ddraw->bpp == 16 || g_ddraw->bpp == 32 || g_ddraw->primary->palette)) { if (warning_end_tick) { diff --git a/src/render_ogl.c b/src/render_ogl.c index 474513d..7c5cd6f 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -48,7 +48,7 @@ DWORD WINAPI ogl_render_main(void) g_ogl.got_error = g_ogl.got_error || !ogl_texture_upload_test(); g_ogl.got_error = g_ogl.got_error || !ogl_shader_test(); g_ogl.got_error = g_ogl.got_error || glGetError() != GL_NO_ERROR; - g_ogl.use_opengl = (g_ogl.main_program || g_ddraw->bpp == 16) && !g_ogl.got_error; + g_ogl.use_opengl = (g_ogl.main_program || g_ddraw->bpp == 16 || g_ddraw->bpp == 32) && !g_ogl.got_error; ogl_render(); @@ -128,7 +128,7 @@ static void ogl_build_programs() g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER_CORE, PALETTE_FRAG_SHADER_CORE); } } - else if (g_ddraw->bpp == 16) + else if (g_ddraw->bpp == 16 || g_ddraw->bpp == 32) { g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER, PASSTHROUGH_FRAG_SHADER); @@ -156,7 +156,7 @@ static void ogl_build_programs() { g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER_110, PALETTE_FRAG_SHADER_110); } - else if (g_ddraw->bpp == 16) + else if (g_ddraw->bpp == 16 || g_ddraw->bpp == 32) { g_ogl.main_program = oglu_build_program(PASSTHROUGH_VERT_SHADER_110, PASSTHROUGH_FRAG_SHADER_110); } @@ -192,7 +192,20 @@ static void ogl_create_textures(int width, int height) while (glGetError() != GL_NO_ERROR); - if (g_ddraw->bpp == 16) + if (g_ddraw->bpp == 32) + { + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGBA8, + g_ogl.surface_tex_width, + g_ogl.surface_tex_height, + 0, + g_ogl.surface_format = GL_RGBA, + g_ogl.surface_type = GL_UNSIGNED_BYTE, + 0); + } + else if (g_ddraw->bpp == 16) { glTexImage2D( GL_TEXTURE_2D, @@ -536,7 +549,7 @@ static void ogl_render() { glUseProgram(g_ogl.main_program); } - else if (g_ddraw->bpp == 16) + else if (g_ddraw->bpp == 16 || g_ddraw->bpp == 32) { glEnable(GL_TEXTURE_2D); } @@ -561,7 +574,7 @@ static void ogl_render() EnterCriticalSection(&g_ddraw->cs); - if (g_ddraw->primary && (g_ddraw->bpp == 16 || g_ddraw->primary->palette)) + if (g_ddraw->primary && (g_ddraw->bpp == 16 || g_ddraw->bpp == 32 || g_ddraw->primary->palette)) { if (g_ddraw->vhack) {