@@ -50,119 +50,125 @@ export const baseUrl$ = atom('');
50
50
51
51
export async function runGame ( entry : GameShelfEntry ) : Promise < void > {
52
52
if ( ! entry ) throw new Error ( 'Game not found' ) ;
53
- baseUrl$ . set ( entry . loadConfig . url ) ;
54
-
55
- let descriptor : GameDescriptor = entry . loadConfig . descriptor || {
56
- id : entry . id ,
57
- mode : entry . mode ,
58
- title : entry . title ,
59
- file : '' ,
60
- } ;
61
53
try {
62
- const configContent = await fetchTextContent ( baseUrl$ . value , 'game.cfg' ) ;
63
- const config = parseToml < PlayerConfig > ( configContent ) ;
64
- if ( config . game ?. length === 1 ) {
65
- [ descriptor ] = config . game ;
66
- } else {
67
- const found = config . game ?. find ( ( game ) => game . id === entry . id ) ;
68
- if ( ! found ) throw new Error ( 'Config not found' ) ;
69
- descriptor = found ;
70
- }
71
- } catch ( e ) {
72
- console . error ( 'Game config not loaded' , e ) ;
73
- }
54
+ baseUrl$ . set ( entry . loadConfig . url ) ;
74
55
75
- if ( descriptor ?. mode === 'classic' || ! descriptor ?. mode ) {
56
+ let descriptor : GameDescriptor = entry . loadConfig . descriptor || {
57
+ id : entry . id ,
58
+ mode : entry . mode ,
59
+ title : entry . title ,
60
+ file : '' ,
61
+ } ;
76
62
try {
77
- const cfgContent = await fetchTextContent ( baseUrl$ . value , 'qspgui.cfg' ) ;
78
- const cfgData = parseCfg ( cfgContent ) ;
79
- if ( ! cfgData || ! Object . keys ( cfgData ) . length ) throw new Error ( 'Invalid config file' ) ;
80
- qspGuiCfg$ . set ( cfgData ) ;
81
- } catch {
82
- // no-op
63
+ const configContent = await fetchTextContent ( baseUrl$ . value , 'game.cfg' ) ;
64
+ const config = parseToml < PlayerConfig > ( configContent ) ;
65
+ if ( config . game ?. length === 1 ) {
66
+ [ descriptor ] = config . game ;
67
+ } else {
68
+ const found = config . game ?. find ( ( game ) => game . id === entry . id ) ;
69
+ if ( ! found ) throw new Error ( 'Config not found' ) ;
70
+ descriptor = found ;
71
+ }
72
+ } catch ( e ) {
73
+ console . error ( 'Game config not loaded' , e ) ;
83
74
}
84
- }
85
75
86
- if ( descriptor . mode === 'aero' ) {
87
- if ( descriptor . aero ) {
88
- descriptor . window = {
89
- ...( descriptor . window ?? { } ) ,
90
- ...descriptor . aero ,
91
- resizable : false ,
92
- } ;
93
- } else {
76
+ if ( descriptor ?. mode === 'classic' || ! descriptor ?. mode ) {
94
77
try {
95
- const content = await fetchTextContent ( baseUrl$ . value , 'config.xml' ) ;
96
- const parser = new DOMParser ( ) ;
97
- const doc = parser . parseFromString ( content , 'application/xml' ) ;
98
- const gameElement = doc . querySelector ( 'game' ) ;
99
- if ( gameElement ) {
100
- const width = parseInt ( gameElement . getAttribute ( 'width' ) || '800' ) ;
101
- const height = parseInt ( gameElement . getAttribute ( 'height' ) || '600' ) ;
78
+ const cfgContent = await fetchTextContent ( baseUrl$ . value , 'qspgui.cfg' ) ;
79
+ const cfgData = parseCfg ( cfgContent ) ;
80
+ if ( ! cfgData || ! Object . keys ( cfgData ) . length ) throw new Error ( 'Invalid config file' ) ;
81
+ qspGuiCfg$ . set ( cfgData ) ;
82
+ } catch {
83
+ // no-op
84
+ }
85
+ }
86
+
87
+ if ( descriptor . mode === 'aero' ) {
88
+ if ( descriptor . aero ) {
89
+ descriptor . window = {
90
+ ...( descriptor . window ?? { } ) ,
91
+ ...descriptor . aero ,
92
+ resizable : false ,
93
+ } ;
94
+ } else {
95
+ try {
96
+ const content = await fetchTextContent ( baseUrl$ . value , 'config.xml' ) ;
97
+ const parser = new DOMParser ( ) ;
98
+ const doc = parser . parseFromString ( content , 'application/xml' ) ;
99
+ const gameElement = doc . querySelector ( 'game' ) ;
100
+ if ( gameElement ) {
101
+ const width = parseInt ( gameElement . getAttribute ( 'width' ) || '800' ) ;
102
+ const height = parseInt ( gameElement . getAttribute ( 'height' ) || '600' ) ;
103
+ descriptor . aero = {
104
+ width,
105
+ height,
106
+ } ;
107
+ descriptor . window = {
108
+ ...( descriptor . window ?? { } ) ,
109
+ width,
110
+ height,
111
+ resizable : false ,
112
+ } ;
113
+ }
114
+ } catch {
102
115
descriptor . aero = {
103
- width,
104
- height,
116
+ width : 800 ,
117
+ height : 600 ,
105
118
} ;
106
119
descriptor . window = {
107
120
...( descriptor . window ?? { } ) ,
108
- width,
109
- height,
121
+ width : 800 ,
122
+ height : 600 ,
110
123
resizable : false ,
111
124
} ;
112
125
}
113
- } catch {
114
- descriptor . aero = {
115
- width : 800 ,
116
- height : 600 ,
117
- } ;
118
- descriptor . window = {
119
- ...( descriptor . window ?? { } ) ,
120
- width : 800 ,
121
- height : 600 ,
122
- resizable : false ,
123
- } ;
124
126
}
125
127
}
126
- }
127
128
128
- windowManager . setTitle ( entry . title ) ;
129
- setupGlobalHotKeys ( ) ;
130
- if ( descriptor ?. hotkeys ) {
131
- setupCustomHotKeys ( descriptor . hotkeys ) ;
132
- }
133
- if ( descriptor ?. resources ?. icon ) {
134
- windowManager . setIcon ( baseUrl$ . value , descriptor . resources . icon ) ;
135
- }
136
- loadAdditionalResources ( descriptor ?. resources ) ;
137
- if ( descriptor ?. themes ) {
138
- await registerThemes ( descriptor . themes ) ;
139
- }
140
- if ( descriptor ?. defaultTheme ) {
141
- const theme = themeRegistry$ . value [ descriptor . defaultTheme ] ;
142
- if ( theme ) {
143
- currentTheme$ . set ( descriptor . defaultTheme ) ;
129
+ windowManager . setTitle ( entry . title ) ;
130
+ setupGlobalHotKeys ( ) ;
131
+ if ( descriptor ?. hotkeys ) {
132
+ setupCustomHotKeys ( descriptor . hotkeys ) ;
133
+ }
134
+ if ( descriptor ?. resources ?. icon ) {
135
+ windowManager . setIcon ( baseUrl$ . value , descriptor . resources . icon ) ;
136
+ }
137
+ loadAdditionalResources ( descriptor ?. resources ) ;
138
+ if ( descriptor ?. themes ) {
139
+ await registerThemes ( descriptor . themes ) ;
140
+ }
141
+ if ( descriptor ?. defaultTheme ) {
142
+ const theme = themeRegistry$ . value [ descriptor . defaultTheme ] ;
143
+ if ( theme ) {
144
+ currentTheme$ . set ( descriptor . defaultTheme ) ;
145
+ } else {
146
+ showNotice ( `Theme ${ descriptor . defaultTheme } not found` ) ;
147
+ }
148
+ } else if ( descriptor ?. mode === 'aero' ) {
149
+ currentTheme$ . set ( AERO_THEME ) ;
144
150
} else {
145
- showNotice ( `Theme ${ descriptor . defaultTheme } not found` ) ;
151
+ currentTheme$ . set ( CLASSIC_THEME ) ;
146
152
}
147
- } else if ( descriptor ?. mode === 'aero' ) {
148
- currentTheme$ . set ( AERO_THEME ) ;
149
- } else {
150
- currentTheme$ . set ( CLASSIC_THEME ) ;
151
- }
152
- loadThemeTranslations ( currentTranslations$ . value ) ;
153
- if ( descriptor ) applyWindowSettings ( descriptor . window ) ;
154
- let gameSource = await fetchBinaryContent ( baseUrl$ . value , entry . loadConfig . entrypoint ) ;
155
- if ( ! gameSource ) throw new Error ( 'Failed to load game' ) ;
156
- const isQsps = entry . loadConfig . entrypoint . toLowerCase ( ) . endsWith ( '.qsps' ) ;
157
- if ( isQsps ) {
158
- gameSource = convertQsps ( gameSource ) ;
153
+ loadThemeTranslations ( currentTranslations$ . value ) ;
154
+ if ( descriptor ) applyWindowSettings ( descriptor . window ) ;
155
+ let gameSource = await fetchBinaryContent ( baseUrl$ . value , entry . loadConfig . entrypoint ) ;
156
+ if ( ! gameSource ) throw new Error ( 'Failed to load game' ) ;
157
+ const isQsps = entry . loadConfig . entrypoint . toLowerCase ( ) . endsWith ( '.qsps' ) ;
158
+ if ( isQsps ) {
159
+ gameSource = convertQsps ( gameSource ) ;
160
+ }
161
+ qspApi$ . value ?. openGame ( gameSource , true ) ;
162
+ qspApi$ . value ?. restartGame ( ) ;
163
+ currentGameEntry$ . set ( entry ) ;
164
+ if ( descriptor ) currentGame$ . set ( descriptor ) ;
165
+ loadSaveList ( ) ;
166
+ isPaused$ . set ( false ) ;
167
+ } catch ( e ) {
168
+ console . error ( e ) ;
169
+ showNotice ( e instanceof Error ? e . message : String ( e ) ) ;
170
+ stopCurrentGame ( ) ;
159
171
}
160
- qspApi$ . value ?. openGame ( gameSource , true ) ;
161
- qspApi$ . value ?. restartGame ( ) ;
162
- currentGameEntry$ . set ( entry ) ;
163
- if ( descriptor ) currentGame$ . set ( descriptor ) ;
164
- loadSaveList ( ) ;
165
- isPaused$ . set ( false ) ;
166
172
}
167
173
168
174
let wasResized = false ;
0 commit comments