package com.riiablo; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.Vector2; import com.riiablo.codec.DC; import com.riiablo.codec.Index; import com.riiablo.codec.util.BBox; import com.riiablo.graphics.PaletteIndexedBatch; import com.riiablo.item.Item; import com.riiablo.item.Location; import com.riiablo.save.ItemData; /** * FIXME: Drawing cursor is proving troublesome. Either draw over in-game cursor or set hardware * cursor to a pixmap. Pixmap is doable, but will require rasterizing an ARGB8888 version * of the pixmap with all the needed transformations to color and some work to make the * animations work in the default case with the hand. Other solution is to simply draw the * cursor over the game and hide the hardware cursor entirely. This doesn't work very well * when v-sync is enabled and is workable once v-sync is disabled and the foreground fps * increased, outside of that, there is a noticeable lag to the hardware cursor position. * -- * Long term I'd like to implement support for the pixmap method since it's more correct, but * I think I'll stick with the other in the meantime because of its simplicity to implement, * and because it will rely on existing code for changing item colors, etc. */ public class Cursor implements ItemData.LocationListener { private static final String TAG = "Cursor"; private static final boolean DEBUG = true; private static final boolean DEBUG_ITEM_BOUNDS = DEBUG && !true; private static final boolean DEBUG_LISTENER = DEBUG && !true; private com.badlogic.gdx.graphics.Cursor cursor; private Item item; private DC dc; private Index transform; private int transformColor; private Vector2 coords = new Vector2(); public Cursor() { //Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); //cursor = Gdx.graphics.newCursor(pixmap, 0, 0); //Gdx.graphics.setCursor(cursor); } public com.badlogic.gdx.graphics.Cursor getCursor() { return cursor; } public void setCursor(DC dc) { setCursor(dc, null, 0); } public void setCursor(DC dc, Index colormap, int id) { if (cursor == null) { Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); cursor = Gdx.graphics.newCursor(pixmap, 0, 0); Gdx.graphics.setCursor(cursor); } this.dc = dc; if (colormap != null) { transform = colormap; transformColor = id; } else { transform = null; transformColor = 0; } } public void resetCursor() { dc = null; Gdx.graphics.setSystemCursor(com.badlogic.gdx.graphics.Cursor.SystemCursor.Arrow); cursor = null; } public Item getItem() { return Riiablo.charData.getItems().getCursor(); } public void setItem(Item item) { if (this.item == null && item != null) { Riiablo.audio.play("item_pickup", true); } this.item = item; if (item != null) { setCursor(item.invFile, item.invColormap, item.invColorIndex); } else { resetCursor(); } } public void act(float delta) { if (dc == null && item != null && item.checkLoaded()) { setCursor(item.invFile, item.invColormap, item.invColorIndex); } } public void render(PaletteIndexedBatch batch) { if (dc != null) { BBox box = dc.getBox(); coords.set(Gdx.input.getX(), Gdx.input.getY()); Riiablo.extendViewport.unproject(coords); coords.sub(box.width / 2f, box.height / 2f); batch.begin(); batch.setColormap(transform, transformColor); if (item.isEthereal()) batch.setAlpha(Item.ETHEREAL_ALPHA); batch.draw(dc.getTexture(), coords.x, coords.y); if (item.isEthereal()) batch.resetColor(); batch.resetColormap(); batch.end(); if (DEBUG_ITEM_BOUNDS) { ShapeRenderer shapes = Riiablo.shapes; shapes.setProjectionMatrix(Riiablo.extendViewport.getCamera().combined); shapes.begin(ShapeRenderer.ShapeType.Line); shapes.setColor(Color.GREEN); shapes.rect(coords.x, coords.y, box.width, box.height); shapes.end(); } } } public int getX() { return Gdx.input.getX(); } public int getY() { return Gdx.input.getY(); } public Vector2 getCoords() { return coords.set(getX(), getY()); } @Override public void onChanged(ItemData items, Location oldLocation, Location location, Item item) { if (DEBUG_LISTENER) Gdx.app.log(TAG, "onChange " + oldLocation + "->" + location + " " + item); if (oldLocation == Location.CURSOR && location != Location.CURSOR) { setItem(null); } else if (location == Location.CURSOR) { setItem(item); } } }