In the summer of 1997, I was an avid gamer of the golden classics of the real-time strategy (RTS) and immersive 3D/sandbox role-playing games that defined those genres. After wasting many hours gaming, I wanted to do something more constructive. I had dreams of building my own video games.
The previous year, I had created a basic textured-mapping, software-rendering 3D engine for a tutorial series called the 3D Coding BlackHole. I was working on developing a clone of a popular RTS game—as a learning experience and a stepping stone to building a new game with potential contributors.
I was also a Linux enthusiast, but Linux games were next to nonexistent. DOS was still the gaming platform of choice, with 32-bit extensions that would let you access more memory and VESA extensions that would give you SuperVGA graphics. With the introduction of DirectX, Windows was starting to take over gaming.
I came up with this crazy idea to start on a lifelong quest to build the ideal SDK, one that would let you program a game that would run on all those platforms without having to write specific code for each of them. Today, the advantages of cross-platform development are obvious and numerous toolkits are available, but 20 years ago, they were few and they were limited.
I was convinced that "write it once, run it everywhere" would become the way to write code in the future, so I rolled up my sleeves and started writing code not for one, but for three different gaming platforms at once. I took my 3D graphics engine, which ran in DOS, and two versions of the RTS game's clone code base (one ran under DOS with SuperVGA and the other under Windows through DirectX), and reorganized it all behind a nice abstraction layer, while also adding support for Linux. The Ecere SDK was born.
2D and 3D graphics
As the toolkit was aimed at game development, the initial focus was on 2D and 3D graphics. As graphical processing units (GPUs) began to appear, we started to support hardware accelerated graphics, initially through the Glide API, and eventually through OpenGL and Direct3D.
The Ecere SDK's display driver system allows users to select which API to use to render graphics while keeping the same application code. The current 2D graphics engine is simple and supports all the basic needs, such as selecting a resolution, toggling full-screen mode, loading and saving images, bitmap operations, generating lines and boxes, and international text output. It also allows users to change mode or driver while the application is running, making it easier to manage resources (such as images and fonts) that must be reloaded in different ways. We are currently working on more advanced vector graphics capabilities for a future release.
The 3D graphics engine can import and render most features from 3DS models and also supports its animation format. We are currently working on support for both Collaborative Design Activity (COLLADA) and GL Transmission Format (glTF).
The engine provides an API for assembling custom meshes, creating hierarchical objects, applying textured and shaded materials with a rich set of properties, and using animated cameras. The OpenGL backend supports both legacy OpenGL as well as modern shader-based OpenGL, offering an API to easily plug in custom shaders, and applications can also be deployed on mobile platforms using OpenGL ES or on the web using WebGL. We are performing major upgrades to the 3D engine that should result in performance improvements and new capabilities.
Graphical user interfaces
Ecere's graphical user interface (GUI) system, invented to provide in-game GUIs (e.g., powering a translucent menu over a paused game), has evolved into a very rich and efficient way to put together user interfaces ranging from simple to complex. It provides a library of common controls including: an edit box (a full-fledged text editor in its multi-line flavor); a list box (with options to act as a tree or grid view); a drop/combo box; a versatile data box (automatically parses based on a specified data type and pops up that type's associated editor); pop-up menus and menu bars; scroll bars and sliders; image boxes; status bars; tab controls; toolbars; and more. More complex controls and dialogs allow the user to select a date from a calendar control, a file, a folder, or a color; find or replace text; or pop up a message.
The GUI system also allows customization of the appearance and the feel of existing components, or building custom controls based on a very flexible system that leverages the object-oriented concepts of composition and inheritance, all centered on the Window base class. Rendering graphics within the window is as simple as issuing drawing calls to the 2D/3D graphics engine, using the surface parameter received by the window's OnRedraw callback. We are now working on an auto layout and styling engine better adept at handling varying pixel density.
An integrated development environment
As I was developing the edit box's text-editing functionality, I started using it as a code editor. Because of its graphics driver, text mode can be used in either a terminal or a graphical environment.
The code editor has evolved from a basic project file format into a rich development environment. It now features syntax highlighting, auto-completion, and parameters tool tips based on context; a form designer; objects properties and methods sheets; an API documentation browser; an integrated debugger that interfaces with the GNU Project Debugger (GDB); Valgrind integration; and even integrated rubber duck debugging to tackle the toughest of bugs. The IDE's cross-platform build system is its true strength, as it can generate GNU makefiles (no "configure"ation required) that will effortlessly build on Unix systems and Windows systems with or without MSYS.
Projects can define a complex set of compiler options using a combining matrix of platform/configuration/file. Multiple compilers can be set up (e.g., different version of GCC or Clang) to cross-build to other targets, such as building for Windows from Linux, Android, or Tizen for mobile or wearable platforms or Emscripten/Binaryen (WebAssembly) for the web. The project resources also offer a way to embed data files within an application's executable or library, easily accessed from an API through a simple file path. We hope to extend and improve support in the IDE for additional programming languages.
The eC programming language
The Ecere runtime library was initially written solely in the C language. Seeing the value of object orientation from writing more complex and more organized C programs, I tried to put together object-oriented wrappers for the library, first in C++, then in Python. Dissatisfied with the API and implementation, in 2004 I took a leap of faith across a giant gulf (perhaps wider than I realized) and set off to design a new programming language.
The rationale was that C was a great language: portable, native, and compiled with all the crucial libraries readily available for it. All it was missing, I reasoned, was:
- a touch of object-orientation (heavily influenced by C++);
- properties (as a nice way to define scene graph APIs and to support an IDE property sheet that could immediately result in a visual update in the form designer);
- reflection (inspired by Python, also essential for the IDE to dynamically query a library's properties and methods and to support custom object designers);
- modules (because header files are painful, and Python inspired making them dynamically loadable/ejectable); and
- while we're at it, why not eliminate the need for forward declaration?
And so eC was defined as a superset (not strictly speaking, but mostly true) of the C language—precisely of the C89 standard, although support for some C99 features was later added. The little "e" represents the little additions to the C language, and also stands for "Ecere," or enhanced, or elegant, or efficient, or whichever nice qualifier you prefer.
A cornerstone of the eC language is its syntax for instantiating an object:
MessageBox msgBox { contents = “Hello, world!!” };
It was inspired by the C initializer syntax of a "struct," which could have looked like this (assuming contents was the first member):
MessageBox msgBox = { “Hello, world!!” };
Member names can be omitted and resolved based on their order, and an instance can also be anonymous (in which case it is an expression rather than a declaration); for example:
Vector3D { 2, 4, 5 }
Its data type can also be inferred based on the destination's expected type; for example:
{ contents = "Hello, world!!" }
if a MessageBox is expected.
ECON: eC object notation
When I first came across JSON, I noticed two things. First, it seemed to be a much saner approach to serialize data as text rather than XML. Second, I thought it looked eerily similar to the eC instantiation syntax, with the exceptions of members (keys) being quoted and the equal (=) symbol replaced by a colon (:).
I decided it would be better to have an object notation that exactly matches eC instantiation syntax. For compatibility's sake, I made eC Object Notation (ECON) a superset of JSON, so that valid JSON is valid ECON. The only requirement for JSON to be writable as ECON is that members are valid C/eC identifiers (starting with a letter and containing only letters and numbers). Fully supporting the eC instantiation syntax brought in some additional improvements to JSON, such as hexadecimal number support, non-quoted enumeration values other than true/false, multi-line strings, implied member names, and the ability to specify a type. It's also very convenient to be able to directly copy an object from code to serialized data files and vice-versa. As was the case with our previous JSON parser/writer, all eC data types can automatically be (de)serialized from/to ECON or JSON files.
We are also hoping to offer libraries to facilitate writing and parsing ECON from other programming languages.
Language bindings: eC as a gateway
Although eC is the main development language for all our libraries, we recognize that requiring other people and organizations to use it will inhibit adoption of technology built with it.
Fortunately, being one of few compiled languages to be both compiled and feature built-in reflection, eC is suitable for generating automatic language bindings from a rich API. The implementation can offer native performance while avoiding the overhead of additional layers. With no extra effort, the API of any library written in eC can morph into a proper object-oriented API for any of the target languages supported by our bindings-generator tool, which strives to balance the advantage of a uniform API across languages while adhering to the language's paradigms, spirit, and best practices. Currently, bindings for the C and Python languages are available, with C++ bindings under development, and support for additional languages to follow.
GNOSIS: An Ecere-based geographic information system
Over the past three years, we've shifted our development focus towards the GNOSIS geospatial visualization products. The Ecere SDK is free and open-source software, and GNOSIS, which leverages the eC programming language and our open-source libraries, is our main commercial offering.
GNOSIS targets development of geomatics applications with the high-performance visualization system capable of both cartographic and 3D projections. The system makes heavy use of multi-resolution tiling for both raster and vector data to minimize the data load and maximize rendering performance. It features an SDK for integrating maps and overlaying geospatially positioned objects into custom applications; a map server implementing standard Open Geospatial Consortium (OGC) web-mapping protocols and highly efficient extensions to minimize bandwidth usage; and a GIS tool to visualize, style, and publish maps. GNOSIS is also the main driving force behind the ongoing development and improvement of the Ecere SDK.
Getting started with Ecere
The Ecere SDK is free and open source software licensed under a 3-Clause BSD License. The latest release is available on the Ecere SDK installation page. On Debian and Ubuntu systems, the SDK is available from the official repository as ecere-sdk, and the code is published at our GitHub repository.
For a quick look at the language's features, see the eC overview, or for a detailed introduction to the language, see the (in progress) programmer's guide The Ecere Tao of Programming. You can also consult the grammar (extended Backus–Naur form, or EBNF), which includes railroad diagrams. There is also a series of coursework (quiz and lab exercises) and a tic-tac-toe game tutorial to help you learn more. For a quick glance at what a typical short eC application look like, take a look at this sample: https://gist.github.com/
The best place to ask for help is on the forums or on our Freenode (irc.freenode.net) IRC channel #ecere (it's best to stay online and wait for an answer).
We welcome new users and potential contributors. If you find a bug, please submit it. If you'd like to see what types of contributions we're looking for, please take a look at our suggestions page.
4 Comments