diff --git a/tilemapper/blockdecoder.go b/tilemapper/blockdecoder.go index 1ab47ea..5c7b6fd 100644 --- a/tilemapper/blockdecoder.go +++ b/tilemapper/blockdecoder.go @@ -144,6 +144,23 @@ func NewDecodedBlock(data []byte, nameIndex map[string]int) (db *DecodedBlock, e return } +func (db *DecodedBlock) Content(x, y, z int) int { + pos := z<<8 + y<<4 + x + + switch { + case db.Version >= 24: + pos <<= 1 + return int(db.MapContent[pos])<<8 | int(db.MapContent[pos+1]) + case db.Version >= 20: + if db.MapContent[pos] <= 0x80 { + return int(db.MapContent[pos]) + } + return int(db.MapContent[pos])<<4 | int(db.MapContent[pos+0x2000])>>4 + default: + return db.IgnoreId + } +} + func NewPosBuf(data []byte) *PosBuf { return &PosBuf{Data: data} } diff --git a/tilemapper/renderer.go b/tilemapper/renderer.go new file mode 100644 index 0000000..7b05dca --- /dev/null +++ b/tilemapper/renderer.go @@ -0,0 +1,83 @@ +// Copyright 2014 by Sascha L. Teichmann +// Use of this source code is governed by the MIT license +// that can be found in the LICENSE file. + +package main + +import ( + "math" + + "bitbucket.org/s_l_teichmann/mtredisalize/common" +) + +type Renderer struct { + width int + height int + xOfs int16 + zOfs int16 + yBuffer []int32 + cBuffer []int32 + filled []byte + minYs []int16 +} + +func NewRenderer(xOfs, zOfs int16, width, height int) (renderer *Renderer) { + dim := width * height + pixSize := dim * 16 * 16 + yBuffer := make([]int32, pixSize) + cBuffer := make([]int32, pixSize) + filled := make([]byte, dim) + minYs := make([]int16, dim) + + for i := 0; i < pixSize; i++ { + yBuffer[i] = math.MinInt32 + cBuffer[i] = -1 + } + + for i := 0; i < dim; i++ { + minYs[i] = math.MinInt16 + } + + renderer = &Renderer{ + width: width, + height: height, + xOfs: xOfs, + zOfs: zOfs, + yBuffer: yBuffer, + cBuffer: cBuffer, + filled: filled, + minYs: minYs} + return +} + +func (r *Renderer) RenderBlock(coord common.Coord, data []byte, nameIndex map[string]int) (err error) { + x := coord.X + r.xOfs + z := coord.Z + r.zOfs + dimIndex := (x << 4) + z + // We do not need to render the block if the whole 16x16 area + // is already filled and the block is strictly below. + if r.filled[dimIndex] == 0xff && r.minYs[dimIndex] > coord.Y { + return + } + + var db *DecodedBlock + if db, err = NewDecodedBlock(data, nameIndex); err != nil { + return + } + + _ = db + + ay := int32(coord.Y) << 4 + + _ = ay + + for x := 0; x < 16; x++ { + for z := 0; z < 16; z++ { + for y := 15; y >= 0; y-- { + _, _, _ = x, y, z + } + } + } + + return +}