From 44159ee3caafa1573e2d365cfb4f52765022f6d4 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 22 Feb 2009 12:28:18 +0200 Subject: [PATCH] imported winuaesrc1600b13.zip --- cpummu.c | 1 + custom.c | 66 ++++--- drawing.c | 9 +- include/custom.h | 13 +- include/sysdeps.h | 2 +- inputdevice.c | 28 ++- missing.c | 2 +- od-win32/clipboard_win32.c | 11 +- od-win32/direct3d.c | 5 +- od-win32/dxwrap.c | 14 +- od-win32/dxwrap.h | 1 + od-win32/opengl.c | 48 +++-- od-win32/resources/winuae.rc | 3 +- od-win32/sounddep/sound.c | 192 ++++++++++++++++++- od-win32/win32.c | 26 ++- od-win32/win32.h | 10 +- od-win32/win32_scale2x.c | 36 ++-- od-win32/win32gfx.c | 22 ++- od-win32/win32gui.c | 243 +++++++++++++++++++++--- od-win32/winuae_msvc/winuae_msvc.vcproj | 18 +- od-win32/winuaechangelog.txt | 29 ++- 21 files changed, 630 insertions(+), 149 deletions(-) diff --git a/cpummu.c b/cpummu.c index 092f886c..fae0dc21 100644 --- a/cpummu.c +++ b/cpummu.c @@ -27,6 +27,7 @@ #include "sysconfig.h" #include "sysdeps.h" +#include "options.h" #include "memory.h" #include "custom.h" #include "newcpu.h" diff --git a/custom.c b/custom.c index b7f42dd9..d0d1c5d4 100644 --- a/custom.c +++ b/custom.c @@ -236,11 +236,11 @@ int bpl_off[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static struct color_entry current_colors; static unsigned int bplcon0, bplcon1, bplcon2, bplcon3, bplcon4; -static unsigned int t_bplcon0_res, t_bplcon0_planes, t_bplcon0_planes_limit; +static unsigned int ta_bplcon0_res, td_bplcon0_res, t_bplcon0_planes, t_bplcon0_planes_limit; static unsigned int diwstrt, diwstop, diwhigh; static int diwhigh_written; static unsigned int ddfstrt, ddfstop, ddfstrt_old_hpos, ddfstrt_old_vpos; -static int ddf_change; +static int ddf_change, badmode; /* The display and data fetch windows */ @@ -301,7 +301,7 @@ static int copper_enabled_thisline; static int cop_min_waittime; static uae_u16 f_bplcon0, f_fmode; -static int f_bplcon0_res, f_bplcon0_planes, f_bplcon0_planes_limit; +static int fa_bplcon0_res, fd_bplcon0_res, f_bplcon0_planes, f_bplcon0_planes_limit; static int f_fetchunit, f_fetchunit_mask; static int f_fetchstart, f_fetchstart_mask, f_fetchstart_shift; static int f_fm_maxplane_shift, f_fm_maxplane; @@ -387,7 +387,7 @@ enum fetchstate { STATIC_INLINE int ecsshres(void) { - return f_bplcon0_res == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA); + return fd_bplcon0_res == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA); } STATIC_INLINE int nodraw (void) @@ -598,7 +598,7 @@ static int real_bitplane_number[3][3][9]; e.g. by the Sanity WOC demo (at the "Party Effect"). */ STATIC_INLINE int GET_PLANES_LIMIT (uae_u16 bc0) { - int res = GET_RES (bc0); + int res = GET_RES_AGNUS (bc0); int planes = GET_PLANES (bc0); return real_bitplane_number[f_fetchmode][res][planes]; } @@ -765,7 +765,7 @@ static int cycle_diagram_shift; static void estimate_last_fetch_cycle (int hpos) { - int fetchunit = fetchunits[f_fetchmode * 4 + f_bplcon0_res]; + int fetchunit = fetchunits[f_fetchmode * 4 + fa_bplcon0_res]; if (plfstate < plf_passed_stop) { int stop = plfstop < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop; @@ -848,7 +848,7 @@ static void record_color_change2 (int hpos, int regno, unsigned long value) // OCS/ECS, lores, 7 planes = 4 "real" planes + BPL5DAT and BPL6DAT as 5th and 6th plane STATIC_INLINE int isocs7planes (void) { - return !(currprefs.chipset_mask & CSMASK_AGA) && f_bplcon0_res == 0 && f_bplcon0_planes == 7; + return !(currprefs.chipset_mask & CSMASK_AGA) && fa_bplcon0_res == 0 && f_bplcon0_planes == 7; } static uae_u16 tmp_bplcon0, tmp_fmode; @@ -879,17 +879,18 @@ static void copy_bpl_params (int pos) f_fetchmode = 1; else f_fetchmode = 2; - f_bplcon0_res = GET_RES (f_bplcon0); + fa_bplcon0_res = GET_RES_AGNUS (f_bplcon0); + fd_bplcon0_res = GET_RES_DENISE (f_bplcon0); f_bplcon0_planes = GET_PLANES (f_bplcon0); f_bplcon0_planes_limit = GET_PLANES_LIMIT (f_bplcon0); - f_fetchunit = fetchunits[fetchmode * 4 + f_bplcon0_res]; + f_fetchunit = fetchunits[fetchmode * 4 + fa_bplcon0_res]; f_fetchunit_mask = t_fetchunit - 1; - f_fetchstart_shift = fetchstarts[f_fetchmode * 4 + f_bplcon0_res]; + f_fetchstart_shift = fetchstarts[f_fetchmode * 4 + fa_bplcon0_res]; f_fetchstart = 1 << t_fetchstart_shift; f_fetchstart_mask = t_fetchstart - 1; - f_fm_maxplane_shift = fm_maxplanes[f_fetchmode * 4 + f_bplcon0_res]; + f_fm_maxplane_shift = fm_maxplanes[f_fetchmode * 4 + fa_bplcon0_res]; f_fm_maxplane = 1 << f_fm_maxplane_shift; - curr_diagram = cycle_diagram_table[f_fetchmode][f_bplcon0_res][f_bplcon0_planes_limit]; + curr_diagram = cycle_diagram_table[f_fetchmode][fa_bplcon0_res][f_bplcon0_planes_limit]; f_fetch_modulo_cycle = t_fetchunit - f_fetchstart; if (toscr_nr_planes < f_bplcon0_planes_limit) toscr_nr_planes = f_bplcon0_planes_limit; @@ -899,17 +900,18 @@ static void copy_bpl_params (int pos) } else { toscr_nr_planes2 = toscr_nr_planes; } - toscr_res = f_bplcon0_res; + toscr_res = fd_bplcon0_res; } static void expand_fmodes (void) { - t_bplcon0_res = GET_RES (bplcon0); + ta_bplcon0_res = GET_RES_AGNUS (bplcon0); + td_bplcon0_res = GET_RES_DENISE (bplcon0); t_bplcon0_planes = GET_PLANES (bplcon0); t_bplcon0_planes_limit = GET_PLANES_LIMIT (bplcon0); - t_fetchunit = fetchunits[fetchmode * 4 + t_bplcon0_res]; + t_fetchunit = fetchunits[fetchmode * 4 + ta_bplcon0_res]; t_fetchunit_mask = t_fetchunit - 1; - t_fetchstart_shift = fetchstarts[fetchmode * 4 + t_bplcon0_res]; + t_fetchstart_shift = fetchstarts[fetchmode * 4 + ta_bplcon0_res]; t_fetchstart = 1 << t_fetchstart_shift; t_fetchstart_mask = t_fetchstart - 1; } @@ -935,7 +937,7 @@ static void compute_toscr_delay_1 (void) static void compute_toscr_delay (int hpos) { - toscr_res = f_bplcon0_res; + toscr_res = fd_bplcon0_res; toscr_nr_planes = f_bplcon0_planes_limit; toscr_nr_planes2 = f_bplcon0_planes; compute_toscr_delay_1 (); @@ -996,7 +998,7 @@ STATIC_INLINE void fetch (int nr, int fm) if (nr == 0) fetch_state = fetch_was_plane0; #if NEW_BPL - else if (nr == 1 && t_bplcon0_res > f_bplcon0_res) + else if (nr == 1 && ta_bplcon0_res > fa_bplcon0_res) fetch_state = fetch_was_plane0; #endif } @@ -1606,7 +1608,7 @@ STATIC_INLINE void update_fetch (int until, int fm) if (plfstate < plf_passed_stop && ddf_change != vpos && ddf_change + 1 != vpos && dma && (fetch_cycle & f_fetchstart_mask) == (f_fm_maxplane & f_fetchstart_mask) - && toscr_delay1 == toscr_delay1x && toscr_delay2 == toscr_delay2x + && toscr_delay1 == toscr_delay1x && toscr_delay2 == toscr_delay2x && badmode # if 0 /* @@@ We handle this case, but the code would be simpler if we * disallowed it - it may even be possible to guarantee that @@ -1714,7 +1716,7 @@ static void start_bpl_dma (int hpos, int hstart) out_nbits = 0; out_offs = 0; toscr_nbits = 0; - thisline_decision.bplres = f_bplcon0_res; + thisline_decision.bplres = fd_bplcon0_res; ddfstate = DIW_waiting_stop; compute_toscr_delay (last_fetch_hpos); @@ -1850,7 +1852,7 @@ static void record_register_change (int hpos, int regno, unsigned long value) thisline_decision.ham_seen = 1; if (hpos < HARD_DDF_START || hpos < plfstrt + 0x20) { thisline_decision.bplcon0 = value; - thisline_decision.bplres = GET_RES (value); + thisline_decision.bplres = GET_RES_DENISE (value); } } record_color_change (hpos, regno + 0x1000, value); @@ -1869,7 +1871,7 @@ static int expand_sprres (uae_u16 con0, uae_u16 con3) break; #ifdef ECS_DENISE case 0: /* ECS defaults (LORES,HIRES=LORES sprite,SHRES=HIRES sprite) */ - if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && GET_RES (con0) == RES_SUPERHIRES) + if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && GET_RES_DENISE (con0) == RES_SUPERHIRES) res = RES_HIRES; else res = RES_LORES; @@ -1893,7 +1895,7 @@ static int expand_sprres (uae_u16 con0, uae_u16 con3) /* handle very rarely needed playfield collision (CLXDAT bit 0) */ static void do_playfield_collisions (void) { - int bplres = t_bplcon0_res; + int bplres = td_bplcon0_res; hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres; hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword); hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword); @@ -1962,7 +1964,7 @@ static void do_sprite_collisions (void) int first = curr_drawinfo[next_lineno].first_sprite_entry; int i; unsigned int collision_mask = clxmask[clxcon >> 12]; - int bplres = t_bplcon0_res; + int bplres = td_bplcon0_res; hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres; hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword); hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword); @@ -2457,7 +2459,7 @@ static void reset_decisions (void) curr_diagram_change = -1; toscr_nr_planes = toscr_nr_planes2 = 0; - thisline_decision.bplres = t_bplcon0_res; + thisline_decision.bplres = td_bplcon0_res; thisline_decision.nr_planes = 0; thisline_decision.plfleft = -1; @@ -3168,7 +3170,7 @@ int is_bitplane_dma (int hpos) || hpos >= estimated_last_fetch_cycle) return 0; if (curr_diagram_change >= 0 && hpos >= curr_diagram_change) { - curr_diagram = cycle_diagram_table[fetchmode][t_bplcon0_res][t_bplcon0_planes_limit]; + curr_diagram = cycle_diagram_table[fetchmode][ta_bplcon0_res][t_bplcon0_planes_limit]; curr_diagram_change = -1; } return curr_diagram[(hpos - cycle_diagram_shift) & f_fetchstart_mask]; @@ -3182,7 +3184,7 @@ STATIC_INLINE int is_bitplane_dma_inline (int hpos) || hpos >= estimated_last_fetch_cycle) return 0; if (curr_diagram_change >= 0 && hpos >= curr_diagram_change) { - curr_diagram = cycle_diagram_table[fetchmode][t_bplcon0_res][t_bplcon0_planes_limit]; + curr_diagram = cycle_diagram_table[fetchmode][ta_bplcon0_res][t_bplcon0_planes_limit]; curr_diagram_change = -1; } return curr_diagram[(hpos - cycle_diagram_shift) & f_fetchstart_mask]; @@ -3246,6 +3248,8 @@ static void BPLCON0 (int hpos, uae_u16 v) decide_fetch (hpos); decide_blitter (hpos); + badmode = GET_RES_AGNUS (v) != GET_RES_DENISE (v); + // fake unused 0x0080 bit as an EHB bit (see below) if (isehb (v, bplcon2)) v |= 0x80; @@ -3254,7 +3258,7 @@ static void BPLCON0 (int hpos, uae_u16 v) record_register_change (hpos, 0x100, (bplcon0 & ~(0x800 | 0x400 | 0x80)) | (v & (0x0800 | 0x400 | 0x80))); // don't ask.. - if (GET_PLANES (v) > GET_PLANES (bplcon0) && GET_RES (v) >= GET_RES (bplcon0) && fetch_state != fetch_not_started) + if (GET_PLANES (v) > GET_PLANES (bplcon0) && GET_RES_AGNUS (v) >= GET_RES_AGNUS (bplcon0) && fetch_state != fetch_not_started) fetch_state = fetch_was_plane0; bplcon0 = v; @@ -3286,7 +3290,7 @@ static void BPLCON0 (int hpos, uae_u16 v) if (fetch_state == fetch_started && diwstate == DIW_waiting_stop) { curr_diagram_change = hpos - 2 + f_fm_maxplane - (fetch_cycle & f_fetchstart_mask); } else { - curr_diagram = cycle_diagram_table[fetchmode][t_bplcon0_res][t_bplcon0_planes_limit]; + curr_diagram = cycle_diagram_table[fetchmode][ta_bplcon0_res][t_bplcon0_planes_limit]; } } @@ -4968,8 +4972,8 @@ static void hsync_handler (void) if (!nocustom()) { if (!currprefs.blitter_cycle_exact && bltstate != BLT_done && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) { blitter_slowdown (thisline_decision.plfleft, thisline_decision.plfright - (16 << f_fetchmode), - cycle_diagram_total_cycles[f_fetchmode][GET_RES (f_bplcon0)][GET_PLANES_LIMIT (f_bplcon0)], - cycle_diagram_free_cycles[f_fetchmode][GET_RES (f_bplcon0)][GET_PLANES_LIMIT (f_bplcon0)]); + cycle_diagram_total_cycles[f_fetchmode][GET_RES_AGNUS (f_bplcon0)][GET_PLANES_LIMIT (f_bplcon0)], + cycle_diagram_free_cycles[f_fetchmode][GET_RES_AGNUS (f_bplcon0)][GET_PLANES_LIMIT (f_bplcon0)]); } hardware_line_completed (next_lineno); if (doflickerfix () && interlace_seen) diff --git a/drawing.c b/drawing.c index abd71a69..28547545 100644 --- a/drawing.c +++ b/drawing.c @@ -350,6 +350,13 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy) if (gclow > 0 && gcloh > 0) ret = -1; + if (doublescan <= 0) { + if (diwfirstword_total < (48 << currprefs.gfx_resolution)) + diwfirstword_total = 48 << currprefs.gfx_resolution; + if (diwlastword_total > (448 << currprefs.gfx_resolution)) + diwlastword_total = 448 << currprefs.gfx_resolution; + } + w = diwlastword_total - diwfirstword_total; dx = diwfirstword_total - visible_left_border; @@ -1834,7 +1841,7 @@ static void pfield_expand_dp_bplcon2 (int regno, int v) { case 0x100: dp_for_drawing->bplcon0 = v; - dp_for_drawing->bplres = GET_RES (v); + dp_for_drawing->bplres = GET_RES_DENISE (v); dp_for_drawing->nr_planes = GET_PLANES (v); dp_for_drawing->ham_seen = !! (v & 0x800); break; diff --git a/include/custom.h b/include/custom.h index d43d5c2a..fd7f241a 100644 --- a/include/custom.h +++ b/include/custom.h @@ -166,10 +166,17 @@ extern int bpl_off[8]; #define RES_SHIFT(res) ((res) == RES_LORES ? 8 : (res) == RES_HIRES ? 4 : 2) /* get resolution from bplcon0 */ -STATIC_INLINE int GET_RES (uae_u16 con0) +STATIC_INLINE int GET_RES_DENISE (uae_u16 con0) { - int res = ((con0) & 0x8000) ? RES_HIRES : ((con0) & 0x40) ? RES_SUPERHIRES : RES_LORES; - return res; + if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) + con0 &= ~0x40; + return ((con0) & 0x8000) ? RES_HIRES : ((con0) & 0x40) ? RES_SUPERHIRES : RES_LORES; +} +STATIC_INLINE int GET_RES_AGNUS (uae_u16 con0) +{ + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + con0 &= ~0x40; + return ((con0) & 0x8000) ? RES_HIRES : ((con0) & 0x40) ? RES_SUPERHIRES : RES_LORES; } /* get sprite width from FMODE */ #define GET_SPRITEWIDTH(FMODE) ((((FMODE) >> 2) & 3) == 3 ? 64 : (((FMODE) >> 2) & 3) == 0 ? 16 : 32) diff --git a/include/sysdeps.h b/include/sysdeps.h index 307500d6..5ccf2a37 100644 --- a/include/sysdeps.h +++ b/include/sysdeps.h @@ -230,7 +230,7 @@ extern char *my_strdup (const char*s); extern void *xmalloc(size_t); extern void *xcalloc(size_t, size_t); -extern void xfree(void*); +extern void xfree(const void*); /* We can only rely on GNU C getting enums right. Mickeysoft VSC++ is known * to have problems, and it's likely that other compilers choke too. */ diff --git a/inputdevice.c b/inputdevice.c index da23a7e9..2854faab 100644 --- a/inputdevice.c +++ b/inputdevice.c @@ -1161,7 +1161,6 @@ static void inputdevice_mh_abs (int x, int y) uae_u8 *p; uae_u8 tmp[4]; uae_u32 off; - int fdy, fdx, fmx, fmy; mousehack_enable (); off = 12 + get_long (rtarea_base + 36); @@ -1169,11 +1168,6 @@ static void inputdevice_mh_abs (int x, int y) memcpy (tmp, p + MH_ABSX, 4); - if (!picasso_on) { - getgfxoffset (&fdx, &fdy, &fmx, &fmy); - x -= fdx - 1; - y -= fdy - 1; - } x -= mouseoffset_x + 1; y -= mouseoffset_y + 2; @@ -1312,6 +1306,7 @@ static void inputdevice_mh_abs_v36 (int x, int y) static void mousehack_helper (void) { int x, y; + int fdy, fdx, fmx, fmy; if (currprefs.input_magic_mouse == 0 || currprefs.input_tablet < TABLET_MOUSEHACK) return; @@ -1321,15 +1316,28 @@ static void mousehack_helper (void) return; } #endif + x = lastmx; + y = lastmy; + getgfxoffset (&fdx, &fdy, &fmx, &fmy); + + #ifdef PICASSO96 if (picasso_on) { - x = lastmx - picasso96_state.XOffset; - y = lastmy - picasso96_state.YOffset; + x -= picasso96_state.XOffset; + y -= picasso96_state.YOffset; + x = x * fmx / 1000; + y = y * fmy / 1000; + x -= fdx * fmx / 1000; + y -= fdy * fmy / 1000; } else #endif { - x = coord_native_to_amiga_x (lastmx); - y = coord_native_to_amiga_y (lastmy) << 1; + x = x * fmx / 1000; + y = y * fmy / 1000; + x -= fdx * fmx / 1000 - 1; + y -= fdy * fmy / 1000 - 2; + x = coord_native_to_amiga_x (x); + y = coord_native_to_amiga_y (y) << 1; } inputdevice_mh_abs (x, y); } diff --git a/missing.c b/missing.c index 54863692..0b645346 100644 --- a/missing.c +++ b/missing.c @@ -35,7 +35,7 @@ void *xcalloc (size_t n, size_t size) return a; } -void xfree (void *p) +void xfree (const void *p) { free (p); diff --git a/od-win32/clipboard_win32.c b/od-win32/clipboard_win32.c index 3866f1ee..12018858 100644 --- a/od-win32/clipboard_win32.c +++ b/od-win32/clipboard_win32.c @@ -163,22 +163,23 @@ static void to_iff_text (char *pctxt) static int clipboard_put_text (const char *txt); static void from_iff_text (uaecptr ftxt, uae_u32 len) { - uae_u8 *addr, *eaddr; + uae_u8 *addr = NULL, *eaddr; char *txt = NULL; int txtsize = 0; char *pctxt; #if 0 { - FILE *f = fopen("c:\\d\\clipboard_a2p.000.dat", "rb"); + FILE *f = fopen("c:\\d\\clipboard_a2p.005.dat", "rb"); if (f) { addr = xmalloc (10000); len = fread (addr, 1, 10000, f); fclose (f); } } -#endif +#else addr = get_real_address (ftxt); +#endif eaddr = addr + len; if (memcmp ("FTXT", addr + 8, 4)) return; @@ -200,10 +201,12 @@ static void from_iff_text (uaecptr ftxt, uae_u32 len) else if (csize >= 1 && addr[-1] == 0x0d && addr[0] == 0x0a) addr++; } + if (txt == NULL) + txt = my_strdup (""); pctxt = amigatopc (txt); clipboard_put_text (pctxt); xfree (pctxt); - free (txt); + xfree (txt); } diff --git a/od-win32/direct3d.c b/od-win32/direct3d.c index ada70379..55d50f0d 100644 --- a/od-win32/direct3d.c +++ b/od-win32/direct3d.c @@ -723,6 +723,7 @@ static void setupscenecoords (void) getfilterrect2 (&dr, &sr, &zr, window_w, window_h, tin_w, tin_h, 1, tin_w, tin_h); // write_log ("(%d %d %d %d) - (%d %d %d %d) (%d %d)\n", // dr.left, dr.top, dr.right, dr.bottom, sr.left, sr.top, sr.right, sr.bottom, zr.left, zr.top); + dw = dr.right - dr.left; dh = dr.bottom - dr.top; w = sr.right - sr.left; @@ -732,8 +733,8 @@ static void setupscenecoords (void) MatrixOrthoOffCenterLH (&m_matProj, 0, w, 0, h, 0.0f, 1.0f); MatrixTranslation (&m_matView, - -0.5f + dw * tin_w / window_w / 2 - zr.left, // - (tin_w - 2 * zr.left - w), - 0.5f + dh * tin_h / window_h / 2 - zr.top - (tin_h - 2 * zr.top - h), // <- ??? + -0.5f + dw * tin_w / window_w / 2 - zr.left - sr.left, // - (tin_w - 2 * zr.left - w), + +0.5f + dh * tin_h / window_h / 2 - zr.top - (tin_h - 2 * zr.top - h) + sr.top, // <- ??? 0); MatrixScaling (&m_matWorld, diff --git a/od-win32/dxwrap.c b/od-win32/dxwrap.c index 084b5f01..207a02ee 100644 --- a/od-win32/dxwrap.c +++ b/od-win32/dxwrap.c @@ -750,7 +750,7 @@ int DirectDraw_BlitToPrimaryScale (RECT *dstrect, RECT *srcrect) return result; } -int DirectDraw_BlitToPrimary (RECT *rect) +static int DirectDraw_BlitToPrimary2 (RECT *rect, int dooffset) { LPDIRECTDRAWSURFACE7 dst; int result = 0; @@ -773,7 +773,8 @@ int DirectDraw_BlitToPrimary (RECT *rect) h = dxdata.sheight - y; SetRect (&srcrect, x, y, x + w, y + h); SetRect (&dstrect, x, y, x + w, y + h); - centerdstrect (&dstrect); + if (rect || dooffset) + centerdstrect (&dstrect); while (FAILED(ddrval = IDirectDrawSurface7_Blt (dst, &dstrect, dxdata.secondary, &srcrect, DDBLT_WAIT, NULL))) { if (ddrval == DDERR_SURFACELOST) { ddrval = restoresurfacex (dst, dxdata.secondary); @@ -789,6 +790,11 @@ int DirectDraw_BlitToPrimary (RECT *rect) return result; } +int DirectDraw_BlitToPrimary (RECT *rect) +{ + return DirectDraw_BlitToPrimary2 (rect, FALSE); +} + static int DirectDraw_Blt_EmuCK (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *srcrect) { DDSURFACEDESC2 dstd, srcd; @@ -878,7 +884,7 @@ int DirectDraw_BlitRectCK (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAW return DirectDraw_Blt (dst, dstrect, src, scrrect, TRUE); } -static void DirectDraw_FillSurface (LPDIRECTDRAWSURFACE7 dst, RECT *rect, uae_u32 color) +void DirectDraw_FillSurface (LPDIRECTDRAWSURFACE7 dst, RECT *rect, uae_u32 color) { HRESULT ddrval; DDBLTFX ddbltfx; @@ -968,7 +974,7 @@ int DirectDraw_Flip (int doflip) DirectDraw_Blit (dxdata.primary, getlocksurface ()); } } else { - DirectDraw_BlitToPrimary (NULL); + DirectDraw_BlitToPrimary2 (NULL, TRUE); } return 1; } diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 348ad72f..0ebe1614 100644 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -129,6 +129,7 @@ int DirectDraw_BlitToPrimaryScale (RECT *dstrect, RECT *srcrect); int DirectDraw_Blit (LPDIRECTDRAWSURFACE7 dst, LPDIRECTDRAWSURFACE7 src); int DirectDraw_BlitRect (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect); int DirectDraw_BlitRectCK (LPDIRECTDRAWSURFACE7 dst, RECT *dstrect, LPDIRECTDRAWSURFACE7 src, RECT *scrrect); +void DirectDraw_FillSurface (LPDIRECTDRAWSURFACE7 dst, RECT *rect, uae_u32 color); void DirectDraw_Fill (RECT *rect, uae_u32 color); void DirectDraw_FillPrimary (void); diff --git a/od-win32/opengl.c b/od-win32/opengl.c index 549a4bdf..49ba2168 100644 --- a/od-win32/opengl.c +++ b/od-win32/opengl.c @@ -464,21 +464,37 @@ void OGL_resize (int width, int height) static void OGL_dorender (int newtex) { uae_u8 *data = gfxvidinfo.bufmem; - float x1, y1, x2, y2; - -#if 0 - RECT sr, dr; - getfilterrect2 (&sr, &dr, w_width, w_height, t_width, t_height, 1, t_width, t_height); - xm = (float)required_texture_size / t_width; - ym = (float)required_texture_size / t_height; - - //write_log ("%fx%f\n", xm, ym); - - x1 = dr.left; - y1 = dr.top; - x2 = dr.right * xm; - y2 = dr.bottom * ym; - + float x1, y1, x2, y2, multx, multy; + +#if 1 + RECT sr, dr, zr; + float w, h; + float dw, dh; + + getfilterrect2 (&dr, &sr, &zr, w_width, w_height, t_width, t_height, 1, t_width, t_height); +// write_log ("(%d %d %d %d) - (%d %d %d %d) (%d %d)\n", +// dr.left, dr.top, dr.right, dr.bottom, sr.left, sr.top, sr.right, sr.bottom, zr.left, zr.top); + dw = dr.right - dr.left; + dh = dr.bottom - dr.top; + w = sr.right - sr.left; + h = sr.bottom - sr.top; + + multx = dw * t_width / w_width; + multy = dh * t_height / w_height; +// write_log ("%fx%f\n", multx, multy); + + x1 = -0.5f + dw * t_width / w_width / 2 - zr.left - sr.left; + y1 = 0.5f + dh * t_height / w_height / 2 - zr.top - (t_height - 2 * zr.top - h) + sr.top; + x1 -= (w * t_width / w_width) / 2; + y1 -= (h * t_height / w_height) / 2; + + x2 = x1 + dw * t_width / w_width; + y2 = y1 + dh * t_height / w_height; + + x1 *= (float)required_texture_size / t_width; + y1 *= (float)required_texture_size / t_height; + x2 *= (float)required_texture_size / t_width; + y2 *= (float)required_texture_size / t_height; #else double fx, fy, xm, ym; float multx, multy; @@ -524,7 +540,7 @@ static void OGL_dorender (int newtex) glLoadIdentity (); glBindTexture (GL_TEXTURE_2D, tex[0]); - if (newtex && gfxvidinfo.bufmem + t_width * t_height * t_depth / 8 <= gfxvidinfo.bufmemend) + if (newtex && data + t_width * t_height * t_depth / 8 <= gfxvidinfo.bufmemend) glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, t_width, t_height, ti2d_format, ti2d_type, data); glBegin (GL_QUADS); diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 91104a38..8cfb0d16 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -282,8 +282,7 @@ IDD_SOUND DIALOGEX 0, 0, 300, 231 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN - RTEXT "Sound device:",IDC_SOUNDCARD,8,9,51,13,SS_CENTERIMAGE - COMBOBOX IDC_SOUNDCARDLIST,64,9,229,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_SOUNDCARDLIST,5,9,291,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Sound Emulation",IDC_SOUNDSETTINGS,5,30,120,81 CONTROL "Disabled",IDC_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,45,101,10 CONTROL "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,57,102,10 diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index c12f7fb0..0217164c 100644 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -37,6 +37,8 @@ #include #include +#include + #include #define ADJUST_SIZE 30 @@ -71,11 +73,15 @@ struct sound_device sound_devices[MAX_SOUND_DEVICES]; struct sound_device record_devices[MAX_SOUND_DEVICES]; static int num_sound_devices, num_record_devices; +// directsound + static LPDIRECTSOUND8 lpDS; static LPDIRECTSOUNDBUFFER8 lpDSBsecondary; static DWORD writepos; +// openal + #define AL_BUFFERS 2 static ALCdevice *al_dev; static ALCcontext *al_ctx; @@ -87,6 +93,17 @@ static uae_u8 *al_bigbuffer; static int al_bufsize, al_offset; +// portaudio + +static volatile int patoggle; +static volatile int pacounter; +static uae_u8 *pasoundbuffer[2]; +static int pasndbufsize; +static int paframesperbuffer; +static PaStream *pastream; +static HANDLE paevent; + + int setup_sound (void) { sound_available = 1; @@ -161,6 +178,19 @@ static void resume_audio_ds (void) clearbuffer (); waiting_for_buffer = 1; } +static void pause_audio_pa (void) +{ + PaError err = Pa_StopStream (pastream); + if (err != paNoError) + write_log ("SOUND: Pa_StopStream() error %d (%s)\n", err, Pa_GetErrorText (err)); +} +static void resume_audio_pa (void) +{ + PaError err = Pa_StartStream (pastream); + if (err != paNoError) + write_log ("SOUND: Pa_StartStream() error %d (%s)\n", err, Pa_GetErrorText (err)); + paused = 0; +} static void pause_audio_al (void) { waiting_for_buffer = 0; @@ -318,6 +348,98 @@ DWORD fillsupportedmodes (LPDIRECTSOUND8 lpDS, int freq, struct dsaudiomodes *ds return speakerconfig; } + +static void finish_sound_buffer_pa (void) +{ + static int opacounter; + + while (opacounter == pacounter && pastream && !paused) + WaitForSingleObject (paevent, 10); + ResetEvent (paevent); + opacounter = pacounter; + memcpy (pasoundbuffer[patoggle], sndbuffer, sndbufsize); +} + +static int portAudioCallback (const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData) +{ + memcpy (outputBuffer, pasoundbuffer[patoggle], sndbufsize); + patoggle ^= 1; + pacounter++; + SetEvent (paevent); + return paContinue; +} + +static void close_audio_pa (void) +{ + int i; + + if (pastream) + Pa_CloseStream (pastream); + pastream = NULL; + for (i = 0; i < 2; i++) { + xfree (pasoundbuffer[i]); + pasoundbuffer[i] = NULL; + } + if (paevent) { + SetEvent (paevent); + CloseHandle (paevent); + } + paevent = NULL; +} + +static int open_audio_pa (int size) +{ + int i; + int freq = currprefs.sound_freq; + int ch = get_audio_nativechannels (); + int dev = sound_devices[currprefs.win32_soundcard].panum; + const PaDeviceInfo *di; + PaStreamParameters p; + PaError err; + + paframesperbuffer = size; + sndbufsize = size * ch * 2; + devicetype = SOUND_DEVICE_PA; + memset (&p, 0, sizeof p); + p.channelCount = ch; + p.device = dev; + p.hostApiSpecificStreamInfo = NULL; + p.sampleFormat = paInt16; + p.suggestedLatency = Pa_GetDeviceInfo (dev)->defaultLowOutputLatency; + p.hostApiSpecificStreamInfo = NULL; + for (;;) { + err = Pa_IsFormatSupported (NULL, &p, freq); + if (err == paFormatIsSupported) + break; + di = Pa_GetDeviceInfo (dev); + freq = di->defaultSampleRate; + err = Pa_IsFormatSupported (NULL, &p, freq); + if (err == paFormatIsSupported) { + currprefs.sound_freq = changed_prefs.sound_freq = freq; + break; + } + write_log ("SOUND: sound format not supported\n"); + goto end; + } + err = Pa_OpenStream (&pastream, NULL, &p, freq, paframesperbuffer, paNoFlag, portAudioCallback, NULL); + if (err != paNoError) { + write_log ("SOUND: Pa_OpenStream() error %d (%s)\n", err, Pa_GetErrorText (err)); + goto end; + } + paevent = CreateEvent (NULL, FALSE, FALSE, NULL); + for (i = 0; i < 2; i++) + pasoundbuffer[i] = xcalloc (sndbufsize, 1); + return 1; +end: + pastream = NULL; + close_audio_pa (); + return 0; +} + static void close_audio_al (void) { int i; @@ -342,7 +464,7 @@ static void close_audio_al (void) static int open_audio_al (int size) { int freq = currprefs.sound_freq; - int ch = get_audio_nativechannels(); + int ch = get_audio_nativechannels (); devicetype = SOUND_DEVICE_AL; size *= ch * 2; @@ -398,7 +520,7 @@ static int open_audio_ds (int size) WAVEFORMATEXTENSIBLE wavfmt; LPDIRECTSOUNDBUFFER pdsb; int freq = currprefs.sound_freq; - int ch = get_audio_nativechannels(); + int ch = get_audio_nativechannels (); int round, i; DWORD speakerconfig; @@ -560,6 +682,8 @@ static int open_sound (void) ret = open_audio_al (size); else if (sound_devices[currprefs.win32_soundcard].type == SOUND_DEVICE_DS) ret = open_audio_ds (size); + else if (sound_devices[currprefs.win32_soundcard].type == SOUND_DEVICE_PA) + ret = open_audio_pa (size); if (!ret) return 0; @@ -592,6 +716,8 @@ void close_sound (void) close_audio_al (); else if (devicetype == SOUND_DEVICE_DS) close_audio_ds (); + else if (devicetype == SOUND_DEVICE_PA) + close_audio_pa (); have_sound = 0; } @@ -624,6 +750,8 @@ void pause_sound (void) pause_audio_al (); else if (devicetype == SOUND_DEVICE_DS) pause_audio_ds (); + else if (devicetype == SOUND_DEVICE_PA) + pause_audio_pa (); } void resume_sound (void) @@ -636,6 +764,8 @@ void resume_sound (void) resume_audio_al (); else if (devicetype == SOUND_DEVICE_DS) resume_audio_ds (); + else if (devicetype == SOUND_DEVICE_PA) + resume_audio_pa (); } void reset_sound (void) @@ -1082,6 +1212,8 @@ void finish_sound_buffer (void) finish_sound_buffer_al (); else if (devicetype == SOUND_DEVICE_DS) finish_sound_buffer_ds (); + else if (devicetype == SOUND_DEVICE_PA) + finish_sound_buffer_pa (); } static BOOL CALLBACK DSEnumProc (LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext) @@ -1099,6 +1231,7 @@ static BOOL CALLBACK DSEnumProc (LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDr memcpy (&sd[i].guid, lpGUID, sizeof (GUID)); sd[i].name = my_strdup (lpszDesc); sd[i].type = SOUND_DEVICE_DS; + sd[i].cfgname = my_strdup (sd[i].name); return TRUE; } @@ -1151,6 +1284,7 @@ static void OpenALEnumerate (struct sound_device *sds, const char *pDeviceNames, sd->alname = my_strdup (pDeviceNames); sd->name = my_strdup (pDeviceNames); } + sd->cfgname = my_strdup (sd->alname); } if (ppDefaultDevice) ppDefaultDevice = NULL; @@ -1188,8 +1322,40 @@ static int isdllversion (const char *name, int version, int revision, int subver } return ok; } - - +#define PORTAUDIO 1 +#if PORTAUDIO +static void PortAudioEnumerate (struct sound_device *sds) +{ + struct sound_device *sd; + int num; + int i, j; + char tmp[MAX_DPATH]; + + num = Pa_GetDeviceCount (); + for (j = 0; j < num; j++) { + const PaDeviceInfo *di; + const PaHostApiInfo *hai; + di = Pa_GetDeviceInfo (j); + if (di->maxOutputChannels == 0) + continue; + hai = Pa_GetHostApiInfo (di->hostApi); + if (!hai) + continue; + for (i = 0; i < MAX_SOUND_DEVICES; i++) { + sd = &sds[i]; + if (sd->name == NULL) + break; + } + if (i >= MAX_SOUND_DEVICES) + return; + sprintf (tmp, "[%s] %s", hai->name, di->name); + sd->type = SOUND_DEVICE_PA; + sd->name = my_strdup (tmp); + sd->cfgname = my_strdup (tmp); + sd->panum = j; + } +} +#endif int enumerate_sound_devices (void) { if (!num_sound_devices) { @@ -1210,6 +1376,24 @@ int enumerate_sound_devices (void) OpenALEnumerate (record_devices, pDeviceNames, ppDefaultDevice, TRUE); } } +#if PORTAUDIO + { + HMODULE hm = WIN32_LoadLibrary ("portaudio_x86.dll"); + if (hm) { + PaError err; + write_log ("Enumerating PortAudio devices..\n"); + write_log ("%s (%d)\n", Pa_GetVersionText (), Pa_GetVersion ()); + err = Pa_Initialize (); + if (err == paNoError) { + PortAudioEnumerate (sound_devices); + } else { + write_log ("Portaudio initializiation failed: %d (%s)\n", + err, Pa_GetErrorText (err)); + FreeLibrary (hm); + } + } + } +#endif write_log("Enumeration end\n"); for (num_sound_devices = 0; num_sound_devices < MAX_SOUND_DEVICES; num_sound_devices++) { if (sound_devices[num_sound_devices].name == NULL) diff --git a/od-win32/win32.c b/od-win32/win32.c index 8a2da406..9d37b297 100644 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -2045,7 +2045,7 @@ void target_default_options (struct uae_prefs *p, int type) p->win32_automount_drives = 0; p->win32_automount_removabledrives = 0; p->win32_automount_cddrives = 0; - p->win32_automount_netdrives = 0; + p->win32_automount_netdrives = 0; p->win32_kbledmode = 0; p->win32_uaescsimode = get_aspi (p->win32_uaescsimode); p->win32_borderless = 0; @@ -2095,8 +2095,8 @@ void target_save_options (struct zfile *f, struct uae_prefs *p) cfgfile_target_dwrite (f, "iconified_pause=%s\n", p->win32_iconified_pause ? "true" : "false"); cfgfile_target_dwrite (f, "ctrl_f11_is_quit=%s\n", p->win32_ctrl_F11_is_quit ? "true" : "false"); - cfgfile_target_dwrite (f, "midiout_device=%d\n", p->win32_midioutdev ); - cfgfile_target_dwrite (f, "midiin_device=%d\n", p->win32_midiindev ); + cfgfile_target_dwrite (f, "midiout_device=%d\n", p->win32_midioutdev); + cfgfile_target_dwrite (f, "midiin_device=%d\n", p->win32_midiindev); cfgfile_target_dwrite (f, "rtg_match_depth=%s\n", p->win32_rtgmatchdepth ? "true" : "false"); cfgfile_target_dwrite (f, "rtg_scale_small=%s\n", p->win32_rtgscaleifsmall ? "true" : "false"); cfgfile_target_dwrite (f, "rtg_scale_allow=%s\n", p->win32_rtgallowscaling ? "true" : "false"); @@ -2110,6 +2110,8 @@ void target_save_options (struct zfile *f, struct uae_prefs *p) cfgfile_target_dwrite (f, "borderless=%s\n", p->win32_borderless ? "true" : "false"); cfgfile_target_dwrite (f, "uaescsimode=%s\n", scsimode[p->win32_uaescsimode]); cfgfile_target_dwrite (f, "soundcard=%d\n", p->win32_soundcard); + if (sound_devices[p->win32_soundcard].cfgname) + cfgfile_target_dwrite (f, "soundcardname=%s\n", sound_devices[p->win32_soundcard].cfgname); cfgfile_target_dwrite (f, "cpu_idle=%d\n", p->cpu_idle); cfgfile_target_dwrite (f, "notaskbarbutton=%s\n", p->win32_notaskbarbutton ? "true" : "false"); cfgfile_target_dwrite (f, "always_on_top=%s\n", p->win32_alwaysontop ? "true" : "false"); @@ -2178,6 +2180,17 @@ int target_parse_option (struct uae_prefs *p, char *option, char *value) if (cfgfile_yesno (option, value, "rtg_scale_allow", &p->win32_rtgallowscaling)) return 1; + if (cfgfile_string (option, value, "soundcardname", tmpbuf, sizeof tmpbuf)) { + int i; + for (i = 0; sound_devices[i].cfgname; i++) { + if (!strcmp (sound_devices[i].cfgname, tmpbuf)) { + p->win32_soundcard = i; + break; + } + } + return 1; + } + if (cfgfile_yesno (option, value, "aspi", &v)) { p->win32_uaescsimode = 0; if (v) @@ -2226,7 +2239,6 @@ int target_parse_option (struct uae_prefs *p, char *option, char *value) if (cfgfile_strval (option, value, "uaescsimode", &p->win32_uaescsimode, scsimode, 0)) return 1; - if (cfgfile_intval (option, value, "active_priority", &v, 1)) { p->win32_active_priority = fetchpri (v, 1); return 1; @@ -3675,11 +3687,13 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR write_log ("Display buffer mode = %d\n", ddforceram); enumerate_sound_devices (); for (i = 0; sound_devices[i].name; i++) { - write_log ("%d:%s: %s\n", i, sound_devices[i].type == SOUND_DEVICE_DS ? "DS" : "AL", sound_devices[i].name); + int type = sound_devices[i].type; + write_log ("%d:%s: %s\n", i, type == SOUND_DEVICE_DS ? "DS" : (type == SOUND_DEVICE_AL ? "AL" : "PA"), sound_devices[i].name); } write_log ("Enumerating recording devices:\n"); for (i = 0; record_devices[i].name; i++) { - write_log ("%d:%s: %s\n", i, record_devices[i].type == SOUND_DEVICE_DS ? "DS" : "AL", record_devices[i].name); + int type = record_devices[i].type; + write_log ("%d:%s: %s\n", i, type == SOUND_DEVICE_DS ? "DS" : (type == SOUND_DEVICE_AL ? "AL" : "PA"), record_devices[i].name); } write_log ("done\n"); memset (&devmode, 0, sizeof (devmode)); diff --git a/od-win32/win32.h b/od-win32/win32.h index 4b84833f..77ca7579 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -17,8 +17,8 @@ #define WINUAEPUBLICBETA 1 -#define WINUAEBETA "12" -#define WINUAEDATE MAKEBD(2009, 2, 14) +#define WINUAEBETA "13" +#define WINUAEDATE MAKEBD(2009, 2, 22) #define WINUAEEXTRA "" #define WINUAEREV "" @@ -147,14 +147,18 @@ extern void logging_cleanup (void); extern LONG WINAPI WIN32_ExceptionFilter (struct _EXCEPTION_POINTERS *pExceptionPointers, DWORD ec); -#define MAX_SOUND_DEVICES 20 +#define MAX_SOUND_DEVICES 32 #define SOUND_DEVICE_DS 1 #define SOUND_DEVICE_AL 2 +#define SOUND_DEVICE_PA 3 + struct sound_device { GUID guid; char *name; char *alname; + char *cfgname; + int panum; int type; }; extern struct sound_device sound_devices[MAX_SOUND_DEVICES]; diff --git a/od-win32/win32_scale2x.c b/od-win32/win32_scale2x.c index d23c667a..3433eebb 100644 --- a/od-win32/win32_scale2x.c +++ b/od-win32/win32_scale2x.c @@ -113,6 +113,9 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height dr->right = dr->left + dst_width; dr->bottom = dr->top + dst_height; + filteroffsetx = 0; + filteroffsety = 0; + xmult = currprefs.gfx_filter_horiz_zoom_mult; ymult = currprefs.gfx_filter_vert_zoom_mult; if (currprefs.gfx_filter_autoscale) { @@ -123,8 +126,6 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height filterxmult = 1000 / scale; filterymult = 1000 / scale; - filteroffsetx = 0; - filteroffsety = 0; xmult = 1000; ymult = 1000; @@ -209,15 +210,23 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height filteroffsety = -zr->top / scale; if (currprefs.gfx_filter_keep_aspect || currprefs.gfx_filter_aspect > 0) { - int xratio = dst_width * 256 / cw; - int yratio = dst_height * 256 / ch; + int dw = dst_width; + int dh = dst_height; + int xratio, yratio; int diffx = dr->right - dr->left; int diffy = dr->bottom - dr->top; - + + xratio = dw * 256 / cw; + yratio = dh * 256 / ch; if (currprefs.gfx_filter_aspect > 0) { int xm = (currprefs.gfx_filter_aspect >> 8) * 256; int ym = (currprefs.gfx_filter_aspect & 0xff) * 256; - xratio = xratio * ((dst_width * ym * 256) / (dst_height * xm)) / 256; + int mult = currprefs.gfx_resolution - (currprefs.gfx_linedbl ? 1 : 0); + if (mult < 0) + xm *= 1 << (-mult); + else + ym *= 1 << mult; + xratio = xratio * ((dw * ym * 256) / (dh * xm)) / 256; } if (xratio > yratio) { @@ -256,15 +265,18 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height else ymult = ymult + ymult * currprefs.gfx_filter_vert_zoom / 2000; } - + if (currprefs.gfx_filter_aspect > 0) { int srcratio, dstratio; + int xmult2 = xmult; + int ymult2 = ymult; dstratio = (currprefs.gfx_filter_aspect >> 8) * 256 / (currprefs.gfx_filter_aspect & 0xff); srcratio = dst_width * 256 / dst_height; - if (srcratio > dstratio) + if (srcratio > dstratio) { xmult = xmult * srcratio / dstratio; - else + } else { ymult = ymult * dstratio / srcratio; + } } v = currprefs.gfx_filter ? currprefs.gfx_filter_horiz_offset : 0; @@ -278,8 +290,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height filterxmult = xmult; filterymult = ymult; - filteroffsetx = (dst_width - amiga_width * 1000 / filterxmult) / 2; - filteroffsety = (dst_height - amiga_height * 1000 / filterymult) / 2; + filteroffsetx += (dst_width - aw * 1000 / filterxmult) / 2; + filteroffsety += (dst_height - ah * 1000 / filterymult) / 2; } @@ -554,7 +566,7 @@ endfail: end: unlocksurface (tempsurf); - getfilterrect2 (&dr, &sr, &zr, dst_width, dst_height, amiga_width, amiga_height, scale, temp_width, temp_height); + getfilterrect2 (&dr, &sr, &zr, dst_width, dst_height, aw, ah, scale, temp_width, temp_height); //write_log ("(%d %d %d %d) - (%d %d %d %d) (%d %d)\n", dr.left, dr.top, dr.right, dr.bottom, sr.left, sr.top, sr.right, sr.bottom, zr.left, zr.top); OffsetRect (&sr, zr.left, zr.top); if (sr.left >= 0 && sr.top >= 0 && sr.right < temp_width && sr.bottom < temp_height) { diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index 3fbfec4b..33506d78 100644 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -132,6 +132,11 @@ int isscreen (void) return hMainWnd ? 1 : 0; } +static void clearscreen (void) +{ + DirectDraw_FillPrimary (); +} + static int isfullscreen_2 (struct uae_prefs *p) { if (screen_is_picasso) @@ -1096,9 +1101,9 @@ int check_prefs_changed_gfx (void) c |= currprefs.win32_notaskbarbutton != changed_prefs.win32_notaskbarbutton ? 32 : 0; c |= currprefs.win32_borderless != changed_prefs.win32_borderless ? 32 : 0; c |= currprefs.win32_rtgmatchdepth != changed_prefs.win32_rtgmatchdepth ? 2 : 0; - c |= currprefs.win32_rtgscaleifsmall != changed_prefs.win32_rtgscaleifsmall ? 8 : 0; - c |= currprefs.win32_rtgallowscaling != changed_prefs.win32_rtgallowscaling ? 8 : 0; - c |= currprefs.win32_rtgscaleaspectratio != changed_prefs.win32_rtgscaleaspectratio ? 8 : 0; + c |= currprefs.win32_rtgscaleifsmall != changed_prefs.win32_rtgscaleifsmall ? (8 | 64) : 0; + c |= currprefs.win32_rtgallowscaling != changed_prefs.win32_rtgallowscaling ? (8 | 64) : 0; + c |= currprefs.win32_rtgscaleaspectratio != changed_prefs.win32_rtgscaleaspectratio ? (8 | 64) : 0; c |= currprefs.win32_rtgvblankrate != changed_prefs.win32_rtgvblankrate ? 8 : 0; if (display_change_requested || c) @@ -1164,6 +1169,10 @@ int check_prefs_changed_gfx (void) currprefs.win32_rtgvblankrate = changed_prefs.win32_rtgvblankrate; inputdevice_unacquire (); + if (c & 64) { + DirectDraw_Fill (NULL, 0); + DirectDraw_BlitToPrimary (NULL); + } if ((c & 16) || ((c & 8) && keepfsmode)) { extern int reopen (int); if (reopen (c & 2)) @@ -1563,6 +1572,8 @@ static int modeswitchneeded (struct winuae_currentmode *wc) return -1; } else { /* fullwindow to fullwindow */ + DirectDraw_Fill (NULL, 0); + DirectDraw_BlitToPrimary (NULL); if (screen_is_picasso) { if (currprefs.win32_rtgscaleifsmall && (wc->native_width > picasso96_state.Width || wc->native_height > picasso96_state.Height)) return -1; @@ -1574,11 +1585,6 @@ static int modeswitchneeded (struct winuae_currentmode *wc) return 0; } -static void clearscreen (void) -{ - DirectDraw_FillPrimary (); -} - void gfx_set_picasso_state (int on) { struct winuae_currentmode wc; diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 67c72fac..53d89652 100644 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -1307,31 +1307,205 @@ static void gui_to_prefs (void) updatewinfsmode (&changed_prefs); } -typedef struct tagOFNX { - DWORD lStructSize; - HWND hwndOwner; - HINSTANCE hInstance; - PWCHAR lpstrFilter; - PWCHAR lpstrCustomFilter; - DWORD nMaxCustFilter; - DWORD nFilterIndex; - PWCHAR lpstrFile; - DWORD nMaxFile; - PWCHAR lpstrFileTitle; - DWORD nMaxFileTitle; - PWCHAR lpstrInitialDir; - PWCHAR lpstrTitle; - DWORD Flags; - WORD nFileOffset; - WORD nFileExtension; - PWCHAR lpstrDefExt; - LPARAM lCustData; - LPOFNHOOKPROC lpfnHook; - PWCHAR lpTemplateName; - void * pvReserved; - DWORD dwReserved; - DWORD FlagsEx; -} OPENFILENAMEX, *LPOPENFILENAMEX; +static char *getfilepath (char *s) +{ + char *p = strrchr (s, '\\'); + if (p) + return p + 1; + return NULL; +} + +typedef HRESULT (CALLBACK* SHCREATEITEMFROMPARSINGNAME) + (PCWSTR,IBindCtx*,REFIID,void**); // Vista+ only + +// OPENFILENAME->IFileOpenDialog wrapper +static BOOL GetFileDialog (OPENFILENAME *opn, const GUID *guid, int save) +{ + SHCREATEITEMFROMPARSINGNAME pSHCreateItemFromParsingName; + WCHAR *title = NULL; + WCHAR *defext = NULL; + WCHAR *initialdir = NULL; + HRESULT hr; + IFileOpenDialog *pfd; + FILEOPENDIALOGOPTIONS pfos; + IShellItem *shellitem = NULL; + int ret; + COMDLG_FILTERSPEC *fs = NULL; + int filtercnt = 0; + + ret = 0; + pSHCreateItemFromParsingName = (SHCREATEITEMFROMPARSINGNAME)GetProcAddress ( + GetModuleHandle ("shell32.dll"), "SHCreateItemFromParsingName"); + if (pSHCreateItemFromParsingName == NULL) { + if (save) + return GetSaveFileName (opn); + else + return GetOpenFileName (opn); + } + hr = CoCreateInstance (&CLSID_FileOpenDialog, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IFileOpenDialog, (LPVOID*)&pfd); + if (FAILED (hr)) { + if (save) + return GetSaveFileName (opn); + else + return GetOpenFileName (opn); + } + IFileDialog_GetOptions (pfd, &pfos); + pfos |= FOS_FORCEFILESYSTEM; + if (opn->Flags & OFN_ALLOWMULTISELECT) + pfos |= FOS_ALLOWMULTISELECT; + IFileDialog_SetOptions (pfd, pfos); + + if (guid) + IFileDialog_SetClientGuid (pfd, guid); + + if (opn->lpstrFilter) { + const char *p = opn->lpstrFilter; + int i; + while (*p) { + p += strlen (p) + 1; + p += strlen (p) + 1; + filtercnt++; + } + if (filtercnt) { + fs = xmalloc (sizeof (COMDLG_FILTERSPEC) * filtercnt); + p = opn->lpstrFilter; + for (i = 0; i < filtercnt; i++) { + fs[i].pszName = au (p); + p += strlen (p) + 1; + fs[i].pszSpec = au (p); + p += strlen (p) + 1; + } + IFileDialog_SetFileTypes (pfd, filtercnt, fs); + } + IFileOpenDialog_SetFileTypeIndex (pfd, opn->nFilterIndex); + } + + if (opn->lpstrTitle) { + title = au (opn->lpstrTitle); + IFileDialog_SetTitle (pfd, title); + } + if (opn->lpstrDefExt) { + defext = au (opn->lpstrDefExt); + IFileDialog_SetDefaultExtension (pfd, defext); + } + if (opn->lpstrInitialDir) { + char tmp[MAX_DPATH]; + const char *p = opn->lpstrInitialDir; + if (GetFullPathName (p, sizeof tmp, tmp, NULL)) + p = tmp; + initialdir = au (p); + hr = pSHCreateItemFromParsingName (initialdir, NULL, &IID_IShellItem, &shellitem); + if (SUCCEEDED (hr)) + IFileDialog_SetFolder (pfd, shellitem); + } + + hr = IFileDialog_Show (pfd, opn->hwndOwner); + if (SUCCEEDED (hr)) { + UINT idx; + IShellItemArray *pitema; + opn->lpstrFile[0] = 0; + opn->lpstrFile[1] = 0; + if (opn->lpstrFileTitle) + opn->lpstrFileTitle[0] = 0; + if (save) { + IShellItem *pitem; + hr = IFileOpenDialog_GetResult (pfd, &pitem); + if (SUCCEEDED (hr)) { + WCHAR *path = NULL; + hr = IShellItem_GetDisplayName (pitem, SIGDN_FILESYSPATH, &path); + if (SUCCEEDED (hr)) { + char *spath = ua (path); + char *p = opn->lpstrFile; + strcpy (p, spath); + p[strlen (p) + 1] = 0; + xfree (spath); + p = getfilepath (opn->lpstrFile); + if (p && opn->lpstrFileTitle) + strcpy (opn->lpstrFileTitle, p); + } + IShellItem_Release (pitem); + } + } else { + hr = IFileOpenDialog_GetResults (pfd, &pitema); + if (SUCCEEDED (hr)) { + DWORD cnt; + hr = IShellItemArray_GetCount (pitema, &cnt); + if (SUCCEEDED (hr)) { + int i; + for (i = 0; i < cnt; i++) { + IShellItem *pitem; + hr = IShellItemArray_GetItemAt (pitema, i, &pitem); + if (SUCCEEDED (hr)) { + WCHAR *path = NULL; + hr = IShellItem_GetDisplayName (pitem, SIGDN_FILESYSPATH, &path); + if (SUCCEEDED (hr)) { + char *spath = ua (path); + char *p = opn->lpstrFile; + while (*p) + p += strlen (p) + 1; + if (p - opn->lpstrFile + strlen (spath) + 2 < opn->nMaxFile) { + strcpy (p, spath); + p[strlen (p) + 1] = 0; + } + xfree (spath); + if (!opn->lpstrFileTitle[0]) { + p = getfilepath (opn->lpstrFile); + if (p && opn->lpstrFileTitle) + strcpy (opn->lpstrFileTitle, p); + } + } + CoTaskMemFree (path); + } + } + } + IShellItemArray_Release (pitema); + } + } + hr = IFileOpenDialog_GetFileTypeIndex (pfd, &idx); + if (SUCCEEDED (hr)) + opn->nFilterIndex = idx; + ret = 1; + } + + + IFileDialog_Release (pfd); + if (shellitem) + IShellItem_Release (shellitem); + if (filtercnt) { + int i; + for (i = 0; i < filtercnt; i++) { + xfree (fs[i].pszName); + xfree (fs[i].pszSpec); + } + xfree (fs); + } + xfree (title); + xfree (defext); + xfree (initialdir); + return ret; +} + +static BOOL GetOpenFileName_2 (OPENFILENAME *opn, const GUID *guid) +{ + return GetFileDialog (opn, guid, 0); +} +static BOOL GetSaveFileName_2 (OPENFILENAME *opn, const GUID *guid) +{ + return GetFileDialog (opn, guid, 1); +} + + +static const GUID diskselectionguids[] = { + { 0x4fa8fa15, 0xc209, 0x4112, { 0x94, 0x7b, 0xc6, 0x00, 0x8e, 0x1f, 0xa3, 0x29 } }, + { 0x32073f09, 0x752d, 0x4783, { 0x84, 0x6c, 0xaa, 0x66, 0x48, 0x84, 0x14, 0x45 } }, + { 0x8047f7ea, 0x8a42, 0x4695, { 0x94, 0x52, 0xf5, 0x0d, 0xb8, 0x43, 0x00, 0x58 } }, + { 0x2412c4e7, 0xf608, 0x4333, { 0x83, 0xd2, 0xa1, 0x2f, 0xdf, 0x66, 0xac, 0xe5 } }, + { 0xe3741dff, 0x11f2, 0x445f, { 0x94, 0xb0, 0xa3, 0xe7, 0x58, 0xe2, 0xcb, 0xb5 } }, + { 0x2056d641, 0xba13, 0x4312, { 0xaa, 0x75, 0xc5, 0xeb, 0x52, 0xa8, 0x1c, 0xe3 } } +}; // Common routine for popping up a file-requester // flag - 0 for floppy loading, 1 for floppy creation, 2 for loading hdf, 3 for saving hdf @@ -1362,6 +1536,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs int all = 1; int next; int nosavepath = 0; + const GUID *guid = NULL; char szTitle[MAX_DPATH] = { 0 }; char szFormat[MAX_DPATH]; @@ -1379,20 +1554,24 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs case 0: case 1: fetch_path ("FloppyPath", init_path, sizeof (init_path)); + guid = &diskselectionguids[0]; break; case 2: case 3: fetch_path ("hdfPath", init_path, sizeof (init_path)); + guid = &diskselectionguids[1]; break; case 6: case 7: case 11: fetch_path ("KickstartPath", init_path, sizeof (init_path)); + guid = &diskselectionguids[2]; break; case 4: case 5: case 8: fetch_path ("ConfigurationPath", init_path, sizeof (init_path)); + guid = &diskselectionguids[3]; break; case 9: case 10: @@ -1416,11 +1595,13 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs } if (!ok) fetch_path ("StatefilePath", init_path, sizeof (init_path)); + guid = &diskselectionguids[4]; } break; case 15: case 16: fetch_path ("InputPath", init_path, sizeof (init_path)); + guid = &diskselectionguids[5]; break; } } @@ -1573,11 +1754,11 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs if (multi) openFileName.Flags |= OFN_ALLOWMULTISELECT; if (flag == 1 || flag == 3 || flag == 5 || flag == 9 || flag == 11 || flag == 16) { - if (!(result = GetSaveFileName (&openFileName))) - write_log ("GetSaveFileName() failed, err=%d.\n", GetLastError()); + if (!(result = GetSaveFileName_2 (&openFileName, guid))) + write_log ("GetSaveFileNameX() failed, err=%d.\n", GetLastError()); } else { - if (!(result = GetOpenFileName (&openFileName))) - write_log ("GetOpenFileName() failed, err=%d.\n", GetLastError()); + if (!(result = GetOpenFileName_2 (&openFileName, guid))) + write_log ("GetOpenFileNameX() failed, err=%d.\n", GetLastError()); } previousfilter[flag] = openFileName.nFilterIndex; @@ -7067,8 +7248,10 @@ static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM } for (card = 0; card < numdevs; card++) { char tmp[MAX_DPATH]; + int type = sound_devices[card].type; if (gotnonds) - sprintf (tmp, "%s: %s", sound_devices[card].type == SOUND_DEVICE_DS ? "DS" : "AL", sound_devices[card].name); + sprintf (tmp, "%s: %s", type == SOUND_DEVICE_DS ? "DS" : (type == SOUND_DEVICE_AL ? "AL" : "PA"), + sound_devices[card].name); else strcpy (tmp, sound_devices[card].name); SendDlgItemMessage (hDlg, IDC_SOUNDCARDLIST, CB_ADDSTRING, 0, (LPARAM)tmp); diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index ab4ee6e4..e1bf8f52 100644 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -52,7 +52,7 @@ AdditionalOptions="" Optimization="0" AdditionalIncludeDirectories="..\..\include,..\..,..\,..\resources,..\osdep,..\sounddep,..\..\prowizard\include,..\tun" - PreprocessorDefinitions="WINVER=0x0500,_DEBUG,WIN32_IE=0x0501;WIN32" + PreprocessorDefinitions="WINVER=0x0500,_DEBUG,WIN32_IE=0x0700;WIN32;CINTERFACE;COBJMACROS" GeneratePreprocessedFile="0" KeepComments="false" ExceptionHandling="0" @@ -86,13 +86,13 @@ native switches didn't clear + old graphics completely +- unofficial/experimental PortAudio audio library support, copy dll + (portaudio_x86.dll) to plugins-directory. Main point is very low + latency sound API (ASIO, WDM-KS, WASAPI) support. WDM-KS (XP) not + tested, WASAPI (VistaSP1/W7 only) confirmed working. Generally + can be ignored, do not ask :) +- file selection dialog uses new IFileDialog interface (if available, + Vista or newer only) Dialogs still should look same, shout if + something looks weird. (currently this is my workaround for + Windows 7b feature/bug of remembering old directory, even if + OPENFILENAME structure has lpstrInitialDir set) +- automatic scaling update, very large DIWSTRT/DIWSTOP values are + clipped to max overscan size when calculating display size + (some demos had really wide autoscaling) +- fixed autoscaling + aspect ratio set + resolution/linedoubling ratio + not 1:1 (for example lores + doubling) = wrong aspect ratio. +- clipboard Amiga->PC conversion crashed if clipboard contained no + text data (empty FORM FTXT structure without data content) + + Beta 12: - file comment was not reset when file already existed and file was @@ -113,7 +138,7 @@ Beta 7: - PAL/NTSC switching in KS3.x early boot screen was ignored until following reboot (old bug) - do not report no_cd-status when loading CD32 statefile without CD - installed + inserted - doublescan modes autoscale/resize better - improved Amiga display size detection - autoscale option saved to configuration file @@ -305,7 +330,7 @@ Beta 2: - fixed b1 slowdown when lots of sprites are visible - CD32 mode CD32.TM detection added (log only) - RTG vblank interrupt changes, use INTB_VERTB if RTG vblank is set - to "Chipset". (very compatible, no extra interrups happening) Uses + to "Chipset". (very compatible, no extra interrupts happening) Uses INTB_PORTS if different than Chipset. (Previously used INTB_EXTER but some games didn't like it, Ports seems to be more compatible) Added "Disabled" option which disables RTG vblank support. -- 2.47.3