Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/AppGameContainer.java
1456 views
1
package org.newdawn.slick;
2
3
import java.io.IOException;
4
import java.io.OutputStream;
5
import java.nio.ByteBuffer;
6
import java.security.AccessController;
7
import java.security.PrivilegedAction;
8
9
import org.lwjgl.BufferUtils;
10
import org.lwjgl.LWJGLException;
11
import org.lwjgl.Sys;
12
import org.lwjgl.input.Cursor;
13
import org.lwjgl.input.Mouse;
14
import org.lwjgl.openal.AL;
15
import org.lwjgl.opengl.Display;
16
import org.lwjgl.opengl.DisplayMode;
17
import org.lwjgl.opengl.PixelFormat;
18
import org.newdawn.slick.openal.SoundStore;
19
import org.newdawn.slick.opengl.CursorLoader;
20
import org.newdawn.slick.opengl.ImageData;
21
import org.newdawn.slick.opengl.ImageIOImageData;
22
import org.newdawn.slick.opengl.InternalTextureLoader;
23
import org.newdawn.slick.opengl.LoadableImageData;
24
import org.newdawn.slick.opengl.TGAImageData;
25
import org.newdawn.slick.util.Log;
26
import org.newdawn.slick.util.ResourceLoader;
27
28
/**
29
* A game container that will display the game as an stand alone
30
* application.
31
*
32
* @author kevin
33
*/
34
public class AppGameContainer extends GameContainer {
35
static {
36
AccessController.doPrivileged(new PrivilegedAction() {
37
public Object run() {
38
try {
39
Display.getDisplayMode();
40
} catch (Exception e) {
41
Log.error(e);
42
}
43
return null;
44
}});
45
}
46
47
/** The original display mode before we tampered with things */
48
protected DisplayMode originalDisplayMode;
49
/** The display mode we're going to try and use */
50
protected DisplayMode targetDisplayMode;
51
/** True if we should update the game only when the display is visible */
52
protected boolean updateOnlyOnVisible = true;
53
/** Alpha background supported */
54
protected boolean alphaSupport = false;
55
56
/**
57
* Create a new container wrapping a game
58
*
59
* @param game The game to be wrapped
60
* @throws SlickException Indicates a failure to initialise the display
61
*/
62
public AppGameContainer(Game game) throws SlickException {
63
this(game,640,480,false);
64
}
65
66
/**
67
* Create a new container wrapping a game
68
*
69
* @param game The game to be wrapped
70
* @param width The width of the display required
71
* @param height The height of the display required
72
* @param fullscreen True if we want fullscreen mode
73
* @throws SlickException Indicates a failure to initialise the display
74
*/
75
public AppGameContainer(Game game,int width,int height,boolean fullscreen) throws SlickException {
76
super(game);
77
78
originalDisplayMode = Display.getDisplayMode();
79
80
setDisplayMode(width,height,fullscreen);
81
}
82
83
/**
84
* Check if the display created supported alpha in the back buffer
85
*
86
* @return True if the back buffer supported alpha
87
*/
88
public boolean supportsAlphaInBackBuffer() {
89
return alphaSupport;
90
}
91
92
/**
93
* Set the title of the window
94
*
95
* @param title The title to set on the window
96
*/
97
public void setTitle(String title) {
98
Display.setTitle(title);
99
}
100
101
/**
102
* Set the display mode to be used
103
*
104
* @param width The width of the display required
105
* @param height The height of the display required
106
* @param fullscreen True if we want fullscreen mode
107
* @throws SlickException Indicates a failure to initialise the display
108
*/
109
public void setDisplayMode(int width, int height, boolean fullscreen) throws SlickException {
110
if ((this.width == width) && (this.height == height) && (isFullscreen() == fullscreen)) {
111
return;
112
}
113
114
try {
115
targetDisplayMode = null;
116
if (fullscreen) {
117
DisplayMode[] modes = Display.getAvailableDisplayModes();
118
int freq = 0;
119
120
for (int i=0;i<modes.length;i++) {
121
DisplayMode current = modes[i];
122
123
if ((current.getWidth() == width) && (current.getHeight() == height)) {
124
if ((targetDisplayMode == null) || (current.getFrequency() >= freq)) {
125
if ((targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel())) {
126
targetDisplayMode = current;
127
freq = targetDisplayMode.getFrequency();
128
}
129
}
130
131
// if we've found a match for bpp and frequence against the
132
// original display mode then it's probably best to go for this one
133
// since it's most likely compatible with the monitor
134
if ((current.getBitsPerPixel() == originalDisplayMode.getBitsPerPixel()) &&
135
(current.getFrequency() == originalDisplayMode.getFrequency())) {
136
targetDisplayMode = current;
137
break;
138
}
139
}
140
}
141
} else {
142
targetDisplayMode = new DisplayMode(width,height);
143
}
144
145
if (targetDisplayMode == null) {
146
throw new SlickException("Failed to find value mode: "+width+"x"+height+" fs="+fullscreen);
147
}
148
149
this.width = width;
150
this.height = height;
151
152
Display.setDisplayMode(targetDisplayMode);
153
Display.setFullscreen(fullscreen);
154
155
if (Display.isCreated()) {
156
initGL();
157
enterOrtho();
158
}
159
160
if (targetDisplayMode.getBitsPerPixel() == 16) {
161
InternalTextureLoader.get().set16BitMode();
162
}
163
} catch (LWJGLException e) {
164
throw new SlickException("Unable to setup mode "+width+"x"+height+" fullscreen="+fullscreen, e);
165
}
166
167
getDelta();
168
}
169
170
/**
171
* Check if the display is in fullscreen mode
172
*
173
* @return True if the display is in fullscreen mode
174
*/
175
public boolean isFullscreen() {
176
return Display.isFullscreen();
177
}
178
179
/**
180
* Indicate whether we want to be in fullscreen mode. Note that the current
181
* display mode must be valid as a fullscreen mode for this to work
182
*
183
* @param fullscreen True if we want to be in fullscreen mode
184
* @throws SlickException Indicates we failed to change the display mode
185
*/
186
public void setFullscreen(boolean fullscreen) throws SlickException {
187
if (isFullscreen() == fullscreen) {
188
return;
189
}
190
191
if (!fullscreen) {
192
try {
193
Display.setFullscreen(fullscreen);
194
} catch (LWJGLException e) {
195
throw new SlickException("Unable to set fullscreen="+fullscreen, e);
196
}
197
} else {
198
setDisplayMode(width, height, fullscreen);
199
}
200
getDelta();
201
}
202
203
/**
204
* @see org.newdawn.slick.GameContainer#setMouseCursor(java.lang.String, int, int)
205
*/
206
public void setMouseCursor(String ref, int hotSpotX, int hotSpotY) throws SlickException {
207
try {
208
Cursor cursor = CursorLoader.get().getCursor(ref, hotSpotX, hotSpotY);
209
Mouse.setNativeCursor(cursor);
210
} catch (Exception e) {
211
Log.error("Failed to load and apply cursor.", e);
212
}
213
}
214
215
/**
216
* @see org.newdawn.slick.GameContainer#setMouseCursor(org.newdawn.slick.opengl.ImageData, int, int)
217
*/
218
public void setMouseCursor(ImageData data, int hotSpotX, int hotSpotY) throws SlickException {
219
try {
220
Cursor cursor = CursorLoader.get().getCursor(data, hotSpotX, hotSpotY);
221
Mouse.setNativeCursor(cursor);
222
} catch (Exception e) {
223
Log.error("Failed to load and apply cursor.", e);
224
}
225
}
226
227
/**
228
* @see org.newdawn.slick.GameContainer#setMouseCursor(org.lwjgl.input.Cursor, int, int)
229
*/
230
public void setMouseCursor(Cursor cursor, int hotSpotX, int hotSpotY) throws SlickException {
231
try {
232
Mouse.setNativeCursor(cursor);
233
} catch (Exception e) {
234
Log.error("Failed to load and apply cursor.", e);
235
}
236
}
237
238
/**
239
* Get the closest greater power of 2 to the fold number
240
*
241
* @param fold The target number
242
* @return The power of 2
243
*/
244
private int get2Fold(int fold) {
245
int ret = 2;
246
while (ret < fold) {
247
ret *= 2;
248
}
249
return ret;
250
}
251
252
/**
253
* @see org.newdawn.slick.GameContainer#setMouseCursor(org.newdawn.slick.Image, int, int)
254
*/
255
public void setMouseCursor(Image image, int hotSpotX, int hotSpotY) throws SlickException {
256
try {
257
Image temp = new Image(get2Fold(image.getWidth()), get2Fold(image.getHeight()));
258
Graphics g = temp.getGraphics();
259
260
ByteBuffer buffer = BufferUtils.createByteBuffer(temp.getWidth() * temp.getHeight() * 4);
261
g.drawImage(image.getFlippedCopy(false, true), 0, 0);
262
g.flush();
263
g.getArea(0,0,temp.getWidth(),temp.getHeight(),buffer);
264
265
Cursor cursor = CursorLoader.get().getCursor(buffer, hotSpotX, hotSpotY,temp.getWidth(),image.getHeight());
266
Mouse.setNativeCursor(cursor);
267
} catch (Exception e) {
268
Log.error("Failed to load and apply cursor.", e);
269
}
270
}
271
272
/**
273
* @see org.newdawn.slick.GameContainer#reinit()
274
*/
275
public void reinit() throws SlickException {
276
InternalTextureLoader.get().clear();
277
SoundStore.get().clear();
278
initSystem();
279
enterOrtho();
280
281
try {
282
game.init(this);
283
} catch (SlickException e) {
284
Log.error(e);
285
running = false;
286
}
287
}
288
289
/**
290
* Try creating a display with the given format
291
*
292
* @param format The format to attempt
293
* @throws LWJGLException Indicates a failure to support the given format
294
*/
295
private void tryCreateDisplay(PixelFormat format) throws LWJGLException {
296
297
if (SHARED_DRAWABLE == null)
298
{
299
Display.create(format);
300
}
301
else
302
{
303
Display.create(format, SHARED_DRAWABLE);
304
}
305
}
306
307
/**
308
* Start running the game
309
*
310
* @throws SlickException Indicates a failure to initialise the system
311
*/
312
public void start() throws SlickException {
313
try {
314
setup();
315
316
getDelta();
317
while (running()) {
318
gameLoop();
319
}
320
} finally {
321
destroy();
322
}
323
324
if (forceExit) {
325
System.exit(0);
326
}
327
}
328
329
/**
330
* Setup the environment
331
*
332
* @throws SlickException Indicates a failure
333
*/
334
protected void setup() throws SlickException {
335
if (targetDisplayMode == null) {
336
setDisplayMode(640,480,false);
337
}
338
339
Display.setTitle(game.getTitle());
340
341
Log.info("LWJGL Version: "+Sys.getVersion());
342
Log.info("OriginalDisplayMode: "+originalDisplayMode);
343
Log.info("TargetDisplayMode: "+targetDisplayMode);
344
345
AccessController.doPrivileged(new PrivilegedAction() {
346
public Object run() {
347
try {
348
PixelFormat format = new PixelFormat(8,8,0,samples);
349
350
tryCreateDisplay(format);
351
supportsMultiSample = true;
352
} catch (Exception e) {
353
Display.destroy();
354
355
try {
356
PixelFormat format = new PixelFormat(8,8,0);
357
358
tryCreateDisplay(format);
359
alphaSupport = false;
360
} catch (Exception e2) {
361
Display.destroy();
362
// if we couldn't get alpha, let us know
363
try {
364
tryCreateDisplay(new PixelFormat());
365
} catch (Exception e3) {
366
Log.error(e3);
367
}
368
}
369
}
370
371
return null;
372
}});
373
374
if (!Display.isCreated()) {
375
throw new SlickException("Failed to initialise the LWJGL display");
376
}
377
378
initSystem();
379
enterOrtho();
380
381
try {
382
getInput().initControllers();
383
} catch (SlickException e) {
384
Log.info("Controllers not available");
385
} catch (Throwable e) {
386
Log.info("Controllers not available");
387
}
388
389
try {
390
game.init(this);
391
} catch (SlickException e) {
392
Log.error(e);
393
running = false;
394
}
395
}
396
397
/**
398
* Strategy for overloading game loop context handling
399
*
400
* @throws SlickException Indicates a game failure
401
*/
402
protected void gameLoop() throws SlickException {
403
int delta = getDelta();
404
if (!Display.isVisible() && updateOnlyOnVisible) {
405
try { Thread.sleep(100); } catch (Exception e) {}
406
} else {
407
try {
408
updateAndRender(delta);
409
} catch (SlickException e) {
410
Log.error(e);
411
running = false;
412
return;
413
}
414
}
415
416
updateFPS();
417
418
Display.update();
419
420
if (Display.isCloseRequested()) {
421
if (game.closeRequested()) {
422
running = false;
423
}
424
}
425
}
426
427
/**
428
* @see org.newdawn.slick.GameContainer#setUpdateOnlyWhenVisible(boolean)
429
*/
430
public void setUpdateOnlyWhenVisible(boolean updateOnlyWhenVisible) {
431
updateOnlyOnVisible = updateOnlyWhenVisible;
432
}
433
434
/**
435
* @see org.newdawn.slick.GameContainer#isUpdatingOnlyWhenVisible()
436
*/
437
public boolean isUpdatingOnlyWhenVisible() {
438
return updateOnlyOnVisible;
439
}
440
441
/**
442
* @see org.newdawn.slick.GameContainer#setIcon(java.lang.String)
443
*/
444
public void setIcon(String ref) throws SlickException {
445
setIcons(new String[] {ref});
446
}
447
448
/**
449
* @see org.newdawn.slick.GameContainer#setMouseGrabbed(boolean)
450
*/
451
public void setMouseGrabbed(boolean grabbed) {
452
Mouse.setGrabbed(grabbed);
453
}
454
455
/**
456
* @see org.newdawn.slick.GameContainer#isMouseGrabbed()
457
*/
458
public boolean isMouseGrabbed() {
459
return Mouse.isGrabbed();
460
}
461
462
/**
463
* @see org.newdawn.slick.GameContainer#hasFocus()
464
*/
465
public boolean hasFocus() {
466
// hmm, not really the right thing, talk to the LWJGL guys
467
return Display.isActive();
468
}
469
470
/**
471
* @see org.newdawn.slick.GameContainer#getScreenHeight()
472
*/
473
public int getScreenHeight() {
474
return originalDisplayMode.getHeight();
475
}
476
477
/**
478
* @see org.newdawn.slick.GameContainer#getScreenWidth()
479
*/
480
public int getScreenWidth() {
481
return originalDisplayMode.getWidth();
482
}
483
484
/**
485
* Destroy the app game container
486
*/
487
public void destroy() {
488
Display.destroy();
489
AL.destroy();
490
}
491
492
/**
493
* A null stream to clear out those horrid errors
494
*
495
* @author kevin
496
*/
497
private class NullOutputStream extends OutputStream {
498
/**
499
* @see java.io.OutputStream#write(int)
500
*/
501
public void write(int b) throws IOException {
502
// null implemetnation
503
}
504
505
}
506
507
/**
508
* @see org.newdawn.slick.GameContainer#setIcons(java.lang.String[])
509
*/
510
public void setIcons(String[] refs) throws SlickException {
511
ByteBuffer[] bufs = new ByteBuffer[refs.length];
512
for (int i=0;i<refs.length;i++) {
513
LoadableImageData data;
514
boolean flip = true;
515
516
if (refs[i].endsWith(".tga")) {
517
data = new TGAImageData();
518
} else {
519
flip = false;
520
data = new ImageIOImageData();
521
}
522
523
try {
524
bufs[i] = data.loadImage(ResourceLoader.getResourceAsStream(refs[i]), flip, false, null);
525
} catch (Exception e) {
526
Log.error(e);
527
throw new SlickException("Failed to set the icon");
528
}
529
}
530
531
Display.setIcon(bufs);
532
}
533
534
/**
535
* @see org.newdawn.slick.GameContainer#setDefaultMouseCursor()
536
*/
537
public void setDefaultMouseCursor() {
538
try {
539
Mouse.setNativeCursor(null);
540
} catch (LWJGLException e) {
541
Log.error("Failed to reset mouse cursor", e);
542
}
543
}
544
}
545
546