enable workshop world submissions
authorhgn <hgodden00@gmail.com>
Thu, 8 Jun 2023 15:39:05 +0000 (16:39 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 8 Jun 2023 15:39:05 +0000 (16:39 +0100)
addon.c
addon.h
ent_skateshop.c
maps_src/template/addon.inf [new file with mode: 0644]
maps_src/template/preview.jpg [new file with mode: 0644]
skaterift.c
skaterift.h
workshop.c
world_load.c
world_load.h
world_routes.c

diff --git a/addon.c b/addon.c
index 29b24a020ba59bf01fba14f3c3fc17f8d564d623..504904fac98c26546869ecc633033924eb7ef42e 100644 (file)
--- a/addon.c
+++ b/addon.c
@@ -4,6 +4,8 @@
 #include "addon.h"
 #include "vg/vg_msg.h"
 #include "steam.h"
+#include "workshop_types.h"
+#include "workshop.h"
 
 static u32 addon_count( enum workshop_file_type type ){
    return addon_system.registry_type_counts[ type ];
@@ -347,4 +349,35 @@ VG_STATIC void addon_mount_content_folder( enum workshop_file_type type,
    vg_dir_close(&dir);
 }
 
+static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){
+   if( reg->workshop_id ){
+      vg_async_item *call = 
+         vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
+      struct async_workshop_filepath_info *info = call->payload;
+      info->buf = folder->buffer;
+      info->id = reg->workshop_id;
+      info->len = folder->len;
+      vg_async_dispatch( call, async_workshop_get_filepath );
+      vg_async_stall(); /* too bad! */
+      if( info->buf[0] == '\0' ){
+         vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n",
+                     reg->workshop_id );
+         return 0;
+      }
+      folder->i = strlen( folder->buffer );
+      return 1;
+   }
+   else{
+      folder->i = 0;
+      if( reg->type == k_workshop_file_type_board )
+         vg_strcat( folder, "boards/" );
+      else if( reg->type == k_workshop_file_type_world )
+         vg_strcat( folder, "maps/" );
+      else return 0;
+
+      vg_strcat( folder, reg->foldername );
+      return 1;
+   }
+}
+
 #endif /* ADDON_C */
diff --git a/addon.h b/addon.h
index 65e88e187ccc0d517defa694f5366270b906c748..f1d466e10f7938237331c95a5e3d565e7af760e8 100644 (file)
--- a/addon.h
+++ b/addon.h
@@ -1,7 +1,8 @@
 #ifndef ADDON_H
 #define ADDON_H
 
-#include "workshop.h"
+#include "common.h"
+#include "vg/vg_steam_ugc.h"
 #include "workshop_types.h"
 #define ADDON_MOUNTED_MAX 128
 #define ADDON_FOLDERNAME_MAX 64
@@ -38,6 +39,7 @@ static void addon_system_init( void );
 static u32 addon_count( enum workshop_file_type type );
 static addon_reg *get_addon_from_index(enum workshop_file_type type, u32 index);
 static u32 get_index_from_addon( enum workshop_file_type type, addon_reg *a );
+static int addon_get_content_folder( addon_reg *reg, vg_str *folder );
 
 /* scanning routines */
 VG_STATIC void addon_mount_content_folder( enum workshop_file_type type,
index 08d32e82e265cccb351394a7fdb72050b4ca8d46..7898f5877d33d7fe185c70a0124d915a0d69963f 100644 (file)
@@ -130,7 +130,6 @@ VG_STATIC void workshop_visibile_load_loop(void)
 {
    vg_info( "Running load loop\n" );
    char path_buf[4096];
-   vg_str folder;
 
    for( u32 i=0; i<SKATESHOP_BOARD_CACHE_MAX; i++ ){
       struct cache_board *cache_ptr = &global_skateshop.cache[i];
@@ -146,36 +145,14 @@ VG_STATIC void workshop_visibile_load_loop(void)
 
          /* continue with the request */
          SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
-
          cache_ptr->reg_ptr = get_addon_from_index( k_workshop_file_type_board,
                                                     cache_ptr->reg_index );
 
-         if( cache_ptr->reg_ptr->workshop_id ){
-            vg_async_item *call = 
-               vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
-
-            struct async_workshop_filepath_info *info = call->payload;
-            info->buf = path_buf;
-            info->id = cache_ptr->reg_ptr->workshop_id;
-            info->len = vg_list_size(path_buf);
-            vg_async_dispatch( call, async_workshop_get_filepath );
-            vg_async_stall(); /* too bad! */
-
-            if( path_buf[0] == '\0' ){
-               vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n",
-                           cache_ptr->reg_ptr->workshop_id );
-               goto file_is_broken;
-            }
+         vg_str folder;
+         vg_strnull( &folder, path_buf, 4096 );
+         if( !addon_get_content_folder( cache_ptr->reg_ptr, &folder ) )
+            goto file_is_broken;
 
-            folder.buffer = path_buf;
-            folder.i = strlen(path_buf);
-            folder.len = 4096;
-         }
-         else{
-            vg_strnull( &folder, path_buf, 4096 );
-            vg_strcat( &folder, "boards/" );
-            vg_strcat( &folder, cache_ptr->reg_ptr->foldername );
-         }
 
          /* load content files
           * --------------------------------- */
@@ -336,45 +313,38 @@ VG_STATIC void pointcloud_clear_async(void *_, u32 __)
 VG_STATIC void skateshop_preview_loader_thread( void *_data )
 {
    addon_reg *reg = _data;
+
+   char path_buf[4096];
+   vg_str path;
+   vg_strnull( &path, path_buf, 4096 );
+   addon_get_content_folder( reg, &path );
+   vg_strcat( &path, "/preview.bin" );
+
+   vg_linear_clear(vg_mem.scratch);
+   u32 size;
    
-   if( reg->workshop_id ){
-      vg_error( "Workshop files unsupported\n" );
-      vg_async_call( pointcloud_clear_async, NULL, 0 );
-   }
-   else{
-      char path_buf[4096];
-      vg_str path;
-      vg_strnull( &path, path_buf, 4096 );
-      vg_strcat( &path, "maps/" );
-      vg_strcat( &path, reg->foldername );
-      vg_strcat( &path, "/preview.bin" );
-
-      vg_linear_clear(vg_mem.scratch);
-      u32 size;
-      
-      void *data = vg_file_read( vg_mem.scratch, path_buf, &size );
-      if( data ){
-         if( size < sizeof(pointcloud_buffer) ){
-            vg_async_call( pointcloud_clear_async, NULL, 0 );
-            return;
-         }
-         
-         vg_async_item *call = vg_async_alloc(size);
-         pointcloud_buffer *pcbuf = call->payload;
-         memcpy( pcbuf, data, size );
-
-         u32 point_count = (size-sizeof(pointcloud_buffer)) /
-                              sizeof(struct pointcloud_vert);
-         pcbuf->max = point_count;
-         pcbuf->count = point_count;
-         pcbuf->op = k_pointcloud_op_clear;
-
-         vg_async_dispatch( call, async_pointcloud_sub );
-         vg_async_call( pointcloud_async_end, NULL, 0 );
-      }
-      else{
+   void *data = vg_file_read( vg_mem.scratch, path_buf, &size );
+   if( data ){
+      if( size < sizeof(pointcloud_buffer) ){
          vg_async_call( pointcloud_clear_async, NULL, 0 );
+         return;
       }
+      
+      vg_async_item *call = vg_async_alloc(size);
+      pointcloud_buffer *pcbuf = call->payload;
+      memcpy( pcbuf, data, size );
+
+      u32 point_count = (size-sizeof(pointcloud_buffer)) /
+                           sizeof(struct pointcloud_vert);
+      pcbuf->max = point_count;
+      pcbuf->count = point_count;
+      pcbuf->op = k_pointcloud_op_clear;
+
+      vg_async_dispatch( call, async_pointcloud_sub );
+      vg_async_call( pointcloud_async_end, NULL, 0 );
+   }
+   else{
+      vg_async_call( pointcloud_clear_async, NULL, 0 );
    }
 }
 
@@ -564,7 +534,9 @@ VG_STATIC void global_skateshop_preupdate(void)
          if( loadable && button_down( k_srbind_maccept ) ){
             vg_info( "Select rift (%u)\n", 
                       global_skateshop.selected_world_id );
-            skaterift_change_world( reg->foldername );
+            world_loader.reg = reg;
+            world_loader.override_name[0] = '\0';
+            skaterift_change_world_start();
             return;
          }
          else{
@@ -711,6 +683,8 @@ fade_out:;
    }
 
    if( global_skateshop.render.reg_id != global_skateshop.selected_board_id ){
+      global_skateshop.render.item_title = "";
+      global_skateshop.render.item_desc = "";
       addon_reg *reg = cache_ptr->reg_ptr;
       vg_msg root;
       vg_msg_init( &root, reg->metadata, reg->metadata_len );
@@ -771,6 +745,8 @@ VG_STATIC void skateshop_render_worldshop(void)
                                   mdl_entity_id_id(shop->boards.id_info));
 
    if( global_skateshop.render.world_reg != global_skateshop.selected_world_id){
+      global_skateshop.render.world_title = "";
+
       addon_reg *reg = get_addon_from_index( k_workshop_file_type_world,
                                        global_skateshop.selected_world_id );
       vg_msg root;
@@ -808,6 +784,12 @@ VG_STATIC void skateshop_render_worldshop(void)
          vg_strcat( &subtext, "Loading..." );
       }
       else{
+         addon_reg *reg = get_addon_from_index( k_workshop_file_type_world,
+                                          global_skateshop.selected_world_id );
+
+         if( reg->workshop_id )
+            vg_strcat( &subtext, "(Workshop) " );
+
          vg_strcat( &subtext, global_skateshop.render.world_loc );
       }
    }
diff --git a/maps_src/template/addon.inf b/maps_src/template/addon.inf
new file mode 100644 (file)
index 0000000..b71b466
Binary files /dev/null and b/maps_src/template/addon.inf differ
diff --git a/maps_src/template/preview.jpg b/maps_src/template/preview.jpg
new file mode 100644 (file)
index 0000000..63b72e4
Binary files /dev/null and b/maps_src/template/preview.jpg differ
index 6cb3579e819c5b5261229e7c25decda86bad586d..5400e76b43f1dd7234d80f2bebc523d9a33a78a4 100644 (file)
@@ -156,10 +156,10 @@ VG_STATIC void vg_load(void)
    /* 'systems' are completely loaded now */
    
    /* load home/permanent world manually */
-   strcpy( world_loader.name, "mp_spawn" );
+   world_loader.reg = NULL;
+   strcpy( world_loader.override_name, "mp_spawn" );
    world_loader.generate_point_cloud = 1;
    world_loader.world_index = 0;
-   world_loader.location = k_world_load_type_local;
    world_load_mdl( "maps/mp_spawn/main.mdl" );
 
    /* Completing addon registrations
@@ -195,6 +195,7 @@ VG_STATIC void vg_load(void)
    vg_async_call( async_addon_reg_update, NULL, 0 );
    vg_console_load_autos();
    menu_link();
+   temp_update_playermodel();
 
    vg_async_call( async_skaterift_complete, NULL, 0 );
 }
index 8f9e3e7596cd4871dd77ca5417f5e7f6036940c2..a139476f8d3878ed8d5d30bb05c86e2217b0fecc 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "common.h"
 #include "world.h"
+#include "addon.h"
 
 struct{
    enum async_operation{
@@ -23,7 +24,7 @@ struct{
 static skaterift = { .async_op = k_async_op_clientloading };
 
 /* Skaterift api */
-static void skaterift_change_world( const char *world_path );
+static void skaterift_change_world_start( void );
 static int  skaterift_change_world_command( int argc, const char *argv[] );
 
 /*
index bcb8574a016497006818e5ad81084cc8083c7876..6f715790a56555e73a9eddbd4c08f5b743712168 100644 (file)
@@ -534,7 +534,19 @@ VG_STATIC void _workshop_form_load_thread( void *data )
 VG_STATIC void workshop_op_load_model(void)
 {
    if( workshop_form.submission.type == k_workshop_file_type_world ){
-      vg_error( "Currently unsupported\n" );
+      vg_warn( "WORLD LOAD INFO Currently unsupported\n" );
+      return;
+   }
+
+   workshop_form.view_world = world_current_instance();
+
+   if( mdl_arrcount( &workshop_form.view_world->ent_swspreview ) ){
+      workshop_form.ptr_ent = 
+            mdl_arritm( &workshop_form.view_world->ent_swspreview, 0 );
+   }
+   else{
+      vg_error( "There is no ent_swspreview in the level. "
+                "Cannot publish here\n" );
       return;
    }
 
@@ -683,7 +695,7 @@ VG_STATIC void workshop_op_download_and_view_submission( int result_index )
          vg_msg root;
          vg_msg_init( &root, metadata_buf, len/2 );
          
-         vg_msg workshop;
+         vg_msg workshop = root;
          if( vg_msg_seekframe( &workshop, "workshop", k_vg_msg_first )){
             vg_msg_cmd kv_type = vg_msg_seekkv( &workshop, "type", 
                                                 k_vg_msg_first );
@@ -900,26 +912,24 @@ VG_STATIC void workshop_init(void)
    vg_console_reg_cmd( "workshop_submit", workshop_submit_command, NULL );
 }
 
-VG_STATIC void workshop_find_preview_entity(void)
-{
-   workshop_form.view_world = world_current_instance();
+VG_STATIC void workshop_render_world_preview(void){
+   render_fb_bind( gpipeline.fb_workshop_preview, 0 );
 
-   if( mdl_arrcount( &workshop_form.view_world->ent_swspreview ) ){
-      workshop_form.ptr_ent = 
-            mdl_arritm( &workshop_form.view_world->ent_swspreview, 0 );
-      workshop_form.page = k_workshop_form_edit;
-   }
-   else{
-      vg_error( "There is no ent_swspreview in the level. "
-                "Cannot publish here\n" );
-   }
+   glClearColor( 0.0f, 0.0f, 0.3f, 1.0f );
+   glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+   glEnable( GL_DEPTH_TEST );
+   glDisable( GL_BLEND );
+
+   render_world( localplayer.viewable_world, &main_camera, 1 );
+
+   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+   glViewport( 0,0, vg.window_x, vg.window_y );
 }
 
 /*
  * Redraw the model file into the workshop framebuffer
  */
-VG_STATIC void workshop_render_preview(void)
-{
+VG_STATIC void workshop_render_board_preview(void){
    if( !workshop_form.ptr_ent ){
       return;
    }
@@ -1024,88 +1034,65 @@ VG_STATIC void workshop_changed_description( char *buf, u32 len ){
    workshop_form.submission.submit_description = 1;
 }
 
-VG_STATIC void workshop_form_gui_edit_page( ui_rect content )
-{
-   if( workshop_form.submission.type == k_workshop_file_type_none ){
-      ui_rect box;
-      rect_copy( content, box );
-      box[3] = 128;
-      box[2] = (box[2]*2)/3;
-      ui_rect_center( content, box );
-
-      ui_rect row;
-      ui_split( box, k_ui_axis_h, 28, 0, row, box );
-      ui_text( row, "Select the type of item\n", 1, k_ui_align_middle_center,0);
-      ui_split( box, k_ui_axis_h, 28, 0, row, box );
-      ui_enum( row, "Type:", workshop_form_type_opts,
-               3, &workshop_form.submission.submission_type_selection );
-      ui_split( box, k_ui_axis_h, 8, 0, row, box );
-      ui_split( box, k_ui_axis_h, 28, 0, row, box );
-
-      ui_rect button_l, button_r;
-      rect_copy( row, button_l );
-      button_l[2] = 128*2;
-      ui_rect_center( row, button_l );
-      ui_split_ratio( button_l, k_ui_axis_v, 0.5f, 2, button_l, button_r );
-
-      if( workshop_form.submission.submission_type_selection.value !=
-            k_workshop_file_type_none ){
-         if( ui_button_text( button_l, "OK", 1 ) ){
-            workshop_form.submission.type = 
+VG_STATIC void workshop_form_gui_page_undecided( ui_rect content ){
+   ui_rect box;
+   rect_copy( content, box );
+   box[3] = 128;
+   box[2] = (box[2]*2)/3;
+   ui_rect_center( content, box );
+
+   ui_rect row;
+   ui_split( box, k_ui_axis_h, 28, 0, row, box );
+   ui_text( row, "Select the type of item\n", 1, k_ui_align_middle_center,0);
+   ui_split( box, k_ui_axis_h, 28, 0, row, box );
+   ui_enum( row, "Type:", workshop_form_type_opts,
+            3, &workshop_form.submission.submission_type_selection );
+   ui_split( box, k_ui_axis_h, 8, 0, row, box );
+   ui_split( box, k_ui_axis_h, 28, 0, row, box );
+
+   ui_rect button_l, button_r;
+   rect_copy( row, button_l );
+   button_l[2] = 128*2;
+   ui_rect_center( row, button_l );
+   ui_split_ratio( button_l, k_ui_axis_v, 0.5f, 2, button_l, button_r );
+
+   if( workshop_form.submission.submission_type_selection.value !=
+         k_workshop_file_type_none ){
+      if( ui_button_text( button_l, "OK", 1 ) ){
+         enum workshop_file_type type = 
                workshop_form.submission.submission_type_selection.value;
+         workshop_form.submission.type = type;
+
+         if( type == k_workshop_file_type_world ){
+            workshop_form.view_changed = 1;
+            workshop_form.file_intent = k_workshop_form_file_intent_new;
          }
       }
-      else{
-         ui_fill( button_l, ui_colour(k_ui_bg) );
-         ui_text( button_l, "OK", 1, k_ui_align_middle_center, 
-                  ui_colour(k_ui_bg+4) );
-      }
-      
-      if( ui_button_text( button_r, "Cancel", 1 ) ){
-         workshop_form.page = k_workshop_form_open;
-         workshop_form.file_intent = k_workshop_form_file_intent_none;
-      }
-      return;
    }
-
-   if( workshop_form.submission.type == k_workshop_file_type_world ){
-      ui_rect box;
-      rect_copy( content, box );
-      box[3] = 128;
-      box[2] = (box[2]*2)/3;
-      ui_rect_center( content, box );
-
-      ui_rect row;
-      ui_split( box, k_ui_axis_h, 28, 0, row, box );
-      ui_text( row, "World submissions are currently not ready, sorry.", 
-               1, k_ui_align_middle_center,0);
-      ui_split( box, k_ui_axis_h, 8, 0, row, box );
-      ui_split( box, k_ui_axis_h, 28, 0, row, box );
-
-      ui_rect button;
-      rect_copy( row, button );
-      button[2] = 128;
-      ui_rect_center( row, button );
-      if( ui_button_text( button, "OK", 1 ) ){
-         workshop_form.page = k_workshop_form_open;
-         workshop_form.file_intent = k_workshop_form_file_intent_none;
-      }
-
-      return;
+   else{
+      ui_fill( button_l, ui_colour(k_ui_bg) );
+      ui_text( button_l, "OK", 1, k_ui_align_middle_center, 
+               ui_colour(k_ui_bg+4) );
    }
+   
+   if( ui_button_text( button_r, "Cancel", 1 ) ){
+      workshop_form.page = k_workshop_form_open;
+      workshop_form.file_intent = k_workshop_form_file_intent_none;
+   }
+}
 
-   ui_rect image_plane;
-   ui_split( content, k_ui_axis_h, 300, 0, image_plane, content );
-   ui_fill( image_plane, ui_colour( k_ui_bg+0 ) );
-
-   ui_rect img_box;
-   ui_fit_item( image_plane, (ui_px[2]){ 3, 2 }, img_box );
-
+VG_STATIC void workshop_form_gui_draw_preview( ui_rect img_box ){
+   enum workshop_file_type type = workshop_form.submission.type;
    if( workshop_form.file_intent == k_workshop_form_file_intent_keep_old ){
       ui_image( img_box, gpipeline.fb_workshop_preview->attachments[0].id );
    }
    else if( workshop_form.file_intent == k_workshop_form_file_intent_new ){
       ui_image( img_box, gpipeline.fb_workshop_preview->attachments[0].id );
+
+      if( type == k_workshop_file_type_world ){
+         return;
+      }
+
       int hover  = ui_inside_rect( img_box, vg_ui.mouse ),
           target = ui_inside_rect( img_box, vg_ui.mouse_click );
       
@@ -1159,12 +1146,28 @@ VG_STATIC void workshop_form_gui_edit_page( ui_rect content )
       ui_text( img_box, "No image", 1, k_ui_align_middle_center,
                ui_colour( k_ui_orange ) );
    }
+}
+
+VG_STATIC void workshop_form_gui_edit_page( ui_rect content ){
+   enum workshop_file_type type = workshop_form.submission.type;
+
+   if( type == k_workshop_file_type_none ){
+      workshop_form_gui_page_undecided( content );
+      return;
+   }
+
+   ui_rect image_plane;
+   ui_split( content, k_ui_axis_h, 300, 0, image_plane, content );
+   ui_fill( image_plane, ui_colour( k_ui_bg+0 ) );
+
+   ui_rect img_box;
+   ui_fit_item( image_plane, (ui_px[2]){ 3, 2 }, img_box );
+   workshop_form_gui_draw_preview( img_box );
 
    /* file path */
    ui_rect null, file_entry, file_button, file_label;
    ui_split( content, k_ui_axis_h, 8, 0, null, content );
    ui_split( content, k_ui_axis_h, 28, 0, file_entry, content );
-   ui_split( file_entry, k_ui_axis_v, -128, 0, file_entry, file_button );
 
    if( workshop_form.submission.type == k_workshop_file_type_board ){
       ui_label( file_entry, "Addon folder: skaterift/boards/", 
@@ -1175,27 +1178,36 @@ VG_STATIC void workshop_form_gui_edit_page( ui_rect content )
                 1, 8, file_entry );
    }
 
-   if( workshop_form.file_intent != k_workshop_form_file_intent_none ){
-      ui_text( file_entry, workshop_form.addon_folder, 1, 
-               k_ui_align_middle_left, ui_colour( k_ui_fg+4 ) );
-
-      if( ui_button_text( file_button, "Remove", 1 ) ){
-         player_board_unload( &workshop_form.board_model );
-         workshop_form.file_intent = k_workshop_form_file_intent_none;
-         workshop_form.addon_folder[0] = '\0';
-      }
-   }
-   else{
+   if( type == k_workshop_file_type_world ){
       struct ui_textbox_callbacks callbacks = {
          .change = workshop_changed_model_path
       };
-
       ui_textbox( file_entry, workshop_form.addon_folder,
                   vg_list_size(workshop_form.addon_folder), 0, &callbacks );
+   }
+   else{
+      ui_split( file_entry, k_ui_axis_v, -128, 0, file_entry, file_button );
+      if( workshop_form.file_intent != k_workshop_form_file_intent_none ){
+         ui_text( file_entry, workshop_form.addon_folder, 1, 
+                  k_ui_align_middle_left, ui_colour( k_ui_fg+4 ) );
+
+         if( ui_button_text( file_button, "Remove", 1 ) ){
+            player_board_unload( &workshop_form.board_model );
+            workshop_form.file_intent = k_workshop_form_file_intent_none;
+            workshop_form.addon_folder[0] = '\0';
+         }
+      }
+      else{
+         struct ui_textbox_callbacks callbacks = {
+            .change = workshop_changed_model_path
+         };
+
+         ui_textbox( file_entry, workshop_form.addon_folder,
+                     vg_list_size(workshop_form.addon_folder), 0, &callbacks );
 
-      if( ui_button_text( file_button, "Load", 1 ) ){
-         workshop_find_preview_entity();
-         workshop_op_load_model();
+         if( ui_button_text( file_button, "Load", 1 ) ){
+            workshop_op_load_model();
+         }
       }
    }
 
@@ -1369,7 +1381,6 @@ VG_STATIC void workshop_form_gui_sidebar( ui_rect sidebar )
       workshop_form.submission.submit_description = 1;
       workshop_form.submission.submit_file_and_image = 1;
       workshop_form.page = k_workshop_form_edit;
-      workshop_find_preview_entity();
    }
 
    for( int i=0; i<workshop_form.published_files_list_length; i++ ){
@@ -1454,7 +1465,14 @@ VG_STATIC void workshop_form_gui(void)
        workshop_form.view_changed && 
        workshop_form.file_intent == k_workshop_form_file_intent_new )
    {
-      workshop_render_preview();
+      enum workshop_file_type type = workshop_form.submission.type;
+      if( type == k_workshop_file_type_board ){
+         workshop_render_board_preview();
+      }
+      else if( type == k_workshop_file_type_world ){
+         vg_success( "Renders world preview\n" );
+         workshop_render_world_preview();
+      }
       workshop_form.view_changed = 0;
    }
 
index 0c4e8ebb9989ecfa983224a5a5860142d5c2d974..448624e971247a04d343370c65e1367fbaa74a93 100644 (file)
@@ -111,19 +111,20 @@ static void async_skaterift_world_loaded( void *payload, u32 size )
 /*
  * Does a complete world switch using the remaining free slots
  */
-static void skaterift_world_changer_thread( void *data )
-{
-   if( world_loader.location == k_world_load_type_workshop ){
-      vg_fatal_error( "Unimplemented\n" );
-   }
-
+static void skaterift_world_changer_thread( void *data ){
    char path_buf[4096];
    vg_str path;
    vg_strnull( &path, path_buf, 4096 );
-   vg_strcat( &path, "maps/" );
+
+   if( world_loader.reg ){
+      addon_get_content_folder( world_loader.reg, &path );
+   }
+   else {
+      vg_strcat( &path, "maps/" );
+      vg_strcat( &path, world_loader.override_name );
+   }
 
    vg_str folder = path;
-   vg_strcat( &folder, world_loader.name );
    if( !vg_strgood( &folder ) ) {
       vg_error( "Load target too long\n" );
       vg_async_call( workshop_async_any_complete, NULL, 0 );
@@ -218,9 +219,14 @@ static void skaterift_change_world_preupdate(void)
 }
 
 /* places all loaded worlds into unloading state */
-static void skaterift_change_world( const char *world_name )
-{
-   vg_info( "switching to %s\n", world_name );
+static void skaterift_change_world_start(void){
+   if( world_loader.reg ){
+      vg_info( "switching to %s ("PRINTF_U64"\n", 
+               world_loader.reg->foldername, world_loader.reg->workshop_id );
+   }
+   else{
+      vg_info( "switching to %s(local)\n", world_loader.override_name );
+   }
 
    if( world_static.active_world != 0 ){
       vg_error( "Cannot change worlds while in non-root world\n" );
@@ -228,10 +234,7 @@ static void skaterift_change_world( const char *world_name )
    else{
       skaterift_begin_op( k_async_op_world_preloading );
 
-      vg_linear_clear( vg_mem.scratch );
-      vg_strncpy( world_name, world_loader.name,
-                  vg_list_size(world_loader.name), k_strncpy_overflow_fatal );
-      
+      vg_linear_clear( vg_mem.scratch ); /* ?? */
       vg_info( "unloading old worlds\n" );
       world_unlink_nonlocal( &world_static.worlds[0] );
       
@@ -249,8 +252,13 @@ static void skaterift_change_world( const char *world_name )
 /* console command for the above function */
 static int skaterift_change_world_command( int argc, const char *argv[] )
 {
-   if( argc == 1 )
-      skaterift_change_world( argv[0] );
+   if( argc == 1 ){
+      world_loader.reg = NULL;
+      vg_strncpy( argv[0], world_loader.override_name,
+                  vg_list_size( world_loader.override_name ),
+                  k_strncpy_always_add_null );
+      skaterift_change_world_start();
+   }
 
    return 0;
 }
index 0b8a912b37e930d013b6ccdc93ac70f5943aee8d..b37bae35fcde5bb24d5e2853bacb5c383cc7bcbb 100644 (file)
@@ -8,15 +8,21 @@
 #include "world_routes.h"
 #include "world_entity.h"
 #include "world_volumes.h"
+#include "addon.h"
 
 struct{
-   char name[64];
+   addon_reg *reg;
 
+#if 0
    enum world_load_type{
+      k_world_load_type_none,
       k_world_load_type_local,
       k_world_load_type_workshop /* unimplemented */
    }
    location;
+#endif
+
+   char override_name[64];
    int generate_point_cloud;
    u32 world_index;
 }
index 1ff33fe8501e9b90201613f1e0701fd63119257a..56e6e4b6c8bbae9dbcb50e3208a845668385366e 100644 (file)
@@ -767,6 +767,33 @@ VG_STATIC void world_routes_surface_grid( world_instance *world,
    }
 }
 
+VG_STATIC void world_write_preview( pointcloud_buffer *pcbuf ){
+   char path_buf[4096];
+   vg_str path;
+   vg_strnull( &path, path_buf, 4096 );
+
+   if( world_loader.reg ){
+      /* Don't want to override the one we get from the workshop */
+      if( world_loader.reg->workshop_id ) return;
+
+      addon_get_content_folder( world_loader.reg, &path );
+   }
+   else{
+      vg_strcat( &path, "maps/" );
+      vg_strcat( &path, world_loader.override_name );
+   }
+
+   vg_strcat( &path, "/preview.bin" );
+
+   if( !vg_strgood( &path ) ) vg_fatal_error( "Path too long\n" );
+   FILE *fp = fopen( path_buf, "wb" );
+   if( !fp ) vg_fatal_error( "Cannot open '%s' for writing\n", path_buf );
+   
+   fwrite( pcbuf, sizeof(struct pointcloud_buffer) + 
+                  sizeof(struct pointcloud_vert)*pcbuf->count, 1, fp );
+   fclose( fp );
+}
+
 /* 
  * Create the strips of colour that run through the world along course paths
  */
@@ -861,23 +888,7 @@ VG_STATIC void world_gen_routes_generate(void)
       vg_info( "Distrubuted %u points over %fkm^2!\n", 
                 pcbuf->count, area/1e6f );
 
-      if( world_loader.location == k_world_load_type_local ){
-         char path_buf[4096];
-         vg_str path;
-         vg_strnull( &path, path_buf, 4096 );
-         vg_strcat( &path, "maps/" );
-         vg_strcat( &path, world_loader.name );
-         vg_strcat( &path, "/preview.bin" );
-
-         if( !vg_strgood( &path ) ) vg_fatal_error( "Path too long\n" );
-         FILE *fp = fopen( path_buf, "wb" );
-         if( !fp ) vg_fatal_error( "Cannot open '%s' for writing\n", path_buf );
-         
-         fwrite( pcbuf, sizeof(pcbuf) + 
-                        sizeof(struct pointcloud_vert)*pcbuf->count, 1, fp );
-         fclose( fp );
-      }
-
+      world_write_preview( pcbuf );
       vg_async_dispatch( call_pointcloud, async_pointcloud_sub );
    }