Thursday, June 1, 2023

Sega Console Game Port

In 2017, we checked out devkitSMS Programming Setup to build code in C for the 8-bit Sega Master System. Then, in 2020, we checked out SGDK Programming Setup to build code in C for the 16-bit Sega Mega Drive.

Leveraging this knowledge, we would now like to port existing code built for the 8-bit Sega Master System, for example, Simpsons Trivia SMS to the 16-bit Mega Drive Simpsons Trivia MD and document the process.
 SEGA MASTER SYSTEM [256 x 192]  SEGA MEGA DRIVE [320 x 224]
Let's check it out!

Software
Follow most instructions from the previous post: this documents how to setup some pre-requisite software.

Here is a summary of some of the software to be installed:
 Name Version
 C IDE Editor Visual Studio 2015
 Emulators Fusion, Gens KMod
 
 Name Version
 Cross compiler GCC
 Make files Cygwin


Setup Project
Create folder C:\SimpsonsTriviaMD. Copy new SGDK custom library lib folder here. Create sub-folder: dev. Change directory to dev folder and create the following sub-folders as indicated per Usage: inc, out, res, src


Launch Visual Studio 2015. File | New | Project... | Visual C++ | Win32 | Win32 Project

 Name:  Game
 Location:  C:\SimpsonsTriviaMD\dev
 Create directory for solution  UNCHECKED
OK

 Application type:  Console application
 Additional options:  Empty project CHECKED
Finish

First, remove x64 build configuration! Right click Solution | Properties. Click Configuration Manager button. Click Active solution platform drop down | Edit. Click x64 option | Remove. Now will have only Win32 build.

Right click Project | Properties | Configuration Properties | General. Set Output and Intermediate directories:

 Output Directory:  $(SolutionDir)..\bin\$(ConfigurationName)
 Intermediate Directory:  $(SolutionDir)..\obj\$(ConfigurationName)

Right click Project | Properties | Configuration Properties | C++ | General. Set Additional Include Directories:

 Value:   $(SolutionDir)..\lib;$(ProjectDir)inc;$(ProjectDir)res;$(GDK_WIN)\inc;$(IncludePath)

Right click Project | Properties | Configuration Properties | Linker | General | Additional Library Directories:

 Value:   $(SolutionDir)..\lib

Right click Project | Properties | Configuration Properties | Linker | Input. Set the Additional Dependencies:

 Value:   _genesis.lib;%(AdditionalDependencies)

The final solution should look like this:


Setup Resources
Import all resources into your project as media files that your game will use such as images for background tiles + sprites, audio for music + sound effects etc. Clone the "Setup Project" folder and follow these steps:

Change directory to res folder under dev folder. Copy all resources here. Create corresponding *.res files. Next execute build.bat to compile all resources then generate all corresponding gfx and sfx header files.

Create folder gfx at same level as dev folder. Create sub folder res. Add dummy corresponding translation unit files under res sub folder. Repeat process with sfx folder. Import all translation units into Visual Studio.


Setup Folders
Larger game projects will require nested folders in the inc or src directories to organize engine and screen code etc. Clone the "Setup Resources" folder and add all necessary subfolders + then update the makefile.

Launch Visual Studio and include resource files as before. Next, scale out engine and screen code but now organize into subfolders. Create as New Filters under Visual Studio Header Files and Source Files solution:

Create corresponding engine and screen subfolders beneath inc folder under dev. Add header files. Create engine and screen subfolders beneath src folder under dev. Add all the corresponding translation unit code.

Right click Project | Properties | Configuration Properties | C++ | General. Set Additional Include Directories:

 Value:   $(SolutionDir)..\lib;$(ProjectDir)inc;$(ProjectDir)res;$(GDK_WIN)\inc;$(IncludePath);
 $(ProjectDir)inc\engine;$(ProjectDir)inc\object;$(ProjectDir)inc\screen

Customize the makefile.gen file to include the new subfolders accordingly. Copy %GDK_WIN%\makefile.gen to local dev folder. Update makefile: Add new $(wildcard $(SRC)/ and -I$(INCLUDE) entries per folder.

Update dev built.bat file to use new local custom makefile.gen instead of de-facto %GDK_WIN% version.
If you remove pre-build step to speed up makefile build then don't forget to create out subfolders manually.


Convert APIs
Finally, copy over all engine, object, screen etc. files from the Sega Master System code base into the Sega Mega Drive port. Convert all devkitSMS APIs to the SGDK equivalents. Allow for different screen resolution!

Here is quick cheat of devkitSMS to SGDK API conversions; of course not all APIs are one-to-one mapping:
   SEGA MASTER SYSTEM  SEGA MEGA DRIVE
 Audio  PSGPlay();
 PSGStop();
 PSGGetStatus();
 XGM_startPlayPCM();
 XGM_stopPlayPCM();
 XGM_isPlayingPCM();
 Dimensions  256 x 192 [32x24]
 320 x 224 [40x28]
 Font  SMS_setNextTileatXY();
 SMS_setTile();
 VDP_setMapEx();
 
 Graphics  SMS_loadPSGaidencompressedTiles();
 SMS_loadBGPalette();
 VDP_drawImageEx();
 VDP_setPalette();
 Hack  Address : 0x0050
 Address : 0x01E0
 Input  SMS_getKeysStatus();
 JOY_readJoypad();
 Random  rand();
 random();
 Sprites  SMS_addSprite();
 SMS_copySpritestoSAT();
 SPR_addSprite();
 SPR_update();


Summary
Repeat process with Skazka. In summary, the Master System to Mega Drive port should be fairly seemless J
 SEGA MASTER SYSTEM [256 x 192]  SEGA MEGA DRIVE [320 x 224]

Monday, May 1, 2023

Lil Evel Knievel Code Complete

A tribute to the greatest daredevil! Lil Evel Knievel is a continuous side-scrolling skateboard platformer video game set in the original Wonderboy aquazone. Lil EK is also an SMS Power! 2023 coding competition entry.

Let's check it out!

Note: all Lil Evel Knievel development is based on devkitSMS Programming Setup and Programming Sample.
Download source code here.


Instructions
Lil Evel Knievel V1.0 game play is very open and simple due to the aggressive coding competition deadline: jump over varying platform gaps and pull off cool skateboard flips and trick combos to complete each level.

There are four jump categories on ground: Skip, Jump, Leap, Hurl. Once airborne, Lil EK can swap direction or flip somersault. Move opposite direction while airborne inverts somersault and down to accelerate land.
 Jump Categories On Ground
 SKIP Smallest Left + Fire1 
 JUMP Standard Left + Fire2 OR Fire1
 LEAP Sizeable Right + Fire1 OR Fire2
 HURL Colossal Right + Fire2 
 Jump Activities Airborne!
 SWAP Direction Fire1 
 FLIP Somersault Fire2 

Tools
Here is a list of Tools and frameworks that were used in the development of this project:
 KEY  VALUE
 Programming  devkitSMS
 Compiler  sdcc 4.1.0
 Assembler  WLA-DX
 IDE  Visual Studio 2015 / Visual Studio Code
 Languages  C / Z80
 Graphics  BMP2Tile 0.43 / GIMP 2 / paint.net
 Music  pcmenc / vgm2psg
 Emulators  Emulicious / Fusion / Meka
 Debugger  Emulicious Debugger

ROM Hacking
You can hack this ROM! Download and dump Lil Evel Knievel into Hex Editor, e.g. HxD, and modify bytes:
 ADDRESS  VARIABLE  DESCRIPTION
 0x004F  Delay  Used to speed through any game delay.
 0x0050  Invincible  Non-zero value enables invincibility.
 0x0051  Gravity Jump  Jump once while falling from gravity.
 0x0052  HarderLands  Tougher platform collision detection.
 0x0053  Music Off  Set 0=Music to play otherwise silent.
 0x0054  Sound Off  Set 0=Sound to play otherwise silent.
 0x0055  Riffs Off  Set 0=Riffs to play otherwise silent.

Hints
  • Four difficulty options: Easier, Normal, Harder, Insane. Difficulty increase = Visibility descreases
  • Watch out for repetitive single turtles mixed in platforms as this can indicate large Leap or Hurl
  • Favour Hurl for medium sized gap with opposite move direction to land inverted somersault OK
  • Leverage down action on descent to land especially if you start to overshoot the target platform

Audio
Lil Evel Knievel includes digitized sound extensively by leveraging the pcmenc tool and uses development techniques outlined in devkitSMS Programming Sample under PCM Samples section. Some riffs you may have missed include: AC/DC, Austin Powers, Gn'R, Simpsons, Van Halen, Wayne's World, WWF Wrestling.

Music is often easy to neglect in a time pressure coding competition but Lil EK has been quoted as having "perhaps the single most impressive audo soundtrack the little PSG has ever seen".

Commands
The Command design pattern encapsulates a command request as an object. In game code, an example of a command request could be a move command: e.g. move sprite left, right or jump command flip, swap etc.

Coindentally, Lil EK uses 8x commands therefore each command stored as single bit mask; all 8x commands stored within a single byte. This way, combos can be bitwised detected rather than flattened out individually.
 #define COMMAND_LEFT_MASK 0b00000001
 #define COMMAND_MIDD_MASK 0b00000010
 #define COMMAND_RGHT_MASK 0b00000100
 #define COMMAND_HIGH_MASK 0b00001000
 #define COMMAND_DOWN_MASK 0b00010000
 #define COMMAND_JUMP_MASK 0b00100000
 #define COMMAND_SWAP_MASK 0b01000000
 #define COMMAND_FLIP_MASK 0b10000000

Critical to the development process, streams commands can be issued to the game engine for debugging all possible game play scenarios. Plus commands can be recorded for playback to show case instructional demo!


Physics
Game physics are aptly based on the "The Motorcycle Daredevil" projectile motion practice problem. Here are player angle / speed combinations to produce four jump types nicknamed Skip, Jump, Leap and Hurl.
 Type  Angle  Speed  Horizontal  Vertical  Max Frames
 SKIP 45 30 92 23 53
 JUMP 45 40 163 41 81
 LEAP 45 55 309 77 133
 HURL 40 65 425 89 177

Sprites
The Title screen uses Zoom sprites in which the 24x32 player sprite is magnified as a 48x64 sprite. However, SMS I has a bug in how the VDP processes zoomed sprites. Therefore, to circumvent the VDP bug you have to draw 4x additional sprites on the same Y coordinates of the original sprites as seen in title_screen.c file.

YouTube
YouTube videos showcasing all SMS Power! 2023 coding competition entries including some with long play:

 TITLE  AUTHOR
 New Master System Games for 2023  Dudley of Yesterzine
 The Ultimate SMS Coding Showdown  CrossGenGameplay
 Présentation SMS Power Competition  Révo SEGA 8-bit
 Master System Game Lil Evel Knievel  Genesis 8:14

Summary
There has been progressive interest in Sega Master System Homebrew as coding competition entries become more impressive. Unfortunately due to time constraints, the game mechanics and level design were not able to be fully developed at this time. However the foundation for potential future development did receive some incredible feedback from the community and Sega 8-bit preservation and fanaticism fans. That is awesome!

Sunday, January 1, 2023

Retrospective XIV

Last year, I conducted a simple retrospective for 2021. Therefore, here is a retrospective for 2022.

2022 Achievements
  • Upgrade devkitSMS setup to SDCC 4.x support Windows and Linux projects cross platform
  • Re-write devkitSMS samples SDCC 4.x compatiblility in graphics, PCM sampling + banking
  • Enter Skazka 1.0 game in SMS Power! 2022 competition converted as Sega SC-3000 code
  • Collaborate with Kagesan at SMS POwer! adding graphics to all screens Skazka 2.0 update
  • Port Skazka 2.0 to the Sega MegaDrive/Genesis using very similar C development process
  • Complete Linux setup on real dedicated Ubuntu Linux workstation / Windows PC dual boot
  • Compile Golang cheat sheet developing scalable + concurrent cloud computing application
  • Extends Golang cheat sheet integrating Go, C, Cgo, and Assembly language code samples
Note: extending Golang development environment to target Go, C, Cgo, and Assembly is an achievement!

2023 Objectives
  • Explore more Sega Master System and Sega MegaDrive sound, graphics and scrolling capabilities
  • Document porting Sega Master System to Sega MegaDrive / Genesis processes for future project
  • Collaborate more over open source projects and communities potentially in professional capactiy
  • Apply Golang C, Cgo, Assembly integration for low level Window and Linux applications like eBPF

Collaboration
In 2021, I was fortunate enough to collaborate with members of the SMS Power! community on an Indie game project. In 2022, I was fortunate enough again to collaborate with members of SC-3000 Survivors Facebook group and port Skazka as a Slavic RGP Adventure game to the Sega Master System.

Later on in 2022, I was fortunate to collaborate with Kagesan at SMS POwer! in order to add graphics to all screens in Skazka. Finally, Skazka was ported to Sega Mega Drive with help of the MegaDrive community.

Future
Ultimate goal would be to apply skills learned from C/ASM Sega Master System programming and some Sega MegaDrive to real world professional development. Of course, this is very niche and non-profitable!

However, low level systems application programming like eBPF, in Linux, is perhaps one of the very few development experiences available in modern day professional Software Engineering that it's similar in stature! Therefore, I believe this is something definitely worth investigating more in the coming year J

Tuesday, November 15, 2022

Golang Cheat Sheet II

In the previous post, we checked out Go as a statically typed and compiled programming language designed at Google. Go is gaining popularity due to its ability to deliver highly scalable concurrent computing software.

Development teams prefer Golang to harness the power of large servers and sophisticated cloud platorms. Go can be used in mobile, web and simple game development and can also invoke C code directly via Cgo.

Let's check it out!

Example
In the previous post, we created a simple Hello World example by setting up the development environment, create a Go module with the code and issue go build and run commands to execute the Hello World program

Modules
A module in Go is a collection of Go packages stored in a file tree with a go.mod file at its root The go.mod file defines the module's path, which is also the import path used for the root directory, and its dependency requirements which are other modules needed for a successful build.

A module is defined by a UTF-8 encoded text file named go.mod in its root directory. Here are some usages:
 go get  Updates module dependencies in the go.mod file
 go install  Builds and installs the packages named by paths
 go list -m  Lists all the modules instead of all the packages
 go mod download  Downloads named modules into the module cache
 go mod init  Initializes + writes new go.mod file in the current directory
 go mod tidy  Ensures the go.mod file matches source code in the module

Packages
Go programs are built by linking together packages. A package is constructed from one or more source files that declare constants, types, variables and functions belonging to the package to which are accessible in all files of the sams package. Those elements may be exported and used in other package(s).

Functional Programming
Functional programming is the paradigm that treats computation as the evaluation of functions and avoids state and mutable data as opposed to imperative programming which empathizes change of state. Without shared data, concurrency becomes easier because this means no locks, race conditions, no dead locks etc.

Concurrency
Concurrency is the "composition of independently executing computations". Concurrency: dealing with lots of things at once but parallelism: about doing lots of things at once. Concurrency is all about structure whereas parallelism is about execution. Consequently, Golang provides first-class language support for concurrency.

Challenges in concurrent programming include co-ordinating tasks + shared memory. Thus, Go concurrency implementation centers around goroutines: functions that execute simultaneously in Go program with other (goroutine) functions and are lightweight threads managed by the Go runtime. Here are some more terms:

 Concurrency  Ability to have multiple things that can be worked on not necessarily at the same time
 Parallelism  Ability to work on multiple concurrent tasks typically all worked on at the same time
 Process  Part of the Operating System resposible for executing an application
 Thread  Unit within the process which executes the code inside an application
 Goroutines  Special function type that can run while other goroutines are running
 WaitGroups  Allows a supervising goroutine to wait on several other go routines
 Mutexes  Allow us to share memory between go routines and our application
 Channels  Another mechanism available to us to coordinate the work between multiple goroutines

Concurrency in Go is also based on Communicating Sequential Processes. CSP is a form to describe patterns of interaction in concurrent systems. CSP involvement in concurrency based on messaging passing channels. Channels in Go allow goroutines to communincate with each other safely + co-ordinate work between them.

Demos
 Introduction  Goroutine ID
 Goroutines  Sequential code, Creating goroutines
 Sync Package  Using WaitGroups, Mutexes, Read/Write Mutexes
 Channels  Unbuffered channels, Buffered channels, Channel types
 Working with closed channels, Using select statements

IMPORTANT
If you are new to goroutines then you may like to log go ID() similar to logging thread ID in multithreading:
go mod init goidtesting
go get "github.com/nikandfor/goid"
go mod tidy
main.go
package main
import (
	"fmt"
	"os"
	"time"
	"github.com/nikandfor/goid"
)
func say(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		_, _ = fmt.Fprintln(os.Stdout, goid.ID(), s)
	}
}
func main() {
	go say("world")
	say("hello")
}
Data Race
A data race occurs when two goroutines access the same variable concurrently and are very hard to debug:
 go run -race mysrc.go // to run the source file
 go build -race mycmd // to build the command
 go install -race mypkg // to install the package
 go test -race mypkg // to test the package

Unit Testing
Unit testing in Golang uses the testing package however more sophisticated Test Driven Design TDD / BDD can be accomplished using the Ginkgo testng framework complemented by the Gomega matching library.

However, unit testing concurrent code in Go is more challenging esp. anonymous goroutines as they are not executed immediately. Instead the calling thread keeps execution priority until it pauses. Only then will the code inside the goroutine get execution. Therefore, a solution could be insert an empty function which acts as a hook for testing purposes; push a value into a channel which blocks until received + TEST code passes.

Cloud Computing
Cloud computing systems are highly scalable that require access to resources which must be shared. Thus, Golang has the capability to develop highly scalable, highly performant, reliable and concurrent applications.

Consequently, Go is often preferred to build tools for distributed systems and containerized applications such as Docker and Kubernetes because of Go's fast compilation, low-level system calls and concurrency features.

Cgo
Cgo lets Go packages call C code. Cgo outputs Go and C files that can be combined into a single Go package.

Hello World
 hello.go  hello.h  hello.c
 package main
 import "fmt"

 // #include "hello.h"
 import "C"

 func main() {
 	fmt.Println("begin")
 	C.hello()
 	fmt.Println("-end-")
 }
 #ifndef _HELLO_H_
 #define _HELLO_H_

 #include <stdio.h>

 void hello();

 #endif//_HELLO_H_
 #include "hello.h"

 void hello()
 {
     fprintf(stderr, "%s\n", "Hello Cgo!");
 }
According to this thread, it is possible to debug Go to C from Visual Studio Code on Linux. Assuming you can F5 run the project then set breakpoints either side the Go code calling into and out of the C function to step.


Mod Security
In the previous post, we coded an example in Go from scratch as full end-to-end Web API demo on our local host, in Docker and on Kubernetes. Extend this example as Web Application Firewall using Mod Sec and Cgo.

Install Mod Security on local host
 git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
 cd ModSecurity
 git submodule init
 git submodule update
 ./build.sh
 ./configure
 make
 sudo make install
Follow all instructions from the example i.e. download OWASP rules, build main, server and waf code. Here, it is critical for Go to C interface to set include + linker flags correctly avoiding runtime PATH for shared libs!

waf.go
 package waf
 // #cgo CFLAGS: -I/usr/local/modsecurity/include
 // #cgo LDFLAGS: -L/usr/local/modsecurity/lib/ -Wl,-rpath -Wl,/usr/local/modsecurity/lib/ -lmodsecurity
 // #include "waf.h"
 import "C"

Asm
Finally, if you would like to reproduce Go example that calls ASM assembly code then replicate goid source:
 main.go  goid_amd64.s
 package main
 import (
 	"fmt"
 	"goidtesting/goid"
 	"os"
 	"time"
 )
 func say(s string) {
 	for i := 0; i < 5; i++ {
 		time.Sleep(100 * time.Millisecond)
 		_, _ = fmt.Fprintln(os.Stdout, goid.ID(), s)
 	}
 }
 func main() {
 	go say("world")
 	say("hello")
 }
 #include "textflag.h"

 TEXT ·ID(SB), NOSPLIT, $0-8
 	MOVQ	(TLS), AX     // AX = getg()
 	MOVQ	0x98(AX), AX   // AX = AX.goid
 	MOVQ	AX, ret+0(FP) // ret = AX
 	RET

Summary
To summarize, Go is now popular due to its ability to deliver highly scalable concurrent computing software. Plus, Cgo also allows Go programs to interoperate with C libraries, distributed cloud computing, and eBPF.

Therefore, writing low level C code to target 8-bit Sega Master System hardware and 16-bit Sega Mega Drive has proved to be very valuable experience for Cgo applications which could assist in Go + Cloud Computing!

Thursday, September 15, 2022

Golang Cheat Sheet

Golang is a statically typed and compiled programming language designed at Google. Go plays a major role in Enterprises by developing highly scalable concurrent cloud computing systems like Docker + Kubernetes.

Let's check it out!

Installation
Download and install Go as per instructions for your target operating system. Afterwards verify go version.

Windows
Download and open the Go MSI file. Follow all prompts and ensure Go added to PATH environment variable.

Mac OS/X
Download and open the Go PKG file. Follow all prompts and ensure Go added to PATH environment variable.

Linux
Download and extract the Go archive. Launch Terminal and ensure Go added to PATH environment variable.
 sudo rm -rf /usr/local/go
 sudo tar -C /usr/local -xzf go1.18.3.linux-amd64.tar.gz
 export PATH=$PATH:/usr/local/go/bin/
 go version
Alternatively, include export PATH="$PATH:/usr/local/go/bin/" to your ~/.bashrc file for future use.

IMPORTANT
If Go does not install or update then you may have to remove snap package using sudo snap remove go. Also, verify Go environment variables by entering go env at the Terminal prompt for all operating systems.

Uninstall
Follow this guide on how to uninstall Go. While there seems to be many options, the following should work:
 sudo apt-get remove golang-go
 sudo apt-get remove --auto-remove golang-go

IDEs
Now we'd like to build Golang software so let's setup 2x main Integrated Development Environments IDEs:

VS Code
Visual Studio Code is a popular lightweight IDE available cross platform on Windows, Mac OS/X and Linux. Install VS Code and install the following plugins: Go, Go Doc, Go Outliner, Go Autotest + Go Test Explorer.
 Go  Rich Go language support for Visual Studio Code
 Go Doc  Show Go's documentation symbols and packages
 Go Outliner  Go code outline explorer and navigation package
 Go Autotest  Adds autotest functionality to vscode's Go mode
 Go Test Explorer  Go Test Explorer for unit and integration testing

Launch VS Code. Press Ctrl + Shift + P. Filter on "Go: Install". Choose "Go: Install/Update Tools". Select all. Ok. Also, if prompted "The "gopls" command is not available." bottom right then click Install to go get gopls.

Miscellaneous
Launch Terminal. Drag tab headings to prefer following order: Terminal, Problems, Output, Debug Console.

Mappings
If you are transitioning from Windows to Linux you may like to update keyboard mappings for example Back to Alt + LeftArrow. File | Preferences | Keyboard Shortcuts. Filter "Go Back". Click pencil. Hit Alt + LeftArrow.

Repeat process for Terminal: Copy Selection: File | Preferences | Keyboard Shortcuts. Hit Ctrl + C and Enter. Repeat process for Terminal: Paste into Active Terminal: File | Preferences | Keyboard Shortcuts. Hit Ctrl + V.

Navigation
If you are transitioning from Visual Studio on Windows to VS Code then the Solution Explorer with folders being represented as folder icons not arrows may be more familiar. Therefore, install vscode-icons plugin. Also, as code bases become larger it can be handier to install the Bookmarks plugin for easier navigation.

Shortcuts
 Ctrl + ,  Open Settings similar to Preferences  F5  Debug | Start w/ Debugging
 Ctrl + P  Search files to open e.g. main.go  Ctrl + F5  Debug | Run w/o Debugger
 Ctrl + R  Select to open from previous files  F9  Debug | Toggle Breakpoint
 Ctrl + Shift + O  Outline file structure for opened file  F10  Debug | Step Over
 F12  Navigate | Go to Definition  F11  Debug | Step Into
 Alt + Left  Navigate | Going Backward  Shift + F11  Debug | Step Out

Zoom In
Finally, you may like to Ctrl + "+" to zoom in on the Explorer and Terminal then reduce the Font Size to 12.


GoLand
GoLand is a cross-platform Go Integrated Development Environment IDE on Windows, Mac OS/X and Linux. Install GoLand and setup the following configurations as commercial alternative with better IDE Intellisense.

Configurations
Launch GoLand. In the "Welcome to GoLand" popup choose Customize | Color theme | IntelliJ Light. Next, choose All settings... Expand Go tab at the top | GOROOT | Add SDK... Local | Navigate to where Go was installed previously e.g. /usr/local/go. Finally update GOPATH. Click "+" select ~/go. OK | Apply | OK.


IMPORTANT
Verify GOROOT path is correct from Terminal via go env | grep GOROOT. Repeat for go env | grep GOPATH. Also, in Go tab | Go Modules ensure "Enable Go modules integration" is checked as may not be by default.


Mappings
Align GoLand Keymap to VS Code Keymap for consistent keyboard shortcuts and developer IDE experience. In the "Welcome to GoLand" popup choose Plugins | VSCode Keymap | Install. Navigate back to Customize. Under Keymap change the default value to VSCode. Now all VS Code shortcuts above will work in GoLand.

Additionally to Ctrl + Shift + O, outline file structure for opened file, GoLand has these handy shortcuts also:
 Ctrl + Numpad -  Collapse struct types for easier overall type visibility in IDE
 Ctrl + Numpad +  Expand struct types to navigate type properties + methods

NOTE
If Ctrl + Shift + O launches Symbols then remove duplicate: Choose Settings | Keymap | filter as "symbol". Double click Navigate | Go to Symbol | Edit | Remove Ctrl+Shift+O | Apply | OK. Repeat this as necessary.

Settings
Finally, from Customize | All settings... here are some more general GoLand IDE settings that can be useful:
 Editor | General | Code Folding | Fold by default | General  UNCHEKED
 Editor | Font  JetBrains Mono | Size: 14.0 | Line: 1.2
 Editor | Color Scheme Font  Scheme: Classic Light
 Editor | Inspections | Proofreading | Typo  UNCHEKED

Example
Create the obligatory Hello World program in both VS Code and GoLand IDE to complete the configration:

main.go
package main
import "fmt"

func main() {
	fmt.Println("Hello World!")
}

VS Code
Create "HelloVSCode" folder at ~/go/src. Launch VS Code. Open folder [Ctrl+K, Ctrl+O] HelloVSCode folder. New File | main.go. Enter + save Hello World source code from package main above. Launch new Terminal:
go mod init HelloVSCode
go mod tidy

go build .
go run .
Set breakpoint in main.go. Run menu and choose either Start Debugging or Run without Debugging option.


GoLand
Launch GoLand. New Project | Enter Location and GOROOT as above i.e. Go 1.18.3 /usr/local/go. Create.

 Location  ~/go/src/HelloGoLand
 GOROOT  Go 1.18.3 /usr/local/go
 Enable vendoring support automatically  CHECKED

In main.go right click triangle next to func main() | Modify Run configuration... Ensure there are no errors. If there are errors then ensure if Run kind is Package the package name matches in go.mod. Otherwise choose File | main.go. Once confirmed no errors then right click triangle and choose the Run or Debug configuration.

Cache
If GoLand complains "cannot resolve symbol" then choose File | Invalidate Caches... | Invalidate and Restart.

Configurations
Track active item in solution explorer similar to Visual Studio: Click cog to right of Project and Always Select Opened File. Hit shift key twice for quick search. Remember Rename files and folder is in the Refactor menu!

Layout
It may be good idea to position Problems tab next to code window so you can see issues as you enter code. In GoLand, click cog on Problems | Move to | Right Top. In VS Code right click Problems | Move Panel Right.

Navigation
As code bases become larger use the Bookmarks feature for easier navigation. Right click the code gutter + Add Bookmark. View menu | Tool Windows | Bookmarks. This can also be used to edit/remove Breakpoints.

Source Control
In GoLand, by default the Staging area may be disabled. Therefore, you wouldn't see any Unversioned files To disable changelists choose File menu | Settings | Version Control | Git | Enable staging area | UNCHECK.

In GoLand, top right under Project is the Control tab. Right click any file and choose Rollback to revert any changes. In VS Code the Source Control tab is third tab. Choose Discard Changes as corresponding action.


Summary
To summarize, we have a simple setup for Golang programming on Windows, Mac OS/X and Linux. There is much to explore e.g. Cloud Computing and developing highly scalable concurrent applications using Golang!
This will be topic of the next post.

Wednesday, August 31, 2022

Linux Setup Cheat Sheet III

In the previous post, we set up Ubuntu Linux on Windows and Mac OS/X using VirtualBox. Now we focus our set up on dedicated Ubuntu Linux workstation or Windows PC that has dual boot with Ubuntu Linux installed.

Let's check it out!

Account
Typically, during the installation process, an admin account is prompted to be created with username and password. However, follow these instructions to add new user account with admin access on Ubuntu Linux.
 adduser stevepro
 usermod -aG sudo stevepro
 id stevepro
 su - stevepro

Alternatively, manage user accounts from Settings | Users user interface to add new user account. Initially, the account user will use the default icon. Consider changing via Settings | Users | Picture | Select File.

Login
If, whenever you attempt to login, you get the Ubuntu black screen with flashing cursor then attempt this fix: Reboot computer and login as recovery mode. Once logged in again, download and install NVIDIA.run.

Checkout here and here how to install nVidia driver on Ubuntu Linux e.g. NVIDIA-Linux-x86_64-460.84.run
 sudo su
 cd Downloads
 ./NVIDIA.run

IMPORTANT
If you are running X server then you may get an error when trying to install NVIDIA.run while still logged in:
 Ensure you are logged out!
 sudo service lightdm stop
 sudo init 3
 ./NVIDIA...run
 sudo service lightdm start

In, Software Updater | Additional Drivers, ensure NVidia is set "Using X.Org X server" as alternative driver.


Graphics
Initially, video file formats like mp4 may result in black screen. If so then install all the Multimedia Codecs:
 sudo apt-get update
 sudo apt install ubuntu-restricted-extras

Ubuntu
Confirm the version of Ubuntu Linux installed on terminal with lsb_release -a. Upgrade now accordingly:
 sudo apt update && sudo apt upgrade
 sudo reboot command
 sudo apt install update-manager-core
 sudo do-release-upgrade
 sudo reboot
 lsb_release -a

Kernel
Mainline is graphical tool to install the latest mainline kernel in Ubuntu Linux. Install Mainline from Terminal:
 sudo add-apt-repository ppa:cappelikan/ppa
 sudo apt update
 sudo apt install mainline
 mainline --check
 mainline --list
Start | Ubuntu Mainline. From the User Interface now install / uninstall Ubuntu Linux versions seemlessly. Once Ubuntu Linux kernel has been updated confirm kernel new version with uname -r.

Diff Tools
On Windows PC, Tortoise Merge is handy tool to compare 2x files whereas WinMerge is handy tool that can compare 2x directories. Meld + KDiff3 are alternatives for Linux both installed from Ubuntu Software Center.

Meld
File | New Comparison. File comparison navigate to file 1. Directory comparison navigate to file 2. Compare.

KDiff3
Similar to WinMerge: A. Directory navigate to directory 1. B. Directory navigate to directory 2. Compare OK.

Disk Space
Use Ubuntu Linux Disk Analyzer utility to identify common locations which can be used to free up disk space:
 rm -rf ~/.local/share/Trash/*
 du -sh ~/.cache/thumbnails
 sudo du -h /var/lib/snapd/snaps
 sudo du -sh /var/cache/apt
 sudo apt-get autoclean
 sudo apt-get clean
 sudo journalctl --disk-usage
 sudo journalctl --vacuum-time=3d
Other utilities to identify excess storage include ncud and bleachbit both which can be sudo apt install[ed].

Find
Here are some simple but effective uses of the find command e.g. find all text in file that follows predicate:
 find -L . -type f -exec grep -HniI 'g++' {} \; > ~/Steven/gpp.txt

Another useful example is how to find all of the distinct file extensions in a particular folder hierarchy:
 find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u

Shortcuts
 General  Minimize all windows  Ctrl + Alt + D
 gedit  Move prev tab  Ctrl + Alt + PgUp
 gedit  Move next tab  Ctrl + Alt + PgDown

SSH
Secure SHell [SSH] may not be enabled after Ubuntu Linux is installed. Therefore you may get the following:
 ssh stevepro@192.168.15.50
 ssh: connect to host 192.168.15.50 port 22: Connection refused

Server
Here is how to fix the Connection refused issue on port 22. On the destination server set up the following:
 # Make sure OpenSSH is installed
 # Install SSH
 # Check SSH service
 # Start SSH service
 sudo apt list --installed | grep openssh-server
 sudo apt install openssh-server
 sudo service ssh status
 sudo service ssh start

Client
On source client connect to Files | Other Locations | Connect to Server sftp://stevepro@192.168.15.50.
Also, ssh stevepro@192.168.15.50 should now work!

Mouse Scroll
After setting up new blue tooth mouse the default scroll was too slow. Therefore, install and set up lmwheel:
 sudo apt-get install imwheel

Create mouse.sh. Integrate the following shell script. Set execute permissions. Configure using ./mouse.sh.
#!/bin/bash
if [ ! -f ~/.imwheelrc ]
then
cat >~/.imwheelrc<<EOF
".*"
None,      Up,   Button4, 1
None,      Down, Button5, 1
Control_L, Up,   Control_L|Button4
Control_L, Down, Control_L|Button5
Shift_L,   Up,   Shift_L|Button4
Shift_L,   Down, Shift_L|Button5
EOF
fi
CURRENT_VALUE=$(awk -F 'Button4,' '{print $2}' ~/.imwheelrc)
NEW_VALUE=$(zenity --scale --window-icon=info --ok-label=Apply --title="Wheelies" --text "Mouse wheel speed:" --min-value=1 --max-value=100 --value="$CURRENT_VALUE" --step 1)
if [ "$NEW_VALUE" == "" ];
then exit 0
fi
sed -i "s/\($TARGET_KEY *Button4, *\).*/\1$NEW_VALUE/" ~/.imwheelrc # find the string Button4, and write new value.
sed -i "s/\($TARGET_KEY *Button5, *\).*/\1$NEW_VALUE/" ~/.imwheelrc # find the string Button5, and write new value.
cat ~/.imwheelrc
imwheel -kill

VNC Viewer
If you are transitioning from Windows to Linux you may like to remote desktop from Windows to Linux box.

Linux
Follow all instructions. Change Ubuntu desktop manager from GNOME to LightDM. Install X11VNC as service on Ubuntu. Launch Terminal and enter the following. When prompted, ensure you choose lightdm not gdm3:
sudo apt-get update
sudo apt-get install lightdm
sudo reboot
sudo apt-get install x11vnc

After installing LightDM, rebooting and installing X11VNC, configure x11vnc.service. Replace your password!
sudo gedit /lib/systemd/system/x11vnc.service

[Unit]
Description=x11vnc service
After=display-manager.service network.target syslog.target

[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -forever -display :0 -auth guess -passwd REPLACE_WITH_YOUR_LOGIN_PASSWORD
ExecStop=/usr/bin/killall x11vnc
Restart=on-failure

[Install]
WantedBy=multi-user.target

Finally, after configuring x11vnc.service, enter the following commands to complete the VNC Viewer setup.
systemctl daemon-reload
systemctl enable x11vnc.service
systemctl start x11vnc.service

systemctl status x11vnc.service
ip addr | grep 192                        # NOTE the IP address 192.168.1.X

IMPORTANT
Don't lock the screen as you won't be able to VNC back in! Change Settings | Privacy | Screen Lock to this:
Windows
Download and install VNC Viewer. Launch VNC Viewer. Setup Team. Choose File | New Connection. Enter the IP address from above on port 5000 for VNC Server e.g. 192.168.1.X:5900. Enter friendly name + Connect.

When prompted choose Continue. Enter password | Check Remember password. Unfortunately not all keys may work e.g. Caps Lock. Also, you may have to disable and re-enable Repeat Keys from Universal Access.

Summary
Now we have a dedicated Ubuntu Linux workstation set up we are all set for cloud computing development!

Thursday, August 4, 2022

Skazka Code Complete

Skazka is a Slavic RGP Adventure game originally written in BASIC for Sega SC-3000 and posted to SC-3000 Survivors Facebook group. The source code is now ported to C using devkitSMS for the Sega Master System.

Let's check it out!

Note: Skazka development based on devkitSMS Programming Setup and devkitSMS Programming Sample.
Download source code here.


Instructions
Skazka captures the core mechanics of old school RPG experience: Kill monsters | level up | upgrade gear. There are 5x different enemies in increasing order: Razboynik, Hungry Wolf, Kikimora, Leshy, Baby Yaga. Defeat final boss Koschey to beat the game!

Tools
Here is a list of Tools and frameworks that were used in the development of this project:
 KEY  VALUE
 Programming  devkitSMS
 Compiler  sdcc 3.6.9
 Assembler  WLA-DX
 IDE  Visual Studio 2015 / Visual Studio Code
 Languages  C / Z80
 Graphics  BMP2Tile 0.43 / BMP Converter / GIMP 2
 Music  pcmenc / vgm2psg
 Emulators  Emulicious / Fusion / Meka
 Debugger  Emulicious Debugger

ROM Hacking
You can hack this ROM! Download and dump Skazka into Hex Editor, e.g. HxD, and modify bytes:
 ADDRESS  VARIABLE  DESCRIPTION
 0x019E  Delay  Used to speed through any game delay.
 0x019F  Invincible  Non-zero value enables invincibility.
 0x01A0  Current XP  Non-zero sets current experience pts.
 0x01A1  Current HP  Non-zero sets default healthy points.
 0x01A2  Set Gold  Non-zero sets current gold available.
 0x01A3  Set Weapon  Set value to 1 or 2 for stock else 0.
 0x01A4  Set Armor  Set value to 1 or 2 for armor else 0.
 0x01A5  Add Life  Set value to 1=Life otherwise 0=None.
 0x01A6  Village Talk  Set value to 1=repeat villagers talk.
 0x01A7  Music Off  Set 0=Music to play otherwise silent.
 0x01A8  Sound Off  Set 0=Sound to play otherwise silent.

Hints
  • Try to buy weapon "Sword" or armor "Tegilay" with your initial gold before entering any forest fights.
  • After completing each forest fight, ensure you "Rest" at the main screen to replenish all health points.
  • In the shop when you buy items you already have then will be deducted unconditionally so be aware!
  • Get "+1 Life" just in case you lose a fight or the final boss battle so you do not have to restart game.
  • Maximize HP + XP + get the best weapon "Axe" and best armor "Kolchuga" before fighting the boss.
  • Fight boss when you have > 60 XP because your weapon and armor may be slightly more powerful!

Cheats
  • On title screen, hold fire2 to skip intro music. Same applies on boss and over screens.
  • On title screen, hold fire2 after intro music completes to reveal hidden credits screen.
  • On stats screen, move joystick left or right to skip over the flashing arrows indication.
  • In Easy mode forest screen, press fire2 to "Run away" without risking losing any HPs.

Debugging
  • On Windows you can debug the source code directly from in Visual Studio Code after pressing F5.
  • On Linux you can debug source code directly from Visual Studio Code but launch Emulicious first.

Credits
Extra special thanks to sverx for the devkitSMS. Plus StevePro Studios would like to thank Calindro all for his 24/7 Tech Support. Plus shout out to Mojon Twins na_th_an in which I found lots of some cool sound effects.

Update
Skazka V1.0 was initially a text-based RPG adventure game. However, after collaboration with Kagesan from SMS Power!, graphics were added for all screens for V2.0 which is the most up-to-date version of the game.



Summary
Despite the fact that Skazka was a simple text-based RPG adventure with limited game play, the cool aspect was collaborating with original developer and working together to port the game to the Sega Master System.

Skazka was entered in the SMS Power! 2022 competition to connect the Sega SC-3000 Facebook group and the SMS Power! community with the goal to spread Sega 8-bit preservation and fanaticism. That's awesome!