func makeSpriteFromFragments(frags []fragment) (s Sprite) { if len(frags) == 0 { return } p := make([]point, 0, len(frags)) for i := range frags { x := int32(math32.Round(frags[i].sx)) y := int32(math32.Round(frags[i].sy)) if -128 <= x && x < 128 && -128 <= y && y < 128 { p = append(p, point{int8(x), int8(y)}) } } sort.Sort(byYX(p)) // Now build s var j int for i := 0; i < len(p); i = j { y := p[i].y for j = i + 1; j < len(p) && p[j].y == y; j++ { } x := make([]int8, j-i) for k := range x { x[k] = p[i+k].x } s.rows = append(s.rows, spriteRow{y, x}) } return }
// drawFrequonsFourier draws the frequency-domain representation of Frequons. func drawFrequonsFourier(pm nimble.PixMap) { c := universe.Zoo h := harmonicStorage[:len(c)] var ampScale float32 if autoGain.Value { // Compute L1 norm of amplitudes norm := float32(0) for i := range c { norm += math32.Abs(c[i].Amplitude) } ampScale = 1 / norm } else { ampScale = 1 / float32(len(c)) } fracX, fracY := universe.BoxFraction() fracX *= zoomCompression fracY *= zoomCompression sizeX, sizeY := pm.Size() // Set up harmonics // (cx,cy) is center of fourier view cx, cy := 0.5*float32(sizeX)*fracX, 0.5*float32(sizeY)*fracY α, β := -0.5*cx, -0.5*cy ωScale := 200. / float32(sizeX*sizeY) for i := range h { ωx := (c[i].Sx - cx) * ωScale ωy := (c[i].Sy - cy) * ωScale h[i].Ωx = ωx h[i].Ωy = ωy h[i].Phase = α*ωx + β*ωy + phaseRoll // Scale amplitude so that DFT values fit within domain of color lookup table. h[i].Amplitude = c[i].Amplitude * ampScale } marginX := int32(math32.Round(0.5 * float32(sizeX) * (1 - fracX))) marginY := int32(math32.Round(0.5 * float32(sizeY) * (1 - fracY))) fourier.Draw(pm.Intersect(nimble.Rect{ Left: marginX, Right: sizeX - marginX, Top: marginY, Bottom: sizeY - marginY, }), h, universe.Scheme()) if marginX != 0 || marginY != 0 { pm.DrawRect(nimble.Rect{Left: 0, Right: sizeX, Top: 0, Bottom: marginY}, nimble.Black) pm.DrawRect(nimble.Rect{Left: 0, Right: sizeX, Top: sizeY - marginY, Bottom: sizeY}, nimble.Black) pm.DrawRect(nimble.Rect{Left: 0, Right: marginX, Top: marginY, Bottom: sizeY - marginY}, nimble.Black) pm.DrawRect(nimble.Rect{Left: sizeX - marginX, Right: sizeX, Top: marginY, Bottom: sizeY - marginY}, nimble.Black) } }
// drawFrequonsSpatial draws the spatial-domain representation of Frequons. // (xf,yf) is the location of the player. func drawFrequonsSpatial(pm nimble.PixMap, xf, yf int32) { nPastel := pastels.Width() for k := 1; k < len(universe.Zoo); k++ { c := &universe.Zoo[k] d := int32(math32.Hypot(float32(xf)-c.Sx, float32(yf)-c.Sy)) if c.Show || d < nPastel { i := c.ImageIndex() if i < len(critterSeq[k]) { j := int32(0) if !c.Show { j = d } sprite.Draw(pm, int32(math32.Round(c.Sx)), int32(math32.Round(c.Sy)), critterSeq[k][i], pastels.Pixel(j, int32(c.Id))) } } } if fourierPort.Contains(mouseX, mouseY) { sprite.Draw(pm, xf, yf, critterSeq[0][0], nimble.White) } }
func (context) Init(width, height int32) { if width < 640 || height < 400 { panic(fmt.Sprintf("screen size of %v x %v is too small!", width, height)) } screenWidth, screenHeight = width, height nShade := int32(math32.Round(math32.Sqrt(float32(width*height)) * (32. / 1440))) initCritterSprites(width, height) pastels = coloring.PastelPalette(universe.MaxCritter, nShade) teletype.Init("Characters.png") if benchmarking { bootSequencePeriod = 0 setMode(modeTraining) } else { setMode(modeSplash) // N.B. also causes partitionScreen to be called if devConfig { teletype.Print("[debug mode]\n") } } }