Menu

Tree [d339cf] master /
 History

HTTPS access


File Date Author Commit
 .vscode 2025-02-11 kevan kevan [80f9f5] Functioning Room Drawer and Walls or Ceiling Dr...
 Bindings 2025-02-27 kevan kevan [73ee00] Created simple bindable objects with generic ty...
 Builder 2025-03-06 kevan kevan [af1daa] Created simple logging
 Logging 2025-05-09 kevan kevan [32b9af] Improved logger by enabling named logging objects.
 LoggingTests 2025-05-09 kevan kevan [32b9af] Improved logger by enabling named logging objects.
 Project 2025-02-06 kevan kevan [9d4001] Renamed unit test project.
 Pyjamarama 2025-05-08 kevan kevan [c17ec0] Fixed boxing glove bug, where Wally wasn't fall...
 PyjamaramaTests 2025-05-15 kevan kevan [9172cc] Create a chunk collection for working with gapp...
 ThreeWeeks 2025-02-17 kevan kevan [1607cd] Updated Builder namespace to be consistant
 ZX 2025-03-03 kevan kevan [df6906] Started to build the house, with animations, te...
 ZX.Drawing 2025-03-19 kevan kevan [78eaeb] Added boxing glove trap test and animation.
 ZX.Game 2025-02-24 kevan kevan [cf4686] Fixed game play state.
 ZX.Platform 2025-03-03 kevan kevan [df6906] Started to build the house, with animations, te...
 ZX.Tests 2025-05-15 kevan kevan [9172cc] Create a chunk collection for working with gapp...
 ZX.Util 2025-05-15 kevan kevan [9172cc] Create a chunk collection for working with gapp...
 pyjamarama.godot 2025-05-15 kevan kevan [d339cf] Update main for logger changes.
 .gitignore 2025-02-27 kevan kevan [73ee00] Created simple bindable objects with generic ty...
 build.sln 2025-03-06 kevan kevan [af1daa] Created simple logging
 readme 2025-05-14 kevan kevan [367814] Tweaked readme

Read Me

Git repo for ZX projects.
=========================

The ZX project acts as a simulator for ease of porting Z80 Spectrum games
to C#. This is a collection of libraries which handle colours, drawing and raw
game data  using a generic interface that can be plugged into a modern front-end 
such as Godot.

Pyjamarama (WIP) has been included as an example of a game specific library and a Godot 
project.

The idea is that the libraries allow the original binary data to be used to create the
graphics, rooms etc. Any Z80 which puts these items together can then be ported into C#.
Over time other libraries will eventually exist to aid converting this raw info
into bitmaps and JSON for quicker use. All portable to different UI platforms.



Architect
=========

 ------------- ----------------------
|   ZX Util   |   Builder            |
 ------------- ----------------------
|     ZX      |  Bindings  | Logging |
 ------------- ------------------    |
| ZX Platform | ZX Game    	    |    |
 ------------------------------------
| ZX Drawing                         |
 ------------------------------------
| Godot project / Platform           |
 ------------------------------------


Builder
-------
Builder uses the Composite and Builder patterns to create a simple form of dependency injection.
Each 'module' or scope can have a composite object (base on IComposition) to own any concrete classes 
belonging to the module. The composite object can also implement the IBuilder class allowing it to
expose any of it's instances (as Interfaces) and request other instances from other modules.

By using interfaces the modules can stay detached and have either a loose dependency or better still
use dependency reversion.

As an example, ZX.Plaform defines the ISurface and IView interfaces which are used by the ZX.Drawing and other modules.
Whereas the actual project (Godot project and relating modules) will create the concrete surface using platform specific
image objects and implement the ISurface in order to allow other modules to use it with a loose coupling.

IComposite objects are automatically instantiated when calling 'BuildAll' on the Builder.Creator class.
The builder will own all composites. From here any composites based on the IBuilder interface will then run through
the builder process by calling

- IBuilder.CreateBuildables to get a list of any child classes that are also IBuildable.
- IBuilder.RegisterObjects to allow the instance to register any child classes for dependency injection.
- IBuilder.AskForDependents to get a list of other instances the object wants injected.

Once all this information has been collected for all instances, the creator will call 

	IBuilder.DependenciesMet
  
for all instances. It is at this point that each object can ask for the dependent instances it requested.

Bindings
--------
Bindings is a way to share values across different scopes and to report when a value changes.
Any module can get the shared BindingsManager and create a bound object. Bound Objects (IBoundObject)
are generic so any value type can be defined during creation. Other modules may then bind to the
object through the manager, if they wish to know when a value has changed. Additionally the object
can be gotten through the manager if another scope wishes to change the value as well. 

ZX.Drawing
----------
This holds classes to aid converting 8 bit bits into onscreen graphics. Graphic drawing is made up of
ILayers, ISurfaces and IDrawers. 

The IDrawers takes the raw bytes from the original game and converts then into colour pixels on the
ISurface.

The ISurfaces acts as a generic interface between the ZX drawing and the platform (Windows / Godot etc).

ILayers can be created to handle any amount of drawers and blend them onto the final screen surface. This 
can be done automatically by adding a layer to the IScreen. Each layer has a Z order as set by ILayer.Z,
and is used by the screen to determine the order of blending.

  [Optional]
 --------------       ---------         --------
| GFX / IChunk | --> | IDrawer | >---> |        |           ---------
 --------------       ---------        |        |          |         | [Update() - Blends all layers in order.]
   ----------                          | ILayer | >------> | IScreen |
  | ISurface | ----------------------> |        |          |         |
   ----------                          |        |           ---------
                                        -------- 
 	                                             [Blend() - Blends surface to another (normally screen)]
                                                 [Update() - Uses IDrawers to draw onto surface.]

The Animation layer (ZX.Drawing.IAnimationLayer), is a surface of a given size which will hold a list of animations
(IAnimation) which all use the same IDrawer object to be displayed and updated for each game cycle.
There are the standard components, which can be used or the user can create their own IAnimation and IDrawer.

ZX.Game
-------
The game module holds the main state machine and game loop. It holds an IGameProvider which keeps track of the current
game state (Titles, game loop, game over etc) and is called by the main game loop. Objects based on the IGameItem (and
any derived interfaces) can be added to the provider and will in turn be called when a game starts, a new level and the
main game frame cycle.


Setting up a new project
========================

Godot
-----

Create a new scene 'main' and make it the default.
Create a scene called 'view'
	Add a child TextureRect node and call it 'view'.

Copy folder, and its contents, ./..../Platform into the project.
Include libraries in projects makefile.

Create a script based on a Node.
Override the void _Ready() method. This will be ran at the start.
Call into you main static Initialisation code from here and any initial loading required.

Make the script run immediately using:

    Project Settings -> Globals -> Autoload

Attach the script 'View.cs' to node 'view'.

Main.cs
This should be a godot Node, IComposition and an IBuildable.
This sould be added as an autostart, where it can invoke the build functionality.
Main should instantiate the view and create the surface for it. This will be the main screen.
The composition should expose the main view (IView) as "Platform.Main.View".


Sub projects are class libraries

    dotnet new classlib -n <NAME>

Make sure new projects build to the output folder.
In the project build file update the main property group:

	<PropertyGroup>
      <TargetFramework>net8.0</TargetFramework>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
      <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
      <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
      <OutputPath>../output/$(Configuration)</OutputPath>
  	</PropertyGroup>


Example node use
----------------

    	Node inst = _commandScene.Instantiate();
		AddChild(inst);	
		FurnitureDisplayNode view = inst.GetNode<FurnitureDisplayNode>("Panel/Window/View");

		if(view is not IView)
		{
			throw new InvalidOperationException($"Node without IView when trying to create command '{name}'");
		}

		return view;

    Where:

        . FurnitureDisplayNode is a script based on a TextureRect and IView.
        . "Panel/Window/View" is the tree path for the physical node added to the Godot scene.

The IView will then give you access to the surface which gets created in the factory.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.