mirror of https://github.com/stella-emu/stella.git
Converted OSystem::getTicks() to use 64-bit integers. This should fix the
problems with integer overflow, which could sometimes cause Stella to sleep for long periods of time. For those who are interested, the problem was that SDL_GetTicks() wraps every 49 days (32-bit int overflow), but since OSystem::getTicks() provides info in microseconds, it multiplied the value by 1000. This caused wraparound in 49/1000 days, or 70.56 minutes. This almost exactly matches the reports on AtariAge of 'lockups' occuring every 71 minutes or so. It also explains why attaching to Stella with GDB and bypassing the delay allows the program to continue (as reported by another bugtester). Added signature to detect UA bankswitching for Gingerbread Man ROM. Bumped version number. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1823 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
1c829fc425
commit
8a8d04031a
|
@ -19,7 +19,7 @@
|
|||
#ifndef VERSION_HXX
|
||||
#define VERSION_HXX
|
||||
|
||||
#define STELLA_BASE_VERSION "2.8.3"
|
||||
#define STELLA_BASE_VERSION "2.8.4_svn"
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
#define STELLA_VERSION STELLA_BASE_VERSION "pre-" NIGHTLY_BUILD
|
||||
|
|
|
@ -527,14 +527,17 @@ bool Cartridge::isProbablyUA(const uInt8* image, uInt32 size)
|
|||
{
|
||||
// UA cart bankswitching switches to bank 1 by accessing address 0x240
|
||||
// using 'STA $240' or 'LDA $240'
|
||||
uInt8 signature[2][3] = {
|
||||
uInt8 signature[3][3] = {
|
||||
{ 0x8D, 0x40, 0x02 }, // STA $240
|
||||
{ 0xAD, 0x40, 0x02 } // LDA $240
|
||||
{ 0xAD, 0x40, 0x02 }, // LDA $240
|
||||
{ 0xBD, 0x1F, 0x02 } // LDA $21F,X
|
||||
};
|
||||
if(searchForBytes(image, size, signature[0], 3, 1))
|
||||
return true;
|
||||
else
|
||||
return searchForBytes(image, size, signature[1], 3, 1);
|
||||
for(uInt32 i = 0; i < 3; ++i)
|
||||
{
|
||||
if(searchForBytes(image, size, signature[i], 3, 1))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -307,7 +307,7 @@ void EventHandler::mapStelladaptors(const string& sa1, const string& sa2)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::poll(uInt32 time)
|
||||
void EventHandler::poll(uInt64 time)
|
||||
{
|
||||
// Synthesize events for platform-specific hardware
|
||||
myOSystem->pollEvent();
|
||||
|
|
|
@ -118,9 +118,9 @@ class EventHandler
|
|||
Collects and dispatches any pending events. This method should be
|
||||
called regularly (at X times per second, where X is the game framerate).
|
||||
|
||||
@param time The current time in milliseconds.
|
||||
@param time The current time in microseconds.
|
||||
*/
|
||||
void poll(uInt32 time);
|
||||
void poll(uInt64 time);
|
||||
|
||||
/**
|
||||
Set the default action for a joystick button to the given event
|
||||
|
|
|
@ -797,8 +797,7 @@ string OSystem::getROMInfo(const Console* console)
|
|||
void OSystem::resetLoopTiming()
|
||||
{
|
||||
memset(&myTimingInfo, 0, sizeof(TimingInfo));
|
||||
myTimingInfo.start = getTicks();
|
||||
myTimingInfo.virt = getTicks();
|
||||
myTimingInfo.start = myTimingInfo.virt = getTicks();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -368,7 +368,7 @@ class OSystem
|
|||
|
||||
@return Current time in microseconds.
|
||||
*/
|
||||
virtual uInt32 getTicks() const = 0;
|
||||
virtual uInt64 getTicks() const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following methods are system-specific and can be overrided in
|
||||
|
@ -520,11 +520,11 @@ class OSystem
|
|||
|
||||
// Indicates whether the main processing loop should proceed
|
||||
struct TimingInfo {
|
||||
uInt32 start;
|
||||
uInt32 current;
|
||||
uInt32 virt;
|
||||
uInt32 totalTime;
|
||||
uInt32 totalFrames;
|
||||
uInt64 start;
|
||||
uInt64 current;
|
||||
uInt64 virt;
|
||||
uInt64 totalTime;
|
||||
uInt64 totalFrames;
|
||||
};
|
||||
TimingInfo myTimingInfo;
|
||||
|
||||
|
|
|
@ -27,17 +27,25 @@
|
|||
@version $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_INTTYPES
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
// Types for 8-bit signed and unsigned integers
|
||||
typedef signed char Int8;
|
||||
typedef unsigned char uInt8;
|
||||
typedef int8_t Int8;
|
||||
typedef uint8_t uInt8;
|
||||
|
||||
// Types for 16-bit signed and unsigned integers
|
||||
typedef signed short Int16;
|
||||
typedef unsigned short uInt16;
|
||||
typedef int16_t Int16;
|
||||
typedef uint16_t uInt16;
|
||||
|
||||
// Types for 32-bit signed and unsigned integers
|
||||
typedef signed int Int32;
|
||||
typedef unsigned int uInt32;
|
||||
typedef int32_t Int32;
|
||||
typedef uint32_t uInt32;
|
||||
|
||||
// Types for 64-bit signed and unsigned integers
|
||||
typedef int64_t Int64;
|
||||
typedef uint64_t uInt64;
|
||||
|
||||
// The following code should provide access to the standard C++ objects and
|
||||
// types: cout, cerr, string, ostream, istream, etc.
|
||||
|
@ -54,10 +62,6 @@ typedef unsigned int uInt32;
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef HAVE_INTTYPES
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
// Defines to help with path handling
|
||||
#if defined BSPF_UNIX
|
||||
#define BSPF_PATH_SEPARATOR "/"
|
||||
|
|
|
@ -41,7 +41,7 @@ DialogContainer::~DialogContainer()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DialogContainer::updateTime(uInt32 time)
|
||||
void DialogContainer::updateTime(uInt64 time)
|
||||
{
|
||||
// We only need millisecond precision
|
||||
myTime = time / 1000;
|
||||
|
|
|
@ -60,7 +60,7 @@ class DialogContainer
|
|||
|
||||
@param time The current time in microseconds
|
||||
*/
|
||||
void updateTime(uInt32 time);
|
||||
void updateTime(uInt64 time);
|
||||
|
||||
/**
|
||||
Handle a keyboard event.
|
||||
|
@ -159,7 +159,7 @@ class DialogContainer
|
|||
};
|
||||
|
||||
// Indicates the most current time (in milliseconds) as set by updateTime()
|
||||
int myTime;
|
||||
uInt64 myTime;
|
||||
|
||||
// For continuous 'key down' events
|
||||
struct {
|
||||
|
@ -167,7 +167,7 @@ class DialogContainer
|
|||
int keycode;
|
||||
int flags;
|
||||
} myCurrentKeyDown;
|
||||
int myKeyRepeatTime;
|
||||
uInt64 myKeyRepeatTime;
|
||||
|
||||
// For continuous 'mouse down' events
|
||||
struct {
|
||||
|
@ -175,14 +175,14 @@ class DialogContainer
|
|||
int y;
|
||||
int button;
|
||||
} myCurrentMouseDown;
|
||||
int myClickRepeatTime;
|
||||
uInt64 myClickRepeatTime;
|
||||
|
||||
// For continuous 'joy button down' events
|
||||
struct {
|
||||
int stick;
|
||||
int button;
|
||||
} myCurrentButtonDown;
|
||||
int myButtonRepeatTime;
|
||||
uInt64 myButtonRepeatTime;
|
||||
|
||||
// For continuous 'joy axis down' events
|
||||
struct {
|
||||
|
@ -190,7 +190,7 @@ class DialogContainer
|
|||
int axis;
|
||||
int value;
|
||||
} myCurrentAxisDown;
|
||||
int myAxisRepeatTime;
|
||||
uInt64 myAxisRepeatTime;
|
||||
|
||||
// For continuous 'joy hat' events
|
||||
struct {
|
||||
|
@ -198,13 +198,13 @@ class DialogContainer
|
|||
int hat;
|
||||
int value;
|
||||
} myCurrentHatDown;
|
||||
int myHatRepeatTime;
|
||||
uInt64 myHatRepeatTime;
|
||||
|
||||
// Position and time of last mouse click (used to detect double clicks)
|
||||
struct {
|
||||
int x, y; // Position of mouse when the click occured
|
||||
int time; // Time
|
||||
int count; // How often was it already pressed?
|
||||
int x, y; // Position of mouse when the click occurred
|
||||
int count; // How often was it already pressed?
|
||||
uInt64 time; // Time
|
||||
} myLastClick;
|
||||
};
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
|
|||
// Only works in a useful fashion if the list entries are sorted.
|
||||
// TODO: Maybe this should be off by default, and instead we add a
|
||||
// method "enableQuickSelect()" or so ?
|
||||
int time = instance().getTicks() / 1000;
|
||||
uInt64 time = instance().getTicks() / 1000;
|
||||
if (_quickSelectTime < time)
|
||||
_quickSelectStr = (char)ascii;
|
||||
else
|
||||
|
@ -456,4 +456,4 @@ void ListWidget::abortEditMode()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int ListWidget::_QUICK_SELECT_DELAY = 300;
|
||||
uInt64 ListWidget::_QUICK_SELECT_DELAY = 300;
|
||||
|
|
|
@ -77,7 +77,7 @@ class ListWidget : public EditableWidget
|
|||
void startEditMode();
|
||||
void endEditMode();
|
||||
|
||||
static void setQuickSelectDelay(int time) { _QUICK_SELECT_DELAY = time; }
|
||||
static void setQuickSelectDelay(uInt64 time) { _QUICK_SELECT_DELAY = time; }
|
||||
|
||||
protected:
|
||||
virtual void drawWidget(bool hilite) = 0;
|
||||
|
@ -113,10 +113,10 @@ class ListWidget : public EditableWidget
|
|||
string _backupString;
|
||||
bool _quickSelect;
|
||||
string _quickSelectStr;
|
||||
int _quickSelectTime;
|
||||
uInt64 _quickSelectTime;
|
||||
|
||||
private:
|
||||
static int _QUICK_SELECT_DELAY;
|
||||
static uInt64 _QUICK_SELECT_DELAY;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,15 +102,15 @@ OSystemMACOSX::~OSystemMACOSX()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 OSystemMACOSX::getTicks() const
|
||||
uInt64 OSystemMACOSX::getTicks() const
|
||||
{
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
|
||||
return (uInt32) (now.tv_sec * 1000000 + now.tv_usec);
|
||||
return uInt64(now.tv_sec) * 1000000 + now.tv_usec;
|
||||
#else
|
||||
return (uInt32) SDL_GetTicks() * 1000;
|
||||
return uInt64(SDL_GetTicks()) * 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class OSystemMACOSX : public OSystem
|
|||
|
||||
@return Current time in microseconds.
|
||||
*/
|
||||
virtual uInt32 getTicks() const;
|
||||
virtual uInt64 getTicks() const;
|
||||
|
||||
/**
|
||||
This method queries the dimensions of the screen for this hardware.
|
||||
|
|
|
@ -52,14 +52,14 @@ OSystemUNIX::~OSystemUNIX()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 OSystemUNIX::getTicks() const
|
||||
uInt64 OSystemUNIX::getTicks() const
|
||||
{
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
|
||||
return (uInt32) (now.tv_sec * 1000000 + now.tv_usec);
|
||||
return uInt64(now.tv_sec) * 1000000 + now.tv_usec;
|
||||
#else
|
||||
return (uInt32) SDL_GetTicks() * 1000;
|
||||
return uInt64(SDL_GetTicks()) * 1000;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ class OSystemUNIX : public OSystem
|
|||
|
||||
@return Current time in microseconds.
|
||||
*/
|
||||
uInt32 getTicks() const;
|
||||
uInt64 getTicks() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -87,7 +87,7 @@ OSystemWin32::~OSystemWin32()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 OSystemWin32::getTicks() const
|
||||
uInt64 OSystemWin32::getTicks() const
|
||||
{
|
||||
return (uInt32) SDL_GetTicks() * 1000;
|
||||
return uInt64(SDL_GetTicks()) * 1000;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class OSystemWin32 : public OSystem
|
|||
|
||||
@return Current time in microseconds.
|
||||
*/
|
||||
virtual uInt32 getTicks() const;
|
||||
virtual uInt64 getTicks() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue