Skip to content

Commit

Permalink
Backport Shape.drawImmediate from 5.2
Browse files Browse the repository at this point in the history
This is another function that should have gone in from the start.  Now
that it's backported I'll be able to lower its API level to 1.
  • Loading branch information
fatcerberus committed May 6, 2018
1 parent c05f244 commit acd244b
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 53 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ miniSphere Changelog
v5.0.2 - TBD
------------

* Adds `Shape.drawImmediate()` function which avoids the overhead of creating
VertexList and Shape objects for immediate-mode drawing.
* Adds `index.mjs` to the list of filenames recognized by the module loader.
* Adds `print()` as an alias for `SSj.log()`.
* Adds support for passing command-line arguments to a game's `main()`.
Expand Down
88 changes: 37 additions & 51 deletions assets/system/game_modules/prim.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,12 @@ class Prim
var v1 = 1.0 - sy / texture.height;
var u2 = (sx + width) / texture.width;
var v2 = 1.0 - (sy + height) / texture.height;
var shape = new Shape(ShapeType.TriStrip, texture,
new VertexList([
{ x: x1, y: y1, u: u1, v: v1, color: mask },
{ x: x2, y: y1, u: u2, v: v1, color: mask },
{ x: x1, y: y2, u: u1, v: v2, color: mask },
{ x: x2, y: y2, u: u2, v: v2, color: mask },
]));
shape.draw(surface);
Shape.drawImmediate(surface, ShapeType.TriStrip, texture, [
{ x: x1, y: y1, u: u1, v: v1, color: mask },
{ x: x2, y: y1, u: u2, v: v1, color: mask },
{ x: x1, y: y2, u: u1, v: v2, color: mask },
{ x: x2, y: y2, u: u2, v: v2, color: mask },
]);
}

static drawCircle(surface, x, y, radius, color)
Expand All @@ -87,9 +85,7 @@ class Prim
color: color
});
}
var vList = new VertexList(vertices);
var shape = new Shape(ShapeType.LineLoop, vList)
shape.draw(surface);
Shape.drawImmediate(surface, ShapeType.LineLoop, vertices);
}

static drawSolidCircle(surface, x, y, radius, color, color2)
Expand Down Expand Up @@ -122,9 +118,7 @@ class Prim
color: color2
};

var vList = new VertexList(vertices);
var shape = new Shape(ShapeType.Fan, vList);
shape.draw(surface);
Shape.drawImmediate(surface, ShapeType.Fan, vertices);
}

static drawSolidRectangle(surface, x, y, width, height, color_ul, color_ur, color_lr, color_ll)
Expand All @@ -133,49 +127,43 @@ class Prim
color_lr = color_lr || color_ul;
color_ll = color_ll || color_ul;

var shape = new Shape(ShapeType.TriStrip,
new VertexList([
{ x: x, y: y, color: color_ul },
{ x: x + width, y: y, color: color_ur },
{ x: x, y: y + height, color: color_ll },
{ x: x + width, y: y + height, color: color_lr },
]));
shape.draw(surface);
Shape.drawImmediate(surface, ShapeType.TriStrip, [
{ x: x, y: y, color: color_ul },
{ x: x + width, y: y, color: color_ur },
{ x: x, y: y + height, color: color_ll },
{ x: x + width, y: y + height, color: color_lr },
]);
}

static drawSolidTriangle(surface, x1, y1, x2, y2, x3, y3, color1, color2, color3)
{
color2 = color2 || color1;
color3 = color3 || color1;

var shape = new Shape(ShapeType.Triangles,
new VertexList([
{ x: x1, y: y1, color: color1 },
{ x: x2, y: y2, color: color2 },
{ x: x3, y: y3, color: color3 },
]));
Shape.drawImmediate(surface, ShapeType.Triangles, [
{ x: x1, y: y1, color: color1 },
{ x: x2, y: y2, color: color2 },
{ x: x3, y: y3, color: color3 },
]);
}

static drawLine(surface, x1, y1, x2, y2, thickness, color1, color2)
{
color2 = color2 || color1;

var shape;
var xSize = x2 - x1;
var ySize = y2 - y1;
var length = Math.sqrt(xSize*xSize + ySize*ySize);
if (length == 0.0)
return;
var tx = 0.5 * thickness * (y2 - y1) / length;
var ty = 0.5 * thickness * -(x2 - x1) / length;
shape = new Shape(ShapeType.Fan,
new VertexList([
{ x: x1 + tx, y: y1 + ty, color: color1 },
{ x: x1 - tx, y: y1 - ty, color: color1 },
{ x: x2 - tx, y: y2 - ty, color: color2 },
{ x: x2 + tx, y: y2 + ty, color: color2 },
]));
shape.draw(surface);
Shape.drawImmediate(surface, ShapeType.Fan, [
{ x: x1 + tx, y: y1 + ty, color: color1 },
{ x: x1 - tx, y: y1 - ty, color: color1 },
{ x: x2 - tx, y: y2 - ty, color: color2 },
{ x: x2 + tx, y: y2 + ty, color: color2 },
]);
}

static drawPoint(surface, x, y, color)
Expand All @@ -190,20 +178,18 @@ class Prim
var y1 = y + t;
var x2 = x1 + width - thickness;
var y2 = y1 + height - thickness;
var shape = new Shape(ShapeType.TriStrip,
new VertexList([
{ x: x1 - t, y: y1 - t, color: color },
{ x: x1 + t, y: y1 + t, color: color },
{ x: x2 + t, y: y1 - t, color: color },
{ x: x2 - t, y: y1 + t, color: color },
{ x: x2 + t, y: y2 + t, color: color },
{ x: x2 - t, y: y2 - t, color: color },
{ x: x1 - t, y: y2 + t, color: color },
{ x: x1 + t, y: y2 - t, color: color },
{ x: x1 - t, y: y1 - t, color: color },
{ x: x1 + t, y: y1 + t, color: color },
]));
shape.draw(surface);
Shape.drawImmediate(surface, ShapeType.TriStrip, [
{ x: x1 - t, y: y1 - t, color: color },
{ x: x1 + t, y: y1 + t, color: color },
{ x: x2 + t, y: y1 - t, color: color },
{ x: x2 - t, y: y1 + t, color: color },
{ x: x2 + t, y: y2 + t, color: color },
{ x: x2 - t, y: y2 - t, color: color },
{ x: x1 - t, y: y2 + t, color: color },
{ x: x1 + t, y: y2 - t, color: color },
{ x: x1 - t, y: y1 - t, color: color },
{ x: x1 + t, y: y1 + t, color: color },
]);
}

static fill(surface, color)
Expand Down
76 changes: 74 additions & 2 deletions src/minisphere/pegasus.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ COLORS[] =
{ "Plum", 221, 160, 221, 255 },
{ "PowderBlue", 176, 224, 230, 255 },
{ "Purple", 128, 0, 128, 255 },
{ "PurwaBlue", 155, 225, 255, 255 },
{ "RebeccaPurple", 102, 51, 153, 255 },
{ "Red", 255, 0, 0, 255 },
{ "RosyBrown", 188, 143, 143, 255 },
{ "RoyalBlue", 65, 105, 225, 255 },
Expand Down Expand Up @@ -352,6 +350,7 @@ static bool js_Shader_setInt (int num_args, bool is_ctor, int ma
static bool js_Shader_setIntArray (int num_args, bool is_ctor, int magic);
static bool js_Shader_setIntVector (int num_args, bool is_ctor, int magic);
static bool js_Shader_setMatrix (int num_args, bool is_ctor, int magic);
static bool js_Shape_drawImmediate (int num_args, bool is_ctor, int magic);
static bool js_new_Shape (int num_args, bool is_ctor, int magic);
static bool js_Shape_get_indexList (int num_args, bool is_ctor, int magic);
static bool js_Shape_get_texture (int num_args, bool is_ctor, int magic);
Expand Down Expand Up @@ -638,6 +637,7 @@ pegasus_init(void)
api_define_method("Shader", "setIntVector", js_Shader_setIntVector, 0);
api_define_method("Shader", "setMatrix", js_Shader_setMatrix, 0);
api_define_class("Shape", PEGASUS_SHAPE, js_new_Shape, js_Shape_finalize);
api_define_function("Shape", "drawImmediate", js_Shape_drawImmediate, 0);
api_define_property("Shape", "indexList", false, js_Shape_get_indexList, js_Shape_set_indexList);
api_define_property("Shape", "texture", false, js_Shape_get_texture, js_Shape_set_texture);
api_define_property("Shape", "vertexList", false, js_Shape_get_vertexList, js_Shape_set_vertexList);
Expand Down Expand Up @@ -3570,6 +3570,78 @@ js_Shader_finalize(void* host_ptr)
shader_unref(host_ptr);
}

static bool
js_Shape_drawImmediate(int num_args, bool is_ctor, int magic)
{
int array_idx;
ALLEGRO_BITMAP* bitmap = NULL;
int draw_mode;
int item_idx;
int num_entries;
image_t* surface;
image_t* texture = NULL;
shape_type_t type;
ALLEGRO_VERTEX* vertices;

int i;

if ((jsal_is_class_obj(0, PEGASUS_SURFACE))) {
surface = jsal_require_class_obj(0, PEGASUS_SURFACE);
type = jsal_require_int(1);
array_idx = 2;
if (num_args >= 4) {
if (!jsal_is_null(2) && !jsal_is_undefined(2))
texture = jsal_require_class_obj(2, PEGASUS_TEXTURE);
array_idx = 3;
}
}
else {
surface = screen_backbuffer(g_screen);
type = jsal_require_int(0);
array_idx = 1;
if (num_args >= 3) {
if (!jsal_is_null(1) && !jsal_is_undefined(1))
texture = jsal_require_class_obj(2, PEGASUS_TEXTURE);
array_idx = 2;
}
}
jsal_require_array(array_idx);

num_entries = jsal_get_length(array_idx);
if (num_entries == 0)
jsal_error(JS_RANGE_ERROR, "Empty list is not allowed");

vertices = alloca(num_entries * sizeof(ALLEGRO_VERTEX));
for (i = 0; i < num_entries; ++i) {
jsal_get_prop_index(array_idx, i);
jsal_require_object_coercible(-1);
item_idx = jsal_normalize_index(-1);
vertices[i].x = jsal_get_prop_key(item_idx, s_key_x) ? jsal_require_number(-1) : 0.0f;
vertices[i].y = jsal_get_prop_key(item_idx, s_key_y) ? jsal_require_number(-1) : 0.0f;
vertices[i].z = jsal_get_prop_key(item_idx, s_key_z) ? jsal_require_number(-1) : 0.0f;
vertices[i].u = jsal_get_prop_key(item_idx, s_key_u) ? jsal_require_number(-1) : 0.0f;
vertices[i].v = jsal_get_prop_key(item_idx, s_key_v) ? jsal_require_number(-1) : 0.0f;
vertices[i].color = jsal_get_prop_key(item_idx, s_key_color)
? nativecolor(jsal_pegasus_require_color(-1))
: al_map_rgba_f(1.0f, 1.0f, 1.0f, 1.0f);
jsal_pop(7);
}

draw_mode = type == SHAPE_LINES ? ALLEGRO_PRIM_LINE_LIST
: type == SHAPE_LINE_LOOP ? ALLEGRO_PRIM_LINE_LOOP
: type == SHAPE_LINE_STRIP ? ALLEGRO_PRIM_LINE_STRIP
: type == SHAPE_TRIANGLES ? ALLEGRO_PRIM_TRIANGLE_LIST
: type == SHAPE_TRI_STRIP ? ALLEGRO_PRIM_TRIANGLE_STRIP
: type == SHAPE_TRI_FAN ? ALLEGRO_PRIM_TRIANGLE_FAN
: ALLEGRO_PRIM_POINT_LIST;
if (texture != NULL)
bitmap = image_bitmap(texture);
image_render_to(surface, NULL);
shader_use(galileo_shader(), false);
al_draw_prim(vertices, NULL, bitmap, 0, num_entries, draw_mode);
return false;
}

static bool
js_new_Shape(int num_args, bool is_ctor, int magic)
{
Expand Down

0 comments on commit acd244b

Please sign in to comment.