mtrevival 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nasser Albusaidi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: mtrevival
3
+ Version: 0.3.1
4
+ Summary: Make Monopoly Tycoon (2001) run on modern Windows
5
+ Author: Nasser Albusaidi
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/NasserAlbusaidi/monopoly-tycoon-revival
8
+ Project-URL: Issues, https://github.com/NasserAlbusaidi/monopoly-tycoon-revival/issues
9
+ Project-URL: Changelog, https://github.com/NasserAlbusaidi/monopoly-tycoon-revival/blob/main/CHANGELOG.md
10
+ Keywords: monopoly-tycoon,game-preservation,windows,directshow
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: End Users/Desktop
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Topic :: Games/Entertainment
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: license-file
22
+
23
+ # Monopoly Tycoon Revival
24
+
25
+ Make **Monopoly Tycoon** (2001, Deep Red Games / Infogrames) install and run on
26
+ Windows 10 and 11.
27
+
28
+ The game installs fine on modern Windows and then crashes on startup — usually
29
+ right after the studio logo, sometimes before anything appears. There are two
30
+ separate causes, both fixable in about a minute. No patched executable, no
31
+ compatibility mode. The soundtrack needs one small COM shim registered for
32
+ your user account; everything else is a text file.
33
+
34
+ **This repository contains no game content.** You need your own copy of the game.
35
+
36
+ ---
37
+
38
+ ## Quick fix, by hand
39
+
40
+ ### 1. Let the game write to its own folder
41
+
42
+ The game stores settings, profiles and savegames next to `mc.exe`. Under
43
+ `C:\Program Files (x86)` a standard user account cannot write there, so the game
44
+ silently fails to save anything — including the settings that fix the crash.
45
+
46
+ Run once in an **elevated** PowerShell:
47
+
48
+ ```powershell
49
+ icacls "C:\Program Files (x86)\Infogrames\Monopoly Tycoon" /grant "$($env:USERNAME):(OI)(CI)M" /T
50
+ ```
51
+
52
+ ### 2. Create `config.cfg`
53
+
54
+ In the game folder, create a file named `config.cfg`:
55
+
56
+ ```
57
+ SysSetup api D3D
58
+ SysSetup device 1
59
+ SysSetup width 640
60
+ SysSetup height 480
61
+ SysSetup bitdepth 32
62
+ SysSetup texbitdepth 16
63
+ SysSetup music 1
64
+ ```
65
+
66
+ **`device` is the display adapter index and is specific to your machine.** Use
67
+ `0` if your primary display is a normal landscape monitor. Use `1` (or higher)
68
+ if your primary display is rotated to portrait, or does not offer a 640×480
69
+ mode. The tool below works this out for you.
70
+
71
+ `music 1` means music **off**. That is the safe setting without the shim
72
+ described under [Music](#music); the game runs, silently.
73
+
74
+ That is the whole fix. Launch `mc.exe`.
75
+
76
+ ---
77
+
78
+ ## Working it out automatically
79
+
80
+ Requires Python 3.12 or newer. Standard library only.
81
+
82
+ ```
83
+ py -m pip install mtrevival # or: pipx install mtrevival
84
+ mtrevival adapters # list adapters, show which support 640x480
85
+ mtrevival check # show what would be written, change nothing
86
+ mtrevival fix # write config.cfg, backing up any existing one
87
+
88
+ mtrevival fix --resolution 1920x1080 # any mode the adapter lists
89
+ mtrevival fix --resolution 1280x720 --windowed # windowed needs patch 1.2
90
+ mtrevival fix --music # restore the soundtrack
91
+ ```
92
+
93
+ `py -m mtrevival …` works too. From a git checkout use `py -m pip install .`;
94
+ the music shim then needs building (see `CONTRIBUTING.md`) or the DLL from a
95
+ [release](https://github.com/NasserAlbusaidi/monopoly-tycoon-revival/releases).
96
+
97
+ Example on a machine with a portrait primary display:
98
+
99
+ ```
100
+ source: D3DEnum.txt
101
+ adapter 0 NVIDIA GeForce RTX 4080 modes=46 no 640x480 [portrait]
102
+ adapter 1 NVIDIA GeForce RTX 4080 modes=54 OK 640x480
103
+ ```
104
+
105
+ `fix` never overwrites an existing `config.cfg` without copying it to a
106
+ timestamped `.bak` first.
107
+
108
+ ### Music
109
+
110
+ The game plays its WMA soundtrack through a DirectShow filter that Windows
111
+ dropped years ago. `fix --music` copies `wmsource-shim.dll` (built from
112
+ [`tools/wmsource-shim`](tools/wmsource-shim), source included) next to
113
+ `mc.exe`, registers it **for your user only** — no elevation, nothing outside
114
+ your profile — and writes `music 0`. The shim hands the game Windows' own
115
+ WM ASF Reader with the two adaptations the game needs. Details, evidence and
116
+ removal in [`docs/music.md`](docs/music.md).
117
+
118
+ Do not run the game "as administrator" with music on: an elevated process
119
+ cannot see per-user COM registrations. `fix --music` warns if that flag is set.
120
+
121
+ ---
122
+
123
+ ## What actually goes wrong
124
+
125
+ Both crashes are the same defect: the game creates an object, never checks
126
+ whether creation succeeded, and then dereferences the null pointer.
127
+
128
+ ### Crash 1 — access violation at `mc.exe+0x000E792E`
129
+
130
+ Windows logs exception `0xC0000005`, fault offset `0x000E792E`, faulting module
131
+ `mc.exe`. The instruction is:
132
+
133
+ ```asm
134
+ 004E78FE call dword ptr [edx+0x3C] ; IDirect3D8::CreateDevice (vtable slot 15)
135
+ 004E7901 mov eax, [ebp+0x44] ; ...continues without checking the HRESULT
136
+ 004E792E mov ecx, [eax] ; <-- faults, EAX = 0
137
+ 004E7932 call dword ptr [ecx+0xA0] ; IDirect3DDevice8::SetViewport (slot 40)
138
+ ```
139
+
140
+ The game requests **640×480 exclusive fullscreen** on adapter 0. Recovered
141
+ `D3DPRESENT_PARAMETERS` from a crash dump:
142
+
143
+ | Field | Value |
144
+ |---|---|
145
+ | BackBufferWidth / Height | 640 × 480 |
146
+ | BackBufferFormat | 22 (`D3DFMT_X8R8G8B8`) |
147
+ | Windowed | 0 — exclusive fullscreen |
148
+ | returned device | **NULL** |
149
+
150
+ For exclusive fullscreen, Direct3D 8 requires the width, height and format to
151
+ match an enumerated display mode. If your primary display is rotated to
152
+ portrait, its mode list contains `480 X 640` and **no** `640 X 480`.
153
+ `CreateDevice` fails, and the unchecked null device is dereferenced by
154
+ `SetViewport`.
155
+
156
+ The game writes its own evidence to `D3DEnum.txt` in the install folder. Look for
157
+ an adapter whose modes are all taller than they are wide — that is the culprit.
158
+
159
+ **Fix:** point `SysSetup device` at an adapter that offers 640×480.
160
+
161
+ ### Crash 2 — access violation at `mc.exe+0x000A801B`
162
+
163
+ ```asm
164
+ 004A8007 call dword ptr [0x96E4E8] ; MultiByteToWideChar -> filename
165
+ 004A800D mov eax, [ebx+0x2CE8] ; media interface -> NULL
166
+ 004A801B mov edx, [eax] ; <-- faults, EAX = 0
167
+ 004A801E call dword ptr [edx+0xC]
168
+ ```
169
+
170
+ The filename recovered from the dump is
171
+ `gamedata\sound\music\music_intro.wma`. The game builds a DirectShow graph to
172
+ play its WMA soundtrack and asks for the 2001 Windows Media DirectShow source
173
+ filter by CLSID. Windows 11 keeps only a 5 KB stub of `dxmasf.dll` and no
174
+ longer registers the class, so `CoCreateInstance` fails. `quartz.dll` and
175
+ `devenum.dll` load; the Windows Media source does not. The interface comes
176
+ back null and is used anyway.
177
+
178
+ **Fix:** `SysSetup music 1` suppresses that path, and the game runs without
179
+ its music. `fix --music` restores it: the filter the game asks for,
180
+ `{6B6D0800-…}`, is answered by a shim that wraps Windows' WM ASF Reader,
181
+ creating a fresh reader per track (the reader refuses a second `Load`) and
182
+ mapping the game's `FindPin(L"Stream 1")` onto the reader's `Raw Audio 0`.
183
+ The 2001 Windows Media redistributable on the CD is not touched. See
184
+ [`docs/music.md`](docs/music.md).
185
+
186
+ ---
187
+
188
+ ## Compatibility notes
189
+
190
+ - Tested on Windows 11 Pro (build 26200), NVIDIA RTX 4080, English CD.
191
+ Verified with game version 1.0 and again after applying the official patch
192
+ 1.2 — the same `config.cfg` works for both. Verified on one machine only.
193
+ - Patch 1.2 applies cleanly on Windows 11 when run **elevated**. It changes
194
+ `mc.exe`, three Lua scripts and the string tables, and leaves `config.cfg`
195
+ alone. Both crashes above are still present in the 1.2 executable. Details
196
+ in [`docs/patch-1.2.md`](docs/patch-1.2.md).
197
+ - Resolution is free. `SysSetup width` / `height` accept any mode the chosen
198
+ adapter enumerates; 1920×1080 exclusive fullscreen and 1280×720 windowed
199
+ (`SysSetup Window 1`, patch 1.2 only) were verified running with a sane UI.
200
+ The 1.0 key `windowed` is ignored; 1.2 renamed it.
201
+ - Music was verified on patch 1.2 (intro track by ear, all ten tracks and
202
+ repeated track changes in a DirectShow harness). It needs Windows Media,
203
+ which N editions get from the Media Feature Pack.
204
+ - Patch 1.2 drops an empty `MTS.txt` in the game folder while it runs and
205
+ removes it on exit. If the game is killed, delete that file, or the next
206
+ launch offers Safe Mode and overwrites `config.cfg`.
207
+ - GameSpy multiplayer is dead and out of scope.
208
+
209
+ ## Modding
210
+
211
+ The game is unusually open for its age, and this is the reason the project
212
+ exists. All verified:
213
+
214
+ - **200 plain-text Lua scripts** in `scripts\`, across 56 namespaces —
215
+ `DEFAULT`, `MAPS`, `SCENARIO1`–`SCENARIO20`, `TUTORIAL1`–`TUTORIAL12`,
216
+ `NET0`–`NET8`. Economy tuning lives in `businesssettings.lua`,
217
+ `blocksettings.lua` and `commoditysettings.lua`.
218
+ - **Saves are Lua too.** `profiles\<name>\settings.lua` contains
219
+ `g_ProfileOptions.BoardName = "gb"`, which selects among **19 national
220
+ boards** shipped on the disc (`usa`, `f`, `ger`, `aus`, `swe`, and more).
221
+ - `parameters\*.prm` holds per-decade tuning, plus `aiparameter.prm` and
222
+ `consumer.prm`.
223
+ - The shipped executable still contains debug flags (`AIDEBUG`, `DEBUGTEXT`,
224
+ `SHOWALLCARS`, `CHEATINGGIT`) and remnants of the developers' block and
225
+ building editors.
226
+
227
+ See [`docs/phase-0-findings.md`](docs/phase-0-findings.md) for the full
228
+ investigation, and
229
+ [`docs/superpowers/specs/`](docs/superpowers/specs/) for the project design.
230
+
231
+ ## Licence
232
+
233
+ MIT — see [LICENSE](LICENSE). This covers the tools and documentation in this
234
+ repository only. Monopoly Tycoon itself is the property of its rights holders
235
+ and is not distributed here.
@@ -0,0 +1,213 @@
1
+ # Monopoly Tycoon Revival
2
+
3
+ Make **Monopoly Tycoon** (2001, Deep Red Games / Infogrames) install and run on
4
+ Windows 10 and 11.
5
+
6
+ The game installs fine on modern Windows and then crashes on startup — usually
7
+ right after the studio logo, sometimes before anything appears. There are two
8
+ separate causes, both fixable in about a minute. No patched executable, no
9
+ compatibility mode. The soundtrack needs one small COM shim registered for
10
+ your user account; everything else is a text file.
11
+
12
+ **This repository contains no game content.** You need your own copy of the game.
13
+
14
+ ---
15
+
16
+ ## Quick fix, by hand
17
+
18
+ ### 1. Let the game write to its own folder
19
+
20
+ The game stores settings, profiles and savegames next to `mc.exe`. Under
21
+ `C:\Program Files (x86)` a standard user account cannot write there, so the game
22
+ silently fails to save anything — including the settings that fix the crash.
23
+
24
+ Run once in an **elevated** PowerShell:
25
+
26
+ ```powershell
27
+ icacls "C:\Program Files (x86)\Infogrames\Monopoly Tycoon" /grant "$($env:USERNAME):(OI)(CI)M" /T
28
+ ```
29
+
30
+ ### 2. Create `config.cfg`
31
+
32
+ In the game folder, create a file named `config.cfg`:
33
+
34
+ ```
35
+ SysSetup api D3D
36
+ SysSetup device 1
37
+ SysSetup width 640
38
+ SysSetup height 480
39
+ SysSetup bitdepth 32
40
+ SysSetup texbitdepth 16
41
+ SysSetup music 1
42
+ ```
43
+
44
+ **`device` is the display adapter index and is specific to your machine.** Use
45
+ `0` if your primary display is a normal landscape monitor. Use `1` (or higher)
46
+ if your primary display is rotated to portrait, or does not offer a 640×480
47
+ mode. The tool below works this out for you.
48
+
49
+ `music 1` means music **off**. That is the safe setting without the shim
50
+ described under [Music](#music); the game runs, silently.
51
+
52
+ That is the whole fix. Launch `mc.exe`.
53
+
54
+ ---
55
+
56
+ ## Working it out automatically
57
+
58
+ Requires Python 3.12 or newer. Standard library only.
59
+
60
+ ```
61
+ py -m pip install mtrevival # or: pipx install mtrevival
62
+ mtrevival adapters # list adapters, show which support 640x480
63
+ mtrevival check # show what would be written, change nothing
64
+ mtrevival fix # write config.cfg, backing up any existing one
65
+
66
+ mtrevival fix --resolution 1920x1080 # any mode the adapter lists
67
+ mtrevival fix --resolution 1280x720 --windowed # windowed needs patch 1.2
68
+ mtrevival fix --music # restore the soundtrack
69
+ ```
70
+
71
+ `py -m mtrevival …` works too. From a git checkout use `py -m pip install .`;
72
+ the music shim then needs building (see `CONTRIBUTING.md`) or the DLL from a
73
+ [release](https://github.com/NasserAlbusaidi/monopoly-tycoon-revival/releases).
74
+
75
+ Example on a machine with a portrait primary display:
76
+
77
+ ```
78
+ source: D3DEnum.txt
79
+ adapter 0 NVIDIA GeForce RTX 4080 modes=46 no 640x480 [portrait]
80
+ adapter 1 NVIDIA GeForce RTX 4080 modes=54 OK 640x480
81
+ ```
82
+
83
+ `fix` never overwrites an existing `config.cfg` without copying it to a
84
+ timestamped `.bak` first.
85
+
86
+ ### Music
87
+
88
+ The game plays its WMA soundtrack through a DirectShow filter that Windows
89
+ dropped years ago. `fix --music` copies `wmsource-shim.dll` (built from
90
+ [`tools/wmsource-shim`](tools/wmsource-shim), source included) next to
91
+ `mc.exe`, registers it **for your user only** — no elevation, nothing outside
92
+ your profile — and writes `music 0`. The shim hands the game Windows' own
93
+ WM ASF Reader with the two adaptations the game needs. Details, evidence and
94
+ removal in [`docs/music.md`](docs/music.md).
95
+
96
+ Do not run the game "as administrator" with music on: an elevated process
97
+ cannot see per-user COM registrations. `fix --music` warns if that flag is set.
98
+
99
+ ---
100
+
101
+ ## What actually goes wrong
102
+
103
+ Both crashes are the same defect: the game creates an object, never checks
104
+ whether creation succeeded, and then dereferences the null pointer.
105
+
106
+ ### Crash 1 — access violation at `mc.exe+0x000E792E`
107
+
108
+ Windows logs exception `0xC0000005`, fault offset `0x000E792E`, faulting module
109
+ `mc.exe`. The instruction is:
110
+
111
+ ```asm
112
+ 004E78FE call dword ptr [edx+0x3C] ; IDirect3D8::CreateDevice (vtable slot 15)
113
+ 004E7901 mov eax, [ebp+0x44] ; ...continues without checking the HRESULT
114
+ 004E792E mov ecx, [eax] ; <-- faults, EAX = 0
115
+ 004E7932 call dword ptr [ecx+0xA0] ; IDirect3DDevice8::SetViewport (slot 40)
116
+ ```
117
+
118
+ The game requests **640×480 exclusive fullscreen** on adapter 0. Recovered
119
+ `D3DPRESENT_PARAMETERS` from a crash dump:
120
+
121
+ | Field | Value |
122
+ |---|---|
123
+ | BackBufferWidth / Height | 640 × 480 |
124
+ | BackBufferFormat | 22 (`D3DFMT_X8R8G8B8`) |
125
+ | Windowed | 0 — exclusive fullscreen |
126
+ | returned device | **NULL** |
127
+
128
+ For exclusive fullscreen, Direct3D 8 requires the width, height and format to
129
+ match an enumerated display mode. If your primary display is rotated to
130
+ portrait, its mode list contains `480 X 640` and **no** `640 X 480`.
131
+ `CreateDevice` fails, and the unchecked null device is dereferenced by
132
+ `SetViewport`.
133
+
134
+ The game writes its own evidence to `D3DEnum.txt` in the install folder. Look for
135
+ an adapter whose modes are all taller than they are wide — that is the culprit.
136
+
137
+ **Fix:** point `SysSetup device` at an adapter that offers 640×480.
138
+
139
+ ### Crash 2 — access violation at `mc.exe+0x000A801B`
140
+
141
+ ```asm
142
+ 004A8007 call dword ptr [0x96E4E8] ; MultiByteToWideChar -> filename
143
+ 004A800D mov eax, [ebx+0x2CE8] ; media interface -> NULL
144
+ 004A801B mov edx, [eax] ; <-- faults, EAX = 0
145
+ 004A801E call dword ptr [edx+0xC]
146
+ ```
147
+
148
+ The filename recovered from the dump is
149
+ `gamedata\sound\music\music_intro.wma`. The game builds a DirectShow graph to
150
+ play its WMA soundtrack and asks for the 2001 Windows Media DirectShow source
151
+ filter by CLSID. Windows 11 keeps only a 5 KB stub of `dxmasf.dll` and no
152
+ longer registers the class, so `CoCreateInstance` fails. `quartz.dll` and
153
+ `devenum.dll` load; the Windows Media source does not. The interface comes
154
+ back null and is used anyway.
155
+
156
+ **Fix:** `SysSetup music 1` suppresses that path, and the game runs without
157
+ its music. `fix --music` restores it: the filter the game asks for,
158
+ `{6B6D0800-…}`, is answered by a shim that wraps Windows' WM ASF Reader,
159
+ creating a fresh reader per track (the reader refuses a second `Load`) and
160
+ mapping the game's `FindPin(L"Stream 1")` onto the reader's `Raw Audio 0`.
161
+ The 2001 Windows Media redistributable on the CD is not touched. See
162
+ [`docs/music.md`](docs/music.md).
163
+
164
+ ---
165
+
166
+ ## Compatibility notes
167
+
168
+ - Tested on Windows 11 Pro (build 26200), NVIDIA RTX 4080, English CD.
169
+ Verified with game version 1.0 and again after applying the official patch
170
+ 1.2 — the same `config.cfg` works for both. Verified on one machine only.
171
+ - Patch 1.2 applies cleanly on Windows 11 when run **elevated**. It changes
172
+ `mc.exe`, three Lua scripts and the string tables, and leaves `config.cfg`
173
+ alone. Both crashes above are still present in the 1.2 executable. Details
174
+ in [`docs/patch-1.2.md`](docs/patch-1.2.md).
175
+ - Resolution is free. `SysSetup width` / `height` accept any mode the chosen
176
+ adapter enumerates; 1920×1080 exclusive fullscreen and 1280×720 windowed
177
+ (`SysSetup Window 1`, patch 1.2 only) were verified running with a sane UI.
178
+ The 1.0 key `windowed` is ignored; 1.2 renamed it.
179
+ - Music was verified on patch 1.2 (intro track by ear, all ten tracks and
180
+ repeated track changes in a DirectShow harness). It needs Windows Media,
181
+ which N editions get from the Media Feature Pack.
182
+ - Patch 1.2 drops an empty `MTS.txt` in the game folder while it runs and
183
+ removes it on exit. If the game is killed, delete that file, or the next
184
+ launch offers Safe Mode and overwrites `config.cfg`.
185
+ - GameSpy multiplayer is dead and out of scope.
186
+
187
+ ## Modding
188
+
189
+ The game is unusually open for its age, and this is the reason the project
190
+ exists. All verified:
191
+
192
+ - **200 plain-text Lua scripts** in `scripts\`, across 56 namespaces —
193
+ `DEFAULT`, `MAPS`, `SCENARIO1`–`SCENARIO20`, `TUTORIAL1`–`TUTORIAL12`,
194
+ `NET0`–`NET8`. Economy tuning lives in `businesssettings.lua`,
195
+ `blocksettings.lua` and `commoditysettings.lua`.
196
+ - **Saves are Lua too.** `profiles\<name>\settings.lua` contains
197
+ `g_ProfileOptions.BoardName = "gb"`, which selects among **19 national
198
+ boards** shipped on the disc (`usa`, `f`, `ger`, `aus`, `swe`, and more).
199
+ - `parameters\*.prm` holds per-decade tuning, plus `aiparameter.prm` and
200
+ `consumer.prm`.
201
+ - The shipped executable still contains debug flags (`AIDEBUG`, `DEBUGTEXT`,
202
+ `SHOWALLCARS`, `CHEATINGGIT`) and remnants of the developers' block and
203
+ building editors.
204
+
205
+ See [`docs/phase-0-findings.md`](docs/phase-0-findings.md) for the full
206
+ investigation, and
207
+ [`docs/superpowers/specs/`](docs/superpowers/specs/) for the project design.
208
+
209
+ ## Licence
210
+
211
+ MIT — see [LICENSE](LICENSE). This covers the tools and documentation in this
212
+ repository only. Monopoly Tycoon itself is the property of its rights holders
213
+ and is not distributed here.
@@ -0,0 +1,42 @@
1
+ [project]
2
+ name = "mtrevival"
3
+ version = "0.3.1"
4
+ description = "Make Monopoly Tycoon (2001) run on modern Windows"
5
+ readme = "README.md"
6
+ license = {text = "MIT"}
7
+ authors = [{name = "Nasser Albusaidi"}]
8
+ requires-python = ">=3.12"
9
+ dependencies = []
10
+ keywords = ["monopoly-tycoon", "game-preservation", "windows", "directshow"]
11
+ classifiers = [
12
+ "Development Status :: 4 - Beta",
13
+ "Environment :: Console",
14
+ "Intended Audience :: End Users/Desktop",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: Microsoft :: Windows",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "Topic :: Games/Entertainment",
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/NasserAlbusaidi/monopoly-tycoon-revival"
23
+ Issues = "https://github.com/NasserAlbusaidi/monopoly-tycoon-revival/issues"
24
+ Changelog = "https://github.com/NasserAlbusaidi/monopoly-tycoon-revival/blob/main/CHANGELOG.md"
25
+
26
+ [project.scripts]
27
+ mtrevival = "mtrevival.__main__:main"
28
+
29
+ [build-system]
30
+ requires = ["setuptools>=68"]
31
+ build-backend = "setuptools.build_meta"
32
+
33
+ [tool.setuptools.packages.find]
34
+ where = ["src"]
35
+
36
+ [tool.setuptools.package-data]
37
+ # The music shim, built from tools/wmsource-shim by build.ps1.
38
+ mtrevival = ["bin/wmsource-shim.dll"]
39
+
40
+ [tool.pytest.ini_options]
41
+ testpaths = ["tests"]
42
+ pythonpath = ["src", "tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """Tools for reviving Monopoly Tycoon (2001)."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,95 @@
1
+ """Command line entry point: ``python -m mtrevival``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import re
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from . import fixpack
11
+
12
+ _RESOLUTION = re.compile(r"^(\d{3,4})x(\d{3,4})$")
13
+
14
+
15
+ def resolution(text: str) -> tuple[int, int]:
16
+ """argparse type for WIDTHxHEIGHT."""
17
+ m = _RESOLUTION.match(text.strip().lower())
18
+ if not m:
19
+ raise argparse.ArgumentTypeError(
20
+ "expected WIDTHxHEIGHT such as 1920x1080, got %r" % text)
21
+ return int(m.group(1)), int(m.group(2))
22
+
23
+
24
+ def main(argv: list[str] | None = None) -> int:
25
+ parser = argparse.ArgumentParser(
26
+ prog="mtrevival",
27
+ description="Make Monopoly Tycoon (2001) run on modern Windows.")
28
+ sub = parser.add_subparsers(dest="command", required=True)
29
+
30
+ def common(p: argparse.ArgumentParser) -> None:
31
+ p.add_argument("--game-dir", type=Path, default=None,
32
+ help="install directory containing mc.exe")
33
+ p.add_argument("--resolution", type=resolution,
34
+ default=(fixpack.DEFAULT_WIDTH, fixpack.DEFAULT_HEIGHT),
35
+ metavar="WxH",
36
+ help="display mode, default %dx%d; the adapter must list it"
37
+ % (fixpack.DEFAULT_WIDTH, fixpack.DEFAULT_HEIGHT))
38
+
39
+ for name, help_text in (("check", "report what would be done, change nothing"),
40
+ ("fix", "write config.cfg with a working adapter")):
41
+ p = sub.add_parser(name, help=help_text)
42
+ common(p)
43
+ p.add_argument("--windowed", action="store_true",
44
+ help="run in a window instead of fullscreen (needs patch 1.2)")
45
+ p.add_argument("--music", action="store_true",
46
+ help="restore the soundtrack: install the wmsource-shim "
47
+ "for this user and write music 0")
48
+ common(sub.add_parser("adapters", help="list adapters and whether they fit"))
49
+
50
+ args = parser.parse_args(argv)
51
+ width, height = args.resolution
52
+ windowed = getattr(args, "windowed", False)
53
+ with_music = getattr(args, "music", False)
54
+
55
+ try:
56
+ game_dir = fixpack.find_install(args.game_dir)
57
+ except fixpack.FixError as error:
58
+ print("error: %s" % error, file=sys.stderr)
59
+ return 2
60
+
61
+ if args.command == "adapters":
62
+ adapters, source = fixpack.read_adapters(game_dir)
63
+ print("source: %s" % source)
64
+ for adapter in adapters:
65
+ fits = adapter.supports(width, height)
66
+ print(" adapter %d %-34s modes=%-4d %s%s"
67
+ % (adapter.index, adapter.description or "(unnamed)",
68
+ len(adapter.modes),
69
+ ("OK %dx%d" if fits else "no %dx%d") % (width, height),
70
+ " [portrait]" if adapter.is_portrait else ""))
71
+ return 0
72
+
73
+ plan = fixpack.build_plan(game_dir, width, height, windowed, with_music)
74
+ print(fixpack.describe(plan))
75
+
76
+ if args.command == "check":
77
+ return 0 if plan.ok else 1
78
+
79
+ try:
80
+ backup = fixpack.apply(plan)
81
+ except fixpack.FixError as error:
82
+ print("\nerror: %s" % error, file=sys.stderr)
83
+ return 1
84
+
85
+ if plan.music:
86
+ print("\nInstalled %s and registered it for this user." % plan.shim_target)
87
+ print("\nWrote %s" % plan.config_path)
88
+ if backup:
89
+ print("Backed up previous config to %s" % backup)
90
+ print("Launch the game with mc.exe.")
91
+ return 0
92
+
93
+
94
+ if __name__ == "__main__":
95
+ sys.exit(main())