refactor Blitterwidget::sync

directdrawblitter: remove unecessary turbo conditions


git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@135 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
This commit is contained in:
sinamas 2008-03-17 20:34:54 +00:00
parent 40b6be8215
commit dc29212d85
4 changed files with 228 additions and 302 deletions

View File

@ -18,56 +18,107 @@
***************************************************************************/
#include "blitterwidget.h"
struct Time {
long sec;
long rsec;
};
#ifdef Q_WS_WIN
#include <windows.h>
class Timer {
LONGLONG freq;
bool qpf;
public:
Timer() : freq(0), qpf(false) {
LARGE_INTEGER li;
qpf = QueryPerformanceFrequency(&li);
freq = qpf ? li.QuadPart : 1000;
}
void get(Time *const time, const long denom) const {
LARGE_INTEGER li;
if (qpf)
QueryPerformanceCounter(&li);
else
li.QuadPart = timeGetTime();
time->sec = li.QuadPart / freq;
time->rsec = (li.QuadPart % freq) * denom / freq;
}
};
static Timer timer;
static void getTime(Time *const time, const long denom) {
timer.get(time, denom);
}
static void sleep(const long secnum, const long secdenom) {
Sleep(static_cast<qlonglong>(secnum) * 1000 / secdenom);
}
#else
#include <sys/time.h>
static void getTime(Time *const time, const long denom) {
timeval t;
gettimeofday(&t, NULL);
time->sec = t.tv_sec;
time->rsec = static_cast<qlonglong>(t.tv_usec) * denom / 1000000;
}
static void sleep(const long secnum, const long secdenom) {
timespec tspec = { tv_sec: 0,
tv_nsec: static_cast<qlonglong>(secnum) * 1000000000 / secdenom };
nanosleep(&tspec, NULL);
}
#endif /*Q_WS_WIN*/
class BlitterWidget::Impl {
struct Time {
long sec;
long rsec;
};
Time time;
Rational ft;
Time last;
long ftnum;
long ftdenom;
long late;
unsigned noSleep;
public:
Impl() : late(0), noSleep(60) { time.sec = time.rsec = 0; }
Impl() : ftnum(Rational().numerator), ftdenom(Rational().denominator), late(0), noSleep(60) { getTime(&last, ftdenom); }
void setFrameTime(Rational ft) { this->ft = ft; }
void setFrameTime(const Rational &ft) {
last.rsec = static_cast<qulonglong>(last.rsec) * ft.denominator / ftdenom;
ftnum = ft.numerator;
ftdenom = ft.denominator;
late = 0;
}
const Rational frameTime() const {
return ft;
return Rational(ftnum, ftdenom);
}
int sync(const bool turbo) {
if (turbo)
return 0;
const long time_usec = static_cast<quint64>(time.rsec) * 1000000 / ft.denominator;
Time current;
getTime(&current, ftdenom);
timeval t;
gettimeofday(&t, NULL);
long diff = (current.sec - last.sec) * ftdenom + current.rsec - last.rsec;
if (time.sec > t.tv_sec || time.sec == t.tv_sec && time_usec > t.tv_usec) {
timeval tmp = { tv_sec: 0, tv_usec: time_usec - t.tv_usec };
if (diff < ftnum) {
diff = ftnum - diff;
if (time.sec != t.tv_sec)
tmp.tv_usec += 1000000;
if (tmp.tv_usec > late) {
tmp.tv_usec -= late;
if (diff > late) {
sleep(diff - late, ftdenom);
if (tmp.tv_usec >= 1000000) {
tmp.tv_usec -= 1000000;
++tmp.tv_sec;
}
timespec tspec = { tmp.tv_sec, tmp.tv_usec * 1000 };
nanosleep(&tspec, NULL);
gettimeofday(&t, NULL);
late -= (time.sec - t.tv_sec) * 1000000 + time_usec - t.tv_usec >> 1;
getTime(&current, ftdenom);
late += ((current.sec - last.sec) * ftdenom + current.rsec - last.rsec - ftnum) / 2;
if (late < 0)
late = 0;
@ -78,19 +129,18 @@ public:
late = 0;
}
while (time.sec > t.tv_sec || time.sec == t.tv_sec && time_usec > t.tv_usec)
gettimeofday(&t, NULL);
while ((current.sec - last.sec) * ftdenom + current.rsec - last.rsec < ftnum)
getTime(&current, ftdenom);
last.rsec += ftnum;
if (last.rsec >= ftdenom) {
last.rsec -= ftdenom;
++last.sec;
}
} else {
//quickfix:catches up to current time
time.sec = t.tv_sec;
time.rsec = static_cast<quint64>(ft.denominator) * t.tv_usec / 1000000;
}
time.rsec += ft.numerator;
if (static_cast<unsigned long>(time.rsec) >= ft.denominator) {
time.rsec -= ft.denominator;
++time.sec;
last = current;
}
return 0;

View File

@ -1,134 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Sindre Aamås *
* aamas@stud.ntnu.no *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "blitterwidget.h"
#include <windows.h>
struct Time {
DWORD sec;
DWORD rsec;
};
class Timer {
LONGLONG freq;
bool qpf;
public:
Timer() : freq(0), qpf(false) {
LARGE_INTEGER li;
qpf = QueryPerformanceFrequency(&li);
freq = qpf ? li.QuadPart : 1000;
}
void get(Time *const time, const BlitterWidget::Rational &ft) const {
LARGE_INTEGER li;
if (qpf)
QueryPerformanceCounter(&li);
else
li.QuadPart = timeGetTime();
time->sec = li.QuadPart / freq;
time->rsec = (li.QuadPart % freq) * ft.denominator / freq;
}
};
static Timer timer;
class BlitterWidget::Impl {
Rational ft;
Time last;
public:
Impl() { timer.get(&last, ft); }
void setFrameTime(const Rational &ft) {
last.rsec = last.rsec * ft.denominator / this->ft.denominator;
this->ft = ft;
}
const Rational& frameTime() const {
return ft;
}
int sync(const bool turbo) {
if (turbo)
return 0;
Time current;
timer.get(&current, ft);
const DWORD diff = (current.sec - last.sec) * ft.denominator + current.rsec - last.rsec;
if (diff < ft.numerator) {
{
const DWORD msdiff = diff * 1000 / ft.denominator;
if (msdiff > 1) {
Sleep(msdiff - 1);
}
}
do {
timer.get(&current, ft);
} while ((current.sec - last.sec) * ft.denominator + current.rsec - last.rsec < ft.numerator);
last.rsec += ft.numerator;
if (last.rsec >= ft.denominator) {
last.rsec -= ft.denominator;
++last.sec;
}
} else {
//quickfix:catches up to current time
last = current;
}
return 0;
}
};
BlitterWidget::BlitterWidget(PixelBufferSetter setPixelBuffer,
const QString &name,
bool integerOnlyScaler,
QWidget *parent) :
QWidget(parent),
impl(new Impl),
setPixelBuffer(setPixelBuffer),
nameString(name),
integerOnlyScaler(integerOnlyScaler)
{
setMouseTracking(true);
}
BlitterWidget::~BlitterWidget() {
delete impl;
}
void BlitterWidget::setFrameTime(Rational ft) {
impl->setFrameTime(ft);
}
const BlitterWidget::Rational BlitterWidget::frameTime() const {
return impl->frameTime();
}
int BlitterWidget::sync(const bool turbo) {
return impl->sync(turbo);
}

View File

@ -370,15 +370,13 @@ int DirectDrawBlitter::sync(const bool turbo) {
RECT rcRectDest;
GetWindowRect(winId(), &rcRectDest);
if (!turbo) {
if (vblank && hz == vblankHz) {
if (!(exclusive && flipping))
lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
} else
BlitterWidget::sync(turbo);
}
if (vblank && hz == vblankHz) {
if (!(exclusive && flipping))
lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
} else
BlitterWidget::sync(turbo);
const bool dontwait = exclusive && flipping && !(vblank && hz == vblankHz && !turbo);
const bool dontwait = exclusive && flipping && !(vblank && hz == vblankHz);
HRESULT ddrval = lpDDSBack->Blt(&rcRectDest, lpDDSVideo, NULL, dontwait ? DDBLT_DONOTWAIT : DDBLT_WAIT, NULL);

View File

@ -1,131 +1,143 @@
SOURCES += main.cpp \
videodialog.cpp \
blittercontainer.cpp \
inputdialog.cpp \
samplescalculator.cpp \
blitterwidgets/qglblitter.cpp \
blitterwidgets/qpainterblitter.cpp \
SDL_Joystick/src/SDL_event.cpp \
SDL_Joystick/src/SDL_error.c \
SDL_Joystick/src/SDL_joystick.c \
SDL_Joystick/src/SDL_string.c \
sounddialog.cpp \
audioengines/customdevconf.cpp \
palettedialog.cpp \
gambattesource.cpp \
gambattemenuhandler.cpp \
mainwindow.cpp
videodialog.cpp \
blittercontainer.cpp \
inputdialog.cpp \
samplescalculator.cpp \
blitterwidgets/qglblitter.cpp \
blitterwidgets/qpainterblitter.cpp \
SDL_Joystick/src/SDL_event.cpp \
SDL_Joystick/src/SDL_error.c \
SDL_Joystick/src/SDL_joystick.c \
SDL_Joystick/src/SDL_string.c \
sounddialog.cpp \
audioengines/customdevconf.cpp \
palettedialog.cpp \
gambattesource.cpp \
gambattemenuhandler.cpp \
mainwindow.cpp \
blitterwidget.cpp
HEADERS += blitterwidget.h \
fullmodetoggler.h \
videodialog.h \
blittercontainer.h \
resinfo.h \
inputdialog.h \
audioengine.h \
samplescalculator.h \
addaudioengines.h \
addblitterwidgets.h \
getfullmodetoggler.h \
blitterwidgets/qglblitter.h \
blitterwidgets/qpainterblitter.h \
fullmodetogglers/nulltoggler.h \
SDL_Joystick/include/SDL_config.h \
SDL_Joystick/include/SDL_error.h \
SDL_Joystick/include/SDL_event.h \
SDL_Joystick/include/SDL_joystick.h \
SDL_Joystick/include/SDL_stdinc.h \
SDL_Joystick/src/SDL_error_c.h \
SDL_Joystick/src/SDL_joystick_c.h \
SDL_Joystick/src/SDL_sysjoystick.h \
sounddialog.h \
audioengines/nullaudioengine.h \
audioengines/customdevconf.h \
palettedialog.h \
mediasource.h \
gambattesource.h \
pixelbuffersetter.h \
gambattemenuhandler.h \
mainwindow.h \
swscale.h
fullmodetoggler.h \
videodialog.h \
blittercontainer.h \
resinfo.h \
inputdialog.h \
audioengine.h \
samplescalculator.h \
addaudioengines.h \
addblitterwidgets.h \
getfullmodetoggler.h \
blitterwidgets/qglblitter.h \
blitterwidgets/qpainterblitter.h \
fullmodetogglers/nulltoggler.h \
SDL_Joystick/include/SDL_config.h \
SDL_Joystick/include/SDL_error.h \
SDL_Joystick/include/SDL_event.h \
SDL_Joystick/include/SDL_joystick.h \
SDL_Joystick/include/SDL_stdinc.h \
SDL_Joystick/src/SDL_error_c.h \
SDL_Joystick/src/SDL_joystick_c.h \
SDL_Joystick/src/SDL_sysjoystick.h \
sounddialog.h \
audioengines/nullaudioengine.h \
audioengines/customdevconf.h \
palettedialog.h \
mediasource.h \
gambattesource.h \
pixelbuffersetter.h \
gambattemenuhandler.h \
mainwindow.h \
swscale.h
TEMPLATE = app
CONFIG += warn_on \
thread \
qt \
release
thread \
qt \
release
QT += opengl
TARGET = ../bin/gambatte_qt
INCLUDEPATH += ../../libgambatte/include SDL_Joystick/include
LIBS += -L../../libgambatte -lgambatte -lz
INCLUDEPATH += ../../libgambatte/include \
SDL_Joystick/include
LIBS += -L../../libgambatte \
-lgambatte
DEFINES += HAVE_STDINT_H
#QMAKE_CXXFLAGS = -g
macx {
SOURCES += addaudioengines_macx.cpp addblitterwidgets.cpp getfullmodetoggler_macx.cpp blitterwidget.cpp
SOURCES += SDL_Joystick/src/darwin/SDL_sysjoystick.c audioengines/openalengine.cpp fullmodetogglers/quartztoggler.cpp
HEADERS += audioengines/openalengine.h fullmodetogglers/quartztoggler.h
LIBS += -framework IOKit -framework OpenAL
}else : unix {
DEFINES += PLATFORM_UNIX
SOURCES += blitterwidget.cpp \
x11getprocaddress.cpp \
addblitterwidgets_unix.cpp \
getfullmodetoggler_unix.cpp \
audioengines/ossengine.cpp \
blitterwidgets/xvblitter.cpp \
blitterwidgets/x11blitter.cpp \
fullmodetogglers/xrandrtoggler.cpp \
fullmodetogglers/xf86vidmodetoggler.cpp
HEADERS += x11getprocaddress.h \
audioengines/ossengine.h \
blitterwidgets/xvblitter.h \
blitterwidgets/x11blitter.h \
fullmodetogglers/xrandrtoggler.h \
fullmodetogglers/xf86vidmodetoggler.h
LIBS += -L/usr/X11R6/lib -lXv -lXrandr
linux-g++ {
SOURCES += addaudioengines_linux.cpp audioengines/alsaengine.cpp SDL_Joystick/src/linux/SDL_sysjoystick.c
HEADERS += audioengines/alsaengine.h
LIBS += -lasound
} else {
SOURCES += addaudioengines_unix.cpp
freebsd-g++|netbsd-g++|openbsd-g++ {
exists( /usr/include/usb.h ): DEFINES += HAVE_USB_H
exists( /usr/include/usbhid.h ): DEFINES += HAVE_USBHID_H
exists( /usr/include/libusb.h ): DEFINES += HAVE_LIBUSB_H
exists( /usr/include/libusbhid.h ): DEFINES += HAVE_LIBUSBHID_H
SOURCES += SDL_Joystick/src/bsd/SDL_sysjoystick.c
} else : darwin-g++ {
SOURCES += SDL_Joystick/src/darwin/SDL_sysjoystick.c
} else {
SOURCES += SDL_Joystick/src/dummy/SDL_sysjoystick.c
}
# QMAKE_CXXFLAGS = -g
macx {
SOURCES += addaudioengines_macx.cpp \
addblitterwidgets.cpp \
getfullmodetoggler_macx.cpp
SOURCES += SDL_Joystick/src/darwin/SDL_sysjoystick.c \
audioengines/openalengine.cpp \
fullmodetogglers/quartztoggler.cpp
HEADERS += audioengines/openalengine.h \
fullmodetogglers/quartztoggler.h
LIBS += -framework \
IOKit \
-framework \
OpenAL
}
else:unix {
DEFINES += PLATFORM_UNIX
SOURCES += x11getprocaddress.cpp \
addblitterwidgets_unix.cpp \
getfullmodetoggler_unix.cpp \
audioengines/ossengine.cpp \
blitterwidgets/xvblitter.cpp \
blitterwidgets/x11blitter.cpp \
fullmodetogglers/xrandrtoggler.cpp \
fullmodetogglers/xf86vidmodetoggler.cpp
HEADERS += x11getprocaddress.h \
audioengines/ossengine.h \
blitterwidgets/xvblitter.h \
blitterwidgets/x11blitter.h \
fullmodetogglers/xrandrtoggler.h \
fullmodetogglers/xf86vidmodetoggler.h
LIBS += -L/usr/X11R6/lib \
-lXv \
-lXrandr
linux-g++ {
SOURCES += addaudioengines_linux.cpp \
audioengines/alsaengine.cpp \
SDL_Joystick/src/linux/SDL_sysjoystick.c
HEADERS += audioengines/alsaengine.h
LIBS += -lasound
}
else {
SOURCES += addaudioengines_unix.cpp
freebsd-g++|netbsd-g++|openbsd-g++ {
exists( /usr/include/usb.h ):DEFINES += HAVE_USB_H
exists( /usr/include/usbhid.h ):DEFINES += HAVE_USBHID_H
exists( /usr/include/libusb.h ):DEFINES += HAVE_LIBUSB_H
exists( /usr/include/libusbhid.h ):DEFINES += HAVE_LIBUSBHID_H
SOURCES += SDL_Joystick/src/bsd/SDL_sysjoystick.c
}
}else : win32 {
DEFINES += PLATFORM_WIN32
SOURCES += getfullmodetoggler_win32.cpp \
blitterwidget_win32.cpp \
addaudioengines_win32.cpp \
addblitterwidgets_win32.cpp \
audioengines/directsoundengine.cpp \
blitterwidgets/directdrawblitter.cpp \
fullmodetogglers/gditoggler.cpp \
SDL_Joystick/src/win32/SDL_mmjoystick.c
HEADERS += audioengines/directsoundengine.h \
blitterwidgets/directdrawblitter.h \
fullmodetogglers/gditoggler.h
LIBS += -lwinmm -lddraw -ldxguid -ldsound
}else {
SOURCES += addaudioengines.cpp addblitterwidgets.cpp getfullmodetoggler.cpp blitterwidget.cpp audioengines/aoengine.cpp
else:darwin-g++:SOURCES += SDL_Joystick/src/darwin/SDL_sysjoystick.c
else:SOURCES += SDL_Joystick/src/dummy/SDL_sysjoystick.c
}
}
else:win32 {
DEFINES += PLATFORM_WIN32
SOURCES += getfullmodetoggler_win32.cpp \
addaudioengines_win32.cpp \
addblitterwidgets_win32.cpp \
audioengines/directsoundengine.cpp \
blitterwidgets/directdrawblitter.cpp \
fullmodetogglers/gditoggler.cpp \
SDL_Joystick/src/win32/SDL_mmjoystick.c
HEADERS += audioengines/directsoundengine.h \
blitterwidgets/directdrawblitter.h \
fullmodetogglers/gditoggler.h
LIBS += -lwinmm \
-lddraw \
-ldxguid \
-ldsound
}
else {
SOURCES += addaudioengines.cpp \
addblitterwidgets.cpp \
getfullmodetoggler.cpp \
blitterwidget.cpp \
audioengines/aoengine.cpp
SOURCES += SDL_Joystick/src/dummy/SDL_sysjoystick.c
HEADERS += audioengines/aoengine.h
CONFIG += link_pkgconfig