|
@@ -1,11 +1,16 @@
|
|
package tile
|
|
package tile
|
|
|
|
|
|
-import import "log"
|
|
|
|
|
|
+// import "log"
|
|
// import "os"
|
|
// import "os"
|
|
// import "math"
|
|
// import "math"
|
|
|
|
|
|
-import al "gitlab.com/beoran/al5go/al"
|
|
|
|
-import al "gitlab.com/beoran/ebsgo/engine/geometry/point"
|
|
|
|
|
|
+import "gitlab.com/beoran/al5go/al"
|
|
|
|
+import "gitlab.com/beoran/ebsgo/engine/geometry/point"
|
|
|
|
+
|
|
|
|
+const TILE_W = 32
|
|
|
|
+const TILE_H = 32
|
|
|
|
+
|
|
|
|
+var showSolid = false;
|
|
|
|
|
|
|
|
|
|
/** A tile set */
|
|
/** A tile set */
|
|
@@ -33,7 +38,7 @@ type Frame struct {
|
|
* pointer and offset which points to the next tile to be drawn in the tileset.
|
|
* pointer and offset which points to the next tile to be drawn in the tileset.
|
|
*/
|
|
*/
|
|
type Tile struct {
|
|
type Tile struct {
|
|
- Tileset Set /* Tileset this tile belongs to */
|
|
|
|
|
|
+ Tileset * Set /* Tileset this tile belongs to */
|
|
Index int /* Index in the tile set. */
|
|
Index int /* Index in the tile set. */
|
|
Flags int /* Information about the tile's properties. */
|
|
Flags int /* Information about the tile's properties. */
|
|
Kind int
|
|
Kind int
|
|
@@ -58,7 +63,7 @@ type Tile struct {
|
|
/* Automatic blending activation and priority. */
|
|
/* Automatic blending activation and priority. */
|
|
Blend int
|
|
Blend int
|
|
/* Mask number to use for automatic blending, if any. */
|
|
/* Mask number to use for automatic blending, if any. */
|
|
- BlendMAsk int
|
|
|
|
|
|
+ BlendMask int
|
|
/* Automatic lighting activation flag. */
|
|
/* Automatic lighting activation flag. */
|
|
Light int
|
|
Light int
|
|
LightMAsk int
|
|
LightMAsk int
|
|
@@ -79,20 +84,20 @@ type Tile struct {
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
|
|
-func NewTileset(sheet * al.Bitmap, tile_w, tile_h, firstgid int) Set {
|
|
|
|
|
|
+func NewSet(sheet * al.Bitmap, tile_w, tile_h, firstgid int) * Set {
|
|
set := &Set{}
|
|
set := &Set{}
|
|
set.Sheet = sheet
|
|
set.Sheet = sheet
|
|
set.TileW = tile_w
|
|
set.TileW = tile_w
|
|
set.TileH = tile_h
|
|
set.TileH = tile_h
|
|
set.FirstGID = firstgid
|
|
set.FirstGID = firstgid
|
|
set.W = sheet.Width() / set.TileW
|
|
set.W = sheet.Width() / set.TileW
|
|
- set.H = shet.Height() / set.TileH
|
|
|
|
|
|
+ set.H = sheet.Height()/ set.TileH
|
|
size := set.W * set.H
|
|
size := set.W * set.H
|
|
set.Tiles = make([]Tile, size)
|
|
set.Tiles = make([]Tile, size)
|
|
- set.Last = 0
|
|
|
|
- for := 0 ; i < size; i ++ {
|
|
|
|
|
|
+ for i := 0 ; i < size; i ++ {
|
|
set.Tiles[i].Init(set, i)
|
|
set.Tiles[i].Init(set, i)
|
|
}
|
|
}
|
|
|
|
+ return set
|
|
}
|
|
}
|
|
|
|
|
|
func (tile * Tile) Init(set * Set, index int) {
|
|
func (tile * Tile) Init(set * Set, index int) {
|
|
@@ -102,31 +107,31 @@ func (tile * Tile) Init(set * Set, index int) {
|
|
tile.Recalculate()
|
|
tile.Recalculate()
|
|
}
|
|
}
|
|
|
|
|
|
-func (tile Tile) SheetY(set Tileset) int {
|
|
|
|
- (tile->Active * set->TileW) / (set->W * set->TileH)
|
|
|
|
|
|
+func (tile Tile) SheetY(set * Set) int {
|
|
|
|
+ return (tile.Active * set.TileW) / (set.W * set.TileH)
|
|
}
|
|
}
|
|
|
|
|
|
-func (tile Tile) SheetX(set Tileset) int {
|
|
|
|
- (tile->Active * set->TileW) % (set->W)
|
|
|
|
|
|
+func (tile Tile) SheetX(set * Set) int {
|
|
|
|
+ return (tile.Active * set.TileW) % (set.W)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Recalculates the tile's position (now) in it's tile set. */
|
|
/** Recalculates the tile's position (now) in it's tile set. */
|
|
func (tile * Tile) Recalculate() {
|
|
func (tile * Tile) Recalculate() {
|
|
- if !tile.Tileset {
|
|
|
|
|
|
+ if nil == tile.Tileset {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
x := float64(tile.SheetX(tile.Tileset))
|
|
x := float64(tile.SheetX(tile.Tileset))
|
|
y := float64(tile.SheetY(tile.Tileset))
|
|
y := float64(tile.SheetY(tile.Tileset))
|
|
|
|
|
|
- tile.now = point.New(x, y)
|
|
|
|
|
|
+ tile.Position = point.New(x, y)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-func (set * Set) Get(index int) * Tile {
|
|
|
|
|
|
+func (set * Set) Tile(index int) * Tile {
|
|
if nil != set && index >= 0 && index <= len(set.Tiles) {
|
|
if nil != set && index >= 0 && index <= len(set.Tiles) {
|
|
- return set.Tiles[index]
|
|
|
|
|
|
+ return &set.Tiles[index]
|
|
}
|
|
}
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
@@ -144,6 +149,8 @@ const (
|
|
TILE_SOUTH = iota
|
|
TILE_SOUTH = iota
|
|
TILE_EAST = iota
|
|
TILE_EAST = iota
|
|
TILE_WEST = iota
|
|
TILE_WEST = iota
|
|
|
|
+ TILE_UP = iota
|
|
|
|
+ TILE_DOWN = iota
|
|
TILE_ICE = iota
|
|
TILE_ICE = iota
|
|
)
|
|
)
|
|
|
|
|
|
@@ -151,17 +158,19 @@ const (
|
|
|
|
|
|
|
|
|
|
/* Helper lookup table for the tile flag names */
|
|
/* Helper lookup table for the tile flag names */
|
|
-var FlagNames := map[string]int {
|
|
|
|
- "wall" , TILE_WALL ,
|
|
|
|
- "water", TILE_WATER ,
|
|
|
|
- "ledge", TILE_LEDGE ,
|
|
|
|
- "stair", TILE_STAIR ,
|
|
|
|
- "push" , TILE_PUSH ,
|
|
|
|
- "north", TILE_NORTH ,
|
|
|
|
- "south", TILE_SOUTH ,
|
|
|
|
- "east" , TILE_EAST ,
|
|
|
|
- "west" , TILE_WEST ,
|
|
|
|
- "ice" , TILE_ICE ,
|
|
|
|
|
|
+var FlagNames map[string]uint = map[string]uint {
|
|
|
|
+ "wall" : TILE_WALL ,
|
|
|
|
+ "water": TILE_WATER ,
|
|
|
|
+ "ledge": TILE_LEDGE ,
|
|
|
|
+ "stair": TILE_STAIR ,
|
|
|
|
+ "push" : TILE_PUSH ,
|
|
|
|
+ "north": TILE_NORTH ,
|
|
|
|
+ "south": TILE_SOUTH ,
|
|
|
|
+ "east" : TILE_EAST ,
|
|
|
|
+ "west" : TILE_WEST ,
|
|
|
|
+ "up" : TILE_UP ,
|
|
|
|
+ "down" : TILE_DOWN ,
|
|
|
|
+ "ice" : TILE_ICE ,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -175,6 +184,14 @@ func (tile * Tile) SetProperty(property string) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (tile * Tile) HasFlag(flag uint) bool {
|
|
|
|
+ return (tile.Flags & (1 << flag)) == (1 << flag)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (tile * Tile) IsWall() bool {
|
|
|
|
+ return tile.HasFlag(TILE_WALL)
|
|
|
|
+}
|
|
|
|
+
|
|
/** Initializes a tile's frame of animation. */
|
|
/** Initializes a tile's frame of animation. */
|
|
func (frame * Frame) Init(index int, duration float64) {
|
|
func (frame * Frame) Init(index int, duration float64) {
|
|
frame.Index = index
|
|
frame.Index = index
|
|
@@ -188,162 +205,130 @@ func (tile Tile) Frame(index int) * Frame {
|
|
if nil == tile.Frames{
|
|
if nil == tile.Frames{
|
|
return nil
|
|
return nil
|
|
} else {
|
|
} else {
|
|
- return tiles.Frames[index]
|
|
|
|
|
|
+ return &tile.Frames[index]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/** Gets the amount of Tiled style animations for this tile, or 0 if none. */
|
|
/** Gets the amount of Tiled style animations for this tile, or 0 if none. */
|
|
-int tile_frame_count(Tile * tile) {
|
|
|
|
|
|
+func (tile Tile) FrameCount() int {
|
|
if nil == tile.Frames {
|
|
if nil == tile.Frames {
|
|
- return nil
|
|
|
|
|
|
+ return 0
|
|
} else {
|
|
} else {
|
|
- return len(tiles.Frames)
|
|
|
|
|
|
+ return len(tile.Frames)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/** Adds a Tiled-style animation frame to the tile. */
|
|
/** Adds a Tiled-style animation frame to the tile. */
|
|
-Tile * tile_add_animation_frame(Tile * tile, int index, double duration) {
|
|
|
|
- if (tile->frames) {
|
|
|
|
- int size;
|
|
|
|
- size = dynar_size(tile->frames);
|
|
|
|
- if (!dynar_size_(tile->frames, size + 1)) return NULL;
|
|
|
|
- tileframe_init(dynar_getdata(tile->frames, size), index, duration);
|
|
|
|
- } else {
|
|
|
|
- tile->frames = dynar_new(1, sizeof(struct TileFrame_));
|
|
|
|
- if (!tile->frames) return NULL;
|
|
|
|
- tileframe_init(dynar_getdata(tile->frames, 0), index, duration);
|
|
|
|
- }
|
|
|
|
- return tile;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
+func (tile * Tile) AddAnimationFrame(index int, duration float64) (frame * Frame) {
|
|
|
|
+ if (nil == tile.Frames) {
|
|
|
|
+ tile.Frames = make([]Frame, 1)
|
|
|
|
+ frame = &tile.Frames[0]
|
|
|
|
+ } else {
|
|
|
|
+ frame = &Frame{}
|
|
|
|
+ tile.Frames = append(tile.Frames, *frame)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ frame.Init(index, duration)
|
|
|
|
+ return frame
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
/** Rewinds a tile's animations. */
|
|
/** Rewinds a tile's animations. */
|
|
-void tile_rewindanime(Tile * tile) {
|
|
|
|
- if (!tile) return;
|
|
|
|
- tile->active = tile->index;
|
|
|
|
- tile->active_frame = 0;
|
|
|
|
|
|
+func (tile * Tile) RewindAnimations() {
|
|
|
|
+ tile.Active = tile.Index
|
|
|
|
+ tile.ActiveFrame = 0
|
|
// Finally recalculate tile position.
|
|
// Finally recalculate tile position.
|
|
- tile_recalculate(tile);
|
|
|
|
|
|
+ tile.Recalculate()
|
|
}
|
|
}
|
|
|
|
|
|
-/** Updates a tile to animate it using classic style animation.*/
|
|
|
|
-void tile_update_classic(Tile * tile, double dt) {
|
|
|
|
- int active = 0;
|
|
|
|
- Tile * aidtile = NULL;
|
|
|
|
- Tile * nowtile = tileset_get(tile->set, tile->active);
|
|
|
|
- // nowtile is the tile that is currently active, that is shown.
|
|
|
|
- // in stead of ourself, but it also may be ourself.
|
|
|
|
- if(!nowtile) return;
|
|
|
|
- tile->time += dt; // advance animation time of tile.
|
|
|
|
- // Don't animate if not enough time has passed
|
|
|
|
- if(tile->time < tile->wait) return;
|
|
|
|
- // if we get here, reset animation time.
|
|
|
|
- tile->time = 0.0;
|
|
|
|
- // take the animation parameter and add it to the active
|
|
|
|
- active = tile->active + nowtile->anim;
|
|
|
|
- aidtile = tileset_get(tile->set, active);
|
|
|
|
- // Check if there is such a tile.
|
|
|
|
- if(!aidtile) return;
|
|
|
|
- // If there is no such tile, don't change the active tile of this tile.
|
|
|
|
- tile->active = active;
|
|
|
|
- // Finally recalculate tile position.
|
|
|
|
- tile_recalculate(tile);
|
|
|
|
-}
|
|
|
|
|
|
|
|
-/** Updates a tile to anmate it using TMX style animation. */
|
|
|
|
-void tile_update_tmx(Tile * tile, double dt) {
|
|
|
|
- int active = 0;
|
|
|
|
- TileFrame * frame = NULL;
|
|
|
|
- Tile * aidtile = NULL;
|
|
|
|
-
|
|
|
|
- frame = tile_frame(tile, tile->active_frame);
|
|
|
|
- if (!frame) { /* Animation overshoit itself somehow??? */
|
|
|
|
- tile->active_frame = 0;
|
|
|
|
- frame = tile_frame(tile, tile->active_frame);
|
|
|
|
- if (!frame) return;
|
|
|
|
|
|
+/** Updates a tile to animate it using TMX style animation. */
|
|
|
|
+func (tile * Tile) UpdateAnimation(dt float64) {
|
|
|
|
+ active := 0;
|
|
|
|
+
|
|
|
|
+ frame := tile.Frame(tile.ActiveFrame)
|
|
|
|
+ if nil == frame { /* Animation overshot itself */
|
|
|
|
+ tile.ActiveFrame = 0
|
|
|
|
+ frame = tile.Frame(tile.ActiveFrame)
|
|
|
|
+ if nil == frame {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- tile->time += dt; // advance animation time of tile.
|
|
|
|
|
|
+ tile.Time += dt // advance animation time of tile.
|
|
// Don't animate if not enough time has passed
|
|
// Don't animate if not enough time has passed
|
|
- if(tile->time < frame->duration) return;
|
|
|
|
|
|
+ if tile.Time < frame.Duration {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
// advance the animation frame, loop it around if needed.
|
|
// advance the animation frame, loop it around if needed.
|
|
- tile->active_frame++;
|
|
|
|
- if (tile->active_frame >= tile_frame_count(tile)) {
|
|
|
|
- tile->active_frame = 0;
|
|
|
|
|
|
+ tile.ActiveFrame++
|
|
|
|
+ if tile.ActiveFrame >= tile.FrameCount() {
|
|
|
|
+ tile.ActiveFrame = 0
|
|
}
|
|
}
|
|
// Get new tile frame
|
|
// Get new tile frame
|
|
- frame = tile_frame(tile, tile->active_frame);
|
|
|
|
|
|
+ frame = tile.Frame(tile.ActiveFrame);
|
|
// If we get here, reset animation time.
|
|
// If we get here, reset animation time.
|
|
- tile->time = 0.0;
|
|
|
|
- if (!frame) return;
|
|
|
|
-
|
|
|
|
- // Get the active tile t use from the animation frame
|
|
|
|
- active = frame->index;
|
|
|
|
- aidtile = tileset_get(tile->set, active);
|
|
|
|
|
|
+ tile.Time = 0.0
|
|
|
|
+ if nil == frame {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // Get the active tile to use from the animation frame
|
|
|
|
+ active = frame.Index
|
|
|
|
+ aidtile := tile.Tileset.Tile(active);
|
|
// Check if there is such a tile.
|
|
// Check if there is such a tile.
|
|
- if(!aidtile) return;
|
|
|
|
|
|
+ if nil == aidtile {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
// If there is no such tile, don't change the active tile of this tile.
|
|
// If there is no such tile, don't change the active tile of this tile.
|
|
- tile->active = active;
|
|
|
|
|
|
+ tile.Active = active
|
|
// Finally recalculate tile position.
|
|
// Finally recalculate tile position.
|
|
- tile_recalculate(tile);
|
|
|
|
- // tile->now = aidtile->now;
|
|
|
|
- // LOG_NOTE("TMX Anim: %d (%d: set(%d, %d)): (x,y)=(%lf, %lf)\n", tile->index, tile->active, tile->set->w, tile->set->h, tile->now.x, tile->now.y);
|
|
|
|
|
|
+ tile.Recalculate();
|
|
}
|
|
}
|
|
|
|
|
|
-/* Animates the tile. If it has a TMX style animation, that takes
|
|
|
|
- * precedence, otherwise, use the classic style animation. */
|
|
|
|
-void tile_update(Tile * tile, double dt) {
|
|
|
|
- if (tile->frames) {
|
|
|
|
- tile_update_tmx(tile, dt);
|
|
|
|
- } else {
|
|
|
|
- tile_update_classic(tile, dt);
|
|
|
|
- }
|
|
|
|
|
|
+/* Animates the tile. Animates the tile if it has animation frames. */
|
|
|
|
+func (tile * Tile) Update(dt float64) {
|
|
|
|
+ if nil != tile.Frames {
|
|
|
|
+ tile.UpdateAnimation(dt)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Updates all tiles in a tile set so they all get animated. */
|
|
/** Updates all tiles in a tile set so they all get animated. */
|
|
-void tileset_update(Tileset * set, double dt) {
|
|
|
|
- int index, size;
|
|
|
|
- if (!set) return;
|
|
|
|
- if (!set->tiles) return;
|
|
|
|
- size = tileset_size(set);
|
|
|
|
- for (index = 0; index < size; index++) {
|
|
|
|
- Tile * tile = tileset_get(set, index);
|
|
|
|
- tile_update(tile, dt);
|
|
|
|
- }
|
|
|
|
|
|
+func (set * Set) Update(dt float64) {
|
|
|
|
+ if nil == set.Tiles {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for i := 0 ; i < len(set.Tiles); i ++ {
|
|
|
|
+ tile := &set.Tiles[i]
|
|
|
|
+ tile.Update(dt)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Draw a tile to the current active drawing target at the
|
|
/** Draw a tile to the current active drawing target at the
|
|
given coordinates. Does nothing if tile is NULL. */
|
|
given coordinates. Does nothing if tile is NULL. */
|
|
-void tile_draw(Tile * tile, int x, int y, int drawflags) {
|
|
|
|
- Tileset * set;
|
|
|
|
- Image * sheet;
|
|
|
|
- Color dcolor = al_map_rgb(0xee, 0xee, 0x00);
|
|
|
|
- if (!tile) return;
|
|
|
|
- set = tile->set;
|
|
|
|
- sheet = set->sheet;
|
|
|
|
- float dx = (float) x;
|
|
|
|
- float dy = (float) y;
|
|
|
|
- float sx = (float) tile->now.x;
|
|
|
|
- float sy = (float) tile->now.y;
|
|
|
|
- float sw = (float) TILE_W;
|
|
|
|
- float sh = (float) TILE_H;
|
|
|
|
- al_draw_bitmap_region(sheet, sx, sy, sw, sh, dx, dy, drawflags);
|
|
|
|
|
|
+func (tile Tile) Draw(x, y float32, drawflags int) {
|
|
|
|
+ set := tile.Tileset
|
|
|
|
+ sheet := set.Sheet
|
|
|
|
+ dx := float32(x)
|
|
|
|
+ dy := float32(y)
|
|
|
|
+ sx := float32(tile.Position.X)
|
|
|
|
+ sy := float32(tile.Position.Y)
|
|
|
|
+ sw := float32(set.TileW)
|
|
|
|
+ sh := float32(set.TileH)
|
|
|
|
+ sheet.DrawRegion(sx, sy, sw, sh, dx, dy, drawflags);
|
|
// debugging solid tiles
|
|
// debugging solid tiles
|
|
-#ifdef TILE_SHOW_SOLID
|
|
|
|
- if (tile_isflag(tile, TILE_WALL)) {
|
|
|
|
- al_draw_rectangle(dx, dy, dx+TILE_W, dy+TILE_H, dcolor, 2);
|
|
|
|
- }
|
|
|
|
-#endif // TILE_SHOW_SOLID
|
|
|
|
-
|
|
|
|
- // al_draw_bitmap(sheet, dx, dy, 0);
|
|
|
|
|
|
+ if showSolid {
|
|
|
|
+ if (tile.Flags & (1<<TILE_WALL)) == (1<<TILE_WALL) {
|
|
|
|
+ dcolor := al.MapRGB(0xee, 0xee, 0x00)
|
|
|
|
+ al.DrawRectangle(dx, dy, dx+sw, dy+sh, dcolor, 2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/* Used for drawing masked tiles. */
|
|
/* Used for drawing masked tiles. */
|
|
-static Image * tile_mask_buffer = NULL;
|
|
|
|
-
|
|
|
|
|
|
+var tileMaskBuffer * al.Bitmap
|
|
|
|
|
|
/** Draw a tile into the given bitmap, which should be of size TILE_W, TILE_H
|
|
/** Draw a tile into the given bitmap, which should be of size TILE_W, TILE_H
|
|
* applying the given mask bitmap, where the mask will
|
|
* applying the given mask bitmap, where the mask will
|
|
@@ -352,162 +337,68 @@ should be white, but with different alpha levels on the white
|
|
which will be applied as the mask. Does nothing if tile is NULL.
|
|
which will be applied as the mask. Does nothing if tile is NULL.
|
|
This requires al_hold_bitmap_drawing to be turned off!
|
|
This requires al_hold_bitmap_drawing to be turned off!
|
|
*/
|
|
*/
|
|
-void tile_draw_masked_to
|
|
|
|
-(Image * result, Tile * tile, Image * mask, float angle, int mask_flags) {
|
|
|
|
|
|
+func (tile * Tile) DrawMaskedTo(result * al.Bitmap, mask * al.Bitmap, angle float32, mask_flags int) {
|
|
/* This function need a mask buffer. */
|
|
/* This function need a mask buffer. */
|
|
- Tileset * set;
|
|
|
|
- Image * sheet;
|
|
|
|
- ALLEGRO_BITMAP * target;
|
|
|
|
- Color dcolor = al_map_rgb(0xee, 0x00, 0xee);
|
|
|
|
- float dx, dy, sx, sy, sw, sh;
|
|
|
|
- int bmpflags;
|
|
|
|
-
|
|
|
|
- if (!tile) return;
|
|
|
|
|
|
|
|
/* Create a 32x32 tile bitmap that will be reused thanks to
|
|
/* Create a 32x32 tile bitmap that will be reused thanks to
|
|
it being static. And leaked at program shutdown, but I don't care :p. */
|
|
it being static. And leaked at program shutdown, but I don't care :p. */
|
|
- if (!tile_mask_buffer) {
|
|
|
|
- bmpflags = al_get_new_bitmap_flags();
|
|
|
|
- al_set_new_bitmap_flags(ALLEGRO_CONVERT_BITMAP);
|
|
|
|
- tile_mask_buffer = al_create_bitmap(TILE_W, TILE_H);
|
|
|
|
- al_set_new_bitmap_flags(bmpflags);
|
|
|
|
|
|
+ if nil == tileMaskBuffer {
|
|
|
|
+ bmpflags := al.NewBitmapFlags()
|
|
|
|
+ al.SetNewBitmapFlags(al.CONVERT_BITMAP)
|
|
|
|
+ tileMaskBuffer = al.CreateBitmap(TILE_W, TILE_H)
|
|
|
|
+ al.SetNewBitmapFlags(bmpflags)
|
|
}
|
|
}
|
|
|
|
|
|
/* Keep the target bitmap. */
|
|
/* Keep the target bitmap. */
|
|
- target = al_get_target_bitmap();
|
|
|
|
|
|
+ target := al.TargetBitmap()
|
|
|
|
|
|
/* Copy the tile into the buffer. */
|
|
/* Copy the tile into the buffer. */
|
|
- al_set_target_bitmap(tile_mask_buffer);
|
|
|
|
- set = tile->set;
|
|
|
|
- sheet = set->sheet;
|
|
|
|
- dx = 0.0;
|
|
|
|
- dy = 0.0;
|
|
|
|
- sx = (float) tile->now.x;
|
|
|
|
- sy = (float) tile->now.y;
|
|
|
|
- sw = (float) TILE_W;
|
|
|
|
- sh = (float) TILE_H;
|
|
|
|
|
|
+ al.SetTargetBitmap(tileMaskBuffer)
|
|
|
|
+ set := tile.Tileset
|
|
|
|
+ sheet := set.Sheet
|
|
|
|
+ dx := float32(0.0)
|
|
|
|
+ dy := float32(0.0)
|
|
|
|
+ sx := float32(tile.Position.X)
|
|
|
|
+ sy := float32(tile.Position.Y)
|
|
|
|
+ sw := float32(set.TileW )
|
|
|
|
+ sh := float32(set.TileH )
|
|
/* Set blender to copy mode. */
|
|
/* Set blender to copy mode. */
|
|
- // al_clear_to_color(al_map_rgba_f(0,0,0,0));
|
|
|
|
-
|
|
|
|
- al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
|
|
|
|
- al_draw_bitmap_region(sheet, sx, sy, sw, sh, 0, 0, 0);
|
|
|
|
|
|
+ al.SetBlender(al.ADD, al.ONE, al.ZERO)
|
|
|
|
+ sheet.DrawRegion(sx, sy, sw, sh, 0, 0, 0);
|
|
|
|
|
|
/* Draw the mask over the tile, taking the alpha of the mask */
|
|
/* Draw the mask over the tile, taking the alpha of the mask */
|
|
- al_set_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ALPHA);
|
|
|
|
- al_draw_bitmap(mask, 0, 0, mask_flags);
|
|
|
|
-
|
|
|
|
- /* Restore normal Allegro blending. */
|
|
|
|
- al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
|
|
|
|
|
|
+ al.SetBlender(al.ADD, al.ZERO, al.ALPHA)
|
|
|
|
+ mask.Draw(0, 0, mask_flags)
|
|
|
|
|
|
- sx = 0.0;
|
|
|
|
- sy = 0.0;
|
|
|
|
|
|
+ /* Restore normal Allegro blending. */
|
|
|
|
+ al.SetBlender(al.ADD, al.ONE, al.INVERSE_ALPHA)
|
|
|
|
+
|
|
|
|
+ sx = 0.0
|
|
|
|
+ sy = 0.0
|
|
if (angle != 0.0) {
|
|
if (angle != 0.0) {
|
|
- sx = TILE_H / 2.0;
|
|
|
|
- sy = TILE_W / 2.0;
|
|
|
|
- dx += sx;
|
|
|
|
- dy += sy;
|
|
|
|
- }
|
|
|
|
|
|
+ sx = float32(set.TileW) / 2.0
|
|
|
|
+ sy = float32(set.TileH) / 2.0
|
|
|
|
+ dx += sx
|
|
|
|
+ dy += sy
|
|
|
|
+ }
|
|
|
|
|
|
/* Draw the tile mask buffer to the result bitmap */
|
|
/* Draw the tile mask buffer to the result bitmap */
|
|
- al_set_target_bitmap(result);
|
|
|
|
- al_draw_rotated_bitmap(tile_mask_buffer, sx, sy, dx, dy, angle, 0);
|
|
|
|
|
|
+ al.SetTargetBitmap(result)
|
|
|
|
+ tileMaskBuffer.DrawRotated(sx, sy, dx, dy, angle, 0)
|
|
/* And restore the target bitmap. */
|
|
/* And restore the target bitmap. */
|
|
- al_set_target_bitmap(target);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Tile's index. Returns -1 if tile is NULL; */
|
|
|
|
-int tile_index(Tile * tile) {
|
|
|
|
- if (!tile) return -1;
|
|
|
|
- return tile->index;
|
|
|
|
|
|
+ al.SetTargetBitmap(target)
|
|
}
|
|
}
|
|
|
|
|
|
-/** Information about the tile's properties. Return -1 if tile is NULL. */
|
|
|
|
-int tile_kind(Tile * tile) {
|
|
|
|
- if (!tile) return -1;
|
|
|
|
- return tile->kind;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Information about tile's blending properties and priority.
|
|
|
|
- * Zero means no blending, positive is a blend priority.
|
|
|
|
- */
|
|
|
|
-int tile_blend(Tile * tile) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->blend;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Set the tile's blending and priority */
|
|
|
|
-int tile_blend_(Tile * tile, int priority) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->blend = priority;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Information about tile's blending mask
|
|
|
|
- * Returns 0 for the default mask if not set.
|
|
|
|
- */
|
|
|
|
-int tile_blend_mask(Tile * tile) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->blend_mask;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Set the tile's blending mask */
|
|
|
|
-int tile_blend_mask_(Tile * tile, int mask) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- if (mask < 0) mask = 0;
|
|
|
|
- if (mask > 2) mask = 0;
|
|
|
|
- return tile->blend_mask = mask;
|
|
|
|
-}
|
|
|
|
|
|
|
|
-/** Get the tile's light flag. Zero means no lighting. */
|
|
|
|
-int tile_light(Tile * tile) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->light;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Set the tile's light flag */
|
|
|
|
-int tile_light_(Tile * tile, int value) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->light = value;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Information about tile's lighting mask
|
|
|
|
- * Returns 0 for the default mask if not set.
|
|
|
|
- */
|
|
|
|
-int tile_light_mask(Tile * tile) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->light_mask;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Set the tile's light mask */
|
|
|
|
-int tile_light_mask_(Tile * tile, int mask) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- if (mask < 0) mask = 0;
|
|
|
|
- return tile->light_mask = mask;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Get the tile's shadow flag. Zero means no autoshadow. */
|
|
|
|
-int tile_shadow(Tile * tile) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->shadow;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Set the tile's light flag */
|
|
|
|
-int tile_shadow_(Tile * tile, int value) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->shadow = value;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Information about tile's shadow mask
|
|
|
|
- * Returns 0 for the default mask if not set.
|
|
|
|
- */
|
|
|
|
-int tile_shadow_mask(Tile * tile) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- return tile->shadow_mask;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** Set the tile's shadow mask */
|
|
|
|
-int tile_shadow_mask_(Tile * tile, int mask) {
|
|
|
|
- if (!tile) return 0;
|
|
|
|
- if (mask < 0) mask = 0;
|
|
|
|
- return tile->shadow_mask = mask;
|
|
|
|
|
|
+func (set Set) Tile(index int) * Tile {
|
|
|
|
+ if set.Tiles == nil {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (index < 0) || (index > len(set.Tiles)) {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return &set.Tiles[index]
|
|
}
|
|
}
|
|
|
|
|