mirror of
https://github.com/bloeys/nterm.git
synced 2025-12-29 14:38:19 +00:00
Rename p *nterm to nt *nterm
This commit is contained in:
305
main.go
305
main.go
@ -91,9 +91,7 @@ type nterm struct {
|
|||||||
scrollPosRel int64
|
scrollPosRel int64
|
||||||
scrollSpd int64
|
scrollSpd int64
|
||||||
|
|
||||||
CellCountX int64
|
gridTiles [][]GridTile
|
||||||
CellCountY int64
|
|
||||||
CellCount int64
|
|
||||||
|
|
||||||
activeCmd *Cmd
|
activeCmd *Cmd
|
||||||
Settings *Settings
|
Settings *Settings
|
||||||
@ -118,6 +116,11 @@ const (
|
|||||||
defaultScrollSpd = 1
|
defaultScrollSpd = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GridTile struct {
|
||||||
|
glyph rune
|
||||||
|
color *gglm.Vec4
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
drawGrid bool
|
drawGrid bool
|
||||||
drawManyLines = false
|
drawManyLines = false
|
||||||
@ -129,6 +132,8 @@ var (
|
|||||||
yOff float32 = 0
|
yOff float32 = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @TODO: We should 'draw' and apply ansi operations on an in-mem grid and send the final grid for rendering
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
err := engine.Init()
|
err := engine.Init()
|
||||||
@ -192,90 +197,90 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) handleSDLEvent(e sdl.Event) {
|
func (nt *nterm) handleSDLEvent(e sdl.Event) {
|
||||||
|
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
|
|
||||||
case *sdl.TextInputEvent:
|
case *sdl.TextInputEvent:
|
||||||
p.WriteToCmdBuf([]rune(e.GetText()))
|
nt.WriteToCmdBuf([]rune(e.GetText()))
|
||||||
case *sdl.WindowEvent:
|
case *sdl.WindowEvent:
|
||||||
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
|
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
|
||||||
p.HandleWindowResize()
|
nt.HandleWindowResize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) Init() {
|
func (nt *nterm) Init() {
|
||||||
|
|
||||||
dpi, _, _, err := sdl.GetDisplayDPI(0)
|
dpi, _, _, err := sdl.GetDisplayDPI(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Failed to get display DPI. Err: " + err.Error())
|
panic("Failed to get display DPI. Err: " + err.Error())
|
||||||
}
|
}
|
||||||
fmt.Printf("DPI: %f, font size: %d\n", dpi, p.FontSize)
|
fmt.Printf("DPI: %f, font size: %d\n", dpi, nt.FontSize)
|
||||||
|
|
||||||
w, h := p.win.SDLWin.GetSize()
|
w, h := nt.win.SDLWin.GetSize()
|
||||||
// p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/tajawal-regular-var.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h)
|
// p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/tajawal-regular-var.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h)
|
||||||
p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/alm-fixed.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h)
|
nt.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/alm-fixed.ttf", &truetype.Options{Size: float64(nt.FontSize), DPI: nt.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Failed to create atlas from font file. Err: " + err.Error())
|
panic("Failed to create atlas from font file. Err: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
p.GlyphRend.OptValues.BgColor = gglm.NewVec4(0, 0, 0, 0)
|
nt.GlyphRend.OptValues.BgColor = gglm.NewVec4(0, 0, 0, 0)
|
||||||
p.GlyphRend.SetOpts(glyphs.GlyphRendOpt_BgColor)
|
nt.GlyphRend.SetOpts(glyphs.GlyphRendOpt_BgColor)
|
||||||
|
|
||||||
// if consts.Mode_Debug {
|
// if consts.Mode_Debug {
|
||||||
// glyphs.SaveImgToPNG(p.GlyphRend.Atlas.Img, "./debug-atlas.png")
|
// glyphs.SaveImgToPNG(p.GlyphRend.Atlas.Img, "./debug-atlas.png")
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//Load resources
|
//Load resources
|
||||||
p.gridMesh, err = meshes.NewMesh("grid", "./res/models/quad.obj", 0)
|
nt.gridMesh, err = meshes.NewMesh("grid", "./res/models/quad.obj", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
p.gridMat = materials.NewMaterial("grid", "./res/shaders/grid.glsl")
|
nt.gridMat = materials.NewMaterial("grid", "./res/shaders/grid.glsl")
|
||||||
p.HandleWindowResize()
|
nt.HandleWindowResize()
|
||||||
|
|
||||||
//Set initial cursor pos
|
//Set initial cursor pos
|
||||||
p.lastCmdCharPos.SetY(p.GlyphRend.Atlas.LineHeight)
|
nt.lastCmdCharPos.SetY(nt.GlyphRend.Atlas.LineHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) Update() {
|
func (nt *nterm) Update() {
|
||||||
|
|
||||||
p.frameStartTime = time.Now()
|
nt.frameStartTime = time.Now()
|
||||||
|
|
||||||
if input.IsQuitClicked() || input.KeyClicked(sdl.K_ESCAPE) {
|
if input.IsQuitClicked() || input.KeyClicked(sdl.K_ESCAPE) {
|
||||||
engine.Quit()
|
engine.Quit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if consts.Mode_Debug {
|
if consts.Mode_Debug {
|
||||||
p.DebugUpdate()
|
nt.DebugUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
//Font sizing
|
//Font sizing
|
||||||
oldFont := p.FontSize
|
oldFont := nt.FontSize
|
||||||
fontSizeChanged := false
|
fontSizeChanged := false
|
||||||
if input.KeyClicked(sdl.K_KP_PLUS) {
|
if input.KeyClicked(sdl.K_KP_PLUS) {
|
||||||
p.FontSize += 2
|
nt.FontSize += 2
|
||||||
fontSizeChanged = true
|
fontSizeChanged = true
|
||||||
} else if input.KeyClicked(sdl.K_KP_MINUS) {
|
} else if input.KeyClicked(sdl.K_KP_MINUS) {
|
||||||
p.FontSize -= 2
|
nt.FontSize -= 2
|
||||||
fontSizeChanged = true
|
fontSizeChanged = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if fontSizeChanged {
|
if fontSizeChanged {
|
||||||
|
|
||||||
err := p.GlyphRend.SetFace(&truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting})
|
err := nt.GlyphRend.SetFace(&truetype.Options{Size: float64(nt.FontSize), DPI: nt.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.FontSize = oldFont
|
nt.FontSize = oldFont
|
||||||
fmt.Println("Failed to update font face. Err: " + err.Error())
|
fmt.Println("Failed to update font face. Err: " + err.Error())
|
||||||
} else {
|
} else {
|
||||||
glyphs.SaveImgToPNG(p.GlyphRend.Atlas.Img, "./debug-atlas.png")
|
glyphs.SaveImgToPNG(nt.GlyphRend.Atlas.Img, "./debug-atlas.png")
|
||||||
fmt.Println("New font size:", p.FontSize, "; New texture size:", p.GlyphRend.Atlas.Img.Rect.Max.X)
|
fmt.Println("New font size:", nt.FontSize, "; New texture size:", nt.GlyphRend.Atlas.Img.Rect.Max.X)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.MainUpdate()
|
nt.MainUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nt *nterm) MainUpdate() {
|
func (nt *nterm) MainUpdate() {
|
||||||
@ -389,14 +394,14 @@ func (nt *nterm) ReadInputs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DrawTextAnsiCodes(bs []byte, pos gglm.Vec3) gglm.Vec3 {
|
func (nt *nterm) DrawTextAnsiCodes(bs []byte, pos gglm.Vec3) gglm.Vec3 {
|
||||||
|
|
||||||
currFgColor := p.Settings.DefaultFgColor
|
currFgColor := nt.Settings.DefaultFgColor
|
||||||
currBgColor := p.Settings.DefaultBgColor
|
currBgColor := nt.Settings.DefaultBgColor
|
||||||
|
|
||||||
draw := func(rs []rune) {
|
draw := func(rs []rune) {
|
||||||
|
|
||||||
p.GlyphRend.OptValues.BgColor.Data = currBgColor.Data
|
nt.GlyphRend.OptValues.BgColor.Data = currBgColor.Data
|
||||||
|
|
||||||
startIndex := 0
|
startIndex := 0
|
||||||
for i := 0; i < len(rs); i++ {
|
for i := 0; i < len(rs); i++ {
|
||||||
@ -405,16 +410,16 @@ func (p *nterm) DrawTextAnsiCodes(bs []byte, pos gglm.Vec3) gglm.Vec3 {
|
|||||||
|
|
||||||
// @PERF We could probably use bytes.IndexByte here
|
// @PERF We could probably use bytes.IndexByte here
|
||||||
if r == '\n' {
|
if r == '\n' {
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbsRectWithStartPos(rs[startIndex:i], &pos, gglm.NewVec3(0, 0, 0), gglm.NewVec2(float32(p.GlyphRend.ScreenWidth), 2*p.GlyphRend.Atlas.LineHeight), &currFgColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbsRectWithStartPos(rs[startIndex:i], &pos, gglm.NewVec3(0, 0, 0), gglm.NewVec2(float32(nt.GlyphRend.ScreenWidth), 2*nt.GlyphRend.Atlas.LineHeight), &currFgColor).Data
|
||||||
pos.SetX(0)
|
pos.SetX(0)
|
||||||
pos.AddY(-p.GlyphRend.Atlas.LineHeight)
|
pos.AddY(-nt.GlyphRend.Atlas.LineHeight)
|
||||||
startIndex = i + 1
|
startIndex = i + 1
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if startIndex < len(rs) {
|
if startIndex < len(rs) {
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbsRectWithStartPos(rs[startIndex:], &pos, gglm.NewVec3(0, 0, 0), gglm.NewVec2(float32(p.GlyphRend.ScreenWidth), 2*p.GlyphRend.Atlas.LineHeight), &currFgColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbsRectWithStartPos(rs[startIndex:], &pos, gglm.NewVec3(0, 0, 0), gglm.NewVec2(float32(nt.GlyphRend.ScreenWidth), 2*nt.GlyphRend.Atlas.LineHeight), &currFgColor).Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +440,7 @@ func (p *nterm) DrawTextAnsiCodes(bs []byte, pos gglm.Vec3) gglm.Vec3 {
|
|||||||
if info.Options.HasOptions(ansi.AnsiCodeOptions_ColorFg) {
|
if info.Options.HasOptions(ansi.AnsiCodeOptions_ColorFg) {
|
||||||
|
|
||||||
if info.Info1.X() == -1 {
|
if info.Info1.X() == -1 {
|
||||||
currFgColor = p.Settings.DefaultFgColor
|
currFgColor = nt.Settings.DefaultFgColor
|
||||||
} else {
|
} else {
|
||||||
currFgColor = info.Info1
|
currFgColor = info.Info1
|
||||||
}
|
}
|
||||||
@ -443,7 +448,7 @@ func (p *nterm) DrawTextAnsiCodes(bs []byte, pos gglm.Vec3) gglm.Vec3 {
|
|||||||
|
|
||||||
if info.Options.HasOptions(ansi.AnsiCodeOptions_ColorBg) {
|
if info.Options.HasOptions(ansi.AnsiCodeOptions_ColorBg) {
|
||||||
if info.Info1.X() == -1 {
|
if info.Info1.X() == -1 {
|
||||||
currBgColor = p.Settings.DefaultBgColor
|
currBgColor = nt.Settings.DefaultBgColor
|
||||||
} else {
|
} else {
|
||||||
currBgColor = info.Info1
|
currBgColor = info.Info1
|
||||||
}
|
}
|
||||||
@ -456,11 +461,11 @@ func (p *nterm) DrawTextAnsiCodes(bs []byte, pos gglm.Vec3) gglm.Vec3 {
|
|||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) SyntaxHighlightAndDraw(text []rune, pos gglm.Vec3) gglm.Vec3 {
|
func (nt *nterm) SyntaxHighlightAndDraw(text []rune, pos gglm.Vec3) gglm.Vec3 {
|
||||||
|
|
||||||
startIndex := 0
|
startIndex := 0
|
||||||
startPos := pos.Clone()
|
startPos := pos.Clone()
|
||||||
currColor := &p.Settings.DefaultFgColor
|
currColor := &nt.Settings.DefaultFgColor
|
||||||
|
|
||||||
inSingleString := false
|
inSingleString := false
|
||||||
inDoubleString := false
|
inDoubleString := false
|
||||||
@ -474,9 +479,9 @@ func (p *nterm) SyntaxHighlightAndDraw(text []rune, pos gglm.Vec3) gglm.Vec3 {
|
|||||||
// to the middle of the text not the start as it uses the start X position of the second half.
|
// to the middle of the text not the start as it uses the start X position of the second half.
|
||||||
// So to get correct new line handling we handle newlines here
|
// So to get correct new line handling we handle newlines here
|
||||||
case '\n':
|
case '\n':
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i], &pos, currColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i], &pos, currColor).Data
|
||||||
pos.SetX(startPos.X())
|
pos.SetX(startPos.X())
|
||||||
pos.AddY(-p.GlyphRend.Atlas.LineHeight)
|
pos.AddY(-nt.GlyphRend.Atlas.LineHeight)
|
||||||
startIndex = i + 1
|
startIndex = i + 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -487,18 +492,18 @@ func (p *nterm) SyntaxHighlightAndDraw(text []rune, pos gglm.Vec3) gglm.Vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !inDoubleString {
|
if !inDoubleString {
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i], &pos, currColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i], &pos, currColor).Data
|
||||||
|
|
||||||
startIndex = i
|
startIndex = i
|
||||||
inDoubleString = true
|
inDoubleString = true
|
||||||
currColor = &p.Settings.StringColor
|
currColor = &nt.Settings.StringColor
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i+1], &pos, currColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i+1], &pos, currColor).Data
|
||||||
startIndex = i + 1
|
startIndex = i + 1
|
||||||
inDoubleString = false
|
inDoubleString = false
|
||||||
currColor = &p.Settings.DefaultFgColor
|
currColor = &nt.Settings.DefaultFgColor
|
||||||
|
|
||||||
case '\'':
|
case '\'':
|
||||||
if inDoubleString {
|
if inDoubleString {
|
||||||
@ -506,72 +511,72 @@ func (p *nterm) SyntaxHighlightAndDraw(text []rune, pos gglm.Vec3) gglm.Vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !inSingleString {
|
if !inSingleString {
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i], &pos, currColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i], &pos, currColor).Data
|
||||||
|
|
||||||
startIndex = i
|
startIndex = i
|
||||||
inSingleString = true
|
inSingleString = true
|
||||||
currColor = &p.Settings.StringColor
|
currColor = &nt.Settings.StringColor
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i+1], &pos, &p.Settings.StringColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbs(text[startIndex:i+1], &pos, &nt.Settings.StringColor).Data
|
||||||
startIndex = i + 1
|
startIndex = i + 1
|
||||||
inSingleString = false
|
inSingleString = false
|
||||||
currColor = &p.Settings.DefaultFgColor
|
currColor = &nt.Settings.DefaultFgColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if startIndex < len(text) {
|
if startIndex < len(text) {
|
||||||
if inDoubleString || inSingleString {
|
if inDoubleString || inSingleString {
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbs(text[startIndex:], &pos, &p.Settings.StringColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbs(text[startIndex:], &pos, &nt.Settings.StringColor).Data
|
||||||
} else {
|
} else {
|
||||||
pos.Data = p.GlyphRend.DrawTextOpenGLAbs(text[startIndex:], &pos, &p.Settings.DefaultFgColor).Data
|
pos.Data = nt.GlyphRend.DrawTextOpenGLAbs(text[startIndex:], &pos, &nt.Settings.DefaultFgColor).Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DeletePrevChar() {
|
func (nt *nterm) DeletePrevChar() {
|
||||||
|
|
||||||
if p.cursorCharIndex == 0 || p.cmdBufLen == 0 {
|
if nt.cursorCharIndex == 0 || nt.cmdBufLen == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(p.cmdBuf[p.cursorCharIndex-1:], p.cmdBuf[p.cursorCharIndex:])
|
copy(nt.cmdBuf[nt.cursorCharIndex-1:], nt.cmdBuf[nt.cursorCharIndex:])
|
||||||
|
|
||||||
p.cmdBufLen--
|
nt.cmdBufLen--
|
||||||
p.cursorCharIndex--
|
nt.cursorCharIndex--
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DeleteNextChar() {
|
func (nt *nterm) DeleteNextChar() {
|
||||||
|
|
||||||
if p.cmdBufLen == 0 || p.cursorCharIndex == p.cmdBufLen {
|
if nt.cmdBufLen == 0 || nt.cursorCharIndex == nt.cmdBufLen {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(p.cmdBuf[p.cursorCharIndex:], p.cmdBuf[p.cursorCharIndex+1:])
|
copy(nt.cmdBuf[nt.cursorCharIndex:], nt.cmdBuf[nt.cursorCharIndex+1:])
|
||||||
|
|
||||||
p.cmdBufLen--
|
nt.cmdBufLen--
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) HandleReturn() {
|
func (nt *nterm) HandleReturn() {
|
||||||
|
|
||||||
cmdRunes := p.cmdBuf[:p.cmdBufLen]
|
cmdRunes := nt.cmdBuf[:nt.cmdBufLen]
|
||||||
p.cmdBufLen = 0
|
nt.cmdBufLen = 0
|
||||||
p.cursorCharIndex = 0
|
nt.cursorCharIndex = 0
|
||||||
|
|
||||||
cmdStr := string(cmdRunes)
|
cmdStr := string(cmdRunes)
|
||||||
cmdBytes := []byte(cmdStr)
|
cmdBytes := []byte(cmdStr)
|
||||||
p.WriteToTextBuf(cmdBytes)
|
nt.WriteToTextBuf(cmdBytes)
|
||||||
|
|
||||||
if p.activeCmd != nil {
|
if nt.activeCmd != nil {
|
||||||
|
|
||||||
// println("Wrote:", string(cmdBytes))
|
// println("Wrote:", string(cmdBytes))
|
||||||
_, err := p.activeCmd.Stdin.Write(cmdBytes)
|
_, err := nt.activeCmd.Stdin.Write(cmdBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.WriteToTextBuf([]byte(fmt.Sprintf("Writing to stdin pipe of '%s' failed. Error: %s\n", p.activeCmd.C.Path, err.Error())))
|
nt.WriteToTextBuf([]byte(fmt.Sprintf("Writing to stdin pipe of '%s' failed. Error: %s\n", nt.activeCmd.C.Path, err.Error())))
|
||||||
p.ClearActiveCmd()
|
nt.ClearActiveCmd()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,29 +599,29 @@ func (p *nterm) HandleReturn() {
|
|||||||
|
|
||||||
outPipe, err := cmd.StdoutPipe()
|
outPipe, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.WriteToTextBuf([]byte(fmt.Sprintf("Creating stdout pipe of '%s' failed. Error: %s\n", cmdName, err.Error())))
|
nt.WriteToTextBuf([]byte(fmt.Sprintf("Creating stdout pipe of '%s' failed. Error: %s\n", cmdName, err.Error())))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
inPipe, err := cmd.StdinPipe()
|
inPipe, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.WriteToTextBuf([]byte(fmt.Sprintf("Creating stdin pipe of '%s' failed. Error: %s\n", cmdName, err.Error())))
|
nt.WriteToTextBuf([]byte(fmt.Sprintf("Creating stdin pipe of '%s' failed. Error: %s\n", cmdName, err.Error())))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
errPipe, err := cmd.StderrPipe()
|
errPipe, err := cmd.StderrPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.WriteToTextBuf([]byte(fmt.Sprintf("Creating stderr pipe of '%s' failed. Error: %s\n", cmdName, err.Error())))
|
nt.WriteToTextBuf([]byte(fmt.Sprintf("Creating stderr pipe of '%s' failed. Error: %s\n", cmdName, err.Error())))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err = cmd.Start()
|
err = cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.WriteToTextBuf([]byte(fmt.Sprintf("Running '%s' failed. Error: %s\n", cmdName, err.Error())))
|
nt.WriteToTextBuf([]byte(fmt.Sprintf("Running '%s' failed. Error: %s\n", cmdName, err.Error())))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.activeCmd = &Cmd{
|
nt.activeCmd = &Cmd{
|
||||||
C: cmd,
|
C: cmd,
|
||||||
Stdout: outPipe,
|
Stdout: outPipe,
|
||||||
Stdin: inPipe,
|
Stdin: inPipe,
|
||||||
@ -630,18 +635,18 @@ func (p *nterm) HandleReturn() {
|
|||||||
fmt.Printf("Cmd '%s' took %0.2fs\n", cmdName, time.Since(startTime).Seconds())
|
fmt.Printf("Cmd '%s' took %0.2fs\n", cmdName, time.Since(startTime).Seconds())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
defer p.ClearActiveCmd()
|
defer nt.ClearActiveCmd()
|
||||||
buf := make([]byte, 4*1024)
|
buf := make([]byte, 4*1024)
|
||||||
for p.activeCmd != nil {
|
for nt.activeCmd != nil {
|
||||||
|
|
||||||
readBytes, err := p.activeCmd.Stdout.Read(buf)
|
readBytes, err := nt.activeCmd.Stdout.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
p.WriteToTextBuf([]byte("Stdout pipe failed. Error: " + err.Error()))
|
nt.WriteToTextBuf([]byte("Stdout pipe failed. Error: " + err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,7 +656,7 @@ func (p *nterm) HandleReturn() {
|
|||||||
|
|
||||||
// @Todo We need to parse ansi codes as data is coming in to update the drawing settings (e.g. color)
|
// @Todo We need to parse ansi codes as data is coming in to update the drawing settings (e.g. color)
|
||||||
b := buf[:readBytes]
|
b := buf[:readBytes]
|
||||||
p.WriteToTextBuf(b)
|
nt.WriteToTextBuf(b)
|
||||||
// println("Read:", string(buf[:readBytes]))
|
// println("Read:", string(buf[:readBytes]))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -660,16 +665,16 @@ func (p *nterm) HandleReturn() {
|
|||||||
go func() {
|
go func() {
|
||||||
|
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
for p.activeCmd != nil {
|
for nt.activeCmd != nil {
|
||||||
|
|
||||||
readBytes, err := p.activeCmd.Stderr.Read(buf)
|
readBytes, err := nt.activeCmd.Stderr.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
p.WriteToTextBuf([]byte("Stderr pipe failed. Error: " + err.Error()))
|
nt.WriteToTextBuf([]byte("Stderr pipe failed. Error: " + err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,12 +682,12 @@ func (p *nterm) HandleReturn() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
p.WriteToTextBuf(buf[:readBytes])
|
nt.WriteToTextBuf(buf[:readBytes])
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) ParseLines(bs []byte) {
|
func (nt *nterm) ParseLines(bs []byte) {
|
||||||
|
|
||||||
// @TODO We should virtually break lines when they are too long
|
// @TODO We should virtually break lines when they are too long
|
||||||
checkedBytes := uint64(0)
|
checkedBytes := uint64(0)
|
||||||
@ -696,57 +701,57 @@ func (p *nterm) ParseLines(bs []byte) {
|
|||||||
bs = bs[index+1:]
|
bs = bs[index+1:]
|
||||||
|
|
||||||
checkedBytes += uint64(index + 1)
|
checkedBytes += uint64(index + 1)
|
||||||
p.LineBeingParsed.EndIndex_WriteCount = p.textBuf.WrittenElements + checkedBytes
|
nt.LineBeingParsed.EndIndex_WriteCount = nt.textBuf.WrittenElements + checkedBytes
|
||||||
p.WriteLine(&p.LineBeingParsed)
|
nt.WriteLine(&nt.LineBeingParsed)
|
||||||
p.LineBeingParsed.StartIndex_WriteCount = p.textBuf.WrittenElements + checkedBytes
|
nt.LineBeingParsed.StartIndex_WriteCount = nt.textBuf.WrittenElements + checkedBytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) WriteLine(l *Line) {
|
func (nt *nterm) WriteLine(l *Line) {
|
||||||
assert.T(l.StartIndex_WriteCount <= l.EndIndex_WriteCount, "Invalid line: %+v\n", l)
|
assert.T(l.StartIndex_WriteCount <= l.EndIndex_WriteCount, "Invalid line: %+v\n", l)
|
||||||
p.Lines.Write(*l)
|
nt.Lines.Write(*l)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) ClearActiveCmd() {
|
func (nt *nterm) ClearActiveCmd() {
|
||||||
|
|
||||||
if p.activeCmd == nil {
|
if nt.activeCmd == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p.activeCmd = nil
|
nt.activeCmd = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DrawCursor() {
|
func (nt *nterm) DrawCursor() {
|
||||||
|
|
||||||
//Position cursor by placing it at the end of the drawn characters then walking backwards
|
//Position cursor by placing it at the end of the drawn characters then walking backwards
|
||||||
pos := p.lastCmdCharPos.Clone()
|
pos := nt.lastCmdCharPos.Clone()
|
||||||
|
|
||||||
pos.AddY(p.GlyphRend.Atlas.LineHeight * 0.5)
|
pos.AddY(nt.GlyphRend.Atlas.LineHeight * 0.5)
|
||||||
for i := clamp(p.cmdBufLen, 0, int64(len(p.cmdBuf))); i > p.cursorCharIndex; i-- {
|
for i := clamp(nt.cmdBufLen, 0, int64(len(nt.cmdBuf))); i > nt.cursorCharIndex; i-- {
|
||||||
|
|
||||||
if p.cmdBuf[i] == '\n' {
|
if nt.cmdBuf[i] == '\n' {
|
||||||
pos.AddY(p.GlyphRend.Atlas.LineHeight)
|
pos.AddY(nt.GlyphRend.Atlas.LineHeight)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pos.AddX(-p.GlyphRend.Atlas.SpaceAdvance)
|
pos.AddX(-nt.GlyphRend.Atlas.SpaceAdvance)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.rend.Draw(p.gridMesh, gglm.NewTrMatId().Translate(pos).Scale(gglm.NewVec3(0.1*p.GlyphRend.Atlas.SpaceAdvance, p.GlyphRend.Atlas.LineHeight, 1)), p.gridMat)
|
nt.rend.Draw(nt.gridMesh, gglm.NewTrMatId().Translate(pos).Scale(gglm.NewVec3(0.1*nt.GlyphRend.Atlas.SpaceAdvance, nt.GlyphRend.Atlas.LineHeight, 1)), nt.gridMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GridSize returns how many cells horizontally (aka chars per line) and how many cells vertically (aka lines)
|
// GridSize returns how many cells horizontally (aka chars per line) and how many cells vertically (aka lines)
|
||||||
func (p *nterm) GridSize() (w, h int64) {
|
func (nt *nterm) GridSize() (w, h int64) {
|
||||||
w = int64(p.GlyphRend.ScreenWidth) / int64(p.GlyphRend.Atlas.SpaceAdvance)
|
w = int64(nt.GlyphRend.ScreenWidth) / int64(nt.GlyphRend.Atlas.SpaceAdvance)
|
||||||
h = int64(p.GlyphRend.ScreenHeight) / int64(p.GlyphRend.Atlas.LineHeight)
|
h = int64(nt.GlyphRend.ScreenHeight) / int64(nt.GlyphRend.Atlas.LineHeight)
|
||||||
return w, h
|
return w, h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) ScreenPosToGridPos(screenPos *gglm.Vec3) {
|
func (nt *nterm) ScreenPosToGridPos(screenPos *gglm.Vec3) {
|
||||||
screenPos.SetX(FloorF32(screenPos.X() / p.GlyphRend.Atlas.SpaceAdvance))
|
screenPos.SetX(FloorF32(screenPos.X() / nt.GlyphRend.Atlas.SpaceAdvance))
|
||||||
screenPos.SetY(FloorF32(screenPos.Y() / p.GlyphRend.Atlas.LineHeight))
|
screenPos.SetY(FloorF32(screenPos.Y() / nt.GlyphRend.Atlas.LineHeight))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DebugUpdate() {
|
func (nt *nterm) DebugUpdate() {
|
||||||
|
|
||||||
//Move text
|
//Move text
|
||||||
var speed float32 = 1
|
var speed float32 = 1
|
||||||
@ -768,24 +773,24 @@ func (p *nterm) DebugUpdate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) Render() {
|
func (nt *nterm) Render() {
|
||||||
|
|
||||||
defer p.GlyphRend.Draw()
|
defer nt.GlyphRend.Draw()
|
||||||
|
|
||||||
if consts.Mode_Debug {
|
if consts.Mode_Debug {
|
||||||
p.DebugRender()
|
nt.DebugRender()
|
||||||
|
|
||||||
sizeX := float32(p.GlyphRend.ScreenWidth)
|
sizeX := float32(nt.GlyphRend.ScreenWidth)
|
||||||
p.rend.Draw(p.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(sizeX/2, p.SepLinePos.Y(), 0)).Scale(gglm.NewVec3(sizeX, 1, 1)), p.gridMat)
|
nt.rend.Draw(nt.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(sizeX/2, nt.SepLinePos.Y(), 0)).Scale(gglm.NewVec3(sizeX, 1, 1)), nt.gridMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.DrawCursor()
|
nt.DrawCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DebugRender() {
|
func (nt *nterm) DebugRender() {
|
||||||
|
|
||||||
if drawGrid {
|
if drawGrid {
|
||||||
p.DrawGrid()
|
nt.DrawGrid()
|
||||||
}
|
}
|
||||||
|
|
||||||
fps := int(timing.GetAvgFPS())
|
fps := int(timing.GetAvgFPS())
|
||||||
@ -795,43 +800,43 @@ func (p *nterm) DebugRender() {
|
|||||||
if drawManyLines {
|
if drawManyLines {
|
||||||
const charsPerFrame = 500_000
|
const charsPerFrame = 500_000
|
||||||
for i := 0; i < charsPerFrame/charCount; i++ {
|
for i := 0; i < charsPerFrame/charCount; i++ {
|
||||||
p.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(p.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &p.Settings.DefaultFgColor)
|
nt.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(nt.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &nt.Settings.DefaultFgColor)
|
||||||
}
|
}
|
||||||
p.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.DefaultGlyphsPerBatch), " chars/f: ", charsPerFrame, " chars/s: ", fps*charsPerFrame))
|
nt.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.DefaultGlyphsPerBatch), " chars/f: ", charsPerFrame, " chars/s: ", fps*charsPerFrame))
|
||||||
} else {
|
} else {
|
||||||
charsPerFrame := float64(charCount)
|
charsPerFrame := float64(charCount)
|
||||||
p.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(p.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &p.Settings.DefaultFgColor)
|
nt.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(nt.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &nt.Settings.DefaultFgColor)
|
||||||
p.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.DefaultGlyphsPerBatch), " chars/f: ", int(charsPerFrame), " chars/s: ", fps*int(charsPerFrame)))
|
nt.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.DefaultGlyphsPerBatch), " chars/f: ", int(charsPerFrame), " chars/s: ", fps*int(charsPerFrame)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps))
|
nt.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DrawGrid() {
|
func (nt *nterm) DrawGrid() {
|
||||||
|
|
||||||
sizeX := float32(p.GlyphRend.ScreenWidth)
|
sizeX := float32(nt.GlyphRend.ScreenWidth)
|
||||||
sizeY := float32(p.GlyphRend.ScreenHeight)
|
sizeY := float32(nt.GlyphRend.ScreenHeight)
|
||||||
|
|
||||||
//columns
|
//columns
|
||||||
adv := p.GlyphRend.Atlas.SpaceAdvance
|
adv := nt.GlyphRend.Atlas.SpaceAdvance
|
||||||
for i := 0; i < int(p.GlyphRend.ScreenWidth); i++ {
|
for i := 0; i < int(nt.GlyphRend.ScreenWidth); i++ {
|
||||||
p.rend.Draw(p.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(adv*float32(i), sizeY/2, 0)).Scale(gglm.NewVec3(1, sizeY, 1)), p.gridMat)
|
nt.rend.Draw(nt.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(adv*float32(i), sizeY/2, 0)).Scale(gglm.NewVec3(1, sizeY, 1)), nt.gridMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
//rows
|
//rows
|
||||||
for i := int32(0); i < p.GlyphRend.ScreenHeight; i += int32(p.GlyphRend.Atlas.LineHeight) {
|
for i := int32(0); i < nt.GlyphRend.ScreenHeight; i += int32(nt.GlyphRend.Atlas.LineHeight) {
|
||||||
p.rend.Draw(p.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(sizeX/2, float32(i), 0)).Scale(gglm.NewVec3(sizeX, 1, 1)), p.gridMat)
|
nt.rend.Draw(nt.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(sizeX/2, float32(i), 0)).Scale(gglm.NewVec3(sizeX, 1, 1)), nt.gridMat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) FrameEnd() {
|
func (nt *nterm) FrameEnd() {
|
||||||
assert.T(p.cursorCharIndex <= p.cmdBufLen, "Cursor char index is larger than cmdBufLen! You probablly forgot to move/reset the cursor index along with the buffer length somewhere. Cursor=%d, cmdBufLen=%d\n", p.cursorCharIndex, p.cmdBufLen)
|
assert.T(nt.cursorCharIndex <= nt.cmdBufLen, "Cursor char index is larger than cmdBufLen! You probablly forgot to move/reset the cursor index along with the buffer length somewhere. Cursor=%d, cmdBufLen=%d\n", nt.cursorCharIndex, nt.cmdBufLen)
|
||||||
|
|
||||||
if p.Settings.LimitFps {
|
if nt.Settings.LimitFps {
|
||||||
|
|
||||||
elapsed := time.Since(p.frameStartTime)
|
elapsed := time.Since(nt.frameStartTime)
|
||||||
microSecondsPerFrame := int64(1 / float32(p.Settings.MaxFps) * 1000_000)
|
microSecondsPerFrame := int64(1 / float32(nt.Settings.MaxFps) * 1000_000)
|
||||||
|
|
||||||
// Sleep time is reduced by a millisecond to compensate for the (nearly) inevitable over-sleeping that will happen.
|
// Sleep time is reduced by a millisecond to compensate for the (nearly) inevitable over-sleeping that will happen.
|
||||||
timeToSleep := time.Duration((microSecondsPerFrame - elapsed.Microseconds()) * 1000)
|
timeToSleep := time.Duration((microSecondsPerFrame - elapsed.Microseconds()) * 1000)
|
||||||
@ -843,42 +848,42 @@ func (p *nterm) FrameEnd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) DeInit() {
|
func (nt *nterm) DeInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) HandleWindowResize() {
|
func (nt *nterm) HandleWindowResize() {
|
||||||
w, h := p.win.SDLWin.GetSize()
|
w, h := nt.win.SDLWin.GetSize()
|
||||||
p.GlyphRend.SetScreenSize(w, h)
|
nt.GlyphRend.SetScreenSize(w, h)
|
||||||
|
|
||||||
projMtx := gglm.Ortho(0, float32(w), float32(h), 0, 0.1, 20)
|
projMtx := gglm.Ortho(0, float32(w), float32(h), 0, 0.1, 20)
|
||||||
viewMtx := gglm.LookAt(gglm.NewVec3(0, 0, -10), gglm.NewVec3(0, 0, 0), gglm.NewVec3(0, 1, 0))
|
viewMtx := gglm.LookAt(gglm.NewVec3(0, 0, -10), gglm.NewVec3(0, 0, 0), gglm.NewVec3(0, 1, 0))
|
||||||
p.gridMat.SetUnifMat4("projViewMat", &projMtx.Mul(viewMtx).Mat4)
|
nt.gridMat.SetUnifMat4("projViewMat", &projMtx.Mul(viewMtx).Mat4)
|
||||||
|
|
||||||
p.CellCountX, p.CellCountY = p.GridSize()
|
gridWidth, gridHeight := nt.GridSize()
|
||||||
p.CellCount = p.CellCountX * p.CellCountY
|
nt.gridTiles = make([][]GridTile, gridWidth*gridHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) WriteToTextBuf(text []byte) {
|
func (nt *nterm) WriteToTextBuf(text []byte) {
|
||||||
// This is locked because running cmds are potentially writing to it same time we are
|
// This is locked because running cmds are potentially writing to it same time we are
|
||||||
p.textBufMutex.Lock()
|
nt.textBufMutex.Lock()
|
||||||
|
|
||||||
p.ParseLines(text)
|
nt.ParseLines(text)
|
||||||
p.textBuf.Write(text...)
|
nt.textBuf.Write(text...)
|
||||||
|
|
||||||
p.textBufMutex.Unlock()
|
nt.textBufMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nterm) WriteToCmdBuf(text []rune) {
|
func (nt *nterm) WriteToCmdBuf(text []rune) {
|
||||||
|
|
||||||
delta := int64(len(text))
|
delta := int64(len(text))
|
||||||
newHeadPos := p.cmdBufLen + delta
|
newHeadPos := nt.cmdBufLen + delta
|
||||||
if newHeadPos <= defaultCmdBufSize {
|
if newHeadPos <= defaultCmdBufSize {
|
||||||
|
|
||||||
copy(p.cmdBuf[p.cursorCharIndex+delta:], p.cmdBuf[p.cursorCharIndex:])
|
copy(nt.cmdBuf[nt.cursorCharIndex+delta:], nt.cmdBuf[nt.cursorCharIndex:])
|
||||||
copy(p.cmdBuf[p.cursorCharIndex:], text)
|
copy(nt.cmdBuf[nt.cursorCharIndex:], text)
|
||||||
|
|
||||||
p.cursorCharIndex += delta
|
nt.cursorCharIndex += delta
|
||||||
p.cmdBufLen = newHeadPos
|
nt.cmdBufLen = newHeadPos
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user