Starsector API
Loading...
Searching...
No Matches
BaseTiledTerrain.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.terrain;
2
3import java.awt.Color;
4import java.util.Arrays;
5import java.util.Random;
6import java.util.zip.DataFormatException;
7import java.util.zip.Deflater;
8import java.util.zip.Inflater;
9
10import javax.xml.bind.DatatypeConverter;
11
12import org.lwjgl.opengl.GL11;
13import org.lwjgl.util.vector.Vector2f;
14
15import com.fs.starfarer.api.Global;
16import com.fs.starfarer.api.campaign.CampaignEngineLayers;
17import com.fs.starfarer.api.campaign.CampaignFleetAPI;
18import com.fs.starfarer.api.campaign.SectorEntityToken;
19import com.fs.starfarer.api.combat.ViewportAPI;
20import com.fs.starfarer.api.graphics.SpriteAPI;
21import com.fs.starfarer.api.util.Misc;
22
23public abstract class BaseTiledTerrain extends BaseTerrain {
24
25 public static class TileParams {
26 public String tiles;
27 public int w;
28 public int h;
29 public String cat;
30 public String key;
31 public int tW;
32 public int tH;
33 public String name;
34 public TileParams(String tiles, int width, int height,
35 String tileTexCat, String tileTexKey, int tilesWide, int tilesHigh, String name) {
36 this.tiles = tiles;
37 this.w = width;
38 this.h = height;
39 this.cat = tileTexCat;
40 this.key = tileTexKey;
41 this.tW = tilesWide;
42 this.tH = tilesHigh;
43 this.name = name;
44 }
45
46 }
47
48// public static class Tile {
49// public int cellX;
50// public int cellY;
51// public int texCellX;
52// public int texCellY;
53// }
54
55 protected TileParams params;
56 protected transient SpriteAPI texture;
57 protected transient SpriteAPI mapTexture;
58 //protected Tile[][] tiles;
59 protected transient int [][] tiles;
60
61 protected long tileSeed;
62 protected String savedTiles;
63 public void init(String terrainId, SectorEntityToken entity, Object param) {
64 super.init(terrainId, entity, param);
65
66 this.params = (TileParams) param;
67 name = params.name;
68 if (name == null) name = "Unknown";
69
70 tiles = new int [params.w][params.h];
71
72
73 tileSeed = new Random().nextLong();
74// Random random = new Random(tileSeed);
75
76 for (int i = 0; i < tiles.length; i++) {
77 for (int j = 0; j < tiles[0].length; j++) {
78 int index = i + (tiles[0].length - j - 1) * tiles.length;
79 char c = params.tiles.charAt(index);
80 if (!Character.isWhitespace(c)) {
81// int texX = (int) (Math.random() * params.tW);
82// int texY = (int) (Math.random() * params.tH);
83// int texX = (int) (random.nextFloat() * params.tW);
84// int texY = (int) (random.nextFloat() * params.tH);
85// tiles[i][j] = texX + texY * params.tW;
86 tiles[i][j] = 1;
87 } else {
88 tiles[i][j] = -1;
89 }
90 }
91 }
92
94 readResolve();
95
96 params.tiles = null; // don't need to save this
97 }
98
99 protected void regenTiles() {
100 Random random = new Random(tileSeed);
101 for (int i = 0; i < tiles.length; i++) {
102 for (int j = 0; j < tiles[0].length; j++) {
103 if (tiles[i][j] >= 0) {
104 int texX = (int) (random.nextFloat() * params.tW);
105 int texY = (int) (random.nextFloat() * params.tH);
106 tiles[i][j] = texX + texY * params.tW;
107 } else {
108 tiles[i][j] = -1;
109 }
110 }
111 }
112 }
113
114
115 public int[][] getTiles() {
116 return tiles;
117 }
118
119 public TileParams getParams() {
120 return params;
121 }
122
123
124 Object readResolve() {
126 mapTexture = Global.getSettings().getSprite(params.cat, params.key + "_map");
127
128 if (savedTiles != null) {
129 try {
131 } catch (DataFormatException e) {
132 throw new RuntimeException("Error decoding tiled terrain tiles", e);
133 }
134 } else {
135 // shouldn't be here, if we are then savedTiles == null and something went badly wrong
136 tiles = new int [params.w][params.h];
137 }
138 regenTiles();
139
140 return this;
141 }
142
143 Object writeReplace() {
144 params.tiles = null;
146 return this;
147 }
148
149 @Override
150 public boolean containsEntity(SectorEntityToken other) {
151 if (other.getContainingLocation() != this.entity.getContainingLocation()) return false;
152 return containsPoint(other.getLocation(), other.getRadius()) && !isPreventedFromAffecting(other);
153 }
154
155 public boolean containsPoint(Vector2f test, float r) {
156
157 float dist = Misc.getDistance(this.entity.getLocation(), test) - r;
158 if (dist > getRenderRange()) return false;
159
160 float x = this.entity.getLocation().x;
161 float y = this.entity.getLocation().y;
162 float size = getTileSize();
163 float containsSize = getTileContainsSize();
164
165 float w = tiles.length * size;
166 float h = tiles[0].length * size;
167
168 x -= w/2f;
169 y -= h/2f;
170
171 float extra = (containsSize - size) / 2f;
172
173 if (test.x + r + extra < x) return false;
174 if (test.y + r + extra < y) return false;
175 if (test.x > x + w + r + extra) return false;
176 if (test.y > y + h + r + extra) return false;
177
178 int xIndex = (int) ((test.x - x) / size);
179 int yIndex = (int) ((test.y - y) / size);
180
181 if (xIndex < 0) xIndex = 0;
182 if (yIndex < 0) yIndex = 0;
183
184 if (xIndex >= tiles.length) xIndex = tiles.length - 1;
185 if (yIndex >= tiles[0].length) yIndex = tiles[0].length - 1;
186
187// if (entity.isPlayerFleet()) {
188// System.out.println(this + " " + xIndex + "," + yIndex);
189// }
190
191 for (float i = Math.max(0, xIndex - 1); i <= xIndex + 1 && i < tiles.length; i++) {
192 for (float j = Math.max(0, yIndex - 1); j <= yIndex + 1 && j < tiles[0].length; j++) {
193 int texIndex = tiles[(int) i][(int) j];
194 if (texIndex >= 0) {
195 float tx = x + i * size + size/2f - containsSize/2f;
196 float ty = y + j * size + size/2f - containsSize/2f;
197
198 if (test.x + r < tx) continue;
199 if (test.y + r < ty) continue;
200 if (test.x > tx + containsSize + r) continue;
201 if (test.y > ty + containsSize + r) continue;
202 return true;
203 }
204 }
205 }
206 return false;
207 }
208
209
210 public abstract float getTileSize();
211 public abstract float getTileRenderSize();
212 public abstract float getTileContainsSize();
213 public abstract void preRender(CampaignEngineLayers layer, float alphaMult);
214 public abstract void preMapRender(float alphaMult);
215 public abstract Color getRenderColor();
216
217 public float getRenderRange() {
218 float size = getTileSize();
219 float renderSize = getTileRenderSize();
220 float w = tiles.length * size * 0.5f + (renderSize - size) * 0.5f;
221 float h = tiles[0].length * size * 0.5f + (renderSize - size) * 0.5f;
222 return Math.max(w, h) * 1.5f;
223 }
224
225 public void render(CampaignEngineLayers layer, ViewportAPI v) {
226 texture.bindTexture();
227 GL11.glEnable(GL11.GL_TEXTURE_2D);
228 //GL11.glDisable(GL11.GL_TEXTURE_2D);
229
230 preRender(layer, v.getAlphaMult());
231 //GL11.glDisable(GL11.GL_TEXTURE_2D);
232
233 float x = this.entity.getLocation().x;
234 float y = this.entity.getLocation().y;
235 float size = getTileSize();
236 float renderSize = getTileRenderSize();
237
238 float w = tiles.length * size;
239 float h = tiles[0].length * size;
240 x -= w/2f;
241 y -= h/2f;
242 float extra = (renderSize - size) / 2f + 100f;
243
244 float llx = v.getLLX();
245 float lly = v.getLLY();
246 float vw = v.getVisibleWidth();
247 float vh = v.getVisibleHeight();
248
249 if (llx > x + w + extra) return;
250 if (lly > y + h + extra) return;
251 if (llx + vw + extra < x) return;
252 if (lly + vh + extra < y) return;
253
254 float xStart = (int)((llx - x - extra) / size);
255 if (xStart < 0) xStart = 0;
256 float yStart = (int)((lly - y - extra) / size);
257 if (yStart < 0) yStart = 0;
258
259 float xEnd = (int)((llx + vw - x + extra) / size) + 1;
260 if (xEnd >= tiles.length) xEnd = tiles.length - 1;
261 float yEnd = (int)((lly + vw - y + extra) / size) + 1;
262 if (yEnd >= tiles.length) yEnd = tiles[0].length - 1;
263
264 renderSubArea(xStart, xEnd, yStart, yEnd, 1f, 1, v.getAlphaMult());
265
266 //renderSubArea(0, tiles.length, 0, tiles[0].length, 1f);
267 }
268
269 public boolean isTileVisible(int i, int j) {
270 float x = this.entity.getLocation().x;
271 float y = this.entity.getLocation().y;
272 float size = getTileSize();
273 float renderSize = getTileRenderSize();
274
275 float w = tiles.length * size;
276 float h = tiles[0].length * size;
277 x -= w/2f;
278 y -= h/2f;
279 float extra = (renderSize - size) / 2f + 100f;
280
281 ViewportAPI v = Global.getSector().getViewport();
282 float llx = v.getLLX();
283 float lly = v.getLLY();
284 float vw = v.getVisibleWidth();
285 float vh = v.getVisibleHeight();
286
287 if (llx > x + w + extra) return false;
288 if (lly > y + h + extra) return false;
289 if (llx + vw + extra < x) return false;
290 if (lly + vh + extra < y) return false;
291
292 float xStart = (int)((llx - x - extra) / size);
293 if (xStart < 0) xStart = 0;
294 float yStart = (int)((lly - y - extra) / size);
295 if (yStart < 0) yStart = 0;
296
297 float xEnd = (int)((llx + vw - x + extra) / size) + 1;
298 if (xEnd >= tiles.length) xEnd = tiles.length - 1;
299 float yEnd = (int)((lly + vw - y + extra) / size) + 1;
300 if (yEnd >= tiles.length) yEnd = tiles[0].length - 1;
301
302 if (i < xStart) return false;
303 if (i > xEnd) return false;
304 if (j < yStart) return false;
305 if (j > yEnd) return false;
306
307 return true;
308 }
309
310 public void renderOnMap(float factor, float alphaMult) {
311 mapTexture.bindTexture();
312 GL11.glEnable(GL11.GL_TEXTURE_2D);
313 preMapRender(alphaMult);
314 renderSubArea(0, tiles.length, 0, tiles[0].length, factor, getNumMapSamples(), alphaMult);
315 }
316
317 public int getNumMapSamples() {
318 return 5;
319 }
320
321 public void renderOnMapAbove(float factor, float alphaMult) {
322
323 }
324
325 public float[] getTileCenter(int i, int j) {
326 float x = entity.getLocation().x;
327 float y = entity.getLocation().y;
328 float size = getTileSize();
329
330 float w = tiles.length * size;
331 float h = tiles[0].length * size;
332
333 float [] result = new float[2];
334 result[0] = x - w / 2f + (float)i * size + size / 2f;
335 result[1] = y - h / 2f + (float)j * size + size / 2f;
336 return result;
337 }
338
339 protected void renderSubArea(float startColumn, float endColumn, float startRow, float endRow, float factor, int samples, float alphaMult) {
340 float x = entity.getLocation().x;
341 float y = entity.getLocation().y;
342 float size = getTileSize();
343 float renderSize = getTileRenderSize();
344
345 float w = tiles.length * size;
346 float h = tiles[0].length * size;
347 //if (true) return;
348
349 //Random rand = new Random(tiles.length + tiles[0].length);
350 //Random rand = new Random();
351
352 if (samples == 1) {
353 GL11.glBegin(GL11.GL_QUADS);
354 for (float i = startColumn; i <= endColumn; i++) {
355 if (i < 0 || i >= tiles.length) continue;
356 for (float j = startRow; j <= endRow; j++) {
357 if (j < 0 || j >= tiles[0].length) continue;
358 int texIndex = tiles[(int) i][(int) j];
359 if (texIndex >= 0) {
360 int texCellX = texIndex % params.tW;
361 int texCellY = texIndex / params.tW;
362
363 Random rand = new Random((long) (i + j * tiles.length) * 1000000);
364 float angle = rand.nextFloat() * 360f;
365 float offRange = renderSize * 0.25f;
366 float xOff = -offRange / 2f + offRange * rand.nextFloat();
367 float yOff = -offRange / 2f + offRange * rand.nextFloat();
368// if (Keyboard.isKeyDown(Keyboard.KEY_O)) {
369// xOff = yOff = 0f;
370// }
371 // angle += angleOffset;
372 // angle = Misc.normalizeAngle(angle);
373 renderQuad((int)i, (int)j,
374 (x + xOff - w / 2f + i * size + size/2f - renderSize/2f) * factor,
375 (y + yOff - h / 2f + j * size + size/2f - renderSize/2f) * factor,
376 renderSize * factor, renderSize * factor,
377 texCellX * 0.25f, texCellY * 0.25f,
378 0.25f, 0.25f,
379 angle);
380 }
381 }
382 }
383 GL11.glEnd();
384 } else {
385 //renderSize = (size * samples) + (renderSize - size);
386 renderSize *= samples;
387 size *= samples;
388 alphaMult *= 0.67f;
389 //alphaMult = 1f;
390 GL11.glBegin(GL11.GL_QUADS);
391 float max = samples * samples;
392 for (float i = startColumn; i <= endColumn; i+=samples) {
393 if (i < 0 || i >= tiles.length) continue;
394 for (float j = startRow; j <= endRow; j+=samples) {
395 int texIndex = -1;
396 float angle = 0;
397 float xOff = 0;
398 float yOff = 0;
399 float weight = 0;
400 for (int m = 0; m < samples && i + m <= endColumn; m++) {
401 if (i + m < 0 || i + m >= tiles.length) continue;
402 for (int n = 0; n < samples && j + n < endRow; n++) {
403 if (j + n < 0 || j + n >= tiles[0].length) continue;
404 int currIndex = tiles[(int) i + m][(int) j + n];
405 if (currIndex >= 0 && texIndex < 0) {
406 texIndex = currIndex;
407 Random rand = new Random((long) (i + j * tiles.length) * 1000000);
408 angle = rand.nextFloat() * 360f;
409 float offRange = renderSize * 0.25f;
410 xOff = -offRange / 2f + offRange * rand.nextFloat();
411 yOff = -offRange / 2f + offRange * rand.nextFloat();
412// if (Keyboard.isKeyDown(Keyboard.KEY_O)) {
413// xOff = yOff = 0f;
414// }
415 }
416 if (currIndex >= 0) {
417 weight++;
418 }
419 }
420 }
421 if (texIndex >= 0) {
422 int texCellX = texIndex % params.tW;
423 int texCellY = texIndex / params.tW;
424
425 Color color = getRenderColor();
426 float b = alphaMult * weight / max;
427// if (tiles.length > 30) {
428// b *= weight / max;
429// b *= weight / max;
430// }
431 //b = alphaMult;
432 GL11.glColor4ub((byte)color.getRed(),
433 (byte)color.getGreen(),
434 (byte)color.getBlue(),
435 (byte)((float)color.getAlpha() * b));
436 //xOff = yOff = 0f;
437 renderQuad((int)i, (int)j, (x + xOff - w / 2f + i/samples * size + size/2f - renderSize/2f) * factor,
438 (y + yOff - h / 2f + j/samples * size + size/2f - renderSize/2f) * factor,
439 renderSize * factor, renderSize * factor,
440 texCellX * 0.25f, texCellY * 0.25f,
441 0.25f, 0.25f,
442 angle);
443 }
444 }
445 }
446 GL11.glEnd();
447 }
448 }
449
450
451 protected float elapsed = 0f;
452 @Override
453 public void advance(float amount) {
454 super.advance(amount);
455// angleOffset += days * 20f;
456 float days = Global.getSector().getClock().convertToDays(amount);
457 elapsed += days;
458 }
459
460 protected void renderQuad(int i, int j, float x, float y, float width, float height, float texX, float texY, float texW, float texH, float angle) {
461 if (angle != 0) {
462 float vw = width / 2f;
463 float vh = height / 2f;
464 float cx = x + vw;
465 float cy = y + vh;
466
467 float cos = (float) Math.cos(angle * Misc.RAD_PER_DEG);
468 float sin = (float) Math.sin(angle * Misc.RAD_PER_DEG);
469
470 GL11.glTexCoord2f(texX, texY);
471 GL11.glVertex2f(cx + (-vw * cos + vh * sin), cy + (-vw * sin - vh * cos));
472
473 GL11.glTexCoord2f(texX, texY + texH);
474 GL11.glVertex2f(cx + (-vw * cos - vh * sin), cy + (-vw * sin + vh * cos));
475
476 GL11.glTexCoord2f(texX + texW, texY + texH);
477 GL11.glVertex2f(cx + (vw * cos - vh * sin), cy + (vw * sin + vh * cos));
478
479 GL11.glTexCoord2f(texX + texW, texY);
480 GL11.glVertex2f(cx + (vw * cos + vh * sin), cy + (vw * sin - vh * cos));
481
482 } else {
483 GL11.glTexCoord2f(texX, texY);
484 GL11.glVertex2f(x, y);
485
486 GL11.glTexCoord2f(texX, texY + texH);
487 GL11.glVertex2f(x, y + height);
488
489 GL11.glTexCoord2f(texX + texW, texY + texH);
490 GL11.glVertex2f(x + width, y + height);
491
492 GL11.glTexCoord2f(texX + texW, texY);
493 GL11.glVertex2f(x + width, y);
494 }
495 }
496
497 public float getMaxEffectRadius(Vector2f locFrom) {
498 // TODO: do intersection check from locFrom to an actual filled tile?
499
500 float size = getTileSize();
501 float renderSize = getTileRenderSize();
502 float w = tiles.length * size * 0.5f + (renderSize - size) * 0.5f;
503 float h = tiles[0].length * size * 0.5f + (renderSize - size) * 0.5f;
504 return Math.max(w, h) * 1.5f;
505 }
506 public float getMinEffectRadius(Vector2f locFrom) {
507 return 0f;
508 }
509
510 public float getOptimalEffectRadius(Vector2f locFrom) {
511 return getMaxEffectRadius(locFrom);
512 }
513
514
515
516 @Override
517 protected float getExtraSoundRadius() {
518 return 200f;
519 }
520
521
522 public float getProximitySoundFactor() {
523 CampaignFleetAPI player = Global.getSector().getPlayerFleet();
524 float r = player.getRadius() + getExtraSoundRadius();
525 Vector2f test = player.getLocation();
526
527 float x = this.entity.getLocation().x;
528 float y = this.entity.getLocation().y;
529 float size = getTileSize();
530 float containsSize = getTileContainsSize();
531
532 float w = tiles.length * size;
533 float h = tiles[0].length * size;
534
535 x -= w/2f;
536 y -= h/2f;
537
538 float extra = (containsSize - size) / 2f;
539
540 if (test.x + r + extra < x) return 0f;
541 if (test.y + r + extra < y) return 0f;
542 if (test.x > x + w + r + extra) return 0f;
543 if (test.y > y + h + r + extra) return 0f;
544
545 int xIndex = (int) ((test.x - x) / size);
546 int yIndex = (int) ((test.y - y) / size);
547
548 if (xIndex < 0) xIndex = 0;
549 if (yIndex < 0) yIndex = 0;
550
551 if (xIndex >= tiles.length) xIndex = tiles.length - 1;
552 if (yIndex >= tiles[0].length) yIndex = tiles[0].length - 1;
553
554
555 float closestDist = Float.MAX_VALUE;
556
557 for (float i = Math.max(0, xIndex - 2); i <= xIndex + 2 && i < tiles.length; i++) {
558 for (float j = Math.max(0, yIndex - 2); j <= yIndex + 2 && j < tiles[0].length; j++) {
559 int texIndex = tiles[(int) i][(int) j];
560 if (texIndex >= 0) {
561 float tx = x + i * size + size/2f - containsSize/2f;
562 float ty = y + j * size + size/2f - containsSize/2f;
563
564 if (test.x + r < tx) continue;
565 if (test.y + r < ty) continue;
566 if (test.x > tx + containsSize + r) continue;
567 if (test.y > ty + containsSize + r) continue;
568
569 //float dist = Misc.getDistance(test, new Vector2f(tx + containsSize/2f, ty + containsSize/2f));
570 float dx = Math.abs(test.x - tx - containsSize / 2f);
571 float dy = Math.abs(test.y - ty - containsSize / 2f);
572 float dist = Math.max(dx, dy);
573 if (dist < closestDist) {
574 closestDist = dist;
575 }
576 }
577 }
578 }
579
580 //System.out.println("Closest: " + closestDist);
581 //float max = containsSize * 0.5f * 1.41f + EXTRA_SOUND_RADIUS;
582 float max = containsSize * 0.5f + getExtraSoundRadius();
583 if (closestDist < containsSize * 0.5f) return 1f;
584
585 float p = (max - closestDist) / (max - containsSize * 0.5f);
586 if (p < 0) p = 0;
587 if (p > 1) p = 1;
588
589 return p;
590 }
591
592
593
594 public static String encodeTiles(int [][] tiles) {
595 int w = tiles.length;
596 int h = tiles[0].length;
597 int total = w * h;
598
599// int [] masks = new int [] {
600// 1,
601// 2,
602// 4,
603// 8,
604// 16,
605// 32,
606// 64,
607// 128,
608// };
609 int [] masks = new int [] {
610 128,
611 64,
612 32,
613 16,
614 8,
615 4,
616 2,
617 1,
618 };
619
620 int bit = 0;
621 int curr = 0;
622 //List<Byte> bytes = new ArrayList<Byte>();
623 byte [] input = new byte [(int) Math.ceil(total / 8f)];
624 for (int i = 0; i < total; i++) {
625 int x = i % w;
626 int y = i / w;
627 int val = tiles[x][y];
628 int mask = masks[bit];
629
630 if (val >= 0) {
631 curr = (curr | mask);
632 }
633
634 bit++;
635 bit %= 8;
636
637 if (bit == 0) {
638 input[i/8] = ((byte) curr);
639 curr = 0;
640 }
641 }
642 if (bit != 0) {
643 input[input.length - 1] = ((byte) curr);
644 curr = 0;
645 }
646
647 /*
648 List<Byte> bytes = new ArrayList<Byte>();
649 String seq = "";
650 for (int i = 0; i < total; i++) {
651 int x = i % w;
652 int y = i / w;
653 int val = tiles[x][y];
654 String curr = "0";
655 if (val >= 0) curr = "1";
656 seq += curr;
657 if (seq.length() == 8) {
658 //byte b = Byte.parseByte(seq, 2);
659 int b = Integer.parseInt(seq, 2);
660 bytes.add((byte) b);
661 seq = "";
662 }
663 }
664 if (seq.length() > 0) {
665 while (seq.length() < 8) {
666 seq = seq + "0";
667 }
668 //byte b = Byte.parseByte(seq, 2);
669 //bytes.add(b);
670 int b = Integer.parseInt(seq, 2);
671 bytes.add((byte) b);
672 }
673
674 byte [] input = new byte [bytes.size()];
675 for (int i = 0; i < bytes.size(); i++) {
676 input[i] = bytes.get(i);
677 }
678 */
679
680 Deflater compressor = new Deflater();
681 //compresser.setLevel(Deflater.BEST_COMPRESSION);
682 //compresser.setStrategy(Deflater.HUFFMAN_ONLY);
683 compressor.setInput(input);
684 compressor.finish();
685
686 StringBuilder result = new StringBuilder();
687 byte [] temp = new byte[100];
688
689 while (!compressor.finished()) {
690 int read = compressor.deflate(temp);
691 result.append(toHexString(Arrays.copyOf(temp, read)));
692 }
693
694// result = new StringBuilder();
695// result.append(toHexString(input));
696
697 compressor.end();
698
699 return result.toString();
700 }
701
702 public static int [][] decodeTiles(String string, int w, int h) throws DataFormatException {
703 byte [] input = toByteArray(string);
704
705 Inflater decompressor = new Inflater();
706 decompressor.setInput(input);
707
708 int [][] tiles = new int [w][h];
709 int total = w * h;
710 int curr = 0;
711
712 byte [] temp = new byte[100];
713 OUTER: while (!decompressor.finished()) {
714 int read = decompressor.inflate(temp);
715 for (int i = 0; i < read; i++) {
716 byte b = temp[i];
717
718 for (int j = 7; j >= 0; j--) {
719 int x = curr % w;
720 int y = curr / w;
721 curr++;
722
723 if (curr > total) break OUTER;
724 //System.out.println("bytes read: " + curr);
725 if ((b & (0x01 << j)) > 0) {
726 tiles[x][y] = 1;
727 } else {
728 tiles[x][y] = -1;
729 }
730 }
731 }
732 }
733
734 decompressor.end();
735
736 return tiles;
737 }
738
739
740 public static String toHexString(byte[] array) {
741 return DatatypeConverter.printBase64Binary(array);
742 }
743
744 public static byte[] toByteArray(String s) {
745 return DatatypeConverter.parseBase64Binary(s);
746 }
747
748
749
750 public static void main(String[] args) throws DataFormatException {
751
752// int [][] tiles = new int[][] {
753// {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
754// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
755// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
756// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1},
757// {1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
758// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
759// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
760// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
761// {1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
762// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
763// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
764// {1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
765// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
766// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
767// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
768// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
769// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1},
770// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
771// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
772// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
773// };
774
775 int [][] tiles = new int[][] {
776 {-1, 1, 1, 1, -1},
777 {1, 1, 1, 1, 1},
778 {1, 1, 1, 1, -1},
779 {1, 1, 1, -1, 1},
780 };
781
782// int w = 128;
783// int h = 128;
784// int [][] tiles = new int [w][h];
785//
786// for (int i = 0; i < w; i++) {
787// for (int j = 0; j < h; j++) {
788// if ((float) Math.random() > 0.8f) {
789// tiles[i][j] = 0;
790// } else {
791// tiles[i][j] = -1;
792// }
793// }
794// }
795
796
797 System.out.println("Original:");
798 for (int i = 0; i < tiles.length; i++) {
799 for (int j = 0; j < tiles[0].length; j++) {
800 System.out.print(String.format("% 2d,", tiles[i][j]));
801 }
802 System.out.println();
803 }
804
805 String result = encodeTiles(tiles);
806 System.out.println(result);
807 //System.out.println(result.length() + ", would be " + (w * h / 4) + " without compression");
808 int [][] tilesBack = decodeTiles(result, tiles.length, tiles[0].length);
809
810 System.out.println("Decoded:");
811 for (int i = 0; i < tilesBack.length; i++) {
812 for (int j = 0; j < tilesBack[0].length; j++) {
813 System.out.print(String.format("% 2d,", tilesBack[i][j]));
814 }
815 System.out.println();
816 }
817
818 boolean equals = true;
819 for (int i = 0; i < tiles.length; i++) {
820 for (int j = 0; j < tiles[0].length; j++) {
821 if (tiles[i][j] != tilesBack[i][j]) {
822 equals = false;
823 }
824 }
825 }
826
827 System.out.println("Equal: " + equals);
828
829// for (int x = 0; x < tilesBack.length; x++) {
830// for (int y = 0; y < tilesBack.length; y++) {
831// System.out.print(tilesBack[x][y] + " ");
832// }
833// System.out.println();
834// }
835 }
836}
837
838
839
840
841
842
843
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
boolean isPreventedFromAffecting(SectorEntityToken other)
void renderQuad(int i, int j, float x, float y, float width, float height, float texX, float texY, float texW, float texH, float angle)
void init(String terrainId, SectorEntityToken entity, Object param)
abstract void preRender(CampaignEngineLayers layer, float alphaMult)
void render(CampaignEngineLayers layer, ViewportAPI v)
static int[][] decodeTiles(String string, int w, int h)
void renderSubArea(float startColumn, float endColumn, float startRow, float endRow, float factor, int samples, float alphaMult)
SpriteAPI getSprite(String filename)