Compare commits

...

7 commits

Author SHA1 Message Date
JetSetIlly ed67f97c5c corrected fa2866c 2024-05-05 17:31:47 +01:00
JetSetIlly 8313ea19b6 bumped version to v0.31.0 in Makefile 2024-05-05 17:01:53 +01:00
JetSetIlly fa2866c45d sdlimgui preferences correctly initialised on first use
this fix is very important because without it, the frame queue is set to
zero. this means that the display is likely to be very choppy creating
a bad impression of the emulator for first time users
2024-05-05 17:00:38 +01:00
JetSetIlly 7be60c0c2a corrected archivefs Set() function so that it works in Windows
Windows volume names confused the Set() function

archivefs.Async no longer exits async goroutine on errors from Path
functions. exiting meant that the channels were no longer being
serviced, causing GUI deadlocks
2024-05-05 17:00:38 +01:00
JetSetIlly 6c96b2f065 comment changes/clarifications 2024-05-05 17:00:38 +01:00
JetSetIlly 788530cd3e shaders package moved to display package 2024-05-05 11:35:51 +01:00
JetSetIlly c827d70c5b gui/crt package is now gui/display
colour preferences are now independent of CRT preferences
2024-05-05 11:35:51 +01:00
41 changed files with 384 additions and 222 deletions

View file

@ -1,5 +1,5 @@
version = v0.31.0 pre-release
version = v0.31.0
goBinary = go
gcflags = -c 3 -B -wb=false

View file

@ -68,12 +68,16 @@ func NewAsyncPath(setter FilenameSetter) AsyncPath {
afs.Close()
case path := <-pth.Set:
afs.Set(path)
err := afs.Set(path)
if err != nil {
pth.err <- err
continue // for loop
}
entries, err := afs.List()
if err != nil {
pth.err <- err
return
continue // for loop
}
pth.results <- AsyncResults{

View file

@ -223,8 +223,12 @@ func (afs *Path) List() ([]Node, error) {
func (afs *Path) Set(path string) error {
afs.Close()
// clean path and split into parts
// clean path and and remove volume name. volume name is not something we
// typically have to worry about in unix type systems
path = filepath.Clean(path)
path = strings.TrimPrefix(path, filepath.VolumeName(path))
// split path into parts
lst := strings.Split(path, string(filepath.Separator))
// strings.Split will remove a leading filepath.Separator. we need to add
@ -284,6 +288,14 @@ func (afs *Path) Set(path string) error {
}
}
// we want the absolute path. this restores any volume name that may have
// been trimmed off at the start of the function
var err error
afs.current, err = filepath.Abs(path)
if err != nil {
return fmt.Errorf("archivefs: set: %v", err)
}
// make sure path is clean
afs.current = filepath.Clean(path)

View file

@ -733,8 +733,8 @@ func regressAdd(mode string, args []string) error {
flgs.StringVar(&notes, "notes", "", "additional annotation for the entry")
flgs.StringVar(&mapping, "mapping", "AUTO", "form cartridge mapper selection")
flgs.StringVar(&spec, "spec", "AUTO", "television specification: NTSC, PAL, PAL60, PALM, SECAM")
flgs.IntVar(&numFrames, "frames", 10, "number of frames to run (ignored if mode is 'playback'")
flgs.StringVar(&state, "state", "", "record emulator state at every CPU step (ignored if mode is 'playback'")
flgs.IntVar(&numFrames, "frames", 10, "number of frames to run [not playback files]")
flgs.StringVar(&state, "state", "", "record emulator state at every CPU step [not playback files]")
flgs.BoolVar(&log, "log", false, "echo debugging log to stdout")
// parse args and get copy of remaining arguments
@ -743,8 +743,8 @@ func regressAdd(mode string, args []string) error {
if err == flag.ErrHelp {
fmt.Println()
fmt.Println(`The regression test to be added can be the path to a cartridge file or a previously
recorded playback file. For playback files, the flags marked [non-playback] do not make
sense and will be ignored.
recorded playback file. For playback files, the flags marked [not playback files] do not
make sense and will be ignored.
Available modes are VIDEO, PLAYBACK and LOG. If not mode is explicitly given then
VIDEO will be used for ROM files and PLAYBACK will be used for playback recordings.

98
gui/display/colour.go Normal file
View file

@ -0,0 +1,98 @@
// This file is part of Gopher2600.
//
// Gopher2600 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Gopher2600 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
package display
import (
"github.com/jetsetilly/gopher2600/prefs"
"github.com/jetsetilly/gopher2600/resources"
)
type Colour struct {
dsk *prefs.Disk
Brightness prefs.Float
Contrast prefs.Float
Saturation prefs.Float
Hue prefs.Float
}
func (p *Colour) String() string {
return p.dsk.String()
}
const (
brightness = 1.0
contrast = 1.0
saturation = 1.0
hue = 0.0
)
func newColour() (*Colour, error) {
p := &Colour{}
p.SetDefaults()
pth, err := resources.JoinPath(prefs.DefaultPrefsFile)
if err != nil {
return nil, err
}
p.dsk, err = prefs.NewDisk(pth)
if err != nil {
return nil, err
}
err = p.dsk.Add("display.color.brightness", &p.Brightness)
if err != nil {
return nil, err
}
err = p.dsk.Add("display.color.contrast", &p.Contrast)
if err != nil {
return nil, err
}
err = p.dsk.Add("display.color.saturation", &p.Saturation)
if err != nil {
return nil, err
}
err = p.dsk.Add("display.color.hue", &p.Hue)
if err != nil {
return nil, err
}
err = p.dsk.Load(true)
if err != nil {
return nil, err
}
return p, nil
}
// SetDefaults reverts all colour values to default
func (p *Colour) SetDefaults() {
p.Brightness.Set(brightness)
p.Contrast.Set(contrast)
p.Saturation.Set(saturation)
p.Hue.Set(hue)
}
// Load colour values from disk
func (p *Colour) Load() error {
return p.dsk.Load(false)
}
// Save current colour values to disk
func (p *Colour) Save() error {
return p.dsk.Save()
}

View file

@ -13,14 +13,14 @@
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
package crt
package display
import (
"github.com/jetsetilly/gopher2600/prefs"
"github.com/jetsetilly/gopher2600/resources"
)
type Preferences struct {
type CRT struct {
dsk *prefs.Disk
Enabled prefs.Bool
@ -53,11 +53,6 @@ type Preferences struct {
Sharpness prefs.Float
BlackLevel prefs.Float
Brightness prefs.Float
Contrast prefs.Float
Saturation prefs.Float
Hue prefs.Float
PixelPerfectFade prefs.Float
VSyncRecovery prefs.Int
@ -66,7 +61,7 @@ type Preferences struct {
IntegerScaling prefs.Bool
}
func (p *Preferences) String() string {
func (p *CRT) String() string {
return p.dsk.String()
}
@ -101,20 +96,14 @@ const (
sharpness = 0.55
blackLevel = 0.045
brightness = 1.0
contrast = 1.0
saturation = 1.0
hue = 0.0
pixelPerfectFade = 0.4
vsyncRecovery = 10
vsyncSensitivity = 2
integerScaling = false
)
// NewPreferences is the preferred method of initialisation for the Preferences type.
func NewPreferences() (*Preferences, error) {
p := &Preferences{}
func newCRT() (*CRT, error) {
p := &CRT{}
p.SetDefaults()
pth, err := resources.JoinPath(prefs.DefaultPrefsFile)
@ -235,22 +224,6 @@ func NewPreferences() (*Preferences, error) {
if err != nil {
return nil, err
}
err = p.dsk.Add("crt.brightness", &p.Brightness)
if err != nil {
return nil, err
}
err = p.dsk.Add("crt.contrast", &p.Contrast)
if err != nil {
return nil, err
}
err = p.dsk.Add("crt.saturation", &p.Saturation)
if err != nil {
return nil, err
}
err = p.dsk.Add("crt.hue", &p.Hue)
if err != nil {
return nil, err
}
err = p.dsk.Add("crt.pixelPerfectFade", &p.PixelPerfectFade)
if err != nil {
return nil, err
@ -277,7 +250,7 @@ func NewPreferences() (*Preferences, error) {
}
// SetDefaults revers all CRT settings to default values.
func (p *Preferences) SetDefaults() {
func (p *CRT) SetDefaults() {
p.Enabled.Set(enabled)
p.Curve.Set(curve)
p.RoundedCorners.Set(roundedCorners)
@ -306,23 +279,18 @@ func (p *Preferences) SetDefaults() {
p.Sharpness.Set(sharpness)
p.BlackLevel.Set(blackLevel)
p.Brightness.Set(brightness)
p.Contrast.Set(contrast)
p.Saturation.Set(saturation)
p.Hue.Set(hue)
p.PixelPerfectFade.Set(pixelPerfectFade)
p.VSyncRecovery.Set(vsyncRecovery)
p.VSyncSensitivity.Set(vsyncSensitivity)
p.IntegerScaling.Set(integerScaling)
}
// Load disassembly preferences and apply to the current disassembly.
func (p *Preferences) Load() error {
// Load CRT values from disk.
func (p *CRT) Load() error {
return p.dsk.Load(false)
}
// Save current disassembly preferences to disk.
func (p *Preferences) Save() error {
// Save current CRT values to disk.
func (p *CRT) Save() error {
return p.dsk.Save()
}

View file

@ -13,6 +13,10 @@
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
// Package CRT contains non-gui-specific and non-VCS-specific information. The
// CRT package is conceptually different to the television package.
package crt
// Package display specifies the preference values for the displaying of a TV
// image by a GUI. The types in this package are intended to be agnostic of
// which GUI system is being used.
//
// The package also houses the shaders subpackage. GLSL shaders should also be
// GUI system agnostic.
package display

View file

@ -0,0 +1,36 @@
// This file is part of Gopher2600.
//
// Gopher2600 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Gopher2600 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
package display
type Preferences struct {
Colour *Colour
CRT *CRT
}
// NewPreferences is the preferred method of initialisation for the Preferences type.
func NewPreferences() (*Preferences, error) {
var p Preferences
var err error
p.CRT, err = newCRT()
if err != nil {
return nil, err
}
p.Colour, err = newColour()
if err != nil {
return nil, err
}
return &p, nil
}

View file

@ -18,7 +18,7 @@
package sdlimgui
import (
"github.com/jetsetilly/gopher2600/gui/crt"
"github.com/jetsetilly/gopher2600/gui/display"
"github.com/jetsetilly/gopher2600/gui/sdlimgui/framebuffer"
"github.com/jetsetilly/gopher2600/hardware/television/specification"
)
@ -61,41 +61,41 @@ type crtSeqPrefs struct {
Hue float64
}
func newCrtSeqPrefs(prefs *crt.Preferences) crtSeqPrefs {
func newCrtSeqPrefs(prefs *display.Preferences) crtSeqPrefs {
return crtSeqPrefs{
Enabled: prefs.Enabled.Get().(bool),
PixelPerfectFade: prefs.PixelPerfectFade.Get().(float64),
Curve: prefs.Curve.Get().(bool),
RoundedCorners: prefs.RoundedCorners.Get().(bool),
Bevel: prefs.Bevel.Get().(bool),
Shine: prefs.Shine.Get().(bool),
Mask: prefs.Mask.Get().(bool),
Scanlines: prefs.Scanlines.Get().(bool),
Interference: prefs.Interference.Get().(bool),
Flicker: prefs.Flicker.Get().(bool),
Fringing: prefs.Fringing.Get().(bool),
Ghosting: prefs.Ghosting.Get().(bool),
Phosphor: prefs.Phosphor.Get().(bool),
CurveAmount: prefs.CurveAmount.Get().(float64),
RoundedCornersAmount: prefs.RoundedCornersAmount.Get().(float64),
BevelSize: prefs.BevelSize.Get().(float64),
MaskIntensity: prefs.MaskIntensity.Get().(float64),
MaskFine: prefs.MaskFine.Get().(float64),
ScanlinesIntensity: prefs.ScanlinesIntensity.Get().(float64),
ScanlinesFine: prefs.ScanlinesFine.Get().(float64),
InterferenceLevel: prefs.InterferenceLevel.Get().(float64),
FlickerLevel: prefs.FlickerLevel.Get().(float64),
FringingAmount: prefs.FringingAmount.Get().(float64),
GhostingAmount: prefs.GhostingAmount.Get().(float64),
PhosphorLatency: prefs.PhosphorLatency.Get().(float64),
PhosphorBloom: prefs.PhosphorBloom.Get().(float64),
Sharpness: prefs.Sharpness.Get().(float64),
BlackLevel: prefs.BlackLevel.Get().(float64),
Enabled: prefs.CRT.Enabled.Get().(bool),
PixelPerfectFade: prefs.CRT.PixelPerfectFade.Get().(float64),
Curve: prefs.CRT.Curve.Get().(bool),
RoundedCorners: prefs.CRT.RoundedCorners.Get().(bool),
Bevel: prefs.CRT.Bevel.Get().(bool),
Shine: prefs.CRT.Shine.Get().(bool),
Mask: prefs.CRT.Mask.Get().(bool),
Scanlines: prefs.CRT.Scanlines.Get().(bool),
Interference: prefs.CRT.Interference.Get().(bool),
Flicker: prefs.CRT.Flicker.Get().(bool),
Fringing: prefs.CRT.Fringing.Get().(bool),
Ghosting: prefs.CRT.Ghosting.Get().(bool),
Phosphor: prefs.CRT.Phosphor.Get().(bool),
CurveAmount: prefs.CRT.CurveAmount.Get().(float64),
RoundedCornersAmount: prefs.CRT.RoundedCornersAmount.Get().(float64),
BevelSize: prefs.CRT.BevelSize.Get().(float64),
MaskIntensity: prefs.CRT.MaskIntensity.Get().(float64),
MaskFine: prefs.CRT.MaskFine.Get().(float64),
ScanlinesIntensity: prefs.CRT.ScanlinesIntensity.Get().(float64),
ScanlinesFine: prefs.CRT.ScanlinesFine.Get().(float64),
InterferenceLevel: prefs.CRT.InterferenceLevel.Get().(float64),
FlickerLevel: prefs.CRT.FlickerLevel.Get().(float64),
FringingAmount: prefs.CRT.FringingAmount.Get().(float64),
GhostingAmount: prefs.CRT.GhostingAmount.Get().(float64),
PhosphorLatency: prefs.CRT.PhosphorLatency.Get().(float64),
PhosphorBloom: prefs.CRT.PhosphorBloom.Get().(float64),
Sharpness: prefs.CRT.Sharpness.Get().(float64),
BlackLevel: prefs.CRT.BlackLevel.Get().(float64),
Brightness: prefs.Brightness.Get().(float64),
Contrast: prefs.Contrast.Get().(float64),
Saturation: prefs.Saturation.Get().(float64),
Hue: prefs.Hue.Get().(float64),
Brightness: prefs.Colour.Brightness.Get().(float64),
Contrast: prefs.Colour.Contrast.Get().(float64),
Saturation: prefs.Colour.Saturation.Get().(float64),
Hue: prefs.Colour.Hue.Get().(float64),
}
}

View file

@ -21,7 +21,7 @@ import (
"time"
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/jetsetilly/gopher2600/gui/sdlimgui/shaders"
"github.com/jetsetilly/gopher2600/gui/display/shaders"
"github.com/jetsetilly/gopher2600/hardware/television/specification"
)

View file

@ -20,7 +20,7 @@ package sdlimgui
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/jetsetilly/gopher2600/debugger/govern"
"github.com/jetsetilly/gopher2600/gui/sdlimgui/shaders"
"github.com/jetsetilly/gopher2600/gui/display/shaders"
"github.com/jetsetilly/gopher2600/hardware/television/specification"
)
@ -202,7 +202,7 @@ func (sh *dbgScrShader) setAttributes(env shaderEnvironment) {
// something for the future.
env.srcTextureID = sh.img.wm.dbgScr.displayTexture.getID()
prefs := newCrtSeqPrefs(sh.img.crtPrefs)
prefs := newCrtSeqPrefs(sh.img.displayPrefs)
prefs.Enabled = true
prefs.Bevel = false
@ -219,7 +219,7 @@ func (sh *dbgScrShader) setAttributes(env shaderEnvironment) {
// note that we specify integer scaling for the non-CRT preview image,
// this is so that the overlay is aligned properly with the TV image
prefs := newCrtSeqPrefs(sh.img.crtPrefs)
prefs := newCrtSeqPrefs(sh.img.displayPrefs)
prefs.Enabled = false
env.srcTextureID = sh.crt.process(env, true, sh.img.wm.dbgScr.numScanlines, specification.ClksVisible, 0, sh.img.wm.dbgScr, prefs, specification.NormalRotation, false)

View file

@ -70,5 +70,5 @@ func (sh *playscrShader) setAttributes(env shaderEnvironment) {
sh.screenshot.process(env, sh.img.playScr)
sh.crt.process(env, false, sh.img.playScr.visibleScanlines, specification.ClksVisible, screenroll, sh.img.playScr, newCrtSeqPrefs(sh.img.crtPrefs), sh.img.screen.rotation.Load().(specification.Rotation), false)
sh.crt.process(env, false, sh.img.playScr.visibleScanlines, specification.ClksVisible, screenroll, sh.img.playScr, newCrtSeqPrefs(sh.img.displayPrefs), sh.img.screen.rotation.Load().(specification.Rotation), false)
}

View file

@ -101,7 +101,7 @@ func (sh *gl32Screenshot) start(mode screenshotMode, finish chan screenshotResul
sh.mode = mode
// description of screenshot to be returned to caller over finish channel
if sh.img.crtPrefs.Enabled.Get().(bool) {
if sh.img.displayPrefs.CRT.Enabled.Get().(bool) {
sh.description = fmt.Sprintf("crt_%s", sh.mode)
} else {
sh.description = fmt.Sprintf("pix_%s", sh.mode)
@ -161,7 +161,7 @@ func (sh *gl32Screenshot) process(env shaderEnvironment, scalingImage textureSpe
}
func (sh *gl32Screenshot) crtProcess(env shaderEnvironment, scalingImage textureSpec) {
prefs := newCrtSeqPrefs(sh.img.crtPrefs)
prefs := newCrtSeqPrefs(sh.img.displayPrefs)
if sh.mode == modeMotion {
switch sh.frames {
@ -335,7 +335,7 @@ func (sh *gl32Screenshot) compositeFinalise(env shaderEnvironment, composite *im
env.srcTextureID = sh.compositeBuffer.Texture(0)
// pass composite image through CRT shaders
textureID := sh.crt.process(env, true, sh.img.playScr.visibleScanlines, specification.ClksVisible, 0, sh, newCrtSeqPrefs(sh.img.crtPrefs), sh.img.screen.rotation.Load().(specification.Rotation), true)
textureID := sh.crt.process(env, true, sh.img.playScr.visibleScanlines, specification.ClksVisible, 0, sh, newCrtSeqPrefs(sh.img.displayPrefs), sh.img.screen.rotation.Load().(specification.Rotation), true)
gl.BindTexture(gl.TEXTURE_2D, textureID)

View file

@ -22,7 +22,7 @@ import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/inkyblackness/imgui-go/v4"
"github.com/jetsetilly/gopher2600/gui/sdlimgui/shaders"
"github.com/jetsetilly/gopher2600/gui/display/shaders"
)
// version string to attach to all shaders

View file

@ -143,7 +143,7 @@ func (win *playScr) setScaling() {
}
// limit scaling to whole integers
if win.img.crtPrefs == nil || win.img.crtPrefs.IntegerScaling.Get().(bool) {
if win.img.displayPrefs == nil || win.img.displayPrefs.CRT.IntegerScaling.Get().(bool) {
scaling = float32(int(scaling))
}

View file

@ -69,9 +69,9 @@ type preferences struct {
codeFontLineSpacing prefs.Int
// display
frameQueueAuto prefs.Bool
frameQueue prefs.Int
glSwapInterval prefs.Int
frameQueueLenAuto prefs.Bool
frameQueueLen prefs.Int
glSwapInterval prefs.Int
// window preferences are split over two prefs.Disk instances, to allow
// geometry to be saved at a different time to the fullscreen preference
@ -85,29 +85,6 @@ type preferences struct {
func newPreferences(img *SdlImgui) (*preferences, error) {
p := &preferences{img: img}
// defaults
p.terminalOnError.Set(true)
p.audioMuteDebugger.Set(true)
p.showTooltips.Set(true)
p.showTimelineThumbnail.Set(false)
p.colorDisasm.Set(true)
p.fpsDetail.Set(false)
p.activePause.Set(false)
p.audioMutePlaymode.Set(false)
p.controllerNotifcations.Set(true)
p.plusromNotifications.Set(true)
p.superchargerNotifications.Set(true)
p.audioMuteNotification.Set(true)
p.notificationVisibility.Set(0.75)
p.memoryUsageInOverlay.Set(false)
p.guiFontSize.Set(13)
p.terminalFontSize.Set(12)
p.codeFontSize.Set(15)
p.codeFontLineSpacing.Set(2.0)
p.frameQueueAuto.Set(false)
p.frameQueue.Set(5)
p.glSwapInterval.Set(1)
// setup preferences
pth, err := resources.JoinPath(prefs.DefaultPrefsFile)
if err != nil {
@ -195,28 +172,27 @@ func newPreferences(img *SdlImgui) (*preferences, error) {
// display options
// frameQueueAuto *must* be added after frameQueue so that the auto
// post-hook can override the frameQueue value on load as required
err = p.dsk.Add("sdlimgui.display.frameQueue", &p.frameQueue)
err = p.dsk.Add("sdlimgui.display.frameQueueLen", &p.frameQueueLen)
if err != nil {
return nil, err
}
p.frameQueue.SetHookPost(func(v prefs.Value) error {
p.img.screen.setFrameQueue(p.frameQueueAuto.Get().(bool), v.(int))
p.frameQueueLen.SetHookPost(func(v prefs.Value) error {
p.img.screen.setFrameQueue(p.frameQueueLenAuto.Get().(bool), v.(int))
return nil
})
err = p.dsk.Add("sdlimgui.display.frameQueueAuto", &p.frameQueueAuto)
err = p.dsk.Add("sdlimgui.display.frameQueueLenAuto", &p.frameQueueLenAuto)
if err != nil {
return nil, err
}
p.frameQueueAuto.SetHookPost(func(v prefs.Value) error {
p.frameQueueLenAuto.SetHookPost(func(v prefs.Value) error {
// set frameQueue value if auto is true. there is no need to call
// screen.setFrameQueue() in that instance becase the post hook for the
// frameQueue value does that
if v.(bool) {
p.img.screen.setFrameQueue(true, 1)
} else {
p.img.screen.setFrameQueue(false, p.frameQueue.Get().(int))
p.img.screen.setFrameQueue(false, p.frameQueueLen.Get().(int))
}
return nil
})
@ -278,8 +254,39 @@ func newPreferences(img *SdlImgui) (*preferences, error) {
return p, nil
}
func (p *preferences) setDefaults() {
p.terminalOnError.Set(true)
p.audioMuteDebugger.Set(true)
p.showTooltips.Set(true)
p.showTimelineThumbnail.Set(false)
p.colorDisasm.Set(true)
p.fpsDetail.Set(false)
p.activePause.Set(false)
p.audioMutePlaymode.Set(false)
p.controllerNotifcations.Set(true)
p.plusromNotifications.Set(true)
p.superchargerNotifications.Set(true)
p.audioMuteNotification.Set(true)
p.notificationVisibility.Set(0.75)
p.memoryUsageInOverlay.Set(false)
p.guiFontSize.Set(13)
p.terminalFontSize.Set(12)
p.codeFontSize.Set(15)
p.codeFontLineSpacing.Set(2.0)
p.frameQueueLenAuto.Set(false)
p.frameQueueLen.Set(3)
p.glSwapInterval.Set(1)
}
// load preferences from disk. does not load window preferences.
func (p *preferences) load() error {
// calling set defaults before loading the values from disk. this makes sure
// that the value hooks have been called at least once
//
// this is important because if the value is not on disk (eg. on first use
// of the emulator) then the hook will not be triggered by the load process
p.setDefaults()
return p.dsk.Load(false)
}

View file

@ -433,8 +433,8 @@ func (scr *screen) NewFrame(frameInfo television.FrameInfo) error {
// set VSYNC recover value if number of vsync scanlines is insufficient. we
// only do this is TV is stable
if frameInfo.Stable && frameInfo.VSyncScanlines < scr.img.crtPrefs.VSyncSensitivity.Get().(int) {
scr.crit.vsyncRecover = scr.img.crtPrefs.VSyncRecovery.Get().(int)
if frameInfo.Stable && frameInfo.VSyncScanlines < scr.img.displayPrefs.CRT.VSyncSensitivity.Get().(int) {
scr.crit.vsyncRecover = scr.img.displayPrefs.CRT.VSyncRecovery.Get().(int)
} else if scr.crit.vsyncRecover >= 0 {
scr.crit.vsyncRecover--
}

View file

@ -23,7 +23,7 @@ import (
"github.com/jetsetilly/gopher2600/debugger"
"github.com/jetsetilly/gopher2600/debugger/govern"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/gui/crt"
"github.com/jetsetilly/gopher2600/gui/display"
"github.com/jetsetilly/gopher2600/gui/sdlaudio"
"github.com/jetsetilly/gopher2600/gui/sdlimgui/caching"
"github.com/jetsetilly/gopher2600/logger"
@ -121,8 +121,8 @@ type SdlImgui struct {
// gui specific preferences. crt preferences are handled separately. all
// other preferences are handled by the emulation
prefs *preferences
crtPrefs *crt.Preferences
prefs *preferences
displayPrefs *display.Preferences
// modal window
modal modal
@ -216,14 +216,14 @@ func NewSdlImgui(dbg *debugger.Debugger) (*SdlImgui, error) {
}
img.dbg.VCS().TV.AddRealtimeAudioMixer(img.audio)
// initialise crt preferences
img.crtPrefs, err = crt.NewPreferences()
// initialise display preferences
img.displayPrefs, err = display.NewPreferences()
if err != nil {
return nil, fmt.Errorf("sdlimgui: %w", err)
}
// set scaling when IntegerScaling prefs value is changed
img.crtPrefs.IntegerScaling.SetHookPost(func(v prefs.Value) error {
img.displayPrefs.CRT.IntegerScaling.SetHookPost(func(v prefs.Value) error {
select {
case img.postRenderFunctions <- func() {
img.screen.crit.section.Lock()

View file

@ -100,16 +100,18 @@ func (win *winPrefs) draw() {
imgui.EndTabItem()
}
if imgui.BeginTabItem("TV") {
win.drawTV()
if imgui.BeginTabItem("Colour") {
win.drawColour()
imgui.EndTabItem()
setDef = win.img.displayPrefs.Colour
setDefLabel = "Colour"
}
if win.img.rnd.supportsCRT() {
if imgui.BeginTabItem("CRT") {
win.drawCRT()
imgui.EndTabItem()
setDef = win.img.crtPrefs
setDef = win.img.displayPrefs.CRT
setDefLabel = "CRT"
}
}
@ -276,7 +278,7 @@ of the ROM.`)
}
if imgui.Checkbox("Automatic Frame Queue Length", &frameQueueAuto) {
win.img.prefs.frameQueueAuto.Set(frameQueueAuto)
win.img.prefs.frameQueueLenAuto.Set(frameQueueAuto)
}
imgui.Spacing()
@ -289,7 +291,7 @@ of the ROM.`)
}
if imgui.SliderInt("Frame Queue Length", &frameQueueLen, 1, maxFrameQueue) {
win.img.prefs.frameQueue.Set(frameQueueLen)
win.img.prefs.frameQueueLen.Set(frameQueueLen)
}
}
}
@ -714,9 +716,13 @@ func (win *winPrefs) drawDiskButtons() {
if err != nil {
logger.Logf(logger.Allow, "sdlimgui", "could not save (imgui debugger) preferences: %v", err)
}
err = win.img.crtPrefs.Save()
err = win.img.displayPrefs.CRT.Save()
if err != nil {
logger.Logf(logger.Allow, "sdlimgui", "could not save (crt) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (display/crt) preferences: %v", err)
}
err = win.img.displayPrefs.Colour.Save()
if err != nil {
logger.Logf(logger.Allow, "sdlimgui", "could not save (display/colour) preferences: %v", err)
}
err = win.img.audio.Prefs.Save()
if err != nil {
@ -762,9 +768,13 @@ func (win *winPrefs) drawDiskButtons() {
if err != nil {
logger.Logf(logger.Allow, "sdlimgui", "could not restore (imgui debugger) preferences: %v", err)
}
err = win.img.crtPrefs.Load()
err = win.img.displayPrefs.CRT.Load()
if err != nil {
logger.Logf(logger.Allow, "sdlimgui", "could not restore (crt) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (display/crt) preferences: %v", err)
}
err = win.img.displayPrefs.Colour.Load()
if err != nil {
logger.Logf(logger.Allow, "sdlimgui", "could not restore (display/colour) preferences: %v", err)
}
err = win.img.audio.Prefs.Load()
if err != nil {

View file

@ -22,9 +22,12 @@ import (
"github.com/jetsetilly/gopher2600/gui/fonts"
)
func (win *winPrefs) drawTV() {
func (win *winPrefs) drawColour() {
imgui.Spacing()
imgui.PushItemWidth(400)
defer imgui.PopItemWidth()
win.drawBrightness()
imgui.Spacing()
win.drawContrast()
@ -35,51 +38,63 @@ func (win *winPrefs) drawTV() {
}
func (win *winPrefs) drawBrightness() {
imgui.BeginGroup()
defer imgui.EndGroup()
imgui.Text(fmt.Sprintf("%c Brightness", fonts.TVBrightness))
f := float32(win.img.crtPrefs.Brightness.Get().(float64))
f := float32(win.img.displayPrefs.Colour.Brightness.Get().(float64))
minv := float32(0.1)
maxv := float32(1.90)
label := fmt.Sprintf("%.0f", 100*(f-minv)/(maxv-minv))
if imgui.SliderFloatV("##brightness", &f, minv, maxv, label, imgui.SliderFlagsNone) {
win.img.crtPrefs.Brightness.Set(f)
win.img.displayPrefs.Colour.Brightness.Set(f)
}
}
func (win *winPrefs) drawContrast() {
imgui.BeginGroup()
defer imgui.EndGroup()
imgui.Text(fmt.Sprintf("%c Contrast", fonts.TVContrast))
f := float32(win.img.crtPrefs.Contrast.Get().(float64))
f := float32(win.img.displayPrefs.Colour.Contrast.Get().(float64))
minv := float32(0.1)
maxv := float32(1.90)
label := fmt.Sprintf("%.0f", 100*(f-minv)/(maxv-minv))
if imgui.SliderFloatV("##contrast", &f, minv, maxv, label, imgui.SliderFlagsNone) {
win.img.crtPrefs.Contrast.Set(f)
win.img.displayPrefs.Colour.Contrast.Set(f)
}
}
func (win *winPrefs) drawSaturation() {
imgui.BeginGroup()
defer imgui.EndGroup()
imgui.Text(fmt.Sprintf("%c Saturation", fonts.TVSaturation))
f := float32(win.img.crtPrefs.Saturation.Get().(float64))
f := float32(win.img.displayPrefs.Colour.Saturation.Get().(float64))
minv := float32(0.1)
maxv := float32(1.90)
label := fmt.Sprintf("%.0f", 100*(f-minv)/(maxv-minv))
if imgui.SliderFloatV("##saturation", &f, minv, maxv, label, imgui.SliderFlagsNone) {
win.img.crtPrefs.Saturation.Set(f)
win.img.displayPrefs.Colour.Saturation.Set(f)
}
}
func (win *winPrefs) drawHue() {
imgui.BeginGroup()
defer imgui.EndGroup()
imgui.Text(fmt.Sprintf("%c Hue", fonts.TVHue))
f := float32(win.img.crtPrefs.Hue.Get().(float64))
f := float32(win.img.displayPrefs.Colour.Hue.Get().(float64))
minv := float32(-0.99)
maxv := float32(0.99)
@ -88,6 +103,6 @@ func (win *winPrefs) drawHue() {
label := fmt.Sprintf("%.0f\u00b0", (f+minv+maxv)/(aminv+amaxv)*360)
if imgui.SliderFloatV("##hue", &f, minv, maxv, label, imgui.SliderFlagsNone) {
win.img.crtPrefs.Hue.Set(f)
win.img.displayPrefs.Colour.Hue.Set(f)
}
}

View file

@ -42,7 +42,7 @@ func (win *winPrefs) drawCRT() {
imgui.Separator()
imgui.Spacing()
if imgui.BeginTableV("crtPrefs", 3, imgui.TableFlagsBordersInnerV, imgui.Vec2{}, 1.0) {
if imgui.BeginTableV("displayPrefs.CRT", 3, imgui.TableFlagsBordersInnerV, imgui.Vec2{}, 1.0) {
imgui.TableSetupColumnV("0", imgui.TableColumnFlagsWidthFixed, 200, 0)
imgui.TableSetupColumnV("1", imgui.TableColumnFlagsWidthFixed, 200, 1)
imgui.TableSetupColumnV("2", imgui.TableColumnFlagsWidthFixed, 200, 2)
@ -97,12 +97,12 @@ func (win *winPrefs) drawCRT() {
}
func (win *winPrefs) drawCurve() {
b := win.img.crtPrefs.Curve.Get().(bool)
b := win.img.displayPrefs.CRT.Curve.Get().(bool)
if imgui.Checkbox("Curve##curve", &b) {
win.img.crtPrefs.Curve.Set(b)
win.img.displayPrefs.CRT.Curve.Set(b)
}
f := float32(win.img.crtPrefs.CurveAmount.Get().(float64))
f := float32(win.img.displayPrefs.CRT.CurveAmount.Get().(float64))
var label string
@ -115,17 +115,17 @@ func (win *winPrefs) drawCurve() {
}
if imgui.SliderFloatV("##curveamount", &f, 1.0, 0.0, label, 1.0) {
win.img.crtPrefs.CurveAmount.Set(f)
win.img.displayPrefs.CRT.CurveAmount.Set(f)
}
}
func (win *winPrefs) drawMask() {
b := win.img.crtPrefs.Mask.Get().(bool)
b := win.img.displayPrefs.CRT.Mask.Get().(bool)
if imgui.Checkbox("Shadow Mask##mask", &b) {
win.img.crtPrefs.Mask.Set(b)
win.img.displayPrefs.CRT.Mask.Set(b)
}
f := float32(win.img.crtPrefs.MaskIntensity.Get().(float64))
f := float32(win.img.displayPrefs.CRT.MaskIntensity.Get().(float64))
var label string
@ -140,10 +140,10 @@ func (win *winPrefs) drawMask() {
}
if imgui.SliderFloatV("##maskintensity", &f, 0.025, 0.125, label, 1.0) {
win.img.crtPrefs.MaskIntensity.Set(f)
win.img.displayPrefs.CRT.MaskIntensity.Set(f)
}
fine := float32(win.img.crtPrefs.MaskFine.Get().(float64))
fine := float32(win.img.displayPrefs.CRT.MaskFine.Get().(float64))
if fine >= 3.0 {
label = "very fine"
@ -156,17 +156,17 @@ func (win *winPrefs) drawMask() {
}
if imgui.SliderFloatV("##maskfine", &fine, 1.5, 3.5, label, 1.0) {
win.img.crtPrefs.MaskFine.Set(fine)
win.img.displayPrefs.CRT.MaskFine.Set(fine)
}
}
func (win *winPrefs) drawScanlines() {
b := win.img.crtPrefs.Scanlines.Get().(bool)
b := win.img.displayPrefs.CRT.Scanlines.Get().(bool)
if imgui.Checkbox("Scanlines##scanlines", &b) {
win.img.crtPrefs.Scanlines.Set(b)
win.img.displayPrefs.CRT.Scanlines.Set(b)
}
f := float32(win.img.crtPrefs.ScanlinesIntensity.Get().(float64))
f := float32(win.img.displayPrefs.CRT.ScanlinesIntensity.Get().(float64))
var label string
@ -181,10 +181,10 @@ func (win *winPrefs) drawScanlines() {
}
if imgui.SliderFloatV("##scanlinesintensity", &f, 0.025, 0.125, label, 1.0) {
win.img.crtPrefs.ScanlinesIntensity.Set(f)
win.img.displayPrefs.CRT.ScanlinesIntensity.Set(f)
}
fine := float32(win.img.crtPrefs.ScanlinesFine.Get().(float64))
fine := float32(win.img.displayPrefs.CRT.ScanlinesFine.Get().(float64))
if fine > 2.25 {
label = "very fine"
@ -197,17 +197,17 @@ func (win *winPrefs) drawScanlines() {
}
if imgui.SliderFloatV("##scanlinesfine", &fine, 1.5, 2.5, label, 1.0) {
win.img.crtPrefs.ScanlinesFine.Set(fine)
win.img.displayPrefs.CRT.ScanlinesFine.Set(fine)
}
}
func (win *winPrefs) drawInterference() {
b := win.img.crtPrefs.Interference.Get().(bool)
b := win.img.displayPrefs.CRT.Interference.Get().(bool)
if imgui.Checkbox("Interference##interference", &b) {
win.img.crtPrefs.Interference.Set(b)
win.img.displayPrefs.CRT.Interference.Set(b)
}
f := float32(win.img.crtPrefs.InterferenceLevel.Get().(float64))
f := float32(win.img.displayPrefs.CRT.InterferenceLevel.Get().(float64))
var label string
@ -222,17 +222,17 @@ func (win *winPrefs) drawInterference() {
}
if imgui.SliderFloatV("##interferencelevel", &f, 0.1, 0.2, label, 1.0) {
win.img.crtPrefs.InterferenceLevel.Set(f)
win.img.displayPrefs.CRT.InterferenceLevel.Set(f)
}
}
func (win *winPrefs) drawFlicker() {
b := win.img.crtPrefs.Flicker.Get().(bool)
b := win.img.displayPrefs.CRT.Flicker.Get().(bool)
if imgui.Checkbox("Flicker##flicker", &b) {
win.img.crtPrefs.Flicker.Set(b)
win.img.displayPrefs.CRT.Flicker.Set(b)
}
f := float32(win.img.crtPrefs.FlickerLevel.Get().(float64))
f := float32(win.img.displayPrefs.CRT.FlickerLevel.Get().(float64))
var label string
@ -247,17 +247,17 @@ func (win *winPrefs) drawFlicker() {
}
if imgui.SliderFloatV("##flickerlevel", &f, 0.01, 0.06, label, 1.0) {
win.img.crtPrefs.FlickerLevel.Set(f)
win.img.displayPrefs.CRT.FlickerLevel.Set(f)
}
}
func (win *winPrefs) drawFringing() {
b := win.img.crtPrefs.Fringing.Get().(bool)
b := win.img.displayPrefs.CRT.Fringing.Get().(bool)
if imgui.Checkbox("Colour Fringing##fringing", &b) {
win.img.crtPrefs.Fringing.Set(b)
win.img.displayPrefs.CRT.Fringing.Set(b)
}
f := float32(win.img.crtPrefs.FringingAmount.Get().(float64))
f := float32(win.img.displayPrefs.CRT.FringingAmount.Get().(float64))
var label string
@ -272,17 +272,17 @@ func (win *winPrefs) drawFringing() {
}
if imgui.SliderFloatV("##fringingamount", &f, 0.0, 0.6, label, 1.0) {
win.img.crtPrefs.FringingAmount.Set(f)
win.img.displayPrefs.CRT.FringingAmount.Set(f)
}
}
func (win *winPrefs) drawGhosting() {
b := win.img.crtPrefs.Ghosting.Get().(bool)
b := win.img.displayPrefs.CRT.Ghosting.Get().(bool)
if imgui.Checkbox("Ghosting##ghosting", &b) {
win.img.crtPrefs.Ghosting.Set(b)
win.img.displayPrefs.CRT.Ghosting.Set(b)
}
f := float32(win.img.crtPrefs.GhostingAmount.Get().(float64))
f := float32(win.img.displayPrefs.CRT.GhostingAmount.Get().(float64))
var label string
@ -297,20 +297,20 @@ func (win *winPrefs) drawGhosting() {
}
if imgui.SliderFloatV("##ghostingamount", &f, 0.0, 4.5, label, 1.0) {
win.img.crtPrefs.GhostingAmount.Set(f)
win.img.displayPrefs.CRT.GhostingAmount.Set(f)
}
}
func (win *winPrefs) drawPhosphor() {
b := win.img.crtPrefs.Phosphor.Get().(bool)
b := win.img.displayPrefs.CRT.Phosphor.Get().(bool)
if imgui.Checkbox("Phosphor##phosphor", &b) {
win.img.crtPrefs.Phosphor.Set(b)
win.img.displayPrefs.CRT.Phosphor.Set(b)
}
var label string
// latency
f := float32(win.img.crtPrefs.PhosphorLatency.Get().(float64))
f := float32(win.img.displayPrefs.CRT.PhosphorLatency.Get().(float64))
if f > 0.7 {
label = "very slow"
@ -323,11 +323,11 @@ func (win *winPrefs) drawPhosphor() {
}
if imgui.SliderFloatV("##phosphorlatency", &f, 0.9, 0.1, label, 1.0) {
win.img.crtPrefs.PhosphorLatency.Set(f)
win.img.displayPrefs.CRT.PhosphorLatency.Set(f)
}
// bloom
g := float32(win.img.crtPrefs.PhosphorBloom.Get().(float64))
g := float32(win.img.displayPrefs.CRT.PhosphorBloom.Get().(float64))
if g > 1.70 {
label = "very high bloom"
@ -340,12 +340,12 @@ func (win *winPrefs) drawPhosphor() {
}
if imgui.SliderFloatV("##phosphorbloom", &g, 0.20, 2.20, label, 1.0) {
win.img.crtPrefs.PhosphorBloom.Set(g)
win.img.displayPrefs.CRT.PhosphorBloom.Set(g)
}
}
func (win *winPrefs) drawSharpness() {
f := float32(win.img.crtPrefs.Sharpness.Get().(float64))
f := float32(win.img.displayPrefs.CRT.Sharpness.Get().(float64))
var label string
@ -360,14 +360,14 @@ func (win *winPrefs) drawSharpness() {
}
if imgui.SliderFloatV("##sharpness", &f, 0.1, 1.1, label, 1.0) {
win.img.crtPrefs.Sharpness.Set(f)
win.img.displayPrefs.CRT.Sharpness.Set(f)
}
}
func (win *winPrefs) drawBlackLevel() {
imgui.Text("Black Level")
f := float32(win.img.crtPrefs.BlackLevel.Get().(float64))
f := float32(win.img.displayPrefs.CRT.BlackLevel.Get().(float64))
var label string
@ -380,17 +380,17 @@ func (win *winPrefs) drawBlackLevel() {
}
if imgui.SliderFloatV("##blacklevel", &f, 0.00, 0.20, label, 1.0) {
win.img.crtPrefs.BlackLevel.Set(f)
win.img.displayPrefs.CRT.BlackLevel.Set(f)
}
}
func (win *winPrefs) drawRoundedCorners() {
b := win.img.crtPrefs.RoundedCorners.Get().(bool)
b := win.img.displayPrefs.CRT.RoundedCorners.Get().(bool)
if imgui.Checkbox("Rounded Corners##roundedcorners", &b) {
win.img.crtPrefs.RoundedCorners.Set(b)
win.img.displayPrefs.CRT.RoundedCorners.Set(b)
}
f := float32(win.img.crtPrefs.RoundedCornersAmount.Get().(float64))
f := float32(win.img.displayPrefs.CRT.RoundedCornersAmount.Get().(float64))
var label string
@ -405,17 +405,17 @@ func (win *winPrefs) drawRoundedCorners() {
}
if imgui.SliderFloatV("##roundedcornersamount", &f, 0.02, 0.09, label, 1.0) {
win.img.crtPrefs.RoundedCornersAmount.Set(f)
win.img.displayPrefs.CRT.RoundedCornersAmount.Set(f)
}
}
func (win *winPrefs) drawBevel() {
b := win.img.crtPrefs.Bevel.Get().(bool)
b := win.img.displayPrefs.CRT.Bevel.Get().(bool)
if imgui.Checkbox("Bevel##bevel", &b) {
win.img.crtPrefs.Bevel.Set(b)
win.img.displayPrefs.CRT.Bevel.Set(b)
}
f := float32(win.img.crtPrefs.BevelSize.Get().(float64))
f := float32(win.img.displayPrefs.CRT.BevelSize.Get().(float64))
var label string
@ -430,24 +430,24 @@ func (win *winPrefs) drawBevel() {
}
if imgui.SliderFloatV("##bevelSize", &f, 0.005, 0.025, label, 1.0) {
win.img.crtPrefs.BevelSize.Set(f)
win.img.displayPrefs.CRT.BevelSize.Set(f)
}
}
func (win *winPrefs) drawShine() {
b := win.img.crtPrefs.Shine.Get().(bool)
b := win.img.displayPrefs.CRT.Shine.Get().(bool)
if imgui.Checkbox("Shine##shine", &b) {
win.img.crtPrefs.Shine.Set(b)
win.img.displayPrefs.CRT.Shine.Set(b)
}
}
func (win *winPrefs) drawPixelPerfect() bool {
b := !win.img.crtPrefs.Enabled.Get().(bool)
b := !win.img.displayPrefs.CRT.Enabled.Get().(bool)
if imgui.Checkbox("Pixel Perfect##pixelpefect", &b) {
win.img.crtPrefs.Enabled.Set(!b)
win.img.displayPrefs.CRT.Enabled.Set(!b)
}
if win.img.crtPrefs.Enabled.Get().(bool) {
if win.img.displayPrefs.CRT.Enabled.Get().(bool) {
imgui.PushItemFlag(imgui.ItemFlagsDisabled, true)
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, disabledAlpha)
defer imgui.PopStyleVar()
@ -456,7 +456,7 @@ func (win *winPrefs) drawPixelPerfect() bool {
imgui.SameLineV(0, 25)
f := float32(win.img.crtPrefs.PixelPerfectFade.Get().(float64))
f := float32(win.img.displayPrefs.CRT.PixelPerfectFade.Get().(float64))
var label string
if f > 0.7 {
@ -471,7 +471,7 @@ func (win *winPrefs) drawPixelPerfect() bool {
imgui.PushItemWidth(imguiRemainingWinWidth() * 0.75)
if imgui.SliderFloatV("##pixelperfectfade", &f, 0.0, 0.9, label, 1.0) {
win.img.crtPrefs.PixelPerfectFade.Set(f)
win.img.displayPrefs.CRT.PixelPerfectFade.Set(f)
}
imgui.PopItemWidth()
@ -484,7 +484,7 @@ available when 'Pixel Perfect' mode is disabled.`)
func (win *winPrefs) drawVSYNC() {
imguiLabel("Recovery")
recovery := int32(win.img.crtPrefs.VSyncRecovery.Get().(int))
recovery := int32(win.img.displayPrefs.CRT.VSyncRecovery.Get().(int))
var label string
if recovery == 0 {
label = "sync immediately"
@ -493,7 +493,7 @@ func (win *winPrefs) drawVSYNC() {
}
if imgui.SliderIntV("##vsyncRecovery", &recovery, 0, 20, label, 1.0) {
win.img.crtPrefs.VSyncRecovery.Set(recovery)
win.img.displayPrefs.CRT.VSyncRecovery.Set(recovery)
}
win.img.imguiTooltipSimple(`The number of frames required for
the TV to recover after desynchronisation`)
@ -501,7 +501,7 @@ the TV to recover after desynchronisation`)
imgui.SameLineV(0, 15)
imguiLabel("Sensitivity")
sensitivity := int32(win.img.crtPrefs.VSyncSensitivity.Get().(int))
sensitivity := int32(win.img.displayPrefs.CRT.VSyncSensitivity.Get().(int))
if sensitivity == 1 {
label = fmt.Sprintf("%d scanline", sensitivity)
} else {
@ -509,7 +509,7 @@ the TV to recover after desynchronisation`)
}
if imgui.SliderIntV("##vsyncSensitivity", &sensitivity, 0, 4, label, 1.0) {
win.img.crtPrefs.VSyncSensitivity.Set(sensitivity)
win.img.displayPrefs.CRT.VSyncSensitivity.Set(sensitivity)
}
win.img.imguiTooltipSimple(`The number of scanlines that VSYNC

View file

@ -68,6 +68,12 @@ var defunct = []string{
"crt.syncSensitivity",
"sdlimgui.playmode.coprocDevNotification",
"sdlimgui.playmode.fpsOverlay",
"crt.brightness",
"crt.contrast",
"crt.hue",
"crt.saturation",
"sdlimgui.display.frameQueue",
"sdlimgui.display.frameQueueAuto",
}
// returns true if string is in list of defunct values.

View file

@ -51,7 +51,9 @@ func (ref *Reflector) AddRenderer(renderer Renderer) {
ref.renderer = renderer
}
// Clear existing reflected information.
// Clear existing reflected information. This doesn't need to be called that
// often and only when a new cartridge is inserted to make sure there is no
// stale data hanging around
func (ref *Reflector) Clear() {
ref.history = make([]ReflectedVideoStep, specification.AbsoluteMaxClks)
}

View file

@ -90,12 +90,12 @@ func (p *Preferences) SetDefaults() {
p.Freq.Set(snapshotFreq)
}
// Load disassembly preferences and apply to the current disassembly.
// Load rewind preferences from disk.
func (p *Preferences) Load() error {
return p.dsk.Load(false)
}
// Save current disassembly preferences to disk.
// Save current rewind preferences to disk.
func (p *Preferences) Save() error {
return p.dsk.Save()
}