+ struct mesh_wire *mw = &world.wire;
+
+ v2f wire_points[ num_segments * 2 ];
+ u16 wire_indices[ 6*(num_segments-1) ];
+
+ for( int i = 0; i < num_segments; i ++ )
+ {
+ float l = (float)i / (float)(num_segments-1);
+
+ v2_copy( (v2f){ l, -0.5f }, wire_points[i*2+0] );
+ v2_copy( (v2f){ l, 0.5f }, wire_points[i*2+1] );
+
+ if( i < num_segments-1 )
+ {
+ wire_indices[ i*6+0 ] = i*2 + 0;
+ wire_indices[ i*6+1 ] = i*2 + 1;
+ wire_indices[ i*6+2 ] = i*2 + 3;
+ wire_indices[ i*6+3 ] = i*2 + 0;
+ wire_indices[ i*6+4 ] = i*2 + 3;
+ wire_indices[ i*6+5 ] = i*2 + 2;
+ }
+ }
+
+ glGenVertexArrays( 1, &mw->vao );
+ glGenBuffers( 1, &mw->vbo );
+ glGenBuffers( 1, &mw->ebo );
+ glBindVertexArray( mw->vao );
+
+ glBindBuffer( GL_ARRAY_BUFFER, mw->vbo );
+
+ glBufferData( GL_ARRAY_BUFFER, sizeof( wire_points ), wire_points, GL_STATIC_DRAW );
+ glBindVertexArray( mw->vao );
+
+ glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mw->ebo );
+ glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( wire_indices ), wire_indices, GL_STATIC_DRAW );
+
+ // XY
+ glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0 );
+ glEnableVertexAttribArray( 0 );
+
+ VG_CHECK_GL();
+
+ mw->em = vg_list_size( wire_indices );
+ }
+
+ // Create info data texture
+ {
+ glGenTextures( 1, &world.background_data );
+ glBindTexture( GL_TEXTURE_2D, world.background_data );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
+ vg_tex2d_nearest();
+ }
+
+ // Create random smaples texture
+ {
+ u8 *data = malloc(512*512*2);
+ for( int i = 0; i < 512*512*2; i ++ )
+ data[ i ] = rand()/(RAND_MAX/255);
+
+ glGenTextures( 1, &world.random_samples );
+ glBindTexture( GL_TEXTURE_2D, world.random_samples );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RG, 512, 512, 0, GL_RG, GL_UNSIGNED_BYTE, data );
+ vg_tex2d_linear();
+ vg_tex2d_repeat();
+
+ free( data );
+ }
+
+ resource_load_main();
+
+ // Restore gamestate
+ career_load();
+ console_load_map( 1, level_pack_1 );
+}
+
+void vg_free(void)
+{
+ console_save_map( 0, NULL );
+ career_serialize();
+
+ resource_free_main();
+
+ glDeleteTextures( 1, &world.background_data );
+ glDeleteTextures( 1, &world.random_samples );
+
+ glDeleteVertexArrays( 1, &world.wire.vao );
+ glDeleteBuffers( 1, &world.wire.vbo );
+ glDeleteBuffers( 1, &world.wire.ebo );
+
+ free_mesh( &world.tile );
+ free_mesh( &world.circle );
+ free_mesh( &world.numbers );
+
+ map_free();
+}
+
+static int cell_interactive( v2i co )
+{
+ // Bounds check
+ if( co[0] < 2 || co[0] >= world.w-2 || co[1] < 2 || co[1] >= world.h-2 )
+ return 0;
+
+ // Flags check
+ if( world.data[ world.w*co[1] + co[0] ].state & (FLAG_WALL|FLAG_INPUT|FLAG_OUTPUT) )