**DISCLAIMER: This project is very much a Work In Progress. We're making it accessible in this very early state so that participants to the [Wheel Reinvention Jam 2023](https://handmade.network/jam/2023) can try it out and maybe use it as their jamming platform. Expect bugs, missing and/or incomplete features, unstable APIs, and sparse documentation. Some current issues might be a show stopper for you, so make sure you can build and run the sample apps before jumping in.**
**If you do choose to try out Orca anyway, well thanks! We'll do our best to answer your questions, and we'd really appreciate to hear your feedback!**
This is a short introduction to developping an application that can be run by the Orca runtime. We'll present the basic structure of an Orca application, and walk through a simple example in C.
Orca exposes a number of types and functions to applications. In order to use them the first thing to do is to include `orca.h`.
```
#include<orca.h>
```
The Orca runtime manages the application's window and event loop. In order to receive a specific kind of event, you can define an associated _event handler_ and export it to the runtime. For instance, to be notified when your application's window is resized, you should define the `oc_on_resize()` handler:
The `ORCA_EXPORT` macro makes the handler visible to the orca runtime, which automatically binds it to the window resize event.
Handlers are optional. If you don't care about an event, you can just omit the associated handler. You probably want to define at least two important handlers:
-`oc_on_init()` is called once when your application starts and can be use to initialize your application's resources
-`oc_on_frame_refresh()` is called when your application needs to render a new frame, typically tied to the refresh rate of the monitor.
For a list of available handlers and their signatures, see the [app cheatsheet](../doc/cheatsheets/cheatsheet_app.h).
Open [`main.c`](../samples/clock/src/main.c) and look at the definition of `oc_on_init()`. This handler is called when the applications starts, right after the application window has been created.
The first thing we do here is set the title and dimensions of the window. We then create the graphics resources that we'll use to draw the clock onto the window.
### Graphics surfaces
The next line of `oc_init()` creates a _graphics surface_. A surface represents a destination you can draw into using a specific API. In this sample, we're going to use a canvas surface, which allows drawing with a 2D vector graphics API. Other samples use a GLES surface to draw with the OpenGL ES API.
Before drawing into it, the surface must be selected as the current surface by calling `oc_surface_select()`. Once all drawing is done you can display the result by calling `oc_surface_present()`.
After creating the surface, we create a _canvas_. A canvas holds some context for drawing commands, like the current color or stroke width, as well as a command buffer that records all drawing commands. All canvas drawing functions use an implicit _current canvas_. You can select a canvas to be the current canvas by calling `oc_canvas_select()`, as seen at the begining of `oc_on_frame_refresh()`.
Canvas drawing functions like `oc_fill()` or `oc_stroke` merely add to the current canvas command buffer. You can later render those commands onto a canvas surface by calling `oc_render()`.
A special case of attribute setting function is the pair `oc_matrix_multiply_push()` and `oc_matrix_pop()`, which are used to manipulate a stack of transform matrices:
The font is loaded from a font file located in a data folder inside the app bundle. By default, Orca apps use this data folder as their "root" for file operations.
The runtime has a console overlay whose visiblity can be toggled on and off with `Shift + Cmd + D` on macOS, or `Shift + Ctrl + D` on Windows. Your application can log messages, warnings or errors to that console using the following functions:
void oc_log_warning(const char* fmt, ...); // warnings, displayed in orange.
void oc_log_error(const char* fmt, ...); // errors, displayed in red.
```
If you started the application from a terminal, the log entries are also duplicated there.
You can assert on a condition using `OC_ASSERT(test, fmt, ...)`. If the test fails, the runtime displays a message box including your message, and terminates the application.
You can unconditionally abort the application with a message box using `OC_ABORT(fmt, ...)`.
## Where to go next?
For more examples of how to use Orca APIs, you can look at the other [sample apps](../samples):
- [breakout](./samples/breakout) is a mini breakout game making use of the vector graphics API. It demonstrates using input and drawing images.
- [triangle](./samples/triangle) shows how to draw a spining triangle using the GLES API.
- [fluid](./samples/fluid) is a fluid simulation using a more complex GLES setup.
You can also ask questions in the [Handmade Network Discord](https://discord.gg/hmn), in particular in the [#orca](https://discord.com/channels/239737791225790464/1121811864066732082) channel.