package domain; import static core.VergeEngine.*; import static core.Script.*; import java.awt.Color; public abstract class MapAbstract implements Map { protected String renderstring = "R"; protected Vsp tileset; protected int startX, startY; // Unsigned short protected boolean horizontalWrapable = false; // [Rafael, the Esper] protected boolean verticalWrapable = false; // [Rafael, the Esper] public boolean getHorizontalWrapable() { return this.horizontalWrapable; } public boolean getVerticalWrapable() { return this.verticalWrapable; } public void setHorizontalWrapable(boolean b) { this.horizontalWrapable = b; } public void setVerticalWrapable(boolean b) { this.verticalWrapable = b; } public Vsp getTileSet() { return this.tileset; } public int getStartX() { return this.startX; } public int getStartY() { return this.startY; } public void render(int x, int y, VImage dest) { boolean first = true; int tx = (dest.width / 16) + 2; int ty = (dest.height / 16) + 2; for (int i = 0; i < renderstring.length(); i++) { char token = renderstring.charAt(i); if (token == ',') { continue; } if (token == 'E') { RenderEntities(dest); continue; } if (token == 'R') { hookretrace(); continue; } if (Character.isDigit(token)) { int layer = Integer.parseInt(Character.toString(token))-1; if (first) { // Rafael: For an unknown reason, it's better to draw the first layer as a // transparent one than the original code drawing it non-transparent (2x FPS) //dest.rectfill(0,0,dest.width,dest.height,java.awt.Color.BLACK); blitLayer(true, layer, tx, ty, x, y, dest); first = false; continue; } blitLayer(true, layer, tx, ty, x, y, dest); } } //dest.g.drawString(myself.getx()/16 + "/" + getWidth(), 0, 30); } private void blitLayer(boolean transparent, int l, int tx, int ty, int xwin, int ywin, VImage dest) { if(l >= this.getNumLayers()) return; //[Rafael, the Esper] // we add offsets here because if the parallax changes while the // xwin and ywin are non-zero, we would jump unless we compensate //int oxw = this.layers[l].x_offset + (int) ((float) xwin * this.layers[l].parallax_x); //int oyw = this.layers[l].y_offset + (int) ((float) ywin * this.layers[l].parallax_y); int oxw = xwin; // TODO Change this simplification to the code above int oyw = ywin; // Same to-do as above int xofs = -(oxw & 15); int yofs = -(oyw & 15); int xtc = oxw >> 4; int ytc = oyw >> 4; if (transparent) if (this.getLayerLucent(l) != 0) setlucent(this.getLayerLucent(l)); if(this.tileset.UpdateAnimations()) { resetCacheArray(); } // Initialize cache arrays if(imgcache.length < this.getNumLayers()) { xcache = getCacheArray(getNumLayers()); ycache = getCacheArray(getNumLayers()); imgcache = new VImage[getNumLayers()]; } if(imgcache[l]==null) { imgcache[l] = new VImage(dest.width+16, dest.height+16); } // Draw layer into the cache if(xtc!=xcache[l] || ytc!=ycache[l]) { if(transparent) { imgcache[l].g.setBackground(new Color(255, 255, 255, 0)); imgcache[l].g.clearRect(0, 0, imgcache[l].width, imgcache[l].height); } for (int y = 0; y < ty+1; y++) { for (int x = 0; x < tx+1; x++) { int c = 0; if(horizontalWrapable && verticalWrapable) // Changed by [Rafael, the Esper] c = gettile((xtc + x+getWidth())%(getWidth()), (ytc + y+getHeight())%(getHeight()), l); else if(!horizontalWrapable && verticalWrapable) c = gettile((xtc + x), (ytc + y+getHeight())%(getHeight()), l); else if(horizontalWrapable && !verticalWrapable) c = gettile((xtc + x+getWidth())%(getWidth()), (ytc + y), l); else if(!horizontalWrapable && !verticalWrapable) c = gettile(xtc + x, ytc + y, l); if (transparent) { if (c != 0 || l==0) { tileset.TBlit((x * 16), (y * 16), c, imgcache[l]); //tileset.TBlit((x * 16) + xofs, (y * 16) + yofs, c, dest); } } else { tileset.Blit((x * 16), (y * 16), c, imgcache[l]); //tileset.Blit((x * 16) + xofs, (y * 16) + yofs, c, dest); } } } } // New code to allow blitting the whole image, instead of tile per tile if(transparent) dest.tblit(xofs, yofs, imgcache[l]); else dest.blit(xofs, yofs, imgcache[l]); xcache[l] = xtc; ycache[l] = ytc; //if (dest == screen) { // TODO Uncomment RenderLayerSprites(l); //} if (transparent) setlucent(0); } static int[] xcache = getCacheArray(1); static int[] ycache = getCacheArray(1); static VImage[] imgcache = new VImage[1]; private static int[] getCacheArray(int size) { int[] ret = new int[size]; for(int i=0; i<ret.length; i++) ret[i] = -1; return ret; } protected static void resetCacheArray() { xcache = getCacheArray(1); ycache = getCacheArray(1); imgcache = new VImage[1]; } }