Captures all findings from the 2026-08-07 debugging session: print flow diagram, DoPrint error codes, which commits changed what, hypotheses explored/ruled out, and next steps once the -debug log is available. Co-authored-by: Claude Sonnet 4.6 (Anthropic) <noreply@anthropic.com> Co-authored-by: GitHub Copilot <copilot@github.com>
5.9 KiB
mw4print ? Known Issues & Research (2026-08-07)
Symptom
Printing is broken in the current build (post-b98cb87e).
- Without MySQL enabled: never prints, neither on mission-end (WM_COPYDATA) nor on manual File ¡æ Open.
- With MySQL enabled: app locks up ~5 seconds, prints one mission, then never prints again until restart.
"Anymore" = it worked before the MySQL/banner commits.
Print Flow (how it works)
Game (MW4.exe)
¦¦¦¡ SendMessage(WM_COPYDATA, filename)
¦¦¦¡ CMainFrame::OnCopyData
¦¦¦¡ CChildView::DoCopyData ¡ç adds CMyPrintInfo to m_lstMPIs queue
1-second WM_TIMER
¦¦¦¡ CChildView::OnTimer
¦¦¦¡ g_RSF.LoadPR(p->m_strFile) ¡ç opens and parses .pr file
¦¦¦¡ g_RSF.DoPrint() ¡ç if nErr==0: remove from queue
¦¦¦¡ g_RSF.Reset()
Manual path (File ¡æ Open) also adds to m_lstMPIs; the timer handles both cases identically.
DoPrint() internal flow
DoPrint()
LoadPrintParams() ¡ç reads options.ini / banner.txt
count m_pScoreObjects ¡æ nPlayers
if nPlayers == 0: return 0 silently (no print, item still removed!)
PrintDlg(PD_RETURNDEFAULT | PD_RETURNDC)
¦§¦¡ fail ¡æ nErr = -1, CommDlgExtendedError() has the reason
¦¦¦¡ ok ¡æ hDC set
MakeInfoTable / params.LoadParameters
[#ifdef MW4PRINT] if g_dbConfig.bEnabled: DB_ExportMatch() ¡ç 5s timeout here
SetupFonts(DPI) fail ¡æ nErr = -2
StartDoc fail ¡æ nErr = -3
per-player loop:
StartPage / DoPrint(hDC, ...) / EndPage fail ¡æ nErr = -4
EndDoc (or AbortDoc on error)
DeleteDC / delete pInfoTable
return nErr
Key return codes
| nErr | Meaning |
|---|---|
| 0 | Success (or nPlayers==0 ? silent non-print) |
| -1 | PrintDlg returned FALSE ? check CommDlgExtendedError() |
| -2 | SetupFonts failed |
| -3 | StartDoc failed |
| -4 | EndPage failed mid-print |
Commits that changed mw4print
| Hash | Description |
|---|---|
b98cb87e |
MySQL export, configurable banner text ? first change |
9f3a5044 / a45be804 |
Version bump to 2.0 (rc only) |
515adc24 |
persist banner text via banner.txt ? second change |
3256c103 |
-debug diagnostic logging (current) |
What b98cb87e actually changed inside DoPrint
The ONLY addition inside DoPrint when MySQL is disabled:
#ifdef MW4PRINT
if (g_dbConfig.bEnabled) {
DB_ExportMatch(...); // ¡ç gated; skipped when bEnabled=false
}
#endif
So with MySQL disabled, DoPrint() is byte-for-byte identical to the pre-b98cb87e code. If it's failing, the failure is NOT in this block.
What 515adc24 changed in LoadPrintParams
Fixed a missing backslash in the options.ini path:
// before: strOI += "options.ini"; ¡æ "C:\MW4options.ini" (wrong)
strOI += "\\options.ini"; ¡æ "C:\MW4\options.ini" (correct)
Side-effect: before the fix, all layout params used their hardcoded defaults. After the fix, they read from the real options.ini. If that file has unusual values, print layout could differ ? but all params are clamped to sane min/max so they can't cause a crash.
Key facts established
MW4PRINTIS defined ? it's inmw4dummy.h(#define MW4PRINT), which is#included before everything inChildView.cpp.DB_ExportMatchis called afterPrintDlg, not before. The 5-second "lockup" with MySQL = connection-timeout insideDB_ExportMatch, which is reached only afterPrintDlghas already succeeded.LoadPRalways returnstrueif the file opens, even if the meta-header parse fails. If parse fails,m_pScoreObjects = NULL¡ænPlayers = 0¡æDoPrintreturns 0 silently.AssetsDirectory1has no trailing backslash (stripped inInitInstance).
Hypotheses explored (and ruled out)
| Hypothesis | Status |
|---|---|
| MySQL blocks before PrintDlg | ? Wrong ? DB_ExportMatch is called after PrintDlg |
| MW4PRINT not defined | ? Defined in mw4dummy.h |
| options.ini path fix breaks layout | ? All params clamped; can't cause crash |
| Message-map corruption from new dialogs | ? Maps look correct |
| LoadPR always fails | ? Returns true if file exists, regardless of parse |
| Memory corruption from DB code | Unconfirmed |
| PrintDlg returns FALSE (no default printer) | Active hypothesis |
| nPlayers == 0 (parse failure / all bots) | Active hypothesis |
Current debugging approach
Commit 3256c103 adds a -debug flag. Run:
mw4print.exe -debug
Output goes to mw4print-debug.txt next to the exe (append, timestamped).
What the log tells us
DoPrint: nPlayers=0
¡æ File opened but no players found. Either the .pr file has an unrecognised meta header,
or all players are bots and g_bPRTest=false (no "Include Bot" checkbox ticked).
DoPrint: PrintDlg FAILED nErr=-1, CommDlgExtendedError=0000100A
¡æ CDERR_NODEFAULTPRN ? no default printer is configured on this machine.
DoPrint: PrintDlg FAILED nErr=-1, CommDlgExtendedError=00000000
¡æ PrintDlg returned FALSE with no error. Unusual; may indicate a hidden dialog or modal conflict.
OnTimer: LoadPR FAILED for 'C:\...'
¡æ fopen failed ? file was deleted between WM_COPYDATA arriving and the timer firing.
Next steps
- Build from current source on Windows (quick ? only
ChildView.cpprecompiles). - Run
mw4print.exe -debug, do File ¡æ Open on a known .pr file, wait 2 seconds. - Read
mw4print-debug.txtand look for the first failure line. - Act on the specific error:
nPlayers=0¡æ check .pr file validity; check if "Include Bot" is neededCommDlgExtendedError=0000100A¡æ configure a default printer on the test machine- Other ¡æ investigate that specific failure path