Portierung der Surreal Engine C++ auf WebAssembly

In diesem Beitrag beschreibe ich, wie ich die Surreal Engine-Spiel-Engine auf WebAssembly portiert habe.

Surreal Engine – eine Spiel-Engine, die die meisten Funktionen der Unreal Engine 1 implementiert, berühmte Spiele auf dieser Engine – Unreal Tournament 99, Unreal, Deus Ex, Undying. Es bezieht sich auf klassische Engines, die hauptsächlich in einer Single-Threaded-Ausführungsumgebung arbeiteten.

Anfangs hatte ich die Idee, ein Projekt zu übernehmen, das ich nicht in angemessener Zeit abschließen konnte, und so meinen Twitch-Followern zu zeigen, dass es Projekte gibt, die selbst ich nicht schaffen kann. Während meines ersten Streams wurde mir plötzlich klar, dass die Aufgabe, Surreal Engine C++ mit Emscripten auf WebAssembly zu portieren, machbar ist.

Surreal Engine Emscripten Demo

Nach einem Monat kann ich meine Gabel- und Motorbaugruppe auf WebAssembly demonstrieren:
https://demensdeum.com/demos/SurrealEngine/

Die Steuerung erfolgt wie im Original über die Tastaturpfeile. Als nächstes plane ich, es für die mobile Steuerung (Tachi) anzupassen und dabei die richtige Beleuchtung und andere grafische Funktionen des Unreal Tournament 99-Renderings hinzuzufügen.

Wo soll ich anfangen?

Das erste, was ich sagen möchte, ist, dass jedes Projekt mit Emscripten von C++ nach WebAssembly portiert werden kann. Die Frage ist nur, wie vollständig die Funktionalität sein wird. Wählen Sie ein Projekt, dessen Bibliotheksports bereits für Emscripten verfügbar sind; im Fall von Surreal Engine haben Sie großes Glück, denn Die Engine verwendet die Bibliotheken SDL 2, OpenAL – Sie sind beide auf Emscripten portiert. Allerdings kommt als Grafik-API Vulkan zum Einsatz, was aktuell nicht für HTML5 verfügbar ist, an der Implementierung von WebGPU wird gearbeitet, befindet sich aber ebenfalls im Entwurfsstadium und es ist auch unbekannt, wie einfach die weitere Portierung von Vulkan auf WebGPU sein wird , nachdem es vollständig standardisiert ist. Daher musste ich mein eigenes grundlegendes OpenGL-ES/WebGL-Rendering für die Surreal Engine schreiben.

Erstellung des Projekts

System in Surreal Engine erstellen – CMake, was auch die Portierung vereinfacht, weil Emscripten stellt seinen nativen Buildern – emcmake, emmake.
Die Surreal Engine-Portierung basierte auf dem Code meines neuesten Spiels in WebGL/OpenGL ES und C++ namens Death-Mask. Dadurch war die Entwicklung viel einfacher, ich hatte alle notwendigen Build-Flags und Codebeispiele dabei.

Einer der wichtigsten Punkte in CMakeLists.txt sind die Build-Flags für Emscripten, unten ist ein Beispiel aus der Projektdatei:


-s MAX_WEBGL_VERSION=2 \

-s EXCEPTION_DEBUG \

-fexceptions \

--preload-file UnrealTournament/ \

--preload-file SurrealEngine.pk3 \

--bind \

--use-preload-plugins \

-Wall \

-Wextra \

-Werror=return-type \

-s USE_SDL=2 \

-s ASSERTIONS=1 \

-w \

-g4 \

-s DISABLE_EXCEPTION_CATCHING=0 \

-O3 \

--no-heap-copy \

-s ALLOW_MEMORY_GROWTH=1 \

-s EXIT_RUNTIME=1")

Das Build-Skript selbst:


emmake make -j 16

cp SurrealEngine.data /srv/http/SurrealEngine/SurrealEngine.data

cp SurrealEngine.js /srv/http/SurrealEngine/SurrealEngine.js

cp SurrealEngine.wasm /srv/http/SurrealEngine/SurrealEngine.wasm

cp ../buildScripts/Emscripten/index.html /srv/http/SurrealEngine/index.html

cp ../buildScripts/Emscripten/background.png /srv/http/SurrealEngine/background.png

Als nächstes bereiten wir den Index vor .html , das den Projektdateisystem-Preloader enthält. Zum Hochladen ins Web habe ich die Unreal Tournament Demo-Version 338 verwendet. Wie Sie der CMake-Datei entnehmen können, wurde der entpackte Spielordner zum Build-Verzeichnis hinzugefügt und als Preload-Datei für Emscripten verlinkt.

Hauptcodeänderungen

Dann war es notwendig, die Spielschleife des Spiels zu ändern, man kann keine Endlosschleife ausführen, das führt zum Einfrieren des Browsers, stattdessen muss man emscripten_set_main_loop verwenden, über diese Funktion habe ich in meiner Notiz von 2017 geschrieben „< a href="https://demensdeum.com /blog/ru/2017/03/29/porting-sdl-c-game-to-html5-emscripten/" rel="noopener" target="_blank">SDL C++-Spiel auf HTML5 (Emscripten) portieren“
Wir ändern den Code zum Beenden der while-Schleife in if, zeigen dann die Hauptklasse der Spiel-Engine, die die Spielschleife enthält, im globalen Bereich an und schreiben eine globale Funktion, die den Spielschleifenschritt vom globalen Objekt aus aufruft :


#include <emscripten.h>

Engine *EMSCRIPTEN_GLOBAL_GAME_ENGINE = nullptr;

void emscripten_game_loop_step() {

	EMSCRIPTEN_GLOBAL_GAME_ENGINE->Run();

}

#endif

Danach müssen Sie sicherstellen, dass in der Anwendung keine Hintergrundthreads vorhanden sind. Wenn ja, dann bereiten Sie sich darauf vor, diese für die Single-Thread-Ausführung neu zu schreiben, oder verwenden Sie die phtread-Bibliothek in Emscripten.
Der Hintergrund-Thread in Surreal Engine wird zum Abspielen von Musik verwendet. Vom Haupt-Engine-Thread kommen Daten über den aktuellen Titel, die Notwendigkeit, Musik abzuspielen, oder dessen Fehlen. Anschließend erhält der Hintergrund-Thread über einen Mutex einen neuen Status und beginnt mit der Wiedergabe neuer Musik , oder pausiert es. Der Hintergrundstream wird auch zum Puffern von Musik während der Wiedergabe verwendet.
Meine Versuche, die Surreal Engine für Emscripten mit pthread zu erstellen, waren erfolglos, da die SDL2- und OpenAL-Ports ohne pthread-Unterstützung erstellt wurden und ich sie nicht aus Gründen der Musik neu erstellen wollte. Daher habe ich die Funktionalität des Hintergrundmusik-Streams mithilfe einer Schleife auf die Single-Threaded-Ausführung übertragen. Durch das Entfernen von pthread-Aufrufen aus dem C++-Code habe ich die Pufferung und Musikwiedergabe in den Hauptthread verschoben, damit es keine Verzögerungen gibt, ich habe den Puffer um einige Sekunden erhöht.

Als nächstes werde ich spezifische Implementierungen von Grafik und Sound beschreiben.

Vulkan wird nicht unterstützt!

Ja, Vulkan wird in HTML5 nicht unterstützt, obwohl alle Marketingbroschüren die plattformübergreifende und breite Plattformunterstützung als Hauptvorteil von Vulkan darstellen. Aus diesem Grund musste ich meinen eigenen grundlegenden Grafikrenderer für einen vereinfachten OpenGL-Typ schreiben – ES, es wird auf mobilen Geräten verwendet, enthält manchmal nicht die modischen Funktionen des modernen OpenGL, lässt sich aber sehr gut auf WebGL portieren, was genau das ist, was Emscripten implementiert. Das Schreiben des grundlegenden Kachel-Renderings, des BSP-Renderings für die einfachste GUI-Anzeige und des Renderns von Modellen und Karten wurde in zwei Wochen abgeschlossen. Dies war vielleicht der schwierigste Teil des Projekts. Es liegt noch viel Arbeit vor uns, die volle Funktionalität des Surreal Engine-Renderings zu implementieren, daher ist jede Hilfe von Lesern in Form von Code und Pull-Requests willkommen.

OpenAL unterstützt!

Das große Glück ist, dass Surreal Engine OpenAL für die Audioausgabe verwendet. Nachdem ich eine einfache Hallo-Welt in OpenAL geschrieben und sie mit Emscripten in WebAssembly zusammengestellt hatte, wurde mir klar, wie einfach alles war, und ich machte mich an die Portierung des Sounds.
Nach mehreren Stunden des Debuggens stellte sich heraus, dass die OpenAL-Implementierung von Emscripten mehrere Fehler aufweist. Beispielsweise gab die Methode beim Initialisieren des Lesens der Anzahl der Monokanäle eine unendliche Zahl zurück, und nachdem versucht wurde, einen Vektor unendlicher Größe zu initialisieren, C++ stürzt mit der Ausnahme vector::length_error ab.

Wir haben es geschafft, dies zu umgehen, indem wir die Anzahl der Monokanäle auf 2048 fest codiert haben:


		alcGetIntegerv(alDevice, ALC_STEREO_SOURCES, 1, &stereoSources);



#if __EMSCRIPTEN__

		monoSources = 2048; // for some reason Emscripten's OpenAL gives infinite monoSources count, bug?

#endif



Gibt es ein Netzwerk?

Surreal Engine unterstützt derzeit kein Online-Spielen, das Spielen mit Bots wird unterstützt, aber wir brauchen jemanden, der KI für diese Bots schreibt. Theoretisch können Sie mithilfe von Websockets ein Netzwerkspiel auf WebAssembly/Emscripten implementieren.

Schlussfolgerung

Abschließend möchte ich sagen, dass die Portierung der Surreal Engine aufgrund der Verwendung von Bibliotheken, für die es Emscripten-Portierungen gibt, sowie meiner bisherigen Erfahrung bei der Implementierung eines Spiels in C++ für WebAssembly recht reibungslos verlief auf Emscripten. Nachfolgend finden Sie Links zu Wissensquellen und Repositories zum Thema.
M-M-M-MONSTER TÖTEN!

Außerdem, wenn Sie dem Projekt helfen möchten, vorzugsweise mit WebGL/OpenGL ES-Rendering-Code, dann schreiben Sie mir per Telegram:
https://t.me/demenscave

Links

https://demensdeum.com/demos/SurrealEngine/
https://github.com/demensdeum/SurrealEngine-Emscripten

https://github.com/dpjudas/SurrealEngine

Flash Forever – Interceptor 2021

Recently, it turned out that Adobe Flash works quite stably under Wine. During a 4-hour stream, I made the game Interceptor 2021, which is a sequel to the game Interceptor 2020, written for the ZX Spectrum.

For those who are not in the know – the Flash technology provided interactivity on the web from 2000 to around 2015. Its shutdown was prompted by an open letter from Steve Jobs, in which he wrote that Flash should be consigned to history because it lagged on the iPhone. Since then, JS has become even more sluggish than Flash, and Flash itself has been wrapped in JS, making it possible to run it on anything thanks to the Ruffle player.

You can play it here:
https://demensdeum.com/demos/Interceptor2021

Video:
https://www.youtube.com/watch?v=-3b5PkBvHQk

Source code:
https://github.com/demensdeum/Interceptor-2021

Masons-DR-Demospiele

Masonry-AR ist ein Augmented-Reality-Spiel, in dem Sie in der realen Welt durch die Stadt navigieren und freimaurerisches Wissen aus Büchern sammeln müssen, um Geld zu erhalten und Gebiete für Ihren Freimaurerorden zu erobern. Das Spiel hat keinen Bezug zu echten Organisationen, alle Spiele sind zufällig.

Spieldemo:
https://demensdeum.com/demos/masonry-ar/client

Vicki:
https://demensdeum.com/masonry-ar-wiki-ru/

Quellcode:
https://github.com/demensdeum/Masonry-AR

Flammenstahl-Lokomotivläufer

Ich präsentiere Ihnen Flame Steel Engine Runner – Plattform zum Starten von Multimedia-Anwendungen basierend auf dem Flame Steel Engine-Toolkit. Unterstützte Plattformen sind Windows, MacOS, Linux, Android, iOS, HTML 5. Der Schwerpunkt der Anwendungscodeentwicklung hat sich in Richtung Skripterstellung verlagert – Derzeit wurde die Unterstützung für JavaScript mit TinyJS hinzugefügt, das Toolkit selbst und die Engine werden weiterhin in hardwarenahen Sprachen (C, C++, Rust usw.) entwickelt
Flame Steel Engine Runner Demo
Auf der Seite unten können Sie den Würfel drehen, Code in JavaScript schreiben, Modelle, Sounds, Musik und Code über die Schaltfläche „Dateien hochladen“ hochladen und mit der Schaltfläche „Ausführen“ von der Datei main.js aus starten.
https://demensdeum.com/demos/FlameSteelEngineRunner/

Space Jaguar Action-Rollenspiel 0.0.4

Der erste Prototyp des Space Jaguar Action-RPG-Spiels für Webassembly:

Das Laden dauert lange (53 MB), ohne dass eine Ladeanzeige angezeigt wird.

Space Jaguar Action-Rollenspiel – Lebenssimulator eines Weltraumpiraten. Im Moment stehen die einfachsten Spielmechaniken zur Verfügung:

  • im Weltraum fliegen
  • sterben
  • essen
  • schlafen
  • Stellen Sie ein Team ein
  • Schauen Sie sich den ruhelosen, schnell fliegenden Strom der Zeit an

Aufgrund der schlechten Optimierung der Darstellung von 3D-Szenen in der Webversion ist die Möglichkeit, in einer 3D-Umgebung herumzulaufen, nicht verfügbar. Die Optimierung wird in zukünftigen Versionen hinzugefügt.

Der Quellcode der Engine, des Spiels und der Skripte ist unter der MIT-Lizenz verfügbar. Alle Verbesserungsvorschläge werden äußerst positiv aufgenommen:

https://gitlab.com/demensdeum/space-jaguar -action-rpg

Screenshots der nativen Version für Linux:

Spieleentwicklung für ZX Spectrum in C

Dieser Nonsens-Beitrag ist der Entwicklung eines Spiels für den alten ZX Spectrum-Computer in C gewidmet. Werfen wir einen Blick auf den hübschen Kerl:

Die Produktion begann 1982 und wurde bis 1992 produziert. Technische Eigenschaften der Maschine: 8-Bit-Z80-Prozessor, 16-128 KB Speicher und weitere Erweiterungen, wie der AY-3-8910-Soundchip.

Im Rahmen des Wettbewerbs Yandex Retro Games Battle 2019 für diese Maschine habe ich ein Spiel geschrieben namens Interceptor 2020. Da ich keine Zeit hatte, die Assemblersprache für den Z80 zu lernen, beschloss ich, sie in C zu entwickeln. Als Toolchain habe ich ein fertiges Set gewählt – z88dk, das C-Compiler und viele Hilfsbibliotheken enthält, um die Implementierung von Anwendungen für das Spectrum zu beschleunigen. Es unterstützt auch viele andere Z80-Geräte, wie z. B. Taschenrechner von MSX und Texas Instruments.

Als nächstes beschreibe ich meinen oberflächlichen Flug über die Computerarchitektur, die z88dk-Toolchain, und zeige, wie ich es geschafft habe, den OOP-Ansatz zu implementieren und Designmuster zu verwenden.

Installationsfunktionen

Die Installation von z88dk sollte gemäß der Anleitung aus dem Repository erfolgen, für Ubuntu-Benutzer möchte ich jedoch eine Funktion anmerken – Wenn Sie bereits Compiler für Z80 aus Deb-Paketen installiert haben, sollten Sie diese entfernen, da z88dk aufgrund der Inkompatibilität der Toolchain-Compiler-Versionen standardmäßig auf sie zugreift.< /p>

Hallo Welt

Hello World zu schreiben ist sehr einfach:

#include 

void main()
{
    printf("Hello World");
}

Es ist noch einfacher, eine Tap-Datei zu kompilieren:

zcc +zx -lndos -create-app -o helloworld helloworld.c

Verwenden Sie zum Ausführen einen beliebigen ZX Spectrum-Emulator mit Tap-Datei-Unterstützung, zum Beispiel online:
http://jsspeccy.zxdemo.org/

Zeichnen Sie im Vollbildmodus auf das Bild

tl;dr Bilder werden in Kacheln gezeichnet, Kacheln mit einer Größe von 8×8 Pixeln, die Kacheln selbst sind in die Schriftart Spectrum eingebaut, dann wird das Bild als Linie aus den Indizes gedruckt.

Die Sprite- und Kachelausgabebibliothek SP1 gibt Kacheln mithilfe von UDG aus. Das Bild wird in eine Reihe einzelner UDGs (Kacheln) übersetzt und dann mithilfe von Indizes auf dem Bildschirm zusammengesetzt. Beachten Sie, dass UDG zum Anzeigen von Text verwendet wird. Wenn Ihr Bild einen sehr großen Satz von Kacheln enthält (z. B. mehr als 128 Kacheln), müssen Sie über die Grenzen des Satzes hinausgehen und das Standardspektrum löschen Schriftart. Um diese Einschränkung zu umgehen, habe ich eine Basis von 128 – 255 durch Vereinfachung der Bilder, wobei die ursprüngliche Schriftart erhalten bleibt. Über die Vereinfachung der Bilder unten.

Um Vollbildbilder zu zeichnen, müssen Sie sich mit drei Dienstprogrammen ausrüsten:
Gimp
img2spec
png2c-z88dk

Für echte ZX-Männer, echte Retro-Krieger gibt es eine Möglichkeit: Öffnen Sie einen Grafikeditor mit der Spectrum-Palette, kennen Sie die Funktionen der Bildausgabe, bereiten Sie sie manuell vor und laden Sie sie mit png2c-z88dk oder png2scr hoch.< /p>

Der einfachere Weg – Nehmen Sie ein 32-Bit-Bild, ändern Sie die Anzahl der Farben in Gimp auf 3-4, bearbeiten Sie es leicht und importieren Sie es dann in img2spec, um nicht manuell mit Farbbeschränkungen zu arbeiten. Exportieren Sie PNG und konvertieren Sie es mit PNG2C in ein C-Array. z88dk.

Sie sollten bedenken, dass für einen erfolgreichen Export jede Kachel nicht mehr als zwei Farben enthalten darf.

Als Ergebnis erhalten Sie eine h-Datei, die die Anzahl der eindeutigen Kacheln enthält. Wenn es mehr als ~128 sind, vereinfachen Sie das Bild in Gimp (erhöhen Sie die Wiederholbarkeit) und führen Sie den Exportvorgang über ein neues aus .

Nach dem Export laden Sie buchstäblich die „Schriftart“ aus den Kacheln und drucken den „Text“ aus den Kachelindizes auf den Bildschirm. Unten ist ein Beispiel aus der Render-„Klasse“:

// грузим шрифт в память
    unsigned char *pt = fullscreenImage->tiles;

    for (i = 0; i < fullscreenImage->tilesLength; i++, pt += 8) {
            sp1_TileEntry(fullscreenImage->tilesBase + i, pt);
    }

    // ставим курсор в 0,0
    sp1_SetPrintPos(&ps0, 0, 0);

    // печатаем строку
    sp1_PrintString(&ps0, fullscreenImage->ptiles);

Sprites auf dem Bildschirm zeichnen

Als nächstes beschreibe ich eine Methode zum Zeichnen von Sprites mit 16 x 16 Pixeln auf dem Bildschirm. Ich bin nicht zur Animation und zum Ändern der Farben gekommen, weil… Es ist trivial, dass mir schon zu diesem Zeitpunkt, wie ich annehme, der Speicher ausgegangen ist. Daher enthält das Spiel nur transparente monochrome Sprites.

Wir zeichnen ein monochromes PNG-Bild 16×16 in Gimp, dann übersetzen wir es mit png2sp1sprite in eine ASM-Assembly-Datei, im C-Code deklarieren wir Arrays aus der Assembly-Datei und fügen die Datei in der Assembly-Phase hinzu.< /p>

Nach der Deklaration der Sprite-Ressource muss diese an der gewünschten Position zum Bildschirm hinzugefügt werden. Nachfolgend finden Sie ein Beispiel für den Code für die „Klasse“ des Spielobjekts:

    struct sp1_ss *bubble_sprite = sp1_CreateSpr(SP1_DRAW_MASK2LB, SP1_TYPE_2BYTE, 3, 0, 0);
    sp1_AddColSpr(bubble_sprite, SP1_DRAW_MASK2,    SP1_TYPE_2BYTE, col2-col1, 0);
    sp1_AddColSpr(bubble_sprite, SP1_DRAW_MASK2RB,  SP1_TYPE_2BYTE, 0, 0);
    sp1_IterateSprChar(bubble_sprite, initialiseColour);

Anhand der Namen der Funktionen können Sie die Bedeutung von – Weisen Sie dem Sprite Speicher zu, fügen Sie zwei 8×8 Spalten hinzu und fügen Sie eine Farbe für das Sprite hinzu.

Die Position des Sprites wird in jedem Frame angezeigt:

sp1_MoveSprPix(gameObject->gameObjectSprite, Renderer_fullScreenRect, gameObject->sprite_col, gameObject->x, gameObject->y);

OOP emulieren

In C gibt es keine Syntax für OOP. Was sollten Sie tun, wenn Sie es trotzdem wirklich wollen? Sie müssen Ihren Geist verbinden und sich darüber im Klaren sein, dass es so etwas wie OOP-Ausrüstung nicht gibt; letztendlich kommt es auf eine der Maschinenarchitekturen an, in denen es einfach kein Konzept eines Objekts und andere damit verbundene Abstraktionen gibt.< /p>

Diese Tatsache hat mich sehr lange daran gehindert zu verstehen, warum OOP überhaupt benötigt wird, warum es notwendig ist, es zu verwenden, wenn am Ende alles auf Maschinencode hinausläuft.

Nachdem ich jedoch in der Produktentwicklung gearbeitet hatte, entdeckte ich die Vorzüge dieses Programmierparadigmas, vor allem natürlich die Entwicklungsflexibilität, Code-Schutzmechanismen mit dem richtigen Ansatz, die Reduzierung der Entropie und die Vereinfachung der Teamarbeit. Alle oben genannten Vorteile basieren auf drei Säulen: Polymorphismus, Kapselung, Vererbung.

Bemerkenswert ist auch die Vereinfachung der Lösung von Problemen im Zusammenhang mit der Anwendungsarchitektur, da 80 % der Architekturprobleme im letzten Jahrhundert von Informatikern gelöst und in der Literatur zu Entwurfsmustern beschrieben wurden. Als Nächstes beschreibe ich Möglichkeiten, C eine OOP-ähnliche Syntax hinzuzufügen.

Es ist bequemer, C-Strukturen als Grundlage für die Speicherung von Daten einer Klasseninstanz zu verwenden. Natürlich können Sie einen Bytepuffer verwenden und Ihre eigene Struktur für Klassen und Methoden erstellen, aber warum das Rad neu erfinden? Schließlich erfinden wir die Syntax bereits neu.

Klassendaten

Beispiel für GameObject-„Klassen“-Datenfelder:

struct GameObjectStruct {
    struct sp1_ss *gameObjectSprite;
    unsigned char *sprite_col;
    unsigned char x;
    unsigned char y;
    unsigned char referenceCount;
    unsigned char beforeHideX;
    unsigned char beforeHideY;
};
typedef struct GameObjectStruct GameObject;

Speichern Sie unsere Klasse als „GameObject.h“, fügen Sie „GameObject.h“ an der richtigen Stelle ein und verwenden Sie sie.

Klassenmethoden

Unter Berücksichtigung der Erfahrung der Entwickler der Objective-C-Sprache besteht die Signatur einer Klassenmethode aus Funktionen in einem globalen Bereich. Das erste Argument ist immer die Datenstruktur, gefolgt von den Methodenargumenten. Unten finden Sie ein Beispiel für eine „Methode“ der „Klasse“ GameObject:

void GameObject_hide(GameObject *gameObject) {
    gameObject->beforeHideX = gameObject->x;
    gameObject->beforeHideY = gameObject->y;
    gameObject->y = 200;
}

Der Methodenaufruf sieht so aus:

GameObject_hide(gameObject);

Konstruktoren und Destruktoren werden auf die gleiche Weise implementiert. Es ist möglich, einen Konstruktor als Allokator und Feldinitialisierer zu implementieren, aber ich bevorzuge es, die Objektzuweisung und -initialisierung separat zu steuern.

Mit dem Gedächtnis arbeiten

Manuelle Speicherverwaltung des Formulars mit malloc und frei in neue und gelöschte Makros eingebunden, passend zu C++:

#define new(X) (X*)malloc(sizeof(X))
#define delete(X) free(X)

Für Objekte, die von mehreren Klassen gleichzeitig verwendet werden, wird eine halbmanuelle Speicherverwaltung basierend auf Referenzzählung implementiert, nach dem Vorbild und der Ähnlichkeit des alten Objective-C Runtime ARC-Mechanismus:

void GameObject_retain(GameObject *gameObject) {
    gameObject->referenceCount++;
}

void GameObject_release(GameObject *gameObject) {
    gameObject->referenceCount--;

    if (gameObject->referenceCount < 1) { sp1_MoveSprAbs(gameObject->gameObjectSprite, &Renderer_fullScreenRect, NULL, 0, 34, 0, 0);
        sp1_DeleteSpr(gameObject->gameObjectSprite);
        delete(gameObject);
    }
}

Daher muss jede Klasse die Verwendung eines gemeinsam genutzten Objekts mithilfe von „Retain“ deklarieren und das Eigentum durch „Release“ freigeben. Die moderne Version von ARC verwendet automatische Aufbewahrungs-/Freigabeaufrufe.

Ton!

Der Spectrum verfügt über einen Hochtöner, der 1-Bit-Musik wiedergeben kann; damalige Komponisten konnten bis zu 4 Tonkanäle gleichzeitig wiedergeben.

Spectrum 128k enthält einen separaten Soundchip AY-3-8910, der Tracker-Musik abspielen kann.

Für die Nutzung des Hochtöners im z88dk wird eine Bibliothek angeboten

Was noch gelernt werden muss

Ich war daran interessiert, das Spectrum kennenzulernen, das Spiel mit dem z88dk zu implementieren und viele interessante Dinge zu lernen. Ich muss noch viel lernen, zum Beispiel den Z80-Assembler, da er mir ermöglicht, die volle Leistung des Spectrum zu nutzen, mit Speicherbänken zu arbeiten und mit dem Soundchip AY-3-8910 zu arbeiten. Ich hoffe, nächstes Jahr am Wettbewerb teilnehmen zu können!

Links

https://rgb.yandex
https://vk.com/sinc_lair
https://www.z88dk.org/forum/

Quellcode

https://gitlab.com/demensdeum/ zx-projects/tree/master/interceptor2020

Death-Maske Wild Beta

Das Spiel Death-Mask geht in den öffentlichen Beta-Status (Wild Beta)
Der Hauptmenübildschirm des Spiels wurde neu gestaltet, eine Ansicht der blauen Zone des Techno-Labyrinths wurde hinzugefügt, mit angenehmer Musik im Hintergrund.

Als nächstes plane ich, den Gameplay-Controller zu überarbeiten, flüssige Bewegungen wie in alten Shootern, hochwertige 3D-Modelle von Kisten, Waffen, Feinden und die Möglichkeit hinzuzufügen, mich nicht nur über Portale in andere Ebenen des Techno-Labyrinths zu bewegen ( Aufzüge, Türen, Stürze durch Löcher im Boden, Löcher in Wänden), werde ich der Umgebung des generierten Labyrinths etwas Abwechslung verleihen. Ich werde auch an der Spielbalance arbeiten.
Die Skelettanimation wird als Polierphase vor der Veröffentlichung hinzugefügt.< /p>