/* pause CD audio */
static int cdrom_command_pause (void)
{
+#if AKIKO_DEBUG_IO_CMD
+ write_log (_T("CD32: pause: %d, %d\n"), cdrom_paused, cdrom_playing);
+#endif
cdrom_audiotimeout = 0;
cdrom_toc_counter = -1;
cdrom_result_buffer[0] = cdrom_command;
/* unpause CD audio */
static int cdrom_command_unpause (void)
{
+#if AKIKO_DEBUG_IO_CMD
+ write_log (_T("CD32: unpause: %d, %d\n"), cdrom_paused, cdrom_playing);
+#endif
cdrom_result_buffer[0] = cdrom_command;
if (checkerr ())
return 2;
int t;
curr_time = read_processor_time ();
vsyncwaittime = vsyncmaxtime = curr_time + vsynctimebase;
- if (!frame_rendered)
- frame_rendered = render_screen ();
+ if (!frame_rendered && !picasso_on)
+ frame_rendered = render_screen (false);
if (!frame_shown)
show_screen ();
t = read_processor_time () - curr_time;
int max, adjust, flipdelay;
frame_time_t now;
+ if (!frame_rendered && !picasso_on) {
+ frame_time_t start, end;
+ start = read_processor_time ();
+ frame_rendered = render_screen (currprefs.gfx_apmode[0].gfx_vflip == 0);
+ end = read_processor_time ();
+ frameskipt += end - start;
+ }
+
curr_time = vsync_busywait_end (&flipdelay); // vsync time
vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0);
vsync_busywait_start ();
now = read_processor_time (); // current time
adjust = (int)now - (int)curr_time;
+ //write_log (_T("%d "), adjust);
if (adjust < 0)
adjust = 0;
+ if (adjust > vsynctimebase * 2 / 3)
+ adjust = 0;
+ //write_log (_T("%d "), adjust);
if (currprefs.gfx_apmode[0].gfx_vflip == 0) {
adjust += skipcnt;
- //write_log (L"%d ", skipcnt);
+ //write_log (_T("%d "), skipcnt);
}
+ adjust += frameskipt;
+ //write_log (_T("%d "), adjust);
if (adjust > vsynctimebase / 2)
adjust = vsynctimebase / 2;
frame_time_t now;
flipdelay = 0;
- frame_rendered = render_screen ();
- curr_time = vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0);
- vsync_busywait_end (&flipdelay);
+ if (!frame_rendered && !picasso_on)
+ frame_rendered = render_screen (false);
+ vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0);
+ curr_time = vsync_busywait_end (&flipdelay);
if (extraframewait)
sleep_millis_main (extraframewait);
now = read_processor_time ();
adjust = (int)now - (int)curr_time;
if (adjust < 0)
adjust = 0;
- if (adjust > vsynctimebase / 3)
- adjust = vsynctimebase / 3;
+ if (adjust > vsynctimebase)
+ adjust = 0;
+ if (adjust > vsynctimebase / 2)
+ adjust = vsynctimebase / 2;
max = vsynctimebase - (adjust * 3 / 2);
vsyncmintime = now;
}
vsynctimeperline = (max - skipcnt * 2) / 3;
- //if (vsynctimeperline < 1)
+ if (vsynctimeperline < 1)
vsynctimeperline = 1;
vsyncmaxtime = now + max;
- //write_log (L"%d ", vsynctimeperline);
+ //write_log (_T("%d:%d:%d "), adjust, skipcnt, vsynctimeperline);
frame_shown = true;
if (currprefs.m68k_speed < 0) {
+ if (!frame_rendered && !picasso_on)
+ frame_rendered = render_screen (false);
+
if (currprefs.m68k_speed_throttle) {
// this delay can safely overshoot frame time by 1-2 ms, following code will compensate for it.
for (;;) {
if (!frame_rendered && !picasso_on) {
start = read_processor_time ();
- frame_rendered = render_screen ();
+ frame_rendered = render_screen (false);
t = read_processor_time () - start;
}
for (;;) {
if (!picasso_on) {
if (!frame_rendered && vblank_hz_state) {
- frame_rendered = render_screen ();
- if (frame_rendered && !frame_shown) {
- frame_shown = show_screen_maybe (isvsync_chipset () >= 0);
- }
+ frame_rendered = render_screen (false);
+ }
+ if (frame_rendered && !frame_shown) {
+ frame_shown = show_screen_maybe (isvsync_chipset () >= 0);
}
}
while (!vblank_found_chipset && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) {
sleep_millis_main (1);
rpt = read_processor_time ();
+ //write_log (L"*");
}
}
}
vsync_rendered = true;
vsync_handle_redraw (lof_store, lof_changed, bplcon0, bplcon3);
if (vblank_hz_state) {
- frame_rendered = render_screen ();
+ frame_rendered = render_screen (true);
}
frame_shown = true;
end = read_processor_time ();
}
}
if (unit < 1000 || is_hardfile (unit) == FILESYS_VIRTUAL || is_hardfile (unit) == FILESYS_CD)
- err = 50; /* c */
+ err = 50; /* HFERR_NoBoard */
} else {
err = IOERR_BADLENGTH;
}
extern void flush_block (struct vidbuffer*, int, int);
extern void flush_screen (struct vidbuffer*, int, int);
extern void flush_clear_screen (struct vidbuffer*);
-extern bool render_screen (void);
+extern bool render_screen (bool);
extern void show_screen (void);
extern bool show_screen_maybe (bool);
!define PRODUCT_NAME "WinUAE"
-!define PRODUCT_VERSION "2.4.0"
+!define PRODUCT_VERSION "2.4.1"
!define PRODUCT_PUBLISHER "Arabuusimiehet"
!define PRODUCT_WEB_SITE "http://www.winuae.net/"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\winuae.exe"
if (!isd3d () || !texture)
return;
- if (currprefs.leds_on_screen & (STATUSLINE_CHIPSET | STATUSLINE_RTG))
- updateleds ();
- if (locked)
+ if (locked) {
+ if (currprefs.leds_on_screen & (STATUSLINE_CHIPSET | STATUSLINE_RTG))
+ updateleds ();
hr = texture->UnlockRect (0);
+ }
locked = 0;
fulllocked = 0;
}
}
}
-bool D3D_renderframe (void)
+bool D3D_renderframe (bool immediate)
{
static int vsync2_cnt;
return false;
if (filenotificationhandle != NULL) {
+ bool notify = false;
while (WaitForSingleObject (filenotificationhandle, 0) == WAIT_OBJECT_0) {
FindNextChangeNotification (filenotificationhandle);
+ notify = true;
+ }
+ if (notify) {
devicelost = 2;
write_log (_T("%s: Shader file modification notification\n"), D3DHEAD);
}
}
D3D_render2 ();
- flushgpu (false);
+ flushgpu (immediate);
return true;
}
extern bool D3D_alloctexture (int, int);
extern void D3D_getpixelformat (int depth,int *rb, int *bb, int *gb, int *rs, int *bs, int *gs, int *ab, int *ar, int *a);
extern void D3D_refresh (void);
-extern bool D3D_renderframe (void);
+extern bool D3D_renderframe (bool);
extern void D3D_showframe (void);
extern uae_u8 *D3D_locktexture(int*, bool);
extern void D3D_unlocktexture(void);
} else if (integerscale) {
hmult = vmult = 1;
p->gfx_filter_autoscale = AUTOSCALE_INTEGER;
- if (sm->lClipWidth > 0)
- p->gfx_xcenter_size = sm->lClipWidth;
- if (sm->lClipHeight > 0)
- p->gfx_ycenter_size = sm->lClipHeight;
-
+ if (sm->dwClipFlags & RP_CLIPFLAGS_AUTOCLIP) {
+ p->gfx_xcenter_pos = -1;
+ p->gfx_ycenter_pos = -1;
+ p->gfx_xcenter_size = -1;
+ p->gfx_ycenter_size = -1;
+ } else {
+ if (sm->lClipWidth > 0)
+ p->gfx_xcenter_size = sm->lClipWidth;
+ if (sm->lClipHeight > 0)
+ p->gfx_ycenter_size = sm->lClipHeight;
+ }
}
if (keepaspect) {
#define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
#define GETBDD(x) ((x) % 100)
-#define WINUAEPUBLICBETA 1
+#define WINUAEPUBLICBETA 0
#define LANG_DLL 1
-//#define WINUAEBETA _T("")
-#define WINUAEBETA _T("14")
-#define WINUAEDATE MAKEBD(2012, 5, 6)
+#define WINUAEBETA _T("")
+//#define WINUAEBETA _T("14")
+#define WINUAEDATE MAKEBD(2012, 5, 9)
#define WINUAEEXTRA _T("")
//#define WINUAEEXTRA _T("AmiKit Preview")
#define WINUAEREV _T("")
cw = gfxvidinfo.outbuffer->outwidth;
ch = gfxvidinfo.outbuffer->outheight;
} else {
- cw = gfxvidinfo.drawbuffer.inwidth;
- ch = gfxvidinfo.drawbuffer.inheight;
cx = 0;
cy = 0;
+ cw = gfxvidinfo.drawbuffer.inwidth;
+ ch = gfxvidinfo.drawbuffer.inheight;
cv = 1;
- if (!(beamcon0 & 0x80) && (scalemode == AUTOSCALE_STATIC_NOMINAL || scalemode == AUTOSCALE_INTEGER)) {
- cw -= 40 << currprefs.gfx_resolution;
- ch -= 25 << currprefs.gfx_vresolution;
+ if (!(beamcon0 & 0x80) && (scalemode == AUTOSCALE_STATIC_NOMINAL)) { // || scalemode == AUTOSCALE_INTEGER)) {
cx = 28 << currprefs.gfx_resolution;
cy = 10 << currprefs.gfx_vresolution;
+ cw -= 40 << currprefs.gfx_resolution;
+ ch -= 25 << currprefs.gfx_vresolution;
}
}
int maxh = currprefs.gfx_size.height;
int mult = 1;
- if (currprefs.gfx_xcenter_pos > 0 || currprefs.gfx_xcenter_size > 0)
- getmanualpos (&cx, &cy, &cw, &ch);
+ if (currprefs.gfx_xcenter_pos >= 0 || currprefs.gfx_ycenter_pos >= 0) {
+ changed_prefs.gfx_filter_horiz_offset = currprefs.gfx_filter_horiz_offset = 0;
+ changed_prefs.gfx_filter_vert_offset = currprefs.gfx_filter_vert_offset = 0;
+ filter_horiz_offset = 0;
+ filter_vert_offset = 0;
+ get_custom_topedge (&cx, &cy);
+ }
+
+ getmanualpos (&cx, &cy, &cw, &ch);
if (cw > maxw || ch > maxh) {
while (cw / mult > maxw || ch / mult > maxh)
static volatile bool render_ok;
-bool render_screen (void)
+bool render_screen (bool immediate)
{
bool v = false;
flushymax = currentmode->amiga_height;
EnterCriticalSection (&screen_cs);
if (currentmode->flags & DM_D3D) {
- v = D3D_renderframe ();
+ v = D3D_renderframe (immediate);
} else if (currentmode->flags & DM_SWSCALE) {
S2X_render ();
v = true;
}
D3D_unlocktexture ();
if (dorender) {
- if (D3D_renderframe ()) {
+ if (D3D_renderframe (false)) {
LeaveCriticalSection (&screen_cs);
render_ok = true;
show_screen_maybe (true);
Sleep (100);
} else if (mode == VBLANKTH_ACTIVE_WAIT) {
sleep_millis (1);
- ResetEvent (vblankwaitevent);
} else if (mode == VBLANKTH_ACTIVE_START) {
// do not start until vblank has been passed
int vp;
sleep_millis (1);
continue;
}
+ ResetEvent (vblankwaitevent);
if (vp > maxscanline / 2)
vp = maxscanline / 2;
frame_time_t rpt = read_processor_time ();
}
show_screen ();
render_ok = false;
- int delay = (read_processor_time () - t) / (vblank_skipeveryother ? 2 : 1);
+ int delay = read_processor_time () - t;
if (delay < 0)
delay = 0;
+ else if (delay > vblankbasefull)
+ delay = 0;
else if (delay > vblankbasefull * 2 / 3)
delay = vblankbasefull * 2 / 3;
vblank_found_flipdelay = delay;
thread_vblank_time = thread_vblank_time2;
vblank_found_rtg = vblank_found_rtg2;
vblank_found = vblank_found2;
- SetEvent (vblankwaitevent);
vblankthread_mode = VBLANKTH_ACTIVE_WAIT;
+ SetEvent (vblankwaitevent);
} else if (!donotwait || ap->gfx_vflip || picasso_on) {
sleep_millis (1);
}
}
prev = vblank_prev_time;
if (!dooddevenskip) {
- if (vblankthread_mode == VBLANKTH_ACTIVE) {
- frame_time_t t = read_processor_time ();
- while (vblankthread_mode == VBLANKTH_ACTIVE)
- WaitForSingleObject (vblankwaitevent, 10);
- idletime += read_processor_time () - t;
+ int delay = 10;
+ frame_time_t t = read_processor_time ();
+ while (delay-- > 0) {
+ if (WaitForSingleObject (vblankwaitevent, 10) != WAIT_TIMEOUT)
+ break;
}
+ idletime += read_processor_time () - t;
}
if (flipdelay)
*flipdelay = vblank_found_flipdelay;
} else {
if (flipdelay)
*flipdelay = vblank_flip_delay;
- return vblank_prev_time + vblankbasefull;
+ return vblank_prev_time;
}
}
- restore only single input target to default.
- hdd from command line
+- no-buffer tearing updates
+- 50/60 autoswitch: support also 100/120
+- cd32 cda problems (universe, rnc loader)
+
+2.4.1
+
+- Try to flush GPU queue after rendering the frame to prevent delayed background flipping that
+ introduces tearing on fastest possible no buffer low latency mode.
+- Integer scaling + gfx_xcenter_pos or gfx_ycenter_pos set had wrong positioning.
Beta 14: (RC3)
- Cycle-exact/approximate CPU speed non-vsync b1 sound sync update didn't work, it did nothing.
-- Some more low latency vsync timing updates, improved dynamic adjusment.
+- Some more low latency vsync timing updates, improved dynamic adjustment.
- Legacy vsync slowdown problems fixed (2.4.0)
- Restored (50Hz) and (60Hz) fake rates that were removed in 2.4.0. Only available in legacy vsync mode.
- RTG + low latency vsync was not stable.