Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix serious building issues due to merging without passing CI 😅 #238

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
200ef6d
Update CMakeLists.txt
k0T0z Aug 13, 2024
d845773
Update and rename keybindingpreferences.cpp to KeyBindingPreferences.cpp
k0T0z Aug 13, 2024
c6cf99b
Update and rename keybindingpreferences.h to KeyBindingPreferences.h
k0T0z Aug 13, 2024
b40da6f
Update CMakeLists.txt
k0T0z Aug 13, 2024
266f820
Fix RoomEditor.cpp
k0T0z Aug 13, 2024
9cc6a5c
Fix RoomEditor.h
k0T0z Aug 13, 2024
79e6637
Update PreferencesDialog.cpp
k0T0z Aug 13, 2024
87bd824
moved the modern way of including protobuf
k0T0z Aug 16, 2024
44bdcb5
fix the server plugin sources are added twice
k0T0z Aug 16, 2024
dca1efa
added commented code for people who will build grpc from scratch and …
k0T0z Aug 17, 2024
eff3918
fix search paths
k0T0z Aug 19, 2024
a8989ee
Add Robert changes to Editors/RoomEditor.cpp
k0T0z Aug 19, 2024
016a05f
fix entitiesListView not exist
k0T0z Aug 19, 2024
3ef991e
add the ability to move the built libraries to ENIGMA root submodule
k0T0z Aug 22, 2024
fc9a84a
fix the debug postfix character with the copying custom command
k0T0z Aug 22, 2024
ebc4031
fix the debug postfix character with the copying custom command
k0T0z Aug 22, 2024
dac3f6f
few improvements
k0T0z Aug 23, 2024
b8796cc
add nodeeditor submodule and linking algorithms
k0T0z Aug 23, 2024
b01c765
Full fix and improve for CMake build system
k0T0z Aug 23, 2024
5ec507b
fixed emake server error and multiple improvements
k0T0z Aug 24, 2024
df42346
Move files to a new dir as requested by Josh
k0T0z Aug 25, 2024
30858d8
delete old files
k0T0z Aug 25, 2024
4fd4a90
Removed nodeeditor package
k0T0z Oct 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/build/
/Submodules/
/.vscode/

# C++ objects and libs
*.slo
Expand Down
96 changes: 69 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 3.14)
project(RadialGM)

# Uncomment to give priority to the local CMake modules
# set(CMAKE_PREFIX_PATH "/usr/local/lib")

include(CMakeDependentOption)

option(RGM_BUILD_EMAKE "Build Emake and the compiler." ON)
Expand All @@ -9,17 +12,34 @@ option(RGM_BUILD_EMAKE "Build Emake and the compiler." ON)
# since we currently don't, I'm force disabling the option on MSVC
cmake_dependent_option(RGM_BUILD_STATIC "Build static libs." ON "MSVC" OFF)

# Check https://stackoverflow.com/q/33062728/14629018 for more information.
# if(MSVC)
# set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
# endif()

if (RGM_BUILD_STATIC)
set(LIB_TYPE STATIC)
set(LIB_TYPE STATIC CACHE STRING "Static Library type")
else()
set(LIB_TYPE SHARED)
set(LIB_TYPE SHARED CACHE STRING "Shared Library type")
endif()

# Set default build type
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Build type not set - defaulting to Debug")
set(
CMAKE_BUILD_TYPE "Debug"
CACHE
STRING
"Choose the type of build from: Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif()

if (CMAKE_BUILD_TYPE MATCHES "Debug")
set(EXE "RadialGM-Debug")
set(EXE "RadialGM-Debug" CACHE STRING "RGM Executable name")
add_definitions(-DRGM_DEBUG)
set(CMAKE_DEBUG_POSTFIX d)
else()
set(EXE "RadialGM")
set(EXE "RadialGM" CACHE STRING "RGM Executable name")
endif()

set(EXE_DESCRIPTION "ENIGMA IDE")
Expand All @@ -40,10 +60,13 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/Dialogs")
set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/" "${CMAKE_CURRENT_SOURCE_DIR}/Dialogs" "${CMAKE_CURRENT_SOURCE_DIR}/Editors")

# Uncomment to be able to use local grpc_cpp_plugin
# set(GRPC_EXE "/usr/local/bin/grpc_cpp_plugin")

# Include ENIGMA things
set(ENIGMA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Submodules/enigma-dev)
set(ENIGMA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Submodules/enigma-dev CACHE PATH "ENIGMA directory")
include_directories("${CMAKE_BINARY_DIR}/Submodules/enigma-dev/shared/protos/" "${ENIGMA_DIR}/CommandLine/libEGM" "${ENIGMA_DIR}/shared")

# Populate a CMake variable with the sources
Expand Down Expand Up @@ -81,12 +104,13 @@ set(RGM_SOURCES
Editors/ScriptEditor.cpp
Editors/CodeEditor.cpp
Editors/TimelineEditor.cpp
Editors/VisualShaderEditor.cpp
main.cpp
Plugins/RGMPlugin.cpp
Plugins/ServerPlugin.cpp
Dialogs/EventArgumentsDialog.cpp
Dialogs/TimelineChangeMoment.cpp
Dialogs/PreferencesDialog.cpp
Dialogs/KeyBindingPreferences.cpp
Utils/ProtoManip.cpp
Utils/FieldPath.cpp
MainWindow.cpp
Expand Down Expand Up @@ -139,13 +163,14 @@ set(RGM_HEADERS
Editors/FontEditor.h
Editors/SpriteEditor.h
Editors/BackgroundEditor.h
Plugins/ServerPlugin.h
Editors/VisualShaderEditor.h
Plugins/RGMPlugin.h
MainWindow.h
Dialogs/EventArgumentsDialog.h
Dialogs/PreferencesDialog.h
Dialogs/PreferencesKeys.h
Dialogs/TimelineChangeMoment.h
Dialogs/KeyBindingPreferences.h
Utils/SafeCasts.h
Utils/ProtoManip.h
Utils/FieldPath.h
Expand Down Expand Up @@ -196,8 +221,8 @@ else()
set(EDITOR_SOURCES Widgets/CodeWidgetScintilla.cpp)
endif()

set(RGM_SOURCES ${RGM_SOURCES} Plugins/ServerPlugin.cpp)
set(RGM_HEADERS ${RGM_HEADERS} Plugins/ServerPlugin.h)
set(RGM_SOURCES ${RGM_SOURCES} Plugins/ServerPlugin.cpp)
set(RGM_HEADERS ${RGM_HEADERS} Plugins/ServerPlugin.h)

# Tell CMake to create the RadialGM executable
add_executable(${EXE} WIN32 ${RGM_UI} ${RGM_HEADERS} ${RGM_SOURCES} ${EDITOR_SOURCES} ${RGM_RC})
Expand Down Expand Up @@ -244,14 +269,13 @@ include_directories(${EXE} PRIVATE ${RAPIDJSON_INCLUDE_DIRS})
find_package(yaml-cpp CONFIG REQUIRED)
target_link_libraries(${EXE} PRIVATE yaml-cpp)

#Find gRPC
find_package(gRPC CONFIG REQUIRED)
target_link_libraries(${EXE} PRIVATE gRPC::gpr gRPC::grpc gRPC::grpc++)
# Find gRPC
find_package(gRPC CONFIG REQUIRED)
target_link_libraries(${EXE} PRIVATE gRPC::gpr gRPC::grpc gRPC::grpc++)

# Find Protobuf
include(FindProtobuf)
include_directories(${Protobuf_INCLUDE_DIRS})
target_link_libraries(${EXE} PRIVATE ${Protobuf_LIBRARIES})
find_package(Protobuf CONFIG REQUIRED)
target_link_libraries(${EXE} PRIVATE protobuf::libprotobuf)

# Find OpenSSL
find_package(OpenSSL REQUIRED)
Expand All @@ -262,11 +286,13 @@ find_package(Qt5 COMPONENTS Core Widgets Gui PrintSupport Multimedia REQUIRED)
target_link_libraries(${EXE} PRIVATE Qt5::Core Qt5::Widgets Qt5::Gui Qt5::PrintSupport Qt5::Multimedia)

# LibProto
add_subdirectory(Submodules/enigma-dev/shared)
# Arrangement of these is important: shared depends on proto and emake depends on all of them
# We need to cache the library names first so we can build on top of them
add_subdirectory(Submodules/enigma-dev/shared/protos)
add_subdirectory(Submodules/enigma-dev/shared)
add_subdirectory(Submodules/enigma-dev/CommandLine/libEGM)
add_dependencies(${EXE} "EGM")
target_link_libraries(${EXE} PRIVATE "EGM" "Protocols" "ENIGMAShared")
add_dependencies(${EXE} ${LIB_EGM})
target_link_libraries(${EXE} PRIVATE ${LIB_EGM} ${LIB_PROTO} ${SHARED_LIB})

# Find FreeType
find_package(Freetype REQUIRED)
Expand All @@ -289,6 +315,14 @@ target_link_libraries(${EXE} PRIVATE ${LIB_PCRE2})
find_library(LIB_DOUBLE_CONVERSION NAMES double-conversion)
target_link_libraries(${EXE} PRIVATE ${LIB_DOUBLE_CONVERSION})

# nodeeditor
# FIXME: In order for BUILD_DEBUG_POSTFIX_D and USE_QT6 to be set correctly, you will need to configure the project twice: https://cmake.org/cmake/help/latest/policy/CMP0077.html
if (CMAKE_BUILD_TYPE MATCHES "Debug")
set(BUILD_DEBUG_POSTFIX_D ON)
endif()
set(USE_QT6 OFF) # We use Qt5
add_subdirectory(Submodules/nodeeditor)

if(WIN32)
# Windows is a turd
target_link_libraries(${EXE} PRIVATE Ws2_32 Wtsapi32 Wldap32 Crypt32 Winmm Userenv Netapi32 version Dwmapi Imm32)
Expand All @@ -302,14 +336,22 @@ endif()
if (RGM_BUILD_EMAKE)
add_subdirectory(Submodules/enigma-dev/CompilerSource)
add_subdirectory(Submodules/enigma-dev/CommandLine/emake)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
set(CLI_TARGET "emake-debug")
else()
set(CLI_TARGET "emake")
endif()
add_dependencies(${EXE} ${CLI_TARGET})
endif()

add_custom_command(
TARGET ${EXE}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_BINARY_DIR}/Submodules/enigma-dev/CommandLine/emake/${CLI_TARGET}${CMAKE_EXECUTABLE_SUFFIX}
${CMAKE_BINARY_DIR}/Submodules/enigma-dev/CommandLine/libEGM/${CMAKE_SHARED_LIBRARY_PREFIX}${LIB_EGM}${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
${CMAKE_BINARY_DIR}/Submodules/enigma-dev/CompilerSource/${CMAKE_SHARED_LIBRARY_PREFIX}${COMPILER_LIB}${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
${CMAKE_BINARY_DIR}/Submodules/enigma-dev/shared/protos/${CMAKE_SHARED_LIBRARY_PREFIX}${LIB_PROTO}${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
${CMAKE_BINARY_DIR}/Submodules/enigma-dev/shared/${CMAKE_SHARED_LIBRARY_PREFIX}${SHARED_LIB}${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
${CMAKE_CURRENT_SOURCE_DIR}/Submodules/enigma-dev
COMMENT "Copying exes to ENIGMA's root directory"
)

install(TARGETS ${EXE} RUNTIME DESTINATION .)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${EXE}.dir/Debug/${EXE}.pdb" DESTINATION . OPTIONAL)

Expand All @@ -324,9 +366,9 @@ file(TO_CMAKE_PATH ${VCPKG_ROOT} VCPKG_ROOT)
set(SEARCH_PATHS "${VCPKG_ROOT}/installed/x64-windows/bin/")
endif()
else()
set(LIBS "${CMAKE_INSTALL_PREFIX}/${CMAKE_SHARED_LIBRARY_PREFIX}EGM${CMAKE_SHARED_LIBRARY_SUFFIX}"
"${CMAKE_INSTALL_PREFIX}/${CMAKE_SHARED_LIBRARY_PREFIX}Protocols${CMAKE_SHARED_LIBRARY_SUFFIX}"
"${CMAKE_INSTALL_PREFIX}/${CMAKE_SHARED_LIBRARY_PREFIX}ENIGMAShared${CMAKE_SHARED_LIBRARY_SUFFIX}")
set(LIBS "${CMAKE_INSTALL_PREFIX}/${CMAKE_SHARED_LIBRARY_PREFIX}${LIB_EGM}${CMAKE_SHARED_LIBRARY_SUFFIX}"
"${CMAKE_INSTALL_PREFIX}/${CMAKE_SHARED_LIBRARY_PREFIX}${LIB_PROTO}${CMAKE_SHARED_LIBRARY_SUFFIX}"
"${CMAKE_INSTALL_PREFIX}/${CMAKE_SHARED_LIBRARY_PREFIX}${SHARED_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX}")
endif()

if (WIN32)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "KeybindingPreferences.h"
#include "KeyBindingPreferences.h"

#include "ui_MainWindow.h"
#include "ui_SpriteEditor.h"
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion Dialogs/PreferencesDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "ui_PreferencesDialog.h"

#include "PreferencesKeys.h"
#include "KeybindingPreferences.h"
#include "KeyBindingPreferences.h"
#include "main.h"
#include "Components/Logger.h"

Expand Down
71 changes: 38 additions & 33 deletions Editors/RoomEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ RoomEditor::RoomEditor(MessageModel* model, QWidget* parent) : BaseEditor(model,
_ui->objectSelectButton->setMenu(objMenu);
_ui->objectSelectButton->setPopupMode(QToolButton::MenuButtonPopup);

auto objects = treeProxy
->match(treeProxy->index(0, 0), TreeModel::UserRoles::TypeCaseRole,
TypeCase::kObject, 1, Qt::MatchRecursive);
if (!objects.empty()) {
QModelIndex firstObjIdx = objects.first();
QString firstObj = firstObjIdx.data(Qt::DisplayRole).toString();
_ui->objectSelectButton->setIcon(firstObjIdx.data(Qt::DecorationRole).value<QIcon>());
_ui->currentObject->setText(firstObj);
}
// auto objects = treeProxy
// ->match(treeProxy->index(0, 0), TreeModel::UserRoles::TypeCaseRole,
// TypeCase::kObject, 1, Qt::MatchRecursive);
// if (!objects.empty()) {
// QModelIndex firstObjIdx = objects.first();
// QString firstObj = firstObjIdx.data(Qt::DisplayRole).toString();
// _ui->objectSelectButton->setIcon(firstObjIdx.data(Qt::DecorationRole).value<QIcon>());
// _ui->currentObject->setText(firstObj);
// }

connect(objMenu, &QMenuView::triggered, [=](const QModelIndex &index) {
_ui->currentObject->setText(treeProxy->data(index, Qt::DisplayRole).toString());
Expand All @@ -116,9 +116,10 @@ RoomEditor::RoomEditor(MessageModel* model, QWidget* parent) : BaseEditor(model,

// This updates all the model views in the event of a sprite is changed
connect(MainWindow::resourceMap, &ResourceModelMap::DataChanged, this, [this]() {
_ui->instancesListView->reset();
_ui->tilesListView->reset();
_ui->layersPropertiesView->reset();
// _ui->entitiesListView->reset();
_ui->elementsListView->reset();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RobertBColton There is no entitiesListView in the ui file, I found elementsListView instead.

_ui->layersListView->reset();
_ui->propertiesView->reset();
});

RoomEditor::RebindSubModels();
Expand All @@ -133,35 +134,35 @@ void RoomEditor::RebindSubModels() {
RepeatedMessageModel* im = _roomModel->GetSubModel<RepeatedMessageModel*>(Room::kInstancesFieldNumber);
RepeatedSortFilterProxyModel* imp = new RepeatedSortFilterProxyModel(this);
imp->SetSourceModel(im);
_ui->instancesListView->setModel(imp);
// _ui->instancesListView->setModel(imp);

for (int c = 0; c < im->columnCount(); ++c) {
if (c != im->FieldToColumn(Room::Instance::kNameFieldNumber) &&
c != im->FieldToColumn(Room::Instance::kObjectTypeFieldNumber) &&
c != im->FieldToColumn(Room::Instance::kIdFieldNumber))
_ui->instancesListView->hideColumn(c);
else
_ui->instancesListView->resizeColumnToContents(c);
}
// for (int c = 0; c < im->columnCount(); ++c) {
// if (c != im->FieldToColumn(Room::Instance::kNameFieldNumber) &&
// c != im->FieldToColumn(Room::Instance::kObjectTypeFieldNumber) &&
// c != im->FieldToColumn(Room::Instance::kIdFieldNumber))
// _ui->instancesListView->hideColumn(c);
// else
// _ui->instancesListView->resizeColumnToContents(c);
// }

_ui->instancesListView->header()->swapSections(im->FieldToColumn(Room::Instance::kNameFieldNumber),
im->FieldToColumn(Room::Instance::kObjectTypeFieldNumber));
// _ui->instancesListView->header()->swapSections(im->FieldToColumn(Room::Instance::kNameFieldNumber),
// im->FieldToColumn(Room::Instance::kObjectTypeFieldNumber));

RepeatedMessageModel* tm = _roomModel->GetSubModel<RepeatedMessageModel*>(Room::kTilesFieldNumber);
RepeatedSortFilterProxyModel* tmp = new RepeatedSortFilterProxyModel(this);
tmp->SetSourceModel(tm);
_ui->tilesListView->setModel(tmp);
_ui->layersListView->setModel(tmp);

for (int c = 0; c < tm->columnCount(); ++c) {
if (c != tm->FieldToColumn(Room::Tile::kBackgroundNameFieldNumber) &&
c != tm->FieldToColumn(Room::Tile::kIdFieldNumber) && c != tm->FieldToColumn(Room::Tile::kDepthFieldNumber) &&
c != tm->FieldToColumn(Room::Tile::kNameFieldNumber))
_ui->tilesListView->hideColumn(c);
_ui->layersListView->hideColumn(c);
else
_ui->tilesListView->resizeColumnToContents(c);
_ui->layersListView->resizeColumnToContents(c);
}

_ui->tilesListView->header()->swapSections(tm->FieldToColumn(Room::Tile::kNameFieldNumber),
_ui->layersListView->header()->swapSections(tm->FieldToColumn(Room::Tile::kNameFieldNumber),
tm->FieldToColumn(Room::Tile::kBackgroundNameFieldNumber));

RepeatedMessageModel* vm = _roomModel->GetSubModel<RepeatedMessageModel*>(Room::kViewsFieldNumber);
Expand All @@ -170,19 +171,19 @@ void RoomEditor::RebindSubModels() {
connect(_ui->elementsListView->selectionModel(), &QItemSelectionModel::selectionChanged,
[=](const QItemSelection& selected, const QItemSelection& /*deselected*/) {
if (selected.empty()) return;
_ui->tilesListView->clearSelection();
_ui->layersListView->clearSelection();
auto selectedIndex = selected.indexes().first();
auto currentInstanceModel = imp->GetSubModel(selectedIndex.row());
_ui->layersPropertiesView->setModel(currentInstanceModel);
_ui->propertiesView->setModel(currentInstanceModel);
});

connect(_ui->tilesListView->selectionModel(), &QItemSelectionModel::selectionChanged,
connect(_ui->layersListView->selectionModel(), &QItemSelectionModel::selectionChanged,
[=](const QItemSelection& selected, const QItemSelection& /*deselected*/) {
if (selected.empty()) return;
_ui->instancesListView->clearSelection();
// _ui->instancesListView->clearSelection();
auto selectedIndex = selected.indexes().first();
auto currentInstanceModel = tmp->GetSubModel(selectedIndex.row());
_ui->layersPropertiesView->setModel(currentInstanceModel);
_ui->propertiesView->setModel(currentInstanceModel);
});

BaseEditor::RebindSubModels();
Expand All @@ -201,7 +202,7 @@ void RoomEditor::MousePressed(Qt::MouseButton button) {
if (button == Qt::MouseButton::LeftButton) {
auto index = layerElements->rowCount();
layerElements->insertRow(index);
layerElements->SetData(_ui->currentObject->text(), index, Room::Instance::kObjectTypeFieldNumber);
// layerElements->SetData(_ui->currentObject->text(), index, Room::Instance::kObjectTypeFieldNumber);
}
}

Expand All @@ -218,3 +219,7 @@ void RoomEditor::on_actionZoom_triggered() { _ui->roomPreviewBackground->ResetZo
void RoomEditor::on_actionShowHideGrid_triggered() {
_ui->roomPreviewBackground->SetGridVisible(_ui->actionShowHideGrid->isChecked());
}

void RoomEditor::updateCursorPositionLabel(const QPoint& pos) {

}
6 changes: 6 additions & 0 deletions Editors/RoomEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ class RoomEditor : public BaseEditor {

void setZoom(qreal zoom);

void MouseMoved(int x, int y);

void MousePressed(Qt::MouseButton button);

void MouseReleased(Qt::MouseButton button);

public slots:
void RebindSubModels() override;

Expand Down
26 changes: 26 additions & 0 deletions Editors/VisualShaderEditor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/********************************************************************************\
** **
** Copyright (C) 2024 Saif Kandil (k0T0z) **
** **
** This file is a part of the ENIGMA Development Environment. **
** **
** **
** ENIGMA is free software: you can redistribute it and/or modify it under the **
** terms of the GNU General Public License as published by the Free Software **
** Foundation, version 3 of the license or any later version. **
** **
** This application and its source code is distributed AS-IS, WITHOUT ANY **
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS **
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more **
** details. **
** **
** You should have recieved a copy of the GNU General Public License along **
** with this code. If not, see <http://www.gnu.org/licenses/> **
** **
** ENIGMA is an environment designed to create games and other programs with a **
** high-level, fully compilable language. Developers of ENIGMA or anything **
** associated with ENIGMA are in no way responsible for its users or **
** applications created by its users, or damages caused by the environment **
** or programs made in the environment. **
** **
\********************************************************************************/
Loading
Loading