Kotcrab.com

import com.kotcrab.Brain;

VisUI 1.3.0 Released, VisEditor Deprecated

VisUI 1.3.0 for latest libGDX 1.9.6 was released. Changes.

Version: 1.3.0 (LibGDX 1.9.6)

  • Added: VisUI#dispose (boolean disposeSkin)
  • Updated to libGDX 1.9.6
  • Excluded AsyncTask API from GWT compilation

I also have an announcement to make: I’ll be no longer maintaining VisEditor and VisRuntime projects. While it was my biggest project and one that was quite successful, it’s never reached the popularity I hoped for and was always surpassed by VisUI. It’s kind of funny considering that VisUI was indented to be internal part of VisEditor. I’d also like to move on to other projects. I feel like I’ve been stuck in the Vis world for too long.

I have to say thanks to everyone who contributed to it, whether it was issue reporting or creating pull requests and I’m sorry to everyone who hoped for more features. To make it clear this deprecation only applies to VisEditor, I’m still going to maintain VisUI project. However, VisUI has reached maturity some time ago and not much needs to be done to maintain it. I’m thinking about moving VisEditor sources to separate repository and renaming main repo to vis-ui. Still not sure, probably not worth it.

VisUI 1.1.2 Released

VisUI 1.1.2 was released. Release notes.

PSA: I’ll be no longer posting release notes on this site. They will be kept on GitHub releases page. You can follow me on Twitter if you want to get notified when I release new version of my libraries.

VisEditor 0.3.2 Released

VisEditor 0.3.2 was released. Download link

Editor Version: 0.3.2

  • Improved: Texture cache speed improved - new texture are available immediately after they are added to project assets. Fixes issues when large textures were loading infinitely.
  • Improved: Entity Properties will now show when field is locked and can’t be edited
  • Improved: When multiple entities are selected and ID is ambiguous then it will be marked in Entity Properties
  • Improved: If some scene assets are missing then dialog with missing files list will be showed
  • Added: #58 - Polygon auto tracing (available via Polygon Tool)
  • Added: Crash and internal exception reporter
  • Added: Option in default exporter to package separate texture atlas for each scene
  • Fixed: #130 - Exit dialog not showed on non Windows OSes
  • Fixed: Unable to open variables settings dialog for newly created scenes
  • Fixed: Minor bug: tabs panel wrong height
  • Fixed: Invisible TTF fonts
  • Fixed: Unable to change Z index and scale when using text entities with auto set origin to center enabled
  • Fixed: Undoing entity delete could place it at wrong position
  • Fixed: Crash when user tried to drag atlas region before any scene had been opened
  • Fixed: Twitter view URL parsing issues
  • Fixed: When opening new scene selection tool as used instead of currently active tool
  • Fixed: [https://github.com/kotcrab/vis-editor/issues/181] - invalid rotate and scale tools size when using non default pixels per unit values
  • Fixed: Error when opening project that doesn’t have vis/assets/gfx folder

Runtime Version: 0.3.2 (LibGDX 1.9.3, Artemis 1.3.1)

  • Updated to LibGDX 1.9.3
  • Updated Spine plugin to use spine-libgdx-runtime 3.2.0
  • Fixed: Changing entity tint could affect tint of all entities
  • Fixed: FitViewport was not applied when rendering
  • Fixed: Spine runtime was not allowing not use multiple instances of same animation with different scales
    • To get SpineAsset assets from AssetManager use spineAsset.getArbitrarySkeletonPath() instead of spineAsset.getSkeletonPath()
  • API Addition: Scene#getPixelsPerUnit(), #getWidth(), #getHeight()
  • API Addition: Tint#set(int rgba), Tint#set(float r, float g, float b, float a), Tint#set(Tint other)
  • API Addition: constructor VisSpriter (Loader<Sprite> loader, Data data, float scale, int entityIndex)

VisUI 1.1.0 Released

PSA: Please use hot fix version 1.1.1 as it fixes NullPointerException in FileChooser.

VisUI 1.1.0 was released.

Version: 1.1.0 (LibGDX 1.9.3)

  • API Moved: JNAFileDeleter was moved to vis-ui-contrib project
  • API Deprecated: FileChooser.setFavoritesPrefsName() replaced by FileChooser.setDefaultPrefsName()
  • API Changed: GridGroup is now taking float for item size instead of int.
    • Warning: There were two constructors GridGroup (float spacing) and GridGroup (int itemSize). Constructor taking float spacing was removed. Constructor taking int item size now takes float.
  • API Changed: Refactored FileChoose.FileIconProvider, new methods added. #provideIcon takes FileChooser.FileItem, was FileHandle
  • API Changed: Refactored VisCheckBox
    • Style was refactored to separate checkbox background and tick drawable (see below for full skin drawables changes)
    • VisCheckBoxStyle now extends TextButtonStyle, was CheckBox (fields was renamed to properly communicate their functions)
    • getImage() removed, use getBackgroundImage() or getTickImage()
    • getImageCell() removed, use getImageStackCell()
    • protected getCheckboxImage() removed, override getCheckboxBgImage() or getCheckboxTickImage()
    • getStyle() returns VisCheckBoxStyle, was CheckBoxStyle
  • Added: default styles for ImageButton and ImageTextButton. Note: this is only applies to standard scene2d widgets. VisUI widgets equivalents (VisImageButton, VisImageTextButton) already had them.
  • Added: SimpleFormValidator#validate
  • Added: ToastManager, Toast, ToastTable
  • Added: VisTextField read-only mode (VisTextField#setReadOnly(boolean))
  • Added: TabbedPane#getUIOrderedTabs()
  • Added: FileChooser#setFavoriteFolderButtonVisible(true) - FileChooser now can display ‘add folder to favorites’ button in the toolbar
  • Added: FileChooser#setPrefsName()
  • Added: FileTypeFilter, FileChooser#setFileTypeFilter(...)
  • Added: MenuItem#getSubMenuIconCell() and MenuItem#getShortcutCell()
  • Added: VisTextField#setEnterKeyFocusTraversal(boolean)
  • Added: VisTextField#setCursorPercentHeight
  • Added: PopupMenuListener
  • Added: PopupMenu#showMenu (Stage stage, Actor actor)
  • Added: ConstantIfVisibleValue
  • Added: Sizes#borderSize
  • Added: Sizes#fileChooserViewModeBigIconsSize, fileChooserViewModeMediumIconsSize, fileChooserViewModeSmallIconsSize, fileChooserViewModeListWidthSize
  • Changed: #169 - TabbedPane#getTable() returns TabbedPaneTable (holds reference to TabbedPane and allow to easily get its cells for customization)
  • Changed: FileChooser now tries to maintain selection while rebuilding file list
  • Changed: FileChooser will now select new folder after creating it
  • Changed: FileChooser will be automatically refreshed when added to Stage
  • Changed: FileChooser when typing file names manually suggestion will be showed
  • Changed: TabbedPane’s Tab now can’t be dragged using it’s close button
  • Changed: Synced VisTextField ans VisTextArea with equivalents of those classes libgdx
  • Changed: PopupMenu now support menu navigation using arrows keys
  • Changed: PopupMenu now optionally takes Sizes instance (added constructor PopupMenu (Sizes sizes, PopupMenuStyle style))
  • Removed deprecated API: NumberSelector - replaced by Spinner
  • Removed deprecated API: Sizes#numberSelectorButtonSize, numberSelectorButtonsWidth, numberSelectorFieldSize, numberSelectorFieldRightPadding
  • Fixed: Sizes.buttonBarSpacing was ignored by ButtonBar
    • Added: constructors ButtonBar(Sizes sizes, String order) and ButtonBar(Sizes sizes)
  • Fixed: TabbedPane layout when no separator image was used. Fixed misc issue with close button style on touch down.
  • Fixed: FileChooser NPE when error occurred during directory deleting
  • Fixed: FileChooser non empty directories are now deleted correctly when using default FileChooser deleter
  • Fixed: FileChooser crash when user manually entered path to file instead of directory
  • Fixed: FocusManager calling focusLost() when the widget that was already focused tried to gain focus again
  • Fixed: VisSplitPane was not implementing hit(...) which could result in widget that was underneath split pane’s handle get touch events
  • Fixed: Now it’s not possible to call VisWindow#fadeOut multiple times
  • Skin changes:
    • Changed: FileChooserStyle: added drawable fields: iconStar, iconStarOutline, iconRefresh, iconListSettings, expandDropdown
    • Added: drawable window-border-bg.9, icon-star, icon-star-outline, icon-refresh, icon-list-settings
    • Added: style BaseToastStyle
    • Added: VisTextField label style - if combined with read-only mode allows to create selectable labels
    • Updated: cursor drawable (cursor.9.png)
    • Removed: check-down-on, check-down, check-on-disabled, check-over-off, check-over-on, radio-down-on, radio-down, radio-on-disabled, radio-over-off, radio-over-on
    • Added: vis-check, vis-check-over, vis-check-down, vis-check-tick, vis-check-tick-disabled, vis-radio, vis-radio-over, vis-radio-down, vis-radio-tick, vis-radio-tick-disabled
  • I18N Changes:
    • FileChooser: added keys contextMenuRefresh, fileType, allFiles, changeViewMode, viewModeList, viewModeDetails, viewModeBigIcons, viewModeMediumIcons, viewModeSmallIcons
  • Misc: Added Gradle tasks to package VisUI skin textures and compile USL into JSON (gradlew :ui:compileSkin)

VisUI 1.0.2 Released

VisUI 1.0.2 was released. Also checkout new vis-ui-contrib project which has more extensions for VisUI and some custom skins.

Version: 1.0.2 (LibGDX 1.9.2)

  • Changed: #163 - When VisCheckBox or VisTextField is disabled and is marked as invalid then error border won’t be drawn.
  • Changed: #163 - Added SimpleFormValidator#setTreatDisabledFieldsAsValid (and it’s getter) - allow to control whether to mark form as invalid when invalid but disabled field is encountered. If set to true then all disabled fields are treated as valid, regardless of their state.
    • Defaults to true! Set to false to preserve old behaviour.
  • API Changed: DragListener: Draggable argument was added to each method
  • API Deprecated: Sizes#numberSelectorButtonSize, numberSelectorButtonsWidth, numberSelectorFieldSize, numberSelectorFieldRightPadding replaced by spinnerButtonSize. spinnerButtonsWidth, spinnerFieldSize, spinnerFieldRightPadding
  • API Deprecated: NumberSelector - replaced by Spinner, NumberSelector will be removed in future version
  • Added: VisTextField#isTextSelected()
  • Added: VisTextField#clearText()
  • Added: FloatingGroup
  • Added: VisWindow#isKeepWithinParent and VisWindow#setKeepWithinParent
  • Added: constructor VisImage (String drawableName)
  • Added: VisUI.load(String internalVisSkinPath)
  • Added: VisTextField#setIgnoreEqualsTextChange(...) - see #165
  • Fixed: OptionDialog#set(...)ButtonText now updates dialog size
  • Fixed: #131 - fixed issue when copying numbers between VisTextFields with FloatDigitsOnlyFilter decimal point was lost
  • Fixed: ListView#AbstractListAdapter error on GWT
  • Fixed: VisTextField was changing system cursor when it was disabled
  • Fixed: #165 - fixed form not refreshed when text field content was changed to the same as before

What I Learned From Game Boy Emulator Development

For some reason I wanted to make emulator for a really long time. There’s something entrancing about this idea that you need to write code to emulate original hardware. It’s quite hard project but it’s certainly fun and rewarding, if you are filling confident enough then definitely try making one!

I’m currently working on Game Boy emulator written in Kotlin using libgdx (cross platform game framework) and VisUI (my UI toolkit). In current state it has fully working CPU emulation (passes cpu_instrs and instr_timing tests), has integrated debugger and simple VRAM viewer. I’ll be focusing on GPU emulation now. Entire project is open source on GitHub so you can check it out here. In this post I would like to focus on general points and observations I made during making this project. I’ll focus more on technical details in next post.

How do I make emulator

Basically you need to write software equivalent of all original hardware parts, certainly biggest of which would be CPU. You start by collecting information about platform you want to emulate - in case of Game Boy it’s quite well documented so this wasn’t hard. I found CPU manual, opcodes tables, official Nintendo development manual. There is also a lot of forum posts (and StackOverflow questions) from people who attempted this task. Then you write CPU emulation, and then implement more and more components: memory controllers, timers, GPU, input, serial port, audio processing unit and so on.

You may be wondering what knowledge do you need to have to make emulator. Do you need a lot of background in low level programming? Not really, you don’t even have to know how to make games on the platform you want to emulate. While it certainly helps that you know even the basic of Assembler etc., it is not needed and with enough self-denial you can learn things while you are making your emulator. That said this is not a project that you should make using unknown language, libraries and tools - stick with what you know. I kind of ignored this by using new language - Kotlin however it is easy enough to pick up if you know Java, and has pretty much the same tooling (IDE, build system) so it wasn’t that bad.

Choosing platform to emulate

Try not to pick up too complicated platform or you simply won’t be able to make it. I’ve often seen Chip-8 recommended as starting emulator, it is quite simple and should give you nice overview on how to start creating more complicated emulators. You can also be like me and go directly for something more complicated like the Game Boy. I’ve chosen it mainly because of my sentiment for this console - I still own working Game Boy Pocket with few games.

Tips

Get test ROMs

You will need to test your emulator somehow, of course you can use standard game ROMs but those won’t test it comprehensively. In case of Game Boy it’s very easy - there are test ROMs that were made to specifically test various part of hardware, CPU, timings, sound and so on. They don’t even need an display to run, they output information to serial port which is easy to emulate and some of them write test result in specific position in RAM. From those ROMs my emulator currently passes cpu_instrs and instr_timing tests. cpu_instrs tests almost every op code of CPU, instr_timing tests well.. instruction timing. And if you haven’t know timing is important when emulating something.

Don’t leave stuff half working

In Game Boy there is this thing called Memory Bank Controller (MBC). CPU addressing space is limited, if game is huge and it can’t fit into 32 KB, MBC is used to allow access to other ROM banks by switching available ROM bank at specific memory address. When running cpu_instrs my emulator was stuck in loop, infinitely running next tests even though there are only 11 test sections. Turned out it wasn’t CPU issue and anything like that but unfinished implementation of MBC1 which did not allowed to switch ROM bank. It resulted in the same code being executed over and over. Lesson? Don’t do that or at least try not to, this can lead to very unexpected issues which may took much time to debug.

Create debugger

This is a must, if you want to efficiently find issues you will need a debugger. Even the simple one is fine, if you can pause execution and step through instructions it will be great help. I’ve observed interesting thing, Run to Line function was more helpful that breakpoints, so much that I haven’t even finished implementing breakpoints. You can see my debugger here. It is showing currently executed op codes, stack, CPU registers and flags status. You can also go to entered memory address and by right clicking instruction run emulator until that instruction is reached. I’ll leave details how exactly debugger is interacting with emulator for another article.

Use multiple info sources

I already mentioned this but it is really important, Game Boy is well documented but I was quite surprised to find so many discrepancies, seriously:

  • This is wrong - opcode E2 and F2 is 1 byte long, not 2. This single thing caused instr_timing to loop infinitely and took few hours to debug. I found out that only source that you can trust for instruction length and timing is the instr_timing test itself. You can get valid values from it’s source code. That site also get few timings for CB instruction wrong if I remember correctly but that is easy enough to find with instr_timing and not so devastating as wrong instruction length.
  • Some errors I found in CPU manual:
    • Timing for conditional instruction are completely wrong, it ignores the fact that the timing is different depending on whether action was taken or not.
    • HALT procedure description skips very important thing that interrupt will always wake up CPU, even if Interrupt Master Enable (IME) flag is not set.
    • Some instruction are missing details on how they affect CPU flags, instead you get: Flags affected: H: Set or reset according to operation - good luck figuring that out.

Use another working emulator

You can use another already working emulator with it’s debugger to test if your emulator is behaving (more or less) the same. Sure you may want not to do that, thinking it will make it too easy (it won’t). This can be somewhat compared to testing on real hardware although made much much easier.

That’s it for the introduction, my tweet gained some attention so I’ll probably write another post explaining more technical details of my emulator.

VisUI 1.0.1 Released

VisUI 1.0.1 was released which fixes few bugs and GWT issue.

Version: 1.0.1 (LibGDX 1.9.2)

  • Added: ListView#getListAdapter()
  • Added: ListView#rebuildView() and UpdatePolicy.MANUAL
  • Added: Draggable#setDeadzoneRadius
  • Fixed: Not being able to resize window with TabbedPane
  • Fixed: OptionDialog not modal by default
  • Fixed: SimpleListAdapter not working on GWT
  • Fixed: VisCheckBox focus border appeared was displayed in wrong place when using Cell#growX()
  • Changed: DragPane: LimitChildren listener now never rejects own children, even when max children amount is achieved.
  • API Changed: ListView#getMainTable() now returns ListViewTable<ItemT> instead of VisTable
  • API Changed: Added ListAdapter.add(ItemT)

VisEditor 0.3.1 Released

VisEditor 0.3.1 was released. Download link

Editor Version: 0.3.1

  • Added: Scale entities tool
  • Added: Rotate entities tool
  • Added: It’s now possible to set scene variables, added “Scene Variables” dialog
  • Added: New command line arguments: --project and --scene for auto loading project
  • Fixed: Wrong entities position after opening same scene for the second time
  • Fixed: Sprite flip Y property was ignored after reloading scene (#103)
  • Fixed: Missing “Enter into Group” button after right clicking entities group (#102)
  • Fixed: Exporting scenes which had used groups with string id’s set (#104)
  • Fixed: Editor crash after undoing changes made in Entity Properties dialog (#106)
  • Fixed: Random editor crashes when working with multiple layers and groups (#104)
  • Fixed: Fixed some key shortcuts not working on locked layers (#109)
  • Fixed: Issues with bounding box problems after undo (#108)
  • Fixed: Negative y origin on text when using “Auto set origin to center”
  • Improved: Rectangular selection is much faster when selecting many entities
  • Removed: Optional usage analytics

Runtime Version: 0.3.1 (LibGDX 1.9.2, Artemis 1.3.1)

  • Updated to LibGDX 1.9.2 and Artemis 1.3.1
  • API Deprecated: SceneConfig#addSystem(BaseSystem system), SceneConfig#addSystem(BaseSystem system, int priority) and SimpleSystemProvider
    • Use SceneConfig#addSystem(Class<? extends BaseSystem> system) and SceneConfig#Class<? extends BaseSystem> systemClass, int priority
    • Adding system in 0.3.0: parameter.config.addSystem(new MySystem())
    • Adding system now: parameter.config.addSystem(MySystem.class)
    • If you need to pass custom arguments to system constructor implement SystemProvider directly.
  • API Change: Variables#variables field is now final
  • API Change: SceneConfig.Priority is now an enum (should not require any code change)
  • API Changes in EntitySupport:
    • If you were using it to register custom renderer use parameter.config.addSystem(SystemProvider)
    • Removed registerSystems(...)
    • Added registerSceneSystems(SceneConfig)
  • API Addition: Variables#put, putInt, putFloat, putBoolean methods for adding new variables
  • API Addition: Variables copy constructors and Variables#setFrom(Variables) method
  • API Addition: Scene#getSceneVariables returns scene variables set from VisEditor
  • API Addition: new Transform constructors
  • Fixed: SystemProvider interface is now public

VisUI 1.0 Released

VisUI 0.0.1 was released on 5th November 2014. Initially meant to be internal VisEditor UI library now became my most popular project, getting about 1500 downloads each month.

Today I can finally announce that VisUI 1.0.0 has been released. Does that mean anything significant? Not really, maybe I will try make less breaking changes now. I’m glad that I was able to work on this project for such long time. I would also like to thanks everyone who contributed to Vis project, either by reporting issues or by creating pull requests.

So, let’s see what new 1.0 has to offer:

  • ListView - creating advanced lists, powerful and flexible. More

  • ButtonBar - creating button panels with buttons such as “Ok”, “Cancel”, “Yes” in platform dependent order. More

  • Bug fixes and breaking changes - more details in changelog.

Full changelog:

Version: 1.0.0 (LibGDX 1.9.2)

  • Changed: InputValidator moved to com.kotcrab.vis.ui.util package
  • Changed: LesserThanValidator#setEquals(boolean) renamed to setUseEquals
  • Changed: GreaterThanValidator#setEquals(boolean) renamed to setUseEquals
  • Changed: FormInputValidator#validateInput is now final and can’t be overridden
  • Changed: FormInputValidator#getLastResult is now package-private
  • Changed: DialogUtils renamed to Dialogs
    • Changed: DialogUtils.properties is now Dialogs.properties
    • Changed: VisUI#setDialogUtilsBundle(...) is now VisUI#setDialogsBundle(...)
    • Changed: VisUI#getDialogUtilsBundle() is now VisUI#getDialogsBundle()
    • Added: showDetailsDialog (Stage stage, String text, String title, String details)
    • Added: showDetailsDialog (Stage stage, String text, String title, String details, boolean expandDetails)
  • Changed: ErrorDialog renamed to DetailsDialog
    • Changed: Constructor ErrorDialog (String text, String stacktrace) changed to DetailsDialog (String text, String title, String details)
    • Added: DetailsDialog#setDetailsVisible(...)
    • Added: DetailsDialog#setCopyDetailsButtonVisible(...)
  • Changed: FileChooserText, FilePopupMenu and ColorPickerText moved to internal subpackages (were not part of public API)
  • Changed: FileChooser#getFileDeleter removed
  • Changed: FileChooserListener was refactored
    • FileChooserListener#selected(FileHandle) removed
    • If user can select single file use SingleFileChooserListener
    • If user can select multiple files use StreamingFileChooserListener or use FileChooserListener directly
  • Changed: VisTextField#toString() now returns field text
  • Changed: OptionDialog now extends VisWindow (was extending VisDialog)
  • Changed: OptionDialog and InputDialog now will show buttons in platform dependant order using ButtonBar
  • Removed: Removed all Tooltip constructors except those taking style
    • Use new Tooltip.Builder(...) eg. new Tooltip.Builder("Tooltip Text").target(label).build()
    • Changed: constructor Tooltip (String text) is now Tooltip (String styleName)
    • Added: constructor Tooltip ()
    • Added: constructor Tooltip (TooltipStyle)
  • Removed: SeparatorStyle#vertical, was not used
  • Removed: constructor Separator (boolean vertical)
  • Added: ListView and ItemAdapter API
  • Added: constructor TabbedPane(TabbedPaneStyle style, Sizes sizes)
  • Added: constructor VisWindow(String title, String styleName)
  • Added: PrefWidthIfVisibleValue
  • Added: HorizontalFlowGroup and VerticalFlowGroup
  • Added: ButtonBar - convenient class for creating button panels arranged in platform dependant order.
    • FileChooser, ColorPicker and Dialogs will now show buttons in platform dependant order
  • Added: LinkLabel, VisTextField, VisTextArea and VisSplitPane supports system cursors when using LWJGL3 or GWT backend
  • Fixed: TabbedPane: Tab close button too small when using SkinScale.X2
  • Fixed: TabbedPane: In vertical mode, tabs buttons were centered instead of being aligned at the top
  • Removed deprecated API: ColumnGroup (use libGDX’s VerticalGroup)
  • Skin:
    • Changed: Color menuitem-grey renamed to menuitem
    • Changed: TabbedPaneStyle#bottomBar renamed to separatorBar
    • Removed: FormValidatorStyle#colorTransition, no longer needed.
      • If colorTransitionDuration is set to 0 then transition will be skipped.
    • Removed: SeparatorStyle#vertical, no longer needed
    • Added: Drawables: grey, vis-blue, vis-red
    • Added: New Window style: resizable
  • I18N:
    • Changed Bundle management moved to Locales class. Instead of calling VisUI.setXYZBundle(...) call Locales.setXYZBundle(...)
    • Removed: Dialogs bundle entries: yes, no, cancel, ok. Now handled by ButtonBar bundle.

Happy coding!

VisEditor 0.3.0 Released

VisEditor 0.3.0 was released. This release is aimed at cleaning up and improving runtime API so there aren’t many new editor features. Those will be added in upcoming 0.3.1. Some biggest changes:

  • Runtime API was cleaned up and improved, components classes were renamed.
  • Bigger control of how Scene systems are loaded, eg. you can set priorities and disable built-in systems.
  • Editor scenes are now saved using JSON format.
  • You can store multiple assets types in single directory.
  • Runtime was updated to latest Artemis 1.2.1 (0.2.x were running on 0.13.x) and libGDX 1.7.1

If you have existing 0.2.x project then you will need to convert it. There are quite many breaking API changes but it should not be very hard to update. See runtime changes for starting point.

As always please report any issues you have found, especially those in 0.2.x project converter. Enjoy!

Useful links:

If you need 0.2.x support: