github.com/racerxdl/gonx@v0.0.0-20210103083128-c5afc43bcbd2/services/display/blit.go (about) 1 package display 2 3 import ( 4 "unsafe" 5 ) 6 7 func pdep(mask, value uint32) uint32 { 8 out := uint32(0) 9 for shift := uint32(0); shift < 32; shift++ { 10 bit := uint32(1 << shift) 11 if mask&bit > 0 { 12 if value&1 > 0 { 13 out |= bit 14 } 15 value >>= 1 16 } 17 } 18 return out 19 } 20 21 //go:inline 22 func swizzleX(v uint32) uint32 { 23 return pdep(^uint32(0x7B4), v) 24 } 25 26 //go:inline 27 func swizzleY(v uint32) uint32 { 28 return pdep(0x7B4, v) 29 } 30 31 //go:inline 32 func setUint32(buffer []byte, idx uint32, v uint32) { 33 *(*uint32)(unsafe.Pointer(&buffer[idx*4])) = v 34 } 35 36 //go:inline 37 func getUint32(buffer []byte, idx uint32) uint32 { 38 return *(*uint32)(unsafe.Pointer(&buffer[idx*4])) 39 } 40 41 //go:nobounds 42 func GFXSlowSwizzlingBlit(buffer []byte, image []byte, w, h, tx, ty int) { 43 const tileHeight = 128 44 const paddedWidth = tileHeight * 10 45 46 x0 := uint32(tx) 47 y0 := uint32(ty) 48 x1 := x0 + uint32(w) 49 y1 := y0 + uint32(h) 50 51 // we're doing this in pixels - should just shift the swizzles instead 52 offsX0 := swizzleX(x0) 53 offsY := swizzleY(y0) 54 XMask := swizzleX(^uint32(0)) 55 YMask := swizzleY(^uint32(0)) 56 IncrY := swizzleX(paddedWidth) 57 58 // step offs_x0 to the right row of tiles 59 offsX0 += IncrY * (y0 / tileHeight) 60 61 srcPos := uint32(0) 62 63 for y := uint32(0); y < y1; y++ { 64 offsX := offsX0 65 66 for x := uint32(0); x < x1; x++ { 67 pixel := getUint32(image, srcPos) 68 srcPos++ 69 setUint32(buffer, offsY+offsX, pixel) 70 offsX = (offsX - XMask) & XMask 71 } 72 73 offsY = (offsY - YMask) & YMask 74 if offsY == 0 { 75 offsX0 += IncrY // wrap into next tile row 76 } 77 } 78 }