Zeus wrote:Was it hard to change the FOV?
Nope, I've done it in a day or two. More time (in addition to this two days) I've spent to fix other small bugs caused by widescreen or 5:4 resolutions. Besides this, I've also done some other interesting changes. I'm not simply changing few bytes. I'm completely rewriting some procedures in machine code. For this moment I've written more than 2500 lines of assembly code for this project.
Also I've tried to fix hangs during loading on multicore systems. But I don't have enough experience in finding deadlocks and I've spent a day for it without any result. As a temporary “solution” I've added SetProcessAffinityMask(GetCurrentProcess(), 1) call to main and corresponding option to ini file. ... And yes, I've added support of ini file. It replaces registry and now NFS3 doesn't require to import any reg files into system. I've made these changes for portability. Just copy NFSIII folder and it will work without any additional movements
If anyone good in deadlock debugging and know how to find which critical section (NFS3 heavily uses EnterCriticalSection/LeaveCriticalSection) blocks two (or more) threads (and which threads)... write to me... I'm good at patching when I definitely know what I have to change. We could overcome the problem together.
Zeus wrote:It's impossible. Otherwise I also would not have to modify nGlide in order to make extended resolutions supported.
I'm sorry, I've said incorrectly. My English isn't good enough. It isn't my native language.
I would like to say that if any other glide3x wrapper will implement this API extension, NFS3 with support of this API extension (my patch) will work without changes in code of NFS3.
Zeus wrote:Glide 2.4 do not implement grQueryResolutions. So you'll either have to use LoadLibrary(glide3x)/GetProcAddress() or I'll have to add the function also for glide.dll and glide2x.dll.
voodoo2a.dll from Future Cop uses glide3x.dll. I have even more to say. I'm using this library in my patch for NFSIII

Original voodoo2a.dll from Need For Speed CD uses glide2x.dll and it doesn't have grQueryResolutions. And this is one of the reasons why I'm using another library. Official voodoo2a.dll update for NFS3 (which uses glide3x.dll) is not fully compatible with NFS3. There is no fog and it is disgusting. This dll is rather intended for NFS4.
Future Cop and NFSIII were released in almost same time. Versions of their voodoo2a.dll libraries almost the same. It seems like voodoo2a.dll is a little updated version of voodoo2a.dll from NFS3, with Glide3x API instead of Glide2x API. As I can see they are fully compatible.
Zeus wrote:BTW, any chance for NFS4 and NFS5?
Maybe in the future. NFS4+ were compiled by Visual C++. NFS3 was compiled by Watcom C++. Different compilers produce very different machine code. It means that porting will be harder for this reason.
Zeus wrote:Code: Select all
USING EXTENDED RESOLUTIONS
- grSstWinOpen( resolution<=0xFF, refresh<=0xFF ) - original behavior using predefined constants
- grSstWinOpen( resolution=(xres<<16)|yres, refresh=(ref<<16) ) - resolution and refresh parameters in an extended format (both greater than 0xFF)
Original format example:
grSstWinOpen( resolution=7, refresh=0 ) - inits 640x480x60
Extended format example:
grSstWinOpen( resolution=0x028001E0, refresh=0x003C0000 ) - inits 640x480x60
Sounds good. I have a small suggestion here: maybe it's better to swap xres and yres:
Code: Select all
grSstWinOpen( resolution=xres|(yres<<16), refresh=(ref<<16) ) - resolution and refresh parameters in an extended format (both greater than 0xFF)
The reason: in memory bytes of integers are reversed. In your case this int32 could be treated as a struct {int16 yres, int16 xres}. In my case this struct will be {int16 xres, int16 yres} which seems a little better IMHO
In C code you even may define this kind of union for clearness (it's pseudocode):
Code: Select all
union
{
uint32 resolution_id;
struct
{
int16 width;
int16 height;
}
}
In asm code you may simply read word [esi+0] for width and word [esi+2] for height (where esi is pointer to this structure). In your case it will be word [esi+2] for width and word [esi+0] for height. Not much difference. But my perfectionism bother me in this case
Zeus wrote:Code: Select all
LISTING EXTENDED RESOLUTIONS
- grQueryResolutions( resTemplate.resolution=0xFFFFFFFF and resTemplate.refresh=0xFFFFFFFF, NULL ) -
get the structure size (extended format)
- grQueryResolutions( resTemplate.resolution=0xFFFFFFFF and resTemplate.refresh=0xFFFFFFFF, pointer ) -
get resolutions list in a GrResolution format, the difference is we will use (xres<<16)|yres for .resolution and
(ref<<16) for .refresh fields instead of predefined constants
Hm. I'm confused. An example from Glide 3x reference:
Code: Select all
GrResolution query;
GrResolution *list;
Int listSize;
/* find all possible modes that include a z-buffer */
query.resolution = GR_QUERY_ANY;
query.refresh = GR_QUERY_ANY;
query.numColorBuffers = GR_QUERY_ANY;
query.numAuxBuffers = 1;
listSize = grQueryResolutions( &query, NULL );
list = malloc( listSize );
grQueryResolutions( &query, list );
glide.h defines GR_QUERY_ANY:
Code: Select all
#define GR_QUERY_ANY ((FxU32)(~0))
It means that GR_QUERY_ANY is 0xFFFFFFFF. How do you planning to detect which type of output is needed: standard or extended? Do you mean that I have to zero query.numColorBuffers and query.numAuxBuffers and it will be a signal to use extended output? Maybe it is better to choose a little more complicated magic number (e.g. 0x7FFF7FFF which means two maximum values in structure {int16 width, int16 height} with signed integers) to avoid unexpected problems with existing games?
Also it will be nice to think about how to detect from game if glide3x.dll supports extended list of resolutions.
What do you think about this algorithm:
Code: Select all
bool is_extended = true;
GrResolution query;
GrResolution *list;
Int listSize;
query.resolution = GR_QUERY_ANY;
query.refresh = GR_QUERY_ANY;
query.numColorBuffers = 0; // extended query?
query.numAuxBuffers = 0; // extended query?
listSize = grQueryResolutions( &query, NULL );
if (!listSize)
{
// standard query
is_extended = false;
query.numColorBuffers = GR_QUERY_ANY;
query.numAuxBuffers = 1;
listSize = grQueryResolutions( &query, NULL );
}
list = malloc( listSize );
grQueryResolutions( &query, list );
It is better to test what original glide3x.dll reports to these extended queries. I would like to save compatibility with original drivers and do a fallback if glide3x.dll doesn't support extended display modes.