func drawPiece(s *sdl.Surface, col, row int, p c4.Piece) { // Load images if redImage == nil { redImage = sdl.Load("red.png") } if blackImage == nil { blackImage = sdl.Load("black.png") } if noneImage == nil { noneImage = sdl.Load("empty.png") } // Select image var image *sdl.Surface if p == c4.Red { image = redImage } else if p == c4.Black { image = blackImage } else { image = noneImage } // Draw image s.Blit( &sdl.Rect{ int16(SCREEN_WIDTH * col / c4.MaxColumns), int16(SCREEN_HEIGHT * (c4.MaxRows - row - 1) / c4.MaxRows), 0, 0}, image, nil) }
func apply_surface(x, y int16, src, dest *sdl.Surface) { var offset sdl.Rect offset.X = x offset.Y = y dest.Blit(&offset, src, nil) }
func undrawColor(ss *sdl.Surface, w, h int32, col uint32) { var x, y int32 for y = 0; y < h; y++ { for x = 0; x < w; x++ { col := sdlGet(x, y, ss) & (^col) sdlSet2(x, y, col, ss) } } ss.Flip() }
func wrap(cSurface *C.SDL_Surface) *sdl.Surface { var s *sdl.Surface if cSurface != nil { var surface sdl.Surface surface.SetCSurface(unsafe.Pointer(cSurface)) s = &surface } else { s = nil } return s }
func (p *Piece) render(screen *sdl.Surface) { if p == nil { return } for i := 0; i < 4; i++ { x := p.pos.x + p.tet.position[p.rot][i].x y := p.pos.y + p.tet.position[p.rot][i].y rect := sdl.Rect{ int16(x * PixPerBrick), int16(y * PixPerBrick), uint16(PixPerBrick), uint16(PixPerBrick)} screen.FillRect(&rect, colorToUint32(colorTable[p.tet.color])) } }
func draw_sdl(o *Object, s *sdl.Surface) { var ss *sdl.Surface if o.Collides { ss = surfaceb } else { ss = surface } s.Blit( &sdl.Rect{int16(float64(o.Pos.X) * ssw), int16(float64(o.Pos.Y) * ssh), uint16(float64((o.Pos.X + o.Size.X)) * ssw), uint16(float64((o.Pos.Y + o.Size.Y)) * ssh)}, ss, &sdl.Rect{0, 0, uint16(o.Size.X), uint16(o.Size.Y)}) }
func (p *Playfield) render(screen *sdl.Surface) { screen.FillRect(nil, 0x000000) for j := 0; j < p.height; j++ { for i := 0; i < p.width; i++ { color := p.at(i, j) if color != 0 { rect := sdl.Rect{ int16(i * PixPerBrick), int16(j * PixPerBrick), uint16(PixPerBrick), uint16(PixPerBrick)} screen.FillRect(&rect, colorToUint32(colorTable[color])) } } } }
// Set distance of nearby points (from point ax,ay -> bx,by) in given dir (0=N, // 1=S, 2=E, 3=W) func setDist(ss *sdl.Surface, rmc [][]int32, dist [][][]int32, aX, aY, bX, bY, dir, w, h, r, currBestDist, lastSetX, lastSetY int32, done, found bool, round int) (newDone, newFound bool, newBest int32, setX, setY int32) { newDone, newFound, newBest, setX, setY = done, found, currBestDist, lastSetX, lastSetY if !inRect(bX, bY, w, h) { return } dA := dist[aX][aY] _, best := bestDist(dA) best += 4 * (r + 1) * (r + 1) if best >= currBestDist { // we alredy have better distance (smaller is better) return } dB := dist[bX][bY] rmCount := removeCount(ss, rmc, w, h, bX, bY, r) if currBestDist == DistMax && rmCount > 0 && best < DistMax { //fmt.Printf("==== found rmCount=%d best=%d bX=%d bY=%d\n", rmCount, best, bX, bY) newBest = best newFound = true } //fmt.Printf("setDist aX=%d aY=%d bX=%d bY=%d rmCount=%d\n", aX, aY, bX, bY, rmCount) if best < dB[dir] && rmCount != -1 { // part of model would be removed if aX&7 == 0 && aY&7 == 0 { if round > 20 { fmt.Printf("setDist x=%d y=%d value=%d dB[dir]=%d\n", aX, aY, best, dB[dir]) } sdlSet(aX, aY, ColDebug, ss) if aX&63 == 0 && aY&63 == 0 { ss.Flip() } } dB[dir] = best - rmCount // favourize paths that remove more material newDone = false setX, setY = bX, bY } return }
func (renderer *SDLRenderer) renderLine(pos int, line string) { x := renderer.commandLineRect.X y := int16(renderer.commandLineRect.Y) - int16(renderer.fontHeight*uint(pos)) w := renderer.commandLineRect.W h := renderer.commandLineRect.H renderer.internalSurface.FillRect(&sdl.Rect{x, y, w, h}, 0) if len(line) == 0 { return } var textSurface *sdl.Surface if renderer.Blended { textSurface = ttf.RenderUTF8_Blended(renderer.Font, line, renderer.Color) } else { textSurface = ttf.RenderUTF8_Solid(renderer.Font, line, renderer.Color) } if textSurface != nil { renderer.internalSurface.Blit(&sdl.Rect{x, y, w, h}, textSurface, nil) textSurface.Free() } }
// Find path from cX,cY to tX,tY so that no part of model is removed func findAndRemove(ss *sdl.Surface, tc *Tco, rmc [][]int32, cX, cY, w, h, r int32) (bool, bool, int32, int32) { //fmt.Printf("findPath cX=%d cY=%d tX=%d tY=%d\n", cX, cY, tX, tY) // The algorithm is flood-fill like: // For earch pixel we remember shortest distance to target point in 4 // directions (N,S,E,W). Starting at point (tX,tY) all the distances are 0, // e.g. for (tX+1,cY) the distnace in W is 1, others are 3 etc.. // // // S=1 // T W=1 W=2 // N=1 N=3 // // It works like that: N=3 means if you go N the shortest path to T is 3 // (after going twice west). From the same point it also implies that W=3 // (after going WN), S=5 (e.g. after going NNWW), E=5 (after WNWW). dist := make([][][]int32, w) for x := range dist { dist[x] = make([][]int32, h) for y := range dist[x] { if int32(x) == cX && int32(y) == cY { dist[x][y] = []int32{0, 0, 0, 0, 0, 0, 0, 0} // value for each dir + removeCount for given point } else { dist[x][y] = []int32{DistMax, DistMax, DistMax, DistMax, DistMax, DistMax, DistMax, DistMax} } } } undrawDebug(ss, w, h) currBestDist := DistMax found := false lastSetX, lastSetY := cX, cY for round := 0; ; round++ { done := true var centerX, centerY int32 undrawBlue(ss, w, h) //drawLine(ss, rmc, cX, cY, tX, tY) if round%8 == 0 { centerX, centerY = cX, cY } else if round%8 == 0 { centerX, centerY = 0, 0 } else if round%8 == 1 { centerX, centerY = 0, w-1 } else if round%8 == 2 { centerX, centerY = 0, h-1 } else if round%8 == 3 { centerX, centerY = w-1, h-1 } else { centerX, centerY = lastSetX, lastSetY } for x, y, a, ok := nearRectBegin(centerX, centerY, w, h, 0); ok; x, y, a, ok = nearRectNext(centerX, centerY, x, y, a, w, h) { /*fmt.Printf(" N S E W NW NE SE SW| N S E W NW NE SE SW| N S E W NW NE SE SW| N S E W NW NE SE SW| N S E W NW NE SE SW\n") for i := cY - 3; i <= cY+3; i++ { for j := cX - 3; j <= cX+3; j++ { if !inRect(i, j, w, h) { continue } dumpDists(dist[j][i]) fmt.Printf("| ") } fmt.Println() } fmt.Printf("x=%d y=%d a=%d done=%t currBestDist=%d\n", x, y, a, done, currBestDist) fmt.Scanln()*/ done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x, y+1, dirN, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x, y-1, dirS, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x-1, y, dirE, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x+1, y, dirW, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x+1, y+1, dirNW, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x-1, y-1, dirSE, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x-1, y+1, dirNE, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) done, found, currBestDist, lastSetX, lastSetY = setDist(ss, rmc, dist, x, y, x+1, y-1, dirSW, w, h, r, currBestDist, lastSetX, lastSetY, done, found, round) } fmt.Printf("round=%d done=%t found=%t currBestDist=%d, lastSetX=%d lastSetY=%d\n", round, done, found, currBestDist, lastSetX, lastSetY) if done { break } } dstMin := DistMax tX, tY := int32(-1), int32(-1) removed := false for x, y, a, ok := nearRectBegin(cX, cY, w, h, 1); ok; x, y, a, ok = nearRectNext(cX, cY, x, y, a, w, h) { if removeCount(ss, rmc, w, h, x, y, r) <= 0 { continue } removed = true dst := DistMax if found { _, dst = bestDist(dist[x][y]) } else { dst = abs32(cX-x) + abs32(cY-y) } if dst < dstMin { dstMin, tX, tY = dst, x, y } } fmt.Printf("removed=%t found=%t dstMin=%d tX=%d tY=%d\n", removed, found, dstMin, tX, tY) if !removed { return false, false, tX, tY } if !found { return true, false, tX, tY } var dirs []int for x, y := tX, tY; x != cX || y != cY; { dir, _ := bestDist(dist[x][y]) dirs = append(dirs, dir) if dir == dir_N { y-- } else if dir == dir_S { y++ } else if dir == dir_E { x++ } else if dir == dir_W { x-- } else if dir == dir_NW { x, y = x-1, y-1 } else if dir == dir_NE { x, y = x+1, y-1 } else if dir == dir_SW { x, y = x-1, y+1 } else if dir == dir_SE { x, y = x+1, y+1 } /*fmt.Printf(" N S E W NW NE SE SW| N S E W NW NE SE SW| N S E W NW NE SE SW| N S E W NW NE SE SW| N S E W NW NE SE SW\n") for i := y - 3; i <= y+3; i++ { for j := x - 3; j <= x+3; j++ { if !inRect(i, j, w, h) { continue } dumpDists(dist[j][i]) fmt.Printf("| ") } fmt.Println() } fmt.Printf("x=%d y=%d dir=%d bestDist=%d\n", x, y, dir, dst) fmt.Scanln()*/ } for x, y, i := cX, cY, len(dirs)-1; i >= 0; i-- { dir := dirs[i] if dir == dir_N { y++ } else if dir == dir_S { y-- } else if dir == dir_E { x-- } else if dir == dir_W { x++ } else if dir == dir_NW { x, y = x+1, y+1 } else if dir == dir_NE { x, y = x-1, y+1 } else if dir == dir_SW { x, y = x+1, y-1 } else if dir == dir_SE { x, y = x-1, y-1 } //fmt.Printf("cX=%d cY=%d tX=%d tY=%d x=%d y=%d\n", cX, cY, tX, tY, x, y) moveXy(tc, x, y, r, removeCount(ss, rmc, w, h, x, y, r)) removeMaterial(ss, rmc, w, h, x, y, r) sdlSet(x, y, ColDebug, ss) ss.Flip() //fmt.Scanln() } return true, true, tX, tY }