Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/ScalableGame.java
1456 views
1
package org.newdawn.slick;
2
3
import org.newdawn.slick.opengl.SlickCallable;
4
import org.newdawn.slick.opengl.renderer.Renderer;
5
import org.newdawn.slick.opengl.renderer.SGL;
6
7
/**
8
* A wrapper to allow any game to be scalable. This relies on knowing the
9
* normal width/height of the game - i.e. the dimensions that the game is
10
* expecting to be run at. The wrapper then takes the size of the container
11
* and scales rendering and input based on the ratio.
12
*
13
* Note: Using OpenGL directly within a ScalableGame can break it
14
*
15
* @author kevin
16
*/
17
public class ScalableGame implements Game {
18
/** The renderer to use for all GL operations */
19
private static SGL GL = Renderer.get();
20
21
/** The normal or native width of the game */
22
private float normalWidth;
23
/** The normal or native height of the game */
24
private float normalHeight;
25
/** The game that is being wrapped */
26
private Game held;
27
/** True if we should maintain the aspect ratio */
28
private boolean maintainAspect;
29
/** The target width */
30
private int targetWidth;
31
/** The target height */
32
private int targetHeight;
33
/** The game container wrapped */
34
private GameContainer container;
35
36
/**
37
* Create a new scalable game wrapper
38
*
39
* @param held The game to be wrapper and displayed at a different resolution
40
* @param normalWidth The normal width of the game
41
* @param normalHeight The noral height of the game
42
*/
43
public ScalableGame(Game held, int normalWidth, int normalHeight) {
44
this(held, normalWidth, normalHeight, false);
45
}
46
47
/**
48
* Create a new scalable game wrapper
49
*
50
* @param held The game to be wrapper and displayed at a different resolution
51
* @param normalWidth The normal width of the game
52
* @param normalHeight The noral height of the game
53
* @param maintainAspect True if we should maintain the aspect ratio
54
*/
55
public ScalableGame(Game held, int normalWidth, int normalHeight, boolean maintainAspect) {
56
this.held = held;
57
this.normalWidth = normalWidth;
58
this.normalHeight = normalHeight;
59
this.maintainAspect = maintainAspect;
60
}
61
62
/**
63
* @see org.newdawn.slick.BasicGame#init(org.newdawn.slick.GameContainer)
64
*/
65
public void init(GameContainer container) throws SlickException {
66
this.container = container;
67
68
recalculateScale();
69
held.init(container);
70
}
71
72
/**
73
* Recalculate the scale of the game
74
*
75
* @throws SlickException Indicates a failure to reinit the game
76
*/
77
public void recalculateScale() throws SlickException {
78
targetWidth = container.getWidth();
79
targetHeight = container.getHeight();
80
81
if (maintainAspect) {
82
boolean normalIsWide = (normalWidth / normalHeight > 1.6 ? true : false);
83
boolean containerIsWide = ((float) targetWidth / (float) targetHeight > 1.6 ? true : false);
84
float wScale = targetWidth / normalWidth;
85
float hScale = targetHeight / normalHeight;
86
87
if (normalIsWide & containerIsWide) {
88
float scale = (wScale < hScale ? wScale : hScale);
89
targetWidth = (int) (normalWidth * scale);
90
targetHeight = (int) (normalHeight * scale);
91
} else if (normalIsWide & !containerIsWide) {
92
targetWidth = (int) (normalWidth * wScale);
93
targetHeight = (int) (normalHeight * wScale);
94
} else if (!normalIsWide & containerIsWide) {
95
targetWidth = (int) (normalWidth * hScale);
96
targetHeight = (int) (normalHeight * hScale);
97
} else {
98
float scale = (wScale < hScale ? wScale : hScale);
99
targetWidth = (int) (normalWidth * scale);
100
targetHeight = (int) (normalHeight * scale);
101
}
102
103
}
104
105
if (held instanceof InputListener) {
106
container.getInput().addListener((InputListener) held);
107
}
108
container.getInput().setScale(normalWidth / targetWidth,
109
normalHeight / targetHeight);
110
111
112
int yoffset = 0;
113
int xoffset = 0;
114
115
if (targetHeight < container.getHeight()) {
116
yoffset = (container.getHeight() - targetHeight) / 2;
117
}
118
if (targetWidth < container.getWidth()) {
119
xoffset = (container.getWidth() - targetWidth) / 2;
120
}
121
container.getInput().setOffset(-xoffset / (targetWidth / normalWidth),
122
-yoffset / (targetHeight / normalHeight));
123
124
}
125
126
/**
127
* @see org.newdawn.slick.BasicGame#update(org.newdawn.slick.GameContainer, int)
128
*/
129
public void update(GameContainer container, int delta) throws SlickException {
130
if ((targetHeight != container.getHeight()) ||
131
(targetWidth != container.getWidth())) {
132
recalculateScale();
133
}
134
135
held.update(container, delta);
136
}
137
138
/**
139
* @see org.newdawn.slick.Game#render(org.newdawn.slick.GameContainer, org.newdawn.slick.Graphics)
140
*/
141
public final void render(GameContainer container, Graphics g)
142
throws SlickException {
143
int yoffset = 0;
144
int xoffset = 0;
145
146
if (targetHeight < container.getHeight()) {
147
yoffset = (container.getHeight() - targetHeight) / 2;
148
}
149
if (targetWidth < container.getWidth()) {
150
xoffset = (container.getWidth() - targetWidth) / 2;
151
}
152
153
SlickCallable.enterSafeBlock();
154
g.setClip(xoffset, yoffset, targetWidth, targetHeight);
155
GL.glTranslatef(xoffset, yoffset, 0);
156
GL.glScalef(targetWidth / normalWidth, targetHeight / normalHeight,0);
157
GL.glPushMatrix();
158
held.render(container, g);
159
GL.glPopMatrix();
160
g.clearClip();
161
SlickCallable.leaveSafeBlock();
162
163
renderOverlay(container, g);
164
}
165
166
/**
167
* Render the overlay that will sit over the scaled screen
168
*
169
* @param container The container holding the game being render
170
* @param g Graphics context on which to render
171
*/
172
protected void renderOverlay(GameContainer container, Graphics g) {
173
}
174
175
/**
176
* @see org.newdawn.slick.Game#closeRequested()
177
*/
178
public boolean closeRequested() {
179
return held.closeRequested();
180
}
181
182
/**
183
* @see org.newdawn.slick.Game#getTitle()
184
*/
185
public String getTitle() {
186
return held.getTitle();
187
}
188
}
189
190