From a1fefe870c2566cbc6ede9b4fed8b48417305ba5 Mon Sep 17 00:00:00 2001 From: death2droid Date: Tue, 22 Dec 2009 06:47:42 +0000 Subject: [PATCH] DX9: - Add hires texture loading. - Add an option to enable the EFB scaled copy *TODO find a better place for it to go. SOIL - Update stb_image to the latest version (1.16 to 1.18) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4716 8ced0084-cf51-0410-be5f-012b33b47a6e --- Externals/SOIL/SOIL.c | 25 ++- Externals/SOIL/stb_image_aug.c | 145 +++++++++++++----- Source/Core/VideoCommon/Src/HiresTextures.h | 1 + .../Plugin_VideoDX9/Src/DlgSettings.cpp | 17 +- .../Src/FramebufferManager.cpp | 1 + .../Plugin_VideoDX9/Src/TextureCache.cpp | 42 ++++- Source/Plugins/Plugin_VideoDX9/Src/resource.h | 2 + .../Plugins/Plugin_VideoDX9/Src/resource.rc | 7 +- 8 files changed, 180 insertions(+), 60 deletions(-) diff --git a/Externals/SOIL/SOIL.c b/Externals/SOIL/SOIL.c index 44d62dbc34..3e359c3551 100644 --- a/Externals/SOIL/SOIL.c +++ b/Externals/SOIL/SOIL.c @@ -19,15 +19,21 @@ #define WIN32_LEAN_AND_MEAN #include #include - #include + #if 0 + #include + #endif #elif defined(__APPLE__) || defined(__APPLE_CC__) /* I can't test this Apple stuff! */ - #include + #if 0 + #include + #endif #include #define APIENTRY #else - #include - #include + #if 0 + #include + #include + #endif #endif #include "SOIL.h" @@ -47,6 +53,7 @@ enum{ SOIL_CAPABILITY_NONE = 0, SOIL_CAPABILITY_PRESENT = 1 }; + static int has_cubemap_capability = SOIL_CAPABILITY_UNKNOWN; int query_cubemap_capability( void ); #define SOIL_TEXTURE_WRAP_R 0x8072 @@ -78,13 +85,17 @@ int query_DXT_capability( void ); #define SOIL_RGBA_S3TC_DXT1 0x83F1 #define SOIL_RGBA_S3TC_DXT3 0x83F2 #define SOIL_RGBA_S3TC_DXT5 0x83F3 + +#if 0 typedef void (APIENTRY * P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data); P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC soilGlCompressedTexImage2D = NULL; + unsigned int SOIL_direct_load_DDS( const char *filename, unsigned int reuse_texture_ID, int flags, int loading_as_cubemap ); + unsigned int SOIL_direct_load_DDS_from_memory( const unsigned char *const buffer, int buffer_length, @@ -92,6 +103,7 @@ unsigned int SOIL_direct_load_DDS_from_memory( int flags, int loading_as_cubemap ); /* other functions */ + unsigned int SOIL_internal_create_OGL_texture ( @@ -1420,6 +1432,7 @@ int SOIL_free_image_data( pixel_data ); return save_result; } +#endif unsigned char* SOIL_load_image @@ -1529,6 +1542,7 @@ const char* return result_string_pointer; } +#if 0 unsigned int SOIL_direct_load_DDS_from_memory( const unsigned char *const buffer, int buffer_length, @@ -1870,6 +1884,7 @@ unsigned int SOIL_direct_load_DDS( return tex_ID; } + int query_NPOT_capability( void ) { /* check for the capability */ @@ -1948,6 +1963,7 @@ int query_cubemap_capability( void ) return has_cubemap_capability; } + int query_DXT_capability( void ) { /* check for the capability */ @@ -2022,3 +2038,4 @@ int query_DXT_capability( void ) /* let the user know if we can do DXT or not */ return has_DXT_capability; } +#endif diff --git a/Externals/SOIL/stb_image_aug.c b/Externals/SOIL/stb_image_aug.c index 2fa7233848..61247ceb1a 100644 --- a/Externals/SOIL/stb_image_aug.c +++ b/Externals/SOIL/stb_image_aug.c @@ -1,4 +1,4 @@ -/* stbi-1.16 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c +/* stbi-1.18 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c when you control the images you're loading QUICK NOTES: @@ -6,7 +6,7 @@ avoid problematic images and only need the trivial interface JPEG baseline (no JPEG progressive, no oddball channel decimations) - PNG non-interlaced + PNG 8-bit only BMP non-1bpp, non-RLE TGA (not sure what subset, if a subset) PSD (composited view only, no extra channels) @@ -14,11 +14,13 @@ writes BMP,TGA (define STBI_NO_WRITE to remove code) decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code) supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) - + TODO: stbi_info_* - + history: + 1.18 fix a threading bug (local mutable static) + 1.17 support interlaced PNG 1.16 major bugfix - convert_format converted one too many pixels 1.15 initialize some fields for thread safety 1.14 fix threadsafe conversion bug; header-file-only version (#define STBI_HEADER_FILE_ONLY before including) @@ -397,7 +399,7 @@ __forceinline static int at_eof(stbi *s) if (s->img_file) return feof(s->img_file); #endif - return s->img_buffer >= s->img_buffer_end; + return s->img_buffer >= s->img_buffer_end; } __forceinline static uint8 get8u(stbi *s) @@ -1116,7 +1118,7 @@ static int process_marker(jpeg *z, int m) z->dequant[t][dezigzag[i]] = get8u(&z->s); #if STBI_SIMD for (i=0; i < 64; ++i) - z->dequant2[t][i] = dequant[t][i]; + z->dequant2[t][i] = z->dequant[t][i]; #endif L -= 65; } @@ -1382,7 +1384,7 @@ static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, in // 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) // VC6 without processor=Pro is generating multiple LEAs per multiply! -static void YCbCr_to_RGB_row(uint8 *out, uint8 *y, uint8 *pcb, uint8 *pcr, int count, int step) +static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) { int i; for (i=0; i < count; ++i) { @@ -1438,7 +1440,7 @@ typedef struct resample_row_func resample; uint8 *line0,*line1; int hs,vs; // expansion factor in each axis - int w_lores; // horizontal pixels pre-expansion + int w_lores; // horizontal pixels pre-expansion int ystep; // how far through vertical expansion we are int ypos; // which pre-expansion row we're on } stbi_resample; @@ -1616,7 +1618,7 @@ typedef struct int maxcode[17]; uint16 firstsymbol[16]; uint8 size[288]; - uint16 value[288]; + uint16 value[288]; } zhuffman; __forceinline static int bitreverse16(int n) @@ -1723,7 +1725,7 @@ __forceinline static unsigned int zreceive(zbuf *z, int n) k = z->code_buffer & ((1 << n) - 1); z->code_buffer >>= n; z->num_bits -= n; - return k; + return k; } __forceinline static int zhuffman_decode(zbuf *a, zhuffman *z) @@ -1815,7 +1817,7 @@ static int parse_huffman_block(zbuf *a) static int compute_huffman_codes(zbuf *a) { static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; - static zhuffman z_codelength; // static just to save stack space + zhuffman z_codelength; uint8 lencodes[286+32+137];//padding for maximum single op uint8 codelength_sizes[19]; int i,n; @@ -1913,6 +1915,7 @@ static void init_defaults(void) for (i=0; i <= 31; ++i) default_distance[i] = 5; } +int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead static int parse_zlib(zbuf *a, int parse_header) { int final, type; @@ -1938,6 +1941,8 @@ static int parse_zlib(zbuf *a, int parse_header) } if (!parse_huffman_block(a)) return 0; } + if (stbi_png_partial && a->zout - a->zout_start > 65536) + break; } while (!final); return 1; } @@ -2076,17 +2081,23 @@ static int paeth(int a, int b, int c) } // create the png data from post-deflated data -static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n) +static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) { stbi *s = &a->s; - uint32 i,j,stride = s->img_x*out_n; + uint32 i,j,stride = x*out_n; int k; int img_n = s->img_n; // copy it into a local for later assert(out_n == s->img_n || out_n == s->img_n+1); - a->out = (uint8 *) malloc(s->img_x * s->img_y * out_n); + if (stbi_png_partial) y = 1; + a->out = (uint8 *) malloc(x * y * out_n); if (!a->out) return e("outofmem", "Out of memory"); - if (raw_len != (img_n * s->img_x + 1) * s->img_y) return e("not enough pixels","Corrupt PNG"); - for (j=0; j < s->img_y; ++j) { + if (!stbi_png_partial) { + if (s->img_x == x && s->img_y == y) + if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + else // interlaced: + if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); + } + for (j=0; j < y; ++j) { uint8 *cur = a->out + stride*j; uint8 *prior = cur - stride; int filter = *raw++; @@ -2113,7 +2124,7 @@ static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n) if (img_n == out_n) { #define CASE(f) \ case f: \ - for (i=s->img_x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ + for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ for (k=0; k < img_n; ++k) switch(filter) { CASE(F_none) cur[k] = raw[k]; break; @@ -2129,7 +2140,7 @@ static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n) assert(img_n+1 == out_n); #define CASE(f) \ case f: \ - for (i=s->img_x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ + for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ for (k=0; k < img_n; ++k) switch(filter) { CASE(F_none) cur[k] = raw[k]; break; @@ -2146,6 +2157,47 @@ static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n) return 1; } +static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) +{ + uint8 *final; + int p; + int save; + if (!interlaced) + return create_png_image_raw(a, raw, raw_len, out_n, a->s.img_x, a->s.img_y); + save = stbi_png_partial; + stbi_png_partial = 0; + + // de-interlacing + final = (uint8 *) malloc(a->s.img_x * a->s.img_y * out_n); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s.img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s.img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { + free(final); + return 0; + } + for (j=0; j < y; ++j) + for (i=0; i < x; ++i) + memcpy(final + (j*yspc[p]+yorig[p])*a->s.img_x*out_n + (i*xspc[p]+xorig[p])*out_n, + a->out + (j*x+i)*out_n, out_n); + free(a->out); + raw += (x*out_n+1)*y; + raw_len -= (x*out_n+1)*y; + } + } + a->out = final; + + stbi_png_partial = save; + return 1; +} + static int compute_transparency(png *z, uint8 tc[3], int out_n) { stbi *s = &z->s; @@ -2210,7 +2262,7 @@ static int parse_png_file(png *z, int scan, int req_comp) uint8 palette[1024], pal_img_n=0; uint8 has_trans=0, tc[3]; uint32 ioff=0, idata_limit=0, i, pal_len=0; - int first=1,k; + int first=1,k,interlace=0; stbi *s = &z->s; if (!check_png_header(s)) return 0; @@ -2223,7 +2275,7 @@ static int parse_png_file(png *z, int scan, int req_comp) return e("first not IHDR","Corrupt PNG"); switch (c.type) { case PNG_TYPE('I','H','D','R'): { - int depth,color,interlace,comp,filter; + int depth,color,comp,filter; if (!first) return e("multiple IHDR","Corrupt PNG"); if (c.length != 13) return e("bad IHDR len","Corrupt PNG"); s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)"); @@ -2233,7 +2285,7 @@ static int parse_png_file(png *z, int scan, int req_comp) if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG"); comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG"); filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG"); - interlace = get8(s); if (interlace) return e("interlaced","PNG not supported: interlaced mode"); + interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG"); if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG"); if (!pal_img_n) { s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); @@ -2318,7 +2370,7 @@ static int parse_png_file(png *z, int scan, int req_comp) s->img_out_n = s->img_n+1; else s->img_out_n = s->img_n; - if (!create_png_image(z, z->expanded, raw_len, s->img_out_n)) return 0; + if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; if (has_trans) if (!compute_transparency(z, tc, s->img_out_n)) return 0; if (pal_img_n) { @@ -2428,7 +2480,23 @@ int stbi_png_test_memory(stbi_uc const *buffer, int len) // TODO: load header from png #ifndef STBI_NO_STDIO -extern int stbi_png_info (char const *filename, int *x, int *y, int *comp); +int stbi_png_info (char const *filename, int *x, int *y, int *comp) +{ + png p; + FILE *f = fopen(filename, "rb"); + if (!f) return 0; + start_file(&p.s, f); + if (parse_png_file(&p, SCAN_header, 0)) { + if(x) *x = p.s.img_x; + if(y) *y = p.s.img_y; + if (comp) *comp = p.s.img_n; + fclose(f); + return 1; + } + fclose(f); + return 0; +} + extern int stbi_png_info_from_file (FILE *f, int *x, int *y, int *comp); #endif extern int stbi_png_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp); @@ -2511,7 +2579,7 @@ static int shiftsigned(int v, int shift, int bits) static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) { uint8 *out; - unsigned int mr=0,mg=0,mb=0,ma=0; + unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; stbi_uc pal[256][4]; int psize=0,i,j,compress=0,width; int bpp, flip_vertically, pad, target, offset, hsz; @@ -2560,6 +2628,8 @@ static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) mr = 0xff << 16; mg = 0xff << 8; mb = 0xff << 0; + ma = 0xff << 24; + fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 } else { mr = 31 << 10; mg = 31 << 5; @@ -2674,7 +2744,7 @@ static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) out[z++] = shiftsigned(v & mg, gshift, gcount); out[z++] = shiftsigned(v & mb, bshift, bcount); a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); - if (target == 4) out[z++] = a; + if (target == 4) out[z++] = a; } } skip(s, pad); @@ -2791,7 +2861,7 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) unsigned char *tga_palette = NULL; int i, j; unsigned char raw_data[4]; - unsigned char trans_data[] = { 0,0,0,0 }; + unsigned char trans_data[4]; int RLE_count = 0; int RLE_repeating = 0; int read_next_pixel = 1; @@ -3070,7 +3140,7 @@ static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) // Read the rows and columns of the image. h = get32(s); w = get32(s); - + // Make sure the depth is 8 bits. if (get16(s) != 8) return epuc("unsupported bit depth", "PSD bit depth is not 8 bit"); @@ -3112,7 +3182,7 @@ static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) // Initialize the data to zero. //memset( out, 0, pixelCount * 4 ); - + // Finally, the image data. if (compression) { // RLE as used by .PSD and .TIFF @@ -3130,7 +3200,7 @@ static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) // Read the RLE data by channel. for (channel = 0; channel < 4; channel++) { uint8 *p; - + p = out+channel; if (channel >= channelCount) { // Fill this channel with default data. @@ -3168,15 +3238,15 @@ static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) } } } - + } else { // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) // where each channel consists of an 8-bit value for each pixel in the image. - + // Read the data by channel. for (channel = 0; channel < 4; channel++) { uint8 *p; - + p = out + channel; if (channel > channelCount) { // Fill this channel with default data. @@ -3198,7 +3268,7 @@ static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) if (comp) *comp = channelCount; *y = h; *x = w; - + return out; } @@ -3266,8 +3336,7 @@ int stbi_hdr_test_file(FILE *f) static char *hdr_gettoken(stbi *z, char *buffer) { int len=0; - //char *s = buffer, - char c = '\0'; + char *s = buffer, c = '\0'; c = get8(z); @@ -3330,7 +3399,7 @@ static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) // Check identifier if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) return epf("not HDR", "Corrupt HDR image"); - + // Parse header while(1) { token = hdr_gettoken(s,buffer); @@ -3394,7 +3463,7 @@ static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) len |= get8(s); if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR"); } if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4); - + for (k = 0; k < 4; ++k) { i = 0; while (i < width) { @@ -3606,7 +3675,7 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, uint32 zero = 0; int i,j,k, j_end; - if (vdir < 0) + if (vdir < 0) j_end = -1, j = y-1; else j_end = y, j = 0; diff --git a/Source/Core/VideoCommon/Src/HiresTextures.h b/Source/Core/VideoCommon/Src/HiresTextures.h index 80f9444ae7..0e65806085 100644 --- a/Source/Core/VideoCommon/Src/HiresTextures.h +++ b/Source/Core/VideoCommon/Src/HiresTextures.h @@ -27,6 +27,7 @@ namespace HiresTextures void Init(const char *gameCode); void Shutdown(); PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int texformat, u8 *data); + }; #endif // _HIRESTEXTURES_H diff --git a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp index e57b9600f8..9eb40f1b5c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp @@ -152,11 +152,13 @@ struct TabAdvanced : public W32Util::Tab Button_SetCheck(GetDlgItem(hDlg,IDC_SHOWSHADERERRORS), g_Config.bShowShaderErrors); Button_SetCheck(GetDlgItem(hDlg,IDC_DISABLEFOG), g_Config.bDisableFog); Button_SetCheck(GetDlgItem(hDlg,IDC_ENABLEEFBCOPY), !g_Config.bEFBCopyDisable); + if(g_Config.bCopyEFBToRAM) Button_SetCheck(GetDlgItem(hDlg,IDC_EFBTORAM), TRUE); else Button_SetCheck(GetDlgItem(hDlg,IDC_EFBTOTEX), TRUE); + Button_SetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY), g_Config.bTexFmtOverlayEnable); Button_SetCheck(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), g_Config.bTexFmtOverlayCenter); Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY)) ? Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), true) : Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), false); @@ -167,12 +169,6 @@ struct TabAdvanced : public W32Util::Tab { switch (LOWORD(wParam)) { - // case IDC_BROWSETEXDUMPPATH: <-- Old method - // { - // std::string path = W32Util::BrowseForFolder(hDlg,"Choose texture dump path:"); - // SetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH),path.c_str()); - // } - // break; case IDC_ENABLEEFBCOPY: { Button_GetCheck(GetDlgItem(hDlg,IDC_ENABLEEFBCOPY)) ? Button_Enable(GetDlgItem(hDlg,IDC_EFBTORAM), true) : Button_Enable(GetDlgItem(hDlg,IDC_EFBTORAM), false); @@ -203,9 +199,7 @@ struct TabAdvanced : public W32Util::Tab g_Config.bDisableFog = Button_GetCheck(GetDlgItem(hDlg,IDC_DISABLEFOG)) ? true : false; g_Config.bEFBCopyDisable = Button_GetCheck(GetDlgItem(hDlg,IDC_ENABLEEFBCOPY)) ? false : true; g_Config.bCopyEFBToRAM = Button_GetCheck(GetDlgItem(hDlg,IDC_EFBTORAM)) ? true : false; - //char temp[MAX_PATH]; - //GetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH), temp, MAX_PATH); <-- Old method - //g_Config.texDumpPath = temp; + g_Config.Save(FULL_CONFIG_DIR "gfx_dx9.ini"); if( D3D::dev != NULL ) { @@ -220,6 +214,9 @@ struct TabEnhancements : public W32Util::Tab { Button_SetCheck(GetDlgItem(hDlg,IDC_FORCEFILTERING),g_Config.bForceFiltering); Button_SetCheck(GetDlgItem(hDlg,IDC_FORCEANISOTROPY),g_Config.iMaxAnisotropy > 1); + Button_SetCheck(GetDlgItem(hDlg, IDC_LOADHIRESTEXTURE), g_Config.bHiresTextures); + Button_SetCheck(GetDlgItem(hDlg,IDC_EFBSCALEDCOPY), g_Config.bCopyEFBScaled); + /* Temporarily disabled the old postprocessing code since it wasn't working anyway. New postprocessing code will come sooner or later, sharing shaders and framework with @@ -254,6 +251,8 @@ struct TabEnhancements : public W32Util::Tab { g_Config.iMaxAnisotropy = Button_GetCheck(GetDlgItem(hDlg, IDC_FORCEANISOTROPY)) ? 8 : 1; g_Config.bForceFiltering = Button_GetCheck(GetDlgItem(hDlg, IDC_FORCEFILTERING)) ? true : false; + g_Config.bHiresTextures = Button_GetCheck(GetDlgItem(hDlg, IDC_LOADHIRESTEXTURE)) ? true : false; + g_Config.bCopyEFBScaled = Button_GetCheck(GetDlgItem(hDlg,IDC_EFBSCALEDCOPY)) ? true : false; g_Config.Save(FULL_CONFIG_DIR "gfx_dx9.ini"); } }; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp index 1abfebaf16..81cc1f1483 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp @@ -96,6 +96,7 @@ void Create() // Simplest possible setup to start with. int target_width = Renderer::GetTargetWidth(); int target_height = Renderer::GetTargetHeight(); + s_efb_color_surface_Format = D3DFMT_A8R8G8B8; //get the framebuffer texture HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format, diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 4f765d88d5..82db970ec6 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -38,6 +38,7 @@ #include "TextureDecoder.h" #include "TextureCache.h" +#include "HiresTextures.h" #include "debugger/debugger.h" @@ -66,6 +67,7 @@ void TextureCache::Init() { temp = (u8*)AllocateMemoryPages(TEMP_SIZE); TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter); + HiresTextures::Init(globals->unique_id); } void TextureCache::Invalidate(bool shutdown) @@ -73,6 +75,7 @@ void TextureCache::Invalidate(bool shutdown) for (TexCache::iterator iter = textures.begin(); iter != textures.end(); iter++) iter->second.Destroy(shutdown); textures.clear(); + HiresTextures::Shutdown(); } void TextureCache::InvalidateRange(u32 start_address, u32 size) @@ -305,7 +308,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, u32 texID = address; u32 texHash; - if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bDumpTextures) + if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures) { texHash = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, expandedHeight, tex_format, 0); if (g_ActiveConfig.bSafeTextureCache) @@ -359,8 +362,32 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, } } } - - PC_TexFormat pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, height, tex_format, tlutaddr, tlutfmt); + + //Make an entry in the table + TCacheEntry& entry = textures[texID]; + PC_TexFormat pcfmt = PC_TEX_FMT_NONE; + + if (g_ActiveConfig.bHiresTextures) + { + //Load Custom textures + char texPathTemp[MAX_PATH]; + int oldWidth = width; + int oldHeight = height; + + sprintf(texPathTemp, "%s_%08x_%i", globals->unique_id, texHash, tex_format); + pcfmt = HiresTextures::GetHiresTex(texPathTemp, &width, &height, tex_format, temp); + + if (pcfmt != PC_TEX_FMT_NONE) + { + expandedWidth = width; + expandedHeight = height; + entry.scaleX = (float) width / oldWidth; + entry.scaleY = (float) height / oldHeight; + } + } + + if(pcfmt == PC_TEX_FMT_NONE) + pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt); D3DFORMAT d3d_fmt; switch (pcfmt) { @@ -387,9 +414,6 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, d3d_fmt = D3DFMT_DXT1; break; } - - //Make an entry in the table - TCacheEntry& entry = textures[texID]; entry.oldpixel = ((u32 *)ptr)[0]; if (g_ActiveConfig.bSafeTextureCache) @@ -421,7 +445,9 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, char szDir[MAX_PATH]; const char* uniqueId = globals->unique_id; bool bCheckedDumpDir = false; + sprintf(szDir, "%s/%s", FULL_DUMP_TEXTURES_DIR, uniqueId); + if (!bCheckedDumpDir) { if (!File::Exists(szDir) || !File::IsDirectory(szDir)) @@ -429,8 +455,9 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, bCheckedDumpDir = true; } + sprintf(szTemp, "%s/%s_%08x_%i.png", szDir, uniqueId, texHash, tex_format); - //sprintf(szTemp, "%s\\txt_%04i_%i.png", g_Config.texDumpPath.c_str(), counter++, format); <-- Old method + if (!File::Exists(szTemp)) D3DXSaveTextureToFileA(szTemp,D3DXIFF_BMP,entry.texture,0); } @@ -503,7 +530,6 @@ have_texture: case 1: // Z8 colmat[0] = colmat[4] = colmat[8] = colmat[12] =1.0f; break; - case 3: // Z16 //? colmat[1] = colmat[5] = colmat[9] = colmat[12] = 1.0f; case 11: // Z16 (reverse order) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/resource.h b/Source/Plugins/Plugin_VideoDX9/Src/resource.h index 89cdab49e1..6bde8398fd 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/resource.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/resource.h @@ -35,6 +35,8 @@ #define IDC_TEXFMT_CENTER 1025 #define IDC_FORCEFILTERING 1026 #define IDC_FORCEANISOTROPY 1027 +#define IDC_LOADHIRESTEXTURE 1028 +#define IDC_EFBSCALEDCOPY 1029 #define IDC_CHECK1 1100 #define IDC_LIST1 1101 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/resource.rc b/Source/Plugins/Plugin_VideoDX9/Src/resource.rc index 8071279577..16e1331697 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/resource.rc +++ b/Source/Plugins/Plugin_VideoDX9/Src/resource.rc @@ -104,11 +104,16 @@ IDD_ENHANCEMENTS DIALOGEX 0, 0, 224, 175 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - GROUPBOX "Texture &filtering",IDC_STATIC,7,7,210,50 + GROUPBOX "Texture &filtering",IDC_STATIC,7,7,210,60 CONTROL "Force &bi/trilinear (breaks video in several Wii games)",IDC_FORCEFILTERING, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,20,192,9 CONTROL "Enable 16x &anisotropy filtering",IDC_FORCEANISOTROPY, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,35,110,10 + CONTROL "Enable hires texture loading", IDC_LOADHIRESTEXTURE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,50,110,11 + GROUPBOX "EFB Hacks",IDC_STATIC,7,70,210,60 + CONTROL "EFB Scaled Copy",IDC_EFBSCALEDCOPY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,80,110,12 END