#define FLAG_FLIP_ROTATING 0x400
#define FLAG_TARGETED 0x800
+#define FLAG_INPUT_NICE 0x1000
+
/*
0000 0 | 0001 1 | 0010 2 | 0011 3
| | | | |
float lvl_load_time;
float world_transition;
+ ui_ctx world_text;
}
st;
if( cell->state & FLAG_WALL )
height = 0xFF-0x3F + hash21i( (v2i){x,y}, 0x3F );
- config = 0xF;
+ config = cell->state & FLAG_INPUT_NICE? 0xB: 0xF;
}
pcell((v2i){x,y})->config = config;
{
text_buffers.title_count = gen_text_buffer( pLevel->title, &font_Ubuntu, (v2f){ -5.0f, -0.6f }, 0.6f, text_buffers.title_start );
text_buffers.desc_count = gen_text_buffer( pLevel->description, &font_Ubuntu, (v2f){ -5.0, -0.9f }, 0.25f, text_buffers.desc_start );
+
+ // Old style UI.
+ ui_px const unit_scale_px = 4*UI_GLYPH_SPACING_X; // 4 char per unit
+ ui_begin( &world.st.world_text, world.w*unit_scale_px, world.h*unit_scale_px );
+
+ for( int i = 0; i < vg_list_size( pLevel->strings ); i ++ )
+ {
+ struct world_string *wstr = &pLevel->strings[i];
+
+ if( wstr->str )
+ {
+ ui_px pos[2];
+
+ pos[0] = -UI_GLYPH_SPACING_X/2;
+
+ if( wstr->placement == k_placement_bottom )
+ pos[1] = 2*-unit_scale_px;
+ else
+ pos[1] = (world.h-1)*-unit_scale_px -6;
+
+ ui_text( &world.st.world_text, pos, wstr->str, 1, k_text_align_left );
+ }
+ }
+
+ ui_resolve( &world.st.world_text );
}
static int map_load( const char *str, const char *name )
reg_end ++;
}
+ else if( *c == '.' ) cell->state = FLAG_INPUT_NICE;
else if( *c == '#' ) cell->state = FLAG_WALL;
else if( ((u32)*c >= (u32)'A') && ((u32)*c <= (u32)'A'+0xf) )
{
struct cell *cell = pcell( (v2i){ x, y } );
if( cell->state & FLAG_WALL ) fputc( '#', stream );
+ else if( cell->state & FLAG_INPUT_NICE ) fputc( '.', stream );
else if( cell->state & FLAG_INPUT ) fputc( '+', stream );
else if( cell->state & FLAG_OUTPUT ) fputc( '-', stream );
else if( cell->state & FLAG_EMITTER ) fputc( '*', stream );
static void render_tile( v2i pos, struct cell *ptr, v4f const regular_colour, v4f const selected_colour )
{
int selected = world.selected == pos[1]*world.w + pos[0];
-
- int tile_offsets[][2] =
- {
- {2, 0}, {0, 3}, {0, 2}, {2, 2},
- {1, 0}, {2, 3}, {3, 2}, {1, 3},
- {3, 1}, {0, 1}, {1, 2}, {2, 1},
- {1, 1}, {3, 3}, {2, 1}, {2, 1}
- };
-
int uv[2];
- uv[0] = tile_offsets[ ptr->config ][0];
- uv[1] = tile_offsets[ ptr->config ][1];
+ uv[0] = ptr->config & 0x3;
+ uv[1] = ptr->config >> 2;
glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ),
(float)pos[0],
{
struct cell *cell = pcell((v2i){x,y});
- if( cell->state & (FLAG_CANAL|FLAG_INPUT|FLAG_OUTPUT|FLAG_EMITTER) )
+ if( cell->state & (FLAG_CANAL|FLAG_INPUT|FLAG_OUTPUT|FLAG_EMITTER|FLAG_INPUT_NICE) )
{
struct render_cmd *cmd;
- if( cell->config == k_cell_type_split || (cell->state & FLAG_EMITTER || cell->state & FLAG_IS_TRIGGER) )
+ if(
+ (cell->config == k_cell_type_split && (cell->state & FLAG_CANAL))
+ || (cell->state & (FLAG_EMITTER|FLAG_IS_TRIGGER))
+ )
cmd = &world.cmd_buf_tiles[ world.max_commands - (++ world.tile_special_count) ];
else
cmd = &world.cmd_buf_tiles[ world.tile_count ++ ];
glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ),
(float)cmd->pos[0],
(float)cmd->pos[1] + 0.125f,
- cell->state & FLAG_TARGETED? 3.0f: 0.0f,
- 0.0f
+ cell->state & FLAG_TARGETED? 3.0f: 2.0f,
+ 3.0f
);
draw_mesh( 0, 2 );
}
glUniform4f( SHADER_UNIFORM( shader_sdf, "uColour" ), 1.0f, 1.0f, 1.0f, 0.17f );
glDrawElements( GL_TRIANGLES, text_buffers.grid_count*6, GL_UNSIGNED_SHORT, (void*)( text_buffers.grid_start*6*sizeof(u16) ) );
+ // Old style
+ m3x3f mvp_text;
+ m3x3_identity( mvp_text );
+ m3x3_scale( mvp_text, (v3f){
+ 1.0f/ ((float)UI_GLYPH_SPACING_X*4.0f),
+ 1.0f/ -((float)UI_GLYPH_SPACING_X*4.0f),
+ 1.0f
+ });
+
+ m3x3_mul( vg_pv, mvp_text, mvp_text );
+ ui_draw( &world.st.world_text, mvp_text );
+
// WIRES
// ========================================================================================================
- //glDisable(GL_BLEND);
+ glEnable(GL_BLEND);
SHADER_USE( shader_wire );
glBindVertexArray( world.wire.vao );
resource_load_main();
+ // Init world text
+ {
+ ui_init_context( &world.st.world_text, 15000 );
+ }
+
// Create text buffers
{
// Work out the counts for each 'segment'
free_mesh( &world.shapes );
+ ui_context_free( &world.st.world_text );
+
map_free();
}
.name = "UI"
};
-ui_colourset ui_fl_colours = {
- .main = 0xff807373,
- .hover = 0xff918484,
- .active = 0xffad9f9e
-};
-
-ui_colourset ui_fl_colours_inactive = {
- .main = 0xff655958,
- .hover = 0xff655958,
- .active = 0xff655958
-};
-
static void resource_load_main(void)
{
// Textures // UI
vg_tex2d_init( texture_list, vg_list_size( texture_list ) );
- ui_global_ctx.colours_main = &ui_fl_colours;
- gui_reset_colours();
// Audio
sfx_set_init( &audio_tile_mod, NULL );
int _unlock, _linked; // When completed, unlock this level
struct cmp_level *unlock, *linked;
+
+ struct world_string
+ {
+ enum placement
+ {
+ k_placement_top,
+ k_placement_bottom
+ }
+ placement;
+
+ const char *str;
+ }
+ strings[2];
int serial_id;
int is_tutorial;
.title = "3 BIT ADDITION",
.map_name = "cmp_add3b",
.description = "",
+ .strings =
+ {
+ {
+ .placement = k_placement_top,
+ //.str ="\t\t\t\t\t\t\t\t\t| NUMBER A | | NUMBER B |\n"
+ .str =""
+"\t\t\t\t\t\t\t\t\t\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82 \x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82\n"
+"\t\t\t\t\t\t\t\t\t\x83 4 2 1 \x84 add \x83 4 2 1 \x84\n"
+"\t\t\t\t\t\t\t\t\t\x83 \x84 \x83 \x84"
+ },
+ {
+ .placement = k_placement_bottom,
+ .str =
+"\t\t\t\x83 \x84\n"
+"\t\t\t\x83 8 4 2 1 \x84 result a+b\n"
+"\t\t\t\x85\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x87\x86"
+ }
+ },
._unlock = 25
},
int start = VG_MIN( vg_console.cursor_pos, vg_console.cursor_user ),
end = VG_MAX( vg_console.cursor_pos, vg_console.cursor_user );
- ui_global_ctx.cursor[0] = (start * ui_glyph_spacing_x * vg_console.scale);
- ui_global_ctx.cursor[2] = (start == end? 0.5f: (float)(end-start)) * (float)ui_glyph_spacing_x * (float)vg_console.scale;
+ ui_global_ctx.cursor[0] = (start * UI_GLYPH_SPACING_X * vg_console.scale);
+ ui_global_ctx.cursor[2] = (start == end? 0.5f: (float)(end-start)) * (float)UI_GLYPH_SPACING_X * (float)vg_console.scale;
ui_fill_rect( &ui_global_ctx, ui_global_ctx.cursor, 0x66ffffff );
}
0x6000060,0,0,0,0x7e0,0xc0,0x300,0,
0x6000060,0,0,0,0x3c0,0,0,0,
0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
+0,0x100,0x800100,0x800000,0,0,0,0,
+0,0x100,0x800100,0x800000,0,0,0,0,
+0,0,0,0,0x2000040,0,0,0,
+0,0x100,0x800100,0x800000,0x4000020,0,0,0,
+0,0x100,0x800100,0x800000,0x8000010,0,0,0,
+0,0,0,0,0x8000010,0,0,0,
+0,0x100,0x800100,0x800000,0x8000010,0,0,0,
+0x1b66db6,0x6d800100,0x800100,0x800000,0x68000016,0,0,0,
+0,0,0,0,0x8000010,0,0,0,
+0x1000000,0x800100,0x8001b6,0x6d806db6,0x8000010,0,0,0,
+0x1000000,0x800100,0x800000,0,0x8000010,0,0,0,
+0,0,0,0,0x8000010,0,0,0,
+0x1000000,0x800100,0x800000,0,0x4000020,0,0,0,
+0x1000000,0x800100,0x800000,0,0x2000040,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
UNIFORMS({ "uPv", "uTexGlyphs" })
)
-#define UI_AUTO_FILL 0
-//#define UI_DEBUG
-
// Types
// ===========================================================================================================
struct ui_ctx
{
- ui_px padding;
-
struct ui_qnode
{
ui_rect rect;
*verts;
#pragma pack(pop)
- u32 override_colour;
-
u32 num_verts;
u16 *indices;
u32 num_indices;
ui_px mouse[2];
int click_state; // 0: released, 1: on down, 2: pressed, 3: on release
- ui_colourset *colours_main;
- ui_colourset *colours_current;
+ ui_colourset *colours;
GLuint vao;
GLuint vbo;
// Globals
// ===========================================================================================================
-// Opengl
-static ui_px ui_glyph_spacing_x = 9;
-static GLuint ui_glyph_texture = 0;
+#define UI_GLYPH_SPACING_X 9
-ui_colourset ui_default_colours = {
- .main = 0xff00ff00,
- .hover = 0xffff00ff,
- .active = 0xffff0000
-};
-ui_ctx ui_global_ctx = {
- .padding = 8,
- .colours_main = &ui_default_colours
+static GLuint ui_glyph_texture = 0;
+static ui_colourset ui_default_colours = {
+ .main = 0xff807373,
+ .hover = 0xff918484,
+ .active = 0xffad9f9e
};
+static ui_ctx ui_global_ctx;
// Initialization
// ===========================================================================================================
-static void ui_reset_colours( ui_ctx *ctx );
static void ui_init_context( ui_ctx *ctx, int index_buffer_size )
{
- ui_reset_colours( ctx );
-
u32 vertex_buffer_size = (index_buffer_size+(index_buffer_size/2));
// Generate the buffer we are gonna be drawing to
{
ctx->verts = (struct ui_vert *)malloc( vertex_buffer_size * sizeof(struct ui_vert) );
ctx->indices = (u16*)malloc( index_buffer_size * sizeof(u16) );
+
+ if( !ctx->colours )
+ ctx->colours = &ui_default_colours;
}
}
static void ui_default_free(void)
{
glDeleteTextures( 1, &ui_glyph_texture );
-
ui_context_free( &ui_global_ctx );
}
rect[3] -= pad*2;
}
-static void ui_vis_rect( ui_rect rect, u32 colour )
-{
- #ifdef UI_DEBUG
- v2f p0;
- v2f p1;
-
- p0[0] = rect[0];
- p0[1] = rect[1];
- p1[0] = rect[0]+rect[2];
- p1[1] = rect[1]+rect[3];
-
- vg_line( p0, (v2f){p1[0],p0[1]}, colour );
- vg_line( (v2f){p1[0],p0[1]}, p1, colour );
- vg_line( p1, (v2f){p0[0],p1[1]}, colour );
- vg_line( (v2f){p0[0],p1[1]}, p0, colour );
- #endif
-}
-
// Stack control
// ===========================================================================================================
static void ui_end( ui_ctx *ctx )
{
struct ui_qnode *node = &ctx->stack[ --ctx->stack_count ];
-
ui_rect_copy( node->rect, ctx->cursor );
- ui_vis_rect( ctx->cursor,
- (node->mouse_over && (node->capture_id == ctx->capture_mouse_id))? 0xffff0000: 0xff0000ff );
}
static void ui_end_down( ui_ctx *ctx )
u32 current_colour = 0x00ffffff;
const char *_c = str;
- char c;
+ u8 c;
text_cursor[0] = pos[0] + ui_text_line_offset( str, scale, align );
text_cursor[1] = pos[1];
if( c == '\n' )
{
text_cursor[1] += 14*scale;
- text_cursor[0] = ctx->cursor[0] + ui_text_line_offset( _c, scale, align );
+ text_cursor[0] = pos[0] + ui_text_line_offset( _c, scale, align );
continue;
}
- else if( c >= 33 && c <= 126 )
+ else if( c >= 33 )
{
u8 glyph_base[2];
u8 glyph_index = c;
break;
}
}
+
+ continue;
}
+ else if( c == '\t' )
+ {
+ text_cursor[0] += UI_GLYPH_SPACING_X*scale*4;
+ continue;
+ }
- text_cursor[0] += 9*scale;
+ text_cursor[0] += UI_GLYPH_SPACING_X*scale;
}
}
if( ui_hasmouse(ctx) )
{
- ui_fill_rect( ctx, ctx->cursor, ctx->colours_current->hover );
+ ui_fill_rect( ctx, ctx->cursor, ctx->colours->hover );
if( ctx->click_state == 1 )
{
return k_button_hold;
}
else
- ui_fill_rect( ctx, ctx->cursor, ctx->colours_current->main );
+ ui_fill_rect( ctx, ctx->cursor, ctx->colours->main );
}
return k_button_released;
ui_new_node( ctx );
{
- ui_fill_rect( ctx, ctx->cursor, ctx->colours_current->background );
+ ui_fill_rect( ctx, ctx->cursor, ctx->colours->background );
ui_capture_mouse( ctx, id );
ctx->cursor[1] += scrollbar->py;
ui_new_node( ctx );
{
ui_capture_mouse( ctx, __COUNTER__ );
- struct ui_vert *drag_bar = ui_fill_rect( ctx, ctx->cursor, ctx->colours_current->bar );
+ struct ui_vert *drag_bar = ui_fill_rect( ctx, ctx->cursor, ctx->colours->bar );
if( ui_hasmouse( ctx ) || scrollbar->drag )
{
- drag_bar[0].colour = ctx->colours_current->bar_hover;
- drag_bar[1].colour = ctx->colours_current->bar_hover;
- drag_bar[2].colour = ctx->colours_current->bar_hover;
- drag_bar[3].colour = ctx->colours_current->bar_hover;
+ drag_bar[0].colour = ctx->colours->bar_hover;
+ drag_bar[1].colour = ctx->colours->bar_hover;
+ drag_bar[2].colour = ctx->colours->bar_hover;
+ drag_bar[3].colour = ctx->colours->bar_hover;
// start drag
if( ctx->click_state == 1 )
return ((float)scrollbar->py / range) * overlap;
}
-static void ui_override_colours( ui_ctx *ctx, ui_colourset *set )
-{
- ctx->colours_current = set;
-}
-
-static void ui_reset_colours( ui_ctx *ctx )
-{
- ctx->colours_current = ctx->colours_main;
- ctx->override_colour = 0xffffffff;
-}
-
static void ui_push_image( ui_ctx *ctx, ui_rect rc, GLuint image )
{
struct ui_image *img = &ctx->images[ ctx->image_count ++ ];
#define gui_want_mouse() ui_want_mouse( &ui_global_ctx )
#define gui_push_image(...) ui_push_image( &ui_global_ctx, __VA_ARGS__ )
#define gui_scrollbar(...) ui_scrollbar( &ui_global_ctx, __VA_ARGS__)
-#define gui_override_colours(...) ui_override_colours( &ui_global_ctx, __VA_ARGS__)
#define gui_reset_colours(...) ui_reset_colours( &ui_global_ctx )