In the new version I have these options...
--vcalc [0|1|2] Method of calculating width on vertical games (1 is wider than 0)
--dcalign <HZ> Align dotclock to Hz (Windows 10000 Linux 1000)
So basically --vcalc 0 (default) is the new correct way, 1 is the old 4/3 way which some people may like even though it's not as accurate. It's interesting because looking through resolution modelines in the past I've seen both methods and now explains it that there's two methods like this or two types of people I guess (I like the new way best, but can see how the old way has appeal too for me).
In Linux the dotclock align is interesting, I haven't played with it in the 2.6.36.2 kernel (stable one currently) only the in between one I've got running at 2.6.37-rc3. It doesn't seem to do much there aligning at 1000 to change refresh rate exactness yet 10000 for some reason kind of hits it close but a little over (and pacman gets that extra 313 line from that and breaks 80% of the time again, but runs when it runs almost exactly 100%). So I'm guessing it's one of those close as you can get things and can't divide up the extra line and fiddle with it any closer, especially when forced down to 1000 granularity.
In Windows how can it utilize those ones you calculated, since it stores them in alignment to 10000? Something this has made me start wondering about, or is it the extra lines doing the work to in theory get to that value? Also I see basically it goes max 5 lines more, mostly think I ported the code right, for at least the align to a value case, but was some difference I think again in C which made it in somewhat different...
if (cs->dcalign) {
int i;
int newPclock = 0;
int vIncr = 0;
double newDiff = 0, Diff = 0;
ModeLine newMode;
memcpy(&newMode, mode, sizeof(struct ModeLine));
if (cs->verbose > 3)
fprintf(stderr, "Vfreq = %f Game Refresh = %f\n", mode->vfreq, game->refresh);
for (i = 0; i < 5; i++) {
/* calculate new horizontal frequency */
mode->hfreq = mode->vfreq * (mode->vtotal + i);
if (mode->hfreq <= monitor->HfreqMax) {
/* Fill horizontal part of modeline */
newMode.hfreq = mode->hfreq;
newMode.hactive = mode->hactive;
ModelineGetLineParams(&newMode, monitor);
newMode.pclock = mode->hfreq * newMode.htotal;
if (fabs(Normalize(newMode.pclock-cs->dcalign, cs->dcalign)-newMode.pclock) < fabs(Normalize(newMode.pclock, cs->dcalign)-newMode.pclock))
newMode.pclock = Normalize(newMode.pclock, cs->dcalign) - cs->dcalign;
else
newMode.pclock = Normalize(newMode.pclock, cs->dcalign);
newMode.vfreq = newMode.pclock / ((mode->vtotal + i) * newMode.htotal);
newDiff = fabs(newMode.vfreq - mode->vfreq);
if (newDiff < Diff || Diff == 0) {
if (cs->verbose > 3)
fprintf(stderr, "[%d] Pclock: %d newVfreq: %f - Vfreq: %f newDiff = %f < Diff = %f\n",
i, newMode.pclock, newMode.vfreq, mode->vfreq, newDiff, Diff);
Diff = newDiff;
vIncr = i;
newPclock = newMode.pclock;
mode->hactive = newMode.hactive;
mode->hbegin = newMode.hbegin;
mode->hend = newMode.hend;
mode->htotal = newMode.htotal;
if (newDiff < 0.01)
break;
}
}
}
if (newPclock) {
mode->vtotal += vIncr;
mode->pclock = newPclock;
} else {
mode->hfreq = mode->vfreq * mode->vtotal;
ModelineGetLineParams(mode, monitor);
mode->pclock = mode->htotal * mode->hfreq;
}
}
There were some oddities that might need working out, like in some cases had to revert to the default method of calculation and I should probably still align it in that case to retain the extra value the OS would chop off. Also abs had to be fabs or else it only works with integers in C, and I break out early when newDiff is what seems like small enough else it didn't seem worth possibly 4 more lines to get .0001 precision which it did in the pacman case (and then broke it going above 312 lines). Also testing that pacman case is interesting, I can also break it by raising the dotclock another 10000 too, without more lines. So it's not just the lines that triggers the random wideness, but also or maybe more importantly the dotclock bandwidth or perhaps the Hfreq above 18900 that does it (like 18920 can trigger the issue from what I can tell, but 18900 perfect every time). I'm wondering if I need to make the cutoff that 1100 Hz lower for that range, currently it's 20000.