diff --git a/Doc/Changelog.txt b/Doc/Changelog.txt index c633a45ec..157c927a3 100644 --- a/Doc/Changelog.txt +++ b/Doc/Changelog.txt @@ -7,7 +7,12 @@ version: 0.7.3 (06/18/03) - Indexed [primitive/vertex] rendering -- Texture fixes (some users couldn't see them!) +- Fixed *part* of the invisible texture problem + +- Technique for solving the Xbox-Never-Sleeps CPU + hogging dilema. This feature is not implemented + in the release, though, as it will be more harm + than good until configuration is available. version: 0.7.2 (06/13/03) -------------------------------- diff --git a/Doc/Todo.txt b/Doc/Todo.txt index be8818fb8..5b25b6101 100644 --- a/Doc/Todo.txt +++ b/Doc/Todo.txt @@ -1,4 +1,9 @@ -Cxbx Todo (* denotes high priority) +Cxbx Todo (* denotes high priority, + denotes medium priority) + + * As a solution to the Xbox-Never-Sleeps problem, EmuSwapFS can increment + and check a global variable, and Sleep(1) after N number of function + interceptions. This could be included in the core configuration options. + Be careful that these sleeps dont take place inside of a critical section. * Perhaps for global variable detection, have some sort of array of function + offset pairs to check. That way if an Xbe happens to not @@ -7,13 +12,9 @@ Cxbx Todo (* denotes high priority) should be set to NULL, and any references to it should not assume it will not be NULL. - * When in critical section, do not print debug trace? - - * Functions like GetRenderTarget need to return a special temporary - X_D3DSurface that will somehow be cleaned up along with the "real" - X_D3DSurface pointer. Perhaps maintain a cache of all the current - temporary buffers, and whenever a resource has it's final Release(), - go through and check if any other handles reference that resource. + * Special temporarily X_D3DResource handles need to be kept track of and + periodically garbage collected. Garbage collection frequency can be a + core configuration option. * Register() probably needn't re-unswizzle each time. cache a copy of the address it was registered to (or a global table) and simply update @@ -24,40 +25,40 @@ Cxbx Todo (* denotes high priority) * GetDisplayMode / GetAdapterDisplayMode should not return real display mode when windowed! - * Stabilize Heap Allocation (i.e. operator new) -> Crashes after initial commit is full + * The notorious Heap Allocation crash still needs to be solved on a low + level. It is strongly preferable to debug this instead of having to + intercept the entire Rtl heap set of functions. * Stabilize TLS (it's close...) - What does SetLastError check Irql for? Should this be emulated? + + Closing a console should not terminate the entire process. - Perfect the timing on KeTickCount + + Perfect the timing on KeTickCount. This could be updated periodically, + similar to the Xbox-Never-Sleeps problem. - Some sort of delete-after-emulation type of functionality? + + Some sort of delete-after-emulation type of functionality? - Use SetDataFormat instead of parsing device input by hand? + + Use SetDataFormat instead of parsing device input by hand? - Batch config all buttons (should be very easy..just click one by one) + + Batch config all buttons (should be very easy..just click one by one) - Encapsulate RecentFiles into a nice little class + + Configuration screens may not necessarily need to be modal windows. - Configuration screens may not necessarily need to be modal windows. - - Closing a console should not terminate the entire process. - - If possible, Direct3D Rendering window should inherit from Wnd. - - Xbe file associations via user configuration. This could include an - option to either automatically execute the Xbe, or simply open it up - in Cxbx's main window. For this purpose, Cxbx.dll should also be - registered in the system so that a converted Exe can run from anywhere. + + Xbe file associations via user configuration. This could include an + option to either automatically execute the Xbe, or simply open it up + in Cxbx's main window. For this purpose, Cxbx.dll should also be + registered in the system so that a converted Exe can run from anywhere. Converted Exe files should use the Cxbx icon - Allow a logo bitmap to be added if one does not exist. This may require that - the size of headers be increased. (sizeof_headers). - When loading a file, menus and WM_CLOSE should be disabled and an update progress should be sent via callback from core. - Xbe::m_Header should be allocated dynamically to make room for huge headers. + Encapsulate RecentFiles into a nice little class + If possible, Direct3D Rendering window should inherit from Wnd. + + Allow a logo bitmap to be added if one does not exist. This may require that + the size of headers be increased. (sizeof_headers). + + Xbe::m_Header should be allocated dynamically to make room for huge headers. diff --git a/Include/Win32/CxbxKrnl/EmuFS.h b/Include/Win32/CxbxKrnl/EmuFS.h index 61775ffb2..a92287985 100644 --- a/Include/Win32/CxbxKrnl/EmuFS.h +++ b/Include/Win32/CxbxKrnl/EmuFS.h @@ -39,24 +39,23 @@ // word @ FS:[0x14] := wSwapFS // byte @ FS:[0x16] := bIsXboxFS +#undef FIELD_OFFSET // prevent macro redefinition warnings +#include + // ****************************************************************** -// * func: EmuSwapFS +// * func: EmuGenerateFS // ****************************************************************** -// * -// * This function is used to swap between the native Win2k/XP FS: -// * structure, and the Emu FS: structure. Before running Windows -// * code, you *must* swap over to Win2k/XP FS. Similarly, before -// * running Xbox code, you *must* swap back over to Emu FS. -// * +extern void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData); + // ****************************************************************** -static inline void EmuSwapFS() -{ - __asm - { - mov ax, fs:[0x14] - mov fs, ax - } -} +// * func: EmuCleanupFS +// ****************************************************************** +extern void EmuCleanupFS(); + +// ****************************************************************** +// * func: EmuInitFS +// ****************************************************************** +extern void EmuInitFS(); // ****************************************************************** // * func: EmuIsXboxFS @@ -81,18 +80,62 @@ static inline bool EmuIsXboxFS() } // ****************************************************************** -// * func: EmuGenerateFS +// * data: EmuAutoSleepRate // ****************************************************************** -extern void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData); +// * +// * Xbox is a single process system, and because of this fact, demos +// * and games are likely to suffer from Xbox-Never-Sleeps syndrome. +// * +// * Basically, there are situations where the Xbe will have no +// * reason to bother yielding to other threads. One solution to this +// * problem is to keep track of the number of function intercepts, +// * and every so often, force a sleep. This is the rate at which +// * those forced sleeps occur. +// * +// ****************************************************************** +extern uint32 EmuAutoSleepRate; // ****************************************************************** -// * func: EmuCleanupFS +// * func: EmuSwapFS // ****************************************************************** -extern void EmuCleanupFS(); +// * +// * This function is used to swap between the native Win2k/XP FS: +// * structure, and the Emu FS: structure. Before running Windows +// * code, you *must* swap over to Win2k/XP FS. Similarly, before +// * running Xbox code, you *must* swap back over to Emu FS. +// * +// ****************************************************************** +static inline void EmuSwapFS() +{ + // Note that this is only the *approximate* interception count, + // because not all interceptions swap the FS register, and some + // non-interception code uses it + static uint32 dwInterceptionCount = 0; -// ****************************************************************** -// * func: EmuInitFS -// ****************************************************************** -extern void EmuInitFS(); + __asm + { + mov ax, fs:[0x14] + mov fs, ax + } + + // ****************************************************************** + // * Every "N" interceptions, perform various periodic services + // ****************************************************************** + if(dwInterceptionCount++ == EmuAutoSleepRate) + { + // If we're in the Xbox FS, wait until the next swap + if(EmuIsXboxFS()) + { + dwInterceptionCount--; + return; + } + + // Yield! + Sleep(1); + + // Back to Zero! + dwInterceptionCount = 0; + } +} #endif diff --git a/Source/Win32/CxbxKrnl/EmuFS.cpp b/Source/Win32/CxbxKrnl/EmuFS.cpp index 3ce433110..c733ee40e 100644 --- a/Source/Win32/CxbxKrnl/EmuFS.cpp +++ b/Source/Win32/CxbxKrnl/EmuFS.cpp @@ -49,6 +49,11 @@ namespace xboxkrnl #include #include +// ****************************************************************** +// * data: EmuAutoSleepRate +// ****************************************************************** +uint32 EmuAutoSleepRate = -1; + // ****************************************************************** // * func: EmuInitFS // ******************************************************************