Skip to content

Commit

Permalink
e2d/raster3d: switch to 32-bit bpp in mixer, to handle direct colors …
Browse files Browse the repository at this point in the history
…with priority
  • Loading branch information
rasky committed Mar 5, 2016
1 parent bd89718 commit 6dc841f
Show file tree
Hide file tree
Showing 8 changed files with 930 additions and 934 deletions.
2 changes: 1 addition & 1 deletion e2d/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ const (
cScreenHeight = 192
)

var modLcd = log.NewModule("2d")
var modLcd = log.ModGfx

var gKeyState []byte
2 changes: 1 addition & 1 deletion e2d/engine2d.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func NewHwEngine2d(idx int, mc MemoryController, l3d gfx.Layer) *HwEngine2d {
Width: cScreenWidth,
Height: cScreenHeight,
ScreenBpp: 4,
LayerBpp: 2,
LayerBpp: 4,
OverflowPixels: 8,
Mixer: e2dMixer_Normal,
MixerCtx: e2d,
Expand Down
31 changes: 14 additions & 17 deletions e2d/mode1_affine.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (e2d *HwEngine2d) DrawBGAffine(ctx *gfx.LayerCtx, lidx int, y int) {
continue
}

pri := regs.priority()
pri := uint32(regs.priority())

mapx := startx
mapy := starty
Expand All @@ -90,9 +90,9 @@ func (e2d *HwEngine2d) DrawBGAffine(ctx *gfx.LayerCtx, lidx int, y int) {
// 8-bit bitmap layers don't use extended palettes, so
// create a layer pixel without ext pal number
// We only encode the priority bit
col := uint16(tmap.Get8(py*size.w + px))
col |= pri << 13
line.Set16(x, col)
col := uint32(tmap.Get8(py*size.w + px))
col |= pri << 29
line.Set32(x, col)
}

mapx += dx
Expand All @@ -109,12 +109,9 @@ func (e2d *HwEngine2d) DrawBGAffine(ctx *gfx.LayerCtx, lidx int, y int) {
if wrap || (px >= 0 && px < size.w && py >= 0 && py < size.h) {
// In Direct Color Bitmaps, bit 15 is used as a transparency
// bit, so if not set, the pixel is not displayed.
col := tmap.Get16(py*size.w + px)
col := uint32(tmap.Get16(py*size.w + px))
if col&0x8000 != 0 {
// NOTE: in our output layer, we must mark direct colors
// with bit 15 = 1, which matches exactly the format of
// direct color bitmaps, so leave it as-is.
line.Set16(x, col)
line.Set32(x, col|0x80000000)
}
}
mapx += dx
Expand Down Expand Up @@ -158,23 +155,23 @@ func (e2d *HwEngine2d) DrawBGAffine(ctx *gfx.LayerCtx, lidx int, y int) {
// (it should be already zero, but better safe than sorry)
attrs := pri << 13
if useExtPal {
attrs |= (pal << 8) | (1 << 12)
attrs |= uint32(pal<<8) | (1 << 12)
}

if !hflip {
p0 := uint16(ch[px&7])
p0 := uint32(ch[px&7])
if p0 != 0 {
line.Set16(0, p0|attrs)
line.Set32(0, p0|attrs)
}
} else {
p0 := uint16(ch[7-(px&7)])
p0 := uint32(ch[7-(px&7)])
if p0 != 0 {
line.Set16(0, p0|attrs)
line.Set32(0, p0|attrs)
}
}
}

line.Add16(1)
line.Add32(1)
mapx += dx
mapy += dy
}
Expand All @@ -197,11 +194,11 @@ func (e2d *HwEngine2d) DrawBGAffine(ctx *gfx.LayerCtx, lidx int, y int) {
tx = px & 7
p0 := chars.Get8(tnum*64 + ty*8 + tx)
if p0 != 0 {
line.Set16(0, uint16(p0)|(pri<<13))
line.Set32(0, uint32(p0)|(pri<<29))
}
}

line.Add16(1)
line.Add32(1)
mapx += dx
mapy += dy
}
Expand Down
46 changes: 23 additions & 23 deletions e2d/mode1_mixer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import "ndsemu/emu"
// A pixel in a layer of the layer manager. It is composed as follows:
// Bits 0-11: color index in the palette
// Bit 12: set if the pixel uses the extended palette for its layer (either obj or bg)
// Bit 13-14: priority
// Bit 15: direct color
type LayerPixel uint16
// Bit 29-30: priority
// Bit 31: direct color
type LayerPixel uint32

func (p LayerPixel) Color() uint16 { return uint16(p & 0xFFF) }
func (p LayerPixel) ExtPal() bool { return uint16(p&(1<<12)) != 0 }
func (p LayerPixel) Priority() uint16 { return uint16(p>>13) & 3 }
func (p LayerPixel) Direct() bool { return int16(p) < 0 }
func (p LayerPixel) ColorIndex() uint16 { return uint16(p & 0xFFF) }
func (p LayerPixel) ExtPal() bool { return (p & (1 << 12)) != 0 }
func (p LayerPixel) Priority() uint32 { return uint32(p>>29) & 3 }
func (p LayerPixel) Direct() bool { return int32(p) < 0 }
func (p LayerPixel) DirectColor() uint16 { return uint16(p & 0x7FFF) }
func (p LayerPixel) Transparent() bool { return p == 0 }

Expand Down Expand Up @@ -67,13 +67,7 @@ func e2dMixer_Normal(layers []uint32, ctx interface{}) (res uint32) {
// case we draw it directly
objpix = LayerPixel(layers[4])
if !objpix.Transparent() {
pix = objpix.Color()
if objpix.ExtPal() {
cram = e2d.objExtPal
} else {
cram = e2d.objPal
}
goto lookup
goto drawobj
}

// No objlayer, and no bglayer. Draw the backdrop.
Expand All @@ -86,19 +80,25 @@ checkobj:
// we need to check the priority to choose between bg and obj which pixel
// to draw (if the priorities are equal, objects win)
objpix = LayerPixel(layers[4])
if !objpix.Transparent() && objpix.Priority() <= bgpix.Priority() {
pix = objpix.Color()
if objpix.ExtPal() {
cram = e2d.objExtPal
} else {
cram = e2d.objPal
}
} else {
if objpix.Transparent() || objpix.Priority() > bgpix.Priority() {
if bgpix.Direct() {
c16 = bgpix.DirectColor()
goto draw
}
pix = bgpix.Color()
pix = bgpix.ColorIndex()
goto lookup
}

drawobj:
if objpix.Direct() {
c16 = objpix.DirectColor()
goto draw
}
pix = objpix.ColorIndex()
if objpix.ExtPal() {
cram = e2d.objExtPal
} else {
cram = e2d.objPal
}

lookup:
Expand Down
23 changes: 12 additions & 11 deletions e2d/mode1_obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,13 @@ func (e2d *HwEngine2d) DrawOBJ(ctx *gfx.LayerCtx, lidx int, sy int) {
src := tiles.FetchPointer(vramOffset)
dst := line

attrs := pri << 13
attrs := uint32(pri) << 29
if depth256 {
if useExtPal {
attrs |= (pal << 8) | (1 << 12)
attrs |= uint32(pal<<8) | (1 << 12)
}
} else {
attrs |= (pal << 4)
attrs |= uint32(pal << 4)
if useExtPal {
attrs |= (1 << 12)
}
Expand All @@ -262,16 +262,16 @@ func (e2d *HwEngine2d) DrawOBJ(ctx *gfx.LayerCtx, lidx int, sy int) {
isx &= 7

if depth256 {
pix := uint16(src[off+isy*8+isx])
pix := uint32(src[off+isy*8+isx])
if pix != 0 {
dst.Set16(x, pix|attrs)
dst.Set32(x, pix|attrs)
}
} else {
pix := uint16(src[off+isy*4+isx/2])
pix := uint32(src[off+isy*4+isx/2])
pix >>= 4 * uint(isx&1)
pix &= 0xF
if pix != 0 {
dst.Set16(x, pix|attrs)
dst.Set32(x, pix|attrs)
}
}
}
Expand All @@ -292,10 +292,11 @@ func (e2d *HwEngine2d) DrawOBJ(ctx *gfx.LayerCtx, lidx int, sy int) {
src := tiles.FetchPointer(vramOffset)
dst := line

attrs := (uint32(pri) << 29) | 0x80000000
for j := 0; j < tw*8; j++ {
if x >= 0 && x < cScreenWidth {
px := emu.Read16LE(src[j*2:])
dst.Set16(x, px|0x8000)
px := uint32(emu.Read16LE(src[j*2:]))
dst.Set32(x, px|attrs)
}
x++
}
Expand All @@ -314,7 +315,7 @@ func (e2d *HwEngine2d) DrawOBJ(ctx *gfx.LayerCtx, lidx int, sy int) {
// Prepare initial src/dst pointer for drawing
src := tiles.FetchPointer(vramOffset)
dst := line
dst.Add16(x)
dst.Add32(x)

for j := 0; j < tw; j++ {
tsrc := src[charSize*j:]
Expand All @@ -332,7 +333,7 @@ func (e2d *HwEngine2d) DrawOBJ(ctx *gfx.LayerCtx, lidx int, sy int) {
e2d.drawChar16(y0, tsrc, dst, hflip, pri, pal, false)
}
}
dst.Add16(8)
dst.Add32(8)
x += 8
}
}
Expand Down
38 changes: 18 additions & 20 deletions e2d/mode1_text.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,58 @@ import (

func (e2d *HwEngine2d) drawChar16(y int, src []byte, dst gfx.Line, hflip bool, pri uint16, pal uint16, extpal bool) {
src = src[y*4:]
attrs := pri<<13 | pal<<4
attrs := uint32(pri)<<29 | uint32(pal)<<4
if extpal {
attrs |= (1 << 12)
}
if !hflip {
for x := 0; x < 4; x++ {
p0, p1 := uint16(src[x]&0xF), uint16(src[x]>>4)
p0, p1 := uint32(src[x]&0xF), uint32(src[x]>>4)
if p0 != 0 {
// p0 = (p0 << 4) | p0
dst.Set16(0, p0|attrs)
dst.Set32(0, p0|attrs)
}
if p1 != 0 {
// p1 = (p1 << 4) | p1
dst.Set16(1, p1|attrs)
dst.Set32(1, p1|attrs)
}
dst.Add16(2)
dst.Add32(2)
}
} else {
for x := 3; x >= 0; x-- {
p1, p0 := uint16(src[x]&0xF), uint16(src[x]>>4)
p1, p0 := uint32(src[x]&0xF), uint32(src[x]>>4)
if p0 != 0 {
// p0 = (p0 << 4) | p0
dst.Set16(0, p0|attrs)
dst.Set32(0, p0|attrs)
}
if p1 != 0 {
// p1 = (p1 << 4) | p1
dst.Set16(1, p1|attrs)
dst.Set32(1, p1|attrs)
}
dst.Add16(2)
dst.Add32(2)
}
}
}

func (e2d *HwEngine2d) drawChar256(y int, src []byte, dst gfx.Line, hflip bool, pri uint16, pal uint16, extpal bool) {
src = src[y*8:]
attrs := pri<<13 | pal<<8
attrs := uint32(pri)<<29 | uint32(pal)<<8
if extpal {
attrs |= (1 << 12)
}
if !hflip {
for x := 0; x < 8; x++ {
p0 := uint16(src[x])
p0 := uint32(src[x])
if p0 != 0 {
dst.Set16(0, p0|attrs)
dst.Set32(0, p0|attrs)
}
dst.Add16(1)
dst.Add32(1)
}
} else {
for x := 7; x >= 0; x-- {
p0 := uint16(src[x])
p0 := uint32(src[x])
if p0 != 0 {
dst.Set16(0, p0|attrs)
dst.Set32(0, p0|attrs)
}
dst.Add16(1)
dst.Add32(1)
}
}
}
Expand Down Expand Up @@ -125,7 +123,7 @@ func (e2d *HwEngine2d) DrawBG(ctx *gfx.LayerCtx, lidx int, y int) {
}
}

line.Add16(-(mapx & 7))
line.Add32(-(mapx & 7))
for x := 0; x <= cScreenWidth/8; x++ {
if doubleh {
mapx &= 511
Expand Down Expand Up @@ -162,7 +160,7 @@ func (e2d *HwEngine2d) DrawBG(ctx *gfx.LayerCtx, lidx int, y int) {
// to the drawChar16() function
e2d.drawChar16(ty, ch, line, hflip, pri, pal, false)
}
line.Add16(8)
line.Add32(8)

mapx += 8
}
Expand Down
8 changes: 4 additions & 4 deletions raster3d/gen/genfillers.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (g *Generator) genFiller(cfg *fillerconfig.FillerConfig) {
// **************************
// PIXEL LOOP
// **************************
fmt.Fprintf(g, "out.Add16(int(x0))\n")
fmt.Fprintf(g, "out.Add32(int(x0))\n")
fmt.Fprintf(g, "zbuf.Add32(int(x0))\n")
if cfg.FillMode == fillerconfig.FillModeAlpha {
fmt.Fprintf(g, "abuf.Add8(int(x0))\n")
Expand Down Expand Up @@ -193,20 +193,20 @@ func (g *Generator) genFiller(cfg *fillerconfig.FillerConfig) {
if cfg.FillMode == fillerconfig.FillModeAlpha {
fmt.Fprintf(g, "if pxa == 0 { goto next }\n")
fmt.Fprintf(g, "if true {\n")
fmt.Fprintf(g, "bkg := out.Get16(0)\n")
fmt.Fprintf(g, "bkg := uint16(out.Get32(0))\n")
fmt.Fprintf(g, "bkga := abuf.Get8(0)\n")
fmt.Fprintf(g, "if bkga != 0 { px = rgbAlphaMix(px, bkg, pxa>>1) }\n")
fmt.Fprintf(g, "if pxa > bkga { abuf.Set8(0, pxa) }\n")
fmt.Fprintf(g, "}\n")
}

// draw pixel
fmt.Fprintf(g, "out.Set16(0, uint16(px)|0x8000)\n")
fmt.Fprintf(g, "out.Set32(0, uint32(px)|0x80000000)\n")
fmt.Fprintf(g, "zbuf.Set32(0, uint32(z0.V))\n")

// Pixel loop footer
fmt.Fprintf(g, "next:\n")
fmt.Fprintf(g, "out.Add16(1)\n")
fmt.Fprintf(g, "out.Add32(1)\n")
fmt.Fprintf(g, "zbuf.Add32(1)\n")
if cfg.FillMode == fillerconfig.FillModeAlpha {
fmt.Fprintf(g, "abuf.Add8(1)\n")
Expand Down
Loading

0 comments on commit 6dc841f

Please sign in to comment.