func loadImageRotated(image_name string, angle float64) (*sdl.Surface, error) { file, err := assets.Asset(image_name) if err != nil { return nil, err } i, _, err := image.Decode(bytes.NewReader(file)) if err != nil { return nil, err } dst := image.NewRGBA(i.Bounds()) err = graphics.Rotate(dst, i, &graphics.RotateOptions{ Angle: angle * tau}) if err != nil { return nil, err } var buf bytes.Buffer err = png.Encode(&buf, dst) if err != nil { return nil, err } b := buf.Bytes() return img.Load_RW(sdl.RWFromMem(unsafe.Pointer(&b[0]), len(b)), 0) }
func loadSounds() ( sounds map[string]*mix.Chunk, err error) { files, err := assets.AssetDir("final/sounds") if err != nil { return nil, err } sounds = make(map[string]*mix.Chunk) for _, file := range files { if !strings.HasSuffix(file, ".wav") { continue } data, err := assets.Asset(filepath.Join("final/sounds", file)) if err != nil { return nil, err } mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data)) sound, err := mix.LoadWAV_RW(mem, false) if err != nil { cleanupSounds(sounds) return nil, err } sounds[file[:len(file)-len(".wav")]] = sound } return sounds, nil }
func NewRenderer(title string, width, height, players int, update_duration time.Duration) (rv *SDLRenderer, err error) { return rv, exec(func() error { window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, width, height, sdl.WINDOW_SHOWN) if err != nil { rv = nil return err } data, err := assets.Asset("final/Fixedsys500c.ttf") if err != nil { window.Destroy() rv = nil return err } mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data)) font, err := ttf.OpenFontRW(mem, 0, 128) if err != nil { window.Destroy() rv = nil return err } frames := int(frameRate * update_duration / time.Second) images, player_rotations, err := loadImages(frames, players) if err != nil { window.Destroy() font.Close() rv = nil return err } sounds, err := loadSounds() if err != nil { cleanupImages(images) cleanupRotations(player_rotations) window.Destroy() font.Close() rv = nil return err } var frame_time time.Duration if frames > 0 { frame_time = update_duration / time.Duration(frames) } rv = &SDLRenderer{Title: title, window: window, font: font, images: images, sounds: sounds, frame_time: frame_time, frames: frames, player_rotations: player_rotations, closed: false} return nil }) }
func docs(w http.ResponseWriter, r *http.Request) { doc, err := assets.Asset("final/docs.md") if err != nil { http.Error(w, err.Error(), 500) return } w.Write([]byte(header)) w.Write(blackfriday.MarkdownCommon([]byte(doc))) w.Write([]byte(footer)) }
func overlay(surface *sdl.Surface, img_name string) error { data, err := assets.Asset(img_name) if err != nil { return err } mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data)) ontop, err := img.Load_RW(mem, 0) defer ontop.Free() if err != nil { return err } return ontop.BlitScaled(nil, surface, nil) }
func BackgroundMusic(asset string) error { return exec(func() error { data, err := assets.Asset(asset) if err != nil { return err } mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data)) music, err := mix.LoadMUS_RW(mem, 0) if err != nil { return err } return music.Play(-1) }) }
func loadImages(frames, players int) ( images map[grid.Cell]*sdl.Surface, rotations map[grid.Owner][]*sdl.Surface, err error) { images = make(map[grid.Cell]*sdl.Surface) for _, simple := range []string{"battery", "floor", "wall"} { for _, exploding := range []bool{false, true} { data, err := assets.Asset(fmt.Sprintf("final/images/%s.png", simple)) if err != nil { cleanupImages(images) return nil, nil, err } mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data)) surface, err := img.Load_RW(mem, 0) if err != nil { cleanupImages(images) return nil, nil, err } if exploding { err = overlay(surface, "final/images/ex.png") if err != nil { surface.Free() cleanupImages(images) return nil, nil, err } } for orientation := 0; orientation < 4; orientation++ { for owner := 0; owner < players+1; owner++ { images[grid.Cell{ Exploding: exploding, Type: typeMapping(simple), Orientation: grid.Orientation(orientation), Owner: grid.Owner(owner)}] = surface } } } } for _, rotateable := range []string{"l", "p"} { for rotations := 0; rotations < 4; rotations++ { for player := 1; player <= players; player++ { for _, exploding := range []bool{false, true} { surface, err := loadImageRotated(fmt.Sprintf("final/images/%s%d.png", rotateable, (player-1)%2+1), float64(rotations)/4) if err != nil { cleanupImages(images) return nil, nil, err } if exploding { err = overlay(surface, "final/images/ex.png") if err != nil { surface.Free() cleanupImages(images) return nil, nil, err } } images[grid.Cell{ Exploding: exploding, Type: typeMapping(rotateable), Owner: grid.Owner(player), Orientation: grid.Orientation(rotations)}] = surface } } } } rotations = make(map[grid.Owner][]*sdl.Surface) for _, rotateable := range []string{"p"} { for player := 1; player <= players; player++ { for frame := 0; frame < 4*frames; frame++ { surface, err := loadImageRotated(fmt.Sprintf("final/images/%s%d.png", rotateable, (player-1)%2+1), float64(frame)/(4*float64(frames))) if err != nil { cleanupImages(images) cleanupRotations(rotations) return nil, nil, err } rotations[grid.Owner(player)] = append( rotations[grid.Owner(player)], surface) } } } return images, rotations, nil }