Vesmir
Vesmir is an artificial universe simulation. It generates a galaxy and about thousand stars in it. Some stars have planets to form solar systems, where some planets has moons as their companions. All the stars and planet images are modeled in realtime based on their chemical composition, so the outlook of those objects are quite close how they would look in reality.
Vesmir demonstrates drawing operations, menues, some of the widgets how they interact with window, and how to bind own C functions to Ano script. Vesmir is not by any means a real space simulator, it is just an example, it should not be taken too serious.
User interface
Move the mouse over the galaxy and press <enter> on some star. View changes to that star, and if star has planets you can see some squares rounding around a cross. Squares indicates planets and cross is the star at the center of the solarsystem. Move mouse over one of the planets, press <enter> again and view changes to planet view. Backspace key navigates back to previous view. Galaxy and solar systems can be zoomed with mouse wheel (or buttons 4 and 5 to be exact), and they can be moved around by pressing mouse button 1 (that's usually the left mouse button) while moving the mouse.
In galaxy there is black holes (hard to find, but one sits exactly at the center of the galaxy), neutron stars, ordinary stars like the Sun, terrestrial planets with atmosphere like Mars, and gas giants like Saturn. Try to find another Earth! Stars also simulates nuclear fusion, so after considerably amount of time you may see a message saying some star has collapsed to neutron star or black hole. Roll the Time warp to southeast and wait.
Star and planet details can be viewed by pressing Print object button. Details are printed to standard output. Star and planet images can be saved to disk by pressing Save object button. Render object button opens star or planet image in separate window.
View reset button resets the view to its default position and sets zooming to zero. Time reset button resets the time warp setting, making clock to run at normal speed.
Compilation
Easiest way to get Vesmir running is to go to examples directory in package root, and run:
$ ./build.sh gui_vesmir
build.sh script compiles Ano script, widget definitions and menu tables to C, copies source files in place and pops up instructions what to do next. Follow them. Check also examples/README for more info.
Screenshots
Preview
; ; @ANO_SCRIPT_NAME gui_vesmir ; @ANO_SCRIPT_VERSION 0.0.3 ; @ANO_SCRIPT_DESCRIPTION Artificial universe simulation ; ; List of files to unveil if unveil() support is in use: ; ; @ANO_UNVEIL_FILES "examples/datafiles/vesmir_appicon.tga = r", \ ; "share/detroit/fonts/NotoSans-Italic.ttf = r", \ ; "share/detroit/fonts/NotoSans-Regular.ttf = r", \ ; "/tmp = rw" ; ; @ANO_FLAGS_VAR_NAME_SUBS [x] ; @ANO_FLAGS_VAR_WARN_UNUSED [ ] ; ; Copyright (c) 2016-2023, Jani Salonen <salojan at goto10 piste co> ; All rights reserved. ; ; Global uninitialized variables var [handle] hnd_win_main var [handle] hnd_win_view var [handle] hnd_win_preview var [handle] hnd_fnt_title var [handle] hnd_fnt_view var [handle] hnd_fnt_selected var [handle] hnd_fnt_selection ; Global variables mov img_dir ("/tmp") mov hlp_txt ("LMB + mouse to move view, wheel to zoom, enter to select, backspace to previous view") mov hlp_clr (# 0xff, 0xff, 0xff, 0x00) mov fnt ("share/detroit/fonts/NotoSans-Regular.ttf") mov fnt_clr (# 0xff, 0xd7, 0x69, 0x00) mov fnt_sz_big ([uint] 14) mov fnt_sz_med ([uint] 10) mov fnt_sz_sml ([uint] 8) mov view (0) mov xpos (0) mov ypos (0) mov xpre (0) mov ypre (0) mov zoom_min (0) mov zoom_max (100) mov zoom_slc (10) mov zoom (zoom_min) mov galaxy ([ulong] 0) mov star ([ulong] 0) mov planet ([ulong] 0) mov moon ([ulong] 0) mov mess ([uint] 1) ; Initialize windowing system window_init ; Open main window window_open ("Vesmir", NULL, \ [handle] @0, [uint] 1, [uint] 0, [uint] 0, \ [int] -1, [int] -1, [uint] 800, [uint] 600, \ NULL, NULL, NULL, NULL, NULL, NULL, \ NULL, NULL, "cb_destroy_main", \ NULL, NULL, NULL, "cb_open_main") end ; ; Main window callbacks ; callback cb_open_main (_hnd) { mov hnd_win_main (_hnd) ; Set window icon window_icon (hnd_win_main, \ "examples/datafiles/vesmir_appicon.tga") ; Open drawing window window_open (NULL, NULL, \ hnd_win_main, [uint] 0, [uint] 0, [uint] 1, \ [int] 20, [int] 180, [uint] 760, [uint] 400, \ "cb_mainloop_draw", NULL, \ "cb_keypress_draw", "cb_keyrelease_draw", \ "cb_buttonpress_draw", "cb_buttonrelease_draw", \ NULL, NULL, NULL, \ "cb_motion_draw", NULL, NULL, "cb_open_draw") ; Open fonts font_open (fnt, fnt_sz_big, [uint] 0) cmp rc (INVALID) je "cb_open_main_end" mov hnd_fnt_title (rc) font_open (fnt, fnt_sz_big, [uint] 0) cmp rc (INVALID) je "cb_open_main_end" mov hnd_fnt_view (rc) font_open (fnt, fnt_sz_med, [uint] 0) cmp rc (INVALID) je "cb_open_main_end" mov hnd_fnt_selected (rc) font_open (fnt, fnt_sz_med, [uint] 0) cmp rc (INVALID) je "cb_open_main_end" mov hnd_fnt_selection (rc) font_open (fnt, fnt_sz_sml, [uint] 0) cmp rc (INVALID) je "cb_open_main_end" mov hnd_fnt_date (rc) ; Pre-render some static strings to be displayed later font_render (hnd_fnt_selected, "UTF-8", "Selected:", \ [uint] 0, fnt_clr) font_render (hnd_fnt_view, "UTF-8", "View:", \ [uint] 0, fnt_clr) ; Map main window window_map (hnd_win_main) : "cb_open_main_end" } callback cb_destroy_main { window_close (hnd_win_main) font_close (hnd_fnt_title) font_close (hnd_fnt_view) font_close (hnd_fnt_selected) font_close (hnd_fnt_selection) font_close (hnd_fnt_date) exit } ; ; Drawing window callbacks ; callback cb_mainloop_draw { draw_wipe (hnd_win_view) cmp view (0) je "cb_mainloop_draw_galaxy" cmp view (1) je "cb_mainloop_draw_star" cmp view (2) je "cb_mainloop_draw_planet" end : "cb_mainloop_draw_galaxy" ; Main loop for galaxy view mov galaxy_x (xpos) mov galaxy_y (ypos) mov galaxy_z (zoom) galaxy_live (hnd_win_view, galaxy, \ galaxy_x, galaxy_y, galaxy_z) galaxy_get_name (galaxy) mov _name (rc) call "cb_mainloop_draw_texts" (_name) jmp "cb_mainloop_draw_done" : "cb_mainloop_draw_star" ; Main loop for star view mov star_x (xpos) mov star_y (ypos) mov star_z (zoom) star_live (hnd_win_view, galaxy, star, \ star_x, star_y, star_z) star_get_name (galaxy, star) mov _name (rc) call "cb_mainloop_draw_texts" (_name) jmp "cb_mainloop_draw_done" : "cb_mainloop_draw_planet" ; Main loop for planet view mov planet_x (xpos) mov planet_y (ypos) mov planet_z (zoom) planet_live (hnd_win_view, galaxy, star, planet, \ planet_x, planet_y, planet_z) planet_get_name (galaxy, star, planet) mov _name (rc) call "cb_mainloop_draw_texts" (_name) jmp "cb_mainloop_draw_done" : "cb_mainloop_draw_done" ; Zoom view slowly back to its base position cmp zoom (zoom_min) jbe "cb_mainloop_draw_end" sub zoom (0.0005) : "cb_mainloop_draw_end" } function cb_mainloop_draw_texts (_object) { universe_chk_message cmp mess (rc) je "cb_mainloop_draw_texts_ok" mov mess (rc) universe_get_message mov _mess (rc) widget_update_label (hnd_win_main, "help", \ _mess, NULL, fnt, 0, 0, 0, hlp_clr) widget_refresh (hnd_win_main) : "cb_mainloop_draw_texts_ok" universe_get_date mov _date (rc) font_render (hnd_fnt_date, "UTF-8", _date, [uint] 0, fnt_clr) font_render (hnd_fnt_title, "UTF-8", _object, [uint] 0, fnt_clr) font_get_width (hnd_fnt_date) mov _w (rc) font_get_height (hnd_fnt_date) mov _h (rc) draw_text (hnd_win_view, hnd_fnt_title, \ [int] 80, [int] 80) draw_text (hnd_win_view, hnd_fnt_view, \ [int] 20, [int] 80) draw_text (hnd_win_view, hnd_fnt_selected, \ [int] 20, [int] 120) draw_text (hnd_win_view, hnd_fnt_selection, \ [int] 80, [int] 120) draw_text (hnd_win_view, hnd_fnt_date, \ [int] 760 - _w, [int] 400 - _h) } callback cb_keypress_draw (x, y, _x_root, _y_root, _state, _keycode, _key) { cmp _keycode (6) je "cb_keypress_draw_enter" cmp _keycode (2) je "cb_keypress_draw_backspace" end : "cb_keypress_draw_enter" cmp view (0) je "cb_keypress_draw_enter_galaxy" cmp view (1) je "cb_keypress_draw_enter_star" end : "cb_keypress_draw_enter_galaxy" ; Switch from galaxy to star view call "cb_keypress_draw_enter_switch" (1) end : "cb_keypress_draw_enter_star" ; Switch from star to planet view call "cb_keypress_draw_enter_switch" (2) end : "cb_keypress_draw_backspace" cmp view (1) je "cb_keypress_draw_backspace_star" cmp view (2) je "cb_keypress_draw_backspace_planet" end : "cb_keypress_draw_backspace_star" ; Switch from star to galaxy view call "cb_keypress_draw_backspace_switch" \ (galaxy_x, galaxy_y, galaxy_z, 0) end : "cb_keypress_draw_backspace_planet" ; Switch from planet to star view call "cb_keypress_draw_backspace_switch" \ (star_x, star_y, star_z, 1) } function cb_keypress_draw_enter_switch (_switch) { mov xpos (0) mov ypos (0) mov xpre (0) mov ypre (0) mov zoom (zoom_min) mov view (_switch) widget_update_label (hnd_win_main, "help", \ hlp_txt, NULL, fnt, 0, 0, 0, hlp_clr) widget_refresh (hnd_win_main) } function cb_keypress_draw_backspace_switch (_switch_x, _switch_y, _switch_z, _switch) { mov xpos (_switch_x) mov ypos (_switch_y) mov zoom (_switch_z) mov view (_switch) widget_update_label (hnd_win_main, "help", \ hlp_txt, NULL, fnt, 0, 0, 0, hlp_clr) widget_refresh (hnd_win_main) } callback cb_keyrelease_draw (x, y, _x_root, _y_root, _state, _keycode, _key) { } callback cb_buttonpress_draw (x, y, _x_root, _y_root, _state, _button) { cmp _button (1) je "cb_buttonpress_draw_zoom_in" cmp _button (5) je "cb_buttonpress_draw_zoom_in" cmp _button (3) je "cb_buttonpress_draw_zoom_out" cmp _button (4) je "cb_buttonpress_draw_zoom_out" ; Clear previous pointer position for motion event mov xpre (0) mov ypre (0) end : "cb_buttonpress_draw_zoom_in" ; Zoom view inwards cmp zoom (zoom_max) jae "cb_buttonpress_draw_zoom_in_end" mov _i (zoom_max) sub _i (zoom) div _i (zoom_slc) add zoom (_i) : "cb_buttonpress_draw_zoom_in_end" end : "cb_buttonpress_draw_zoom_out" ; Zoom view outwards cmp zoom (zoom_min) jbe "cb_buttonpress_draw_zoom_out_end" mov _o (zoom_max) sub _o (zoom) div _o (zoom_slc) sub zoom (_o) : "cb_buttonpress_draw_zoom_out_end" } callback cb_buttonrelease_draw (x, y, _x_root, _y_root, _state, _button) { } callback cb_motion_draw (x, y, _x_root, _y_root, _state, _detail) { ; 256 = Button1Mask, 1 << 8 cmp _state (256) jne "cb_motion_draw_view" ; Button 1 pressed with mouse motion, move view cmp xpre (0) jne "cb_motion_draw_a" mov xpre (x) : "cb_motion_draw_a" cmp ypre (0) jne "cb_motion_draw_b" mov ypre (y) : "cb_motion_draw_b" mov _x (x) mov _y (y) sub _x (xpre) sub _y (ypre) mul _x (1.5) mul _y (1.5) add xpos (_x) add ypos (_y) mov xpre (x) mov ypre (y) end : "cb_motion_draw_view" ; Select object closest to mouse pointer cmp view (0) je "cb_motion_draw_view_galaxy" cmp view (1) je "cb_motion_draw_view_star" cmp view (2) je "cb_motion_draw_view_planet" end : "cb_motion_draw_view_galaxy" ; Get the closest star galaxy_live_closest (galaxy, x, y) cmp rc (0) je "cb_motion_draw_view_galaxy_end" mov star (rc) dec star ; Get the closest star name and render it star_get_name (galaxy, star) mov _name (rc) font_render (hnd_fnt_selection, "UTF-8", _name, [uint] 0, fnt_clr) : "cb_motion_draw_view_galaxy_end" end : "cb_motion_draw_view_star" ; Get the closest planet star_live_closest (galaxy, star, x, y) cmp rc (0) je "cb_motion_draw_view_star_end" mov planet (rc) dec planet ; Get the closest planet name and render it planet_get_name (galaxy, star, planet) mov _name (rc) font_render (hnd_fnt_selection, "UTF-8", _name, [uint] 0, fnt_clr) : "cb_motion_draw_view_star_end" end : "cb_motion_draw_view_planet" ; Get the closest moon planet_live_closest (galaxy, star, planet, x, y) cmp rc (0) je "cb_motion_draw_view_planet_end" mov moon (rc) dec moon ; Get the closest moon name and render it satellite_get_name (galaxy, star, planet, moon) mov _name (rc) font_render (hnd_fnt_selection, "UTF-8", _name, [uint] 0, fnt_clr) : "cb_motion_draw_view_planet_end" } callback cb_open_draw (_hnd) { mov hnd_win_view (_hnd) ; Map drawing window window_map (hnd_win_view) } ; ; Preview window callbacks ; callback cb_open_preview (_hnd) { mov hnd_win_preview (_hnd) cmp view (1) jne "cb_open_preview_planet" star_render (hnd_win_preview, galaxy, star) jmp "cb_open_preview_end" : "cb_open_preview_planet" cmp view (2) jne "cb_open_preview_end" planet_render (hnd_win_preview, galaxy, star, planet) jmp "cb_open_preview_end" : "cb_open_preview_end" ; Map preview window window_map (hnd_win_preview) } callback cb_destroy_preview { window_close (hnd_win_preview) mov hnd_win_preview (INVALID) } ; ; Widget callbacks ; callback cb_push_renderobject (_widget_name, _widget_id, _min, _max, _steps, _step) { cmp view (0) je "cb_push_renderobject_galaxy" cmp view (1) je "cb_push_renderobject_star" cmp view (2) je "cb_push_renderobject_planet" end : "cb_push_renderobject_galaxy" universe_set_message \ ("Rendering galaxy is not supported") end : "cb_push_renderobject_star" ; Open preview window for star call "cb_push_renderobject_open" \ ("Vesmir star preview") end : "cb_push_renderobject_planet" ; Open preview window for planet call "cb_push_renderobject_open" \ ("Vesmir planet preview") } function cb_push_renderobject_open (_title) { cmp hnd_win_preview (INVALID) je "cb_push_renderobject_ok" window_close (hnd_win_preview) : "cb_push_renderobject_ok" window_open (_title, NULL, \ [handle] @0, [uint] 2, [uint] 0, [uint] 0, \ [int] -1, [int] -1, [uint] 256, [uint] 256, \ NULL, NULL, NULL, NULL, NULL, NULL, \ NULL, NULL, "cb_destroy_preview", \ NULL, NULL, NULL, "cb_open_preview") } callback cb_push_printobject (_widget_name, _widget_id, _min, _max, _steps, _step) { cmp view (0) je "cb_push_printobject_galaxy" cmp view (1) je "cb_push_printobject_star" cmp view (2) je "cb_push_printobject_planet" end : "cb_push_printobject_galaxy" ; Print galaxy details galaxy_print (galaxy) end : "cb_push_printobject_star" ; Print star details star_print (galaxy, star) end : "cb_push_printobject_planet" ; Print planet details planet_print (galaxy, star, planet) } callback cb_push_saveobject (_widget_name, _widget_id, _min, _max, _steps, _step) { cmp view (0) je "cb_push_saveobject_galaxy" cmp view (1) je "cb_push_saveobject_star" cmp view (2) je "cb_push_saveobject_planet" end : "cb_push_saveobject_galaxy" universe_set_message ("Saving galaxy is not supported") end : "cb_push_saveobject_star" ; Save star image star_store (galaxy, star, img_dir) end : "cb_push_saveobject_planet" ; Save planet image planet_store (galaxy, star, planet, img_dir) } callback cb_push_viewreset (_widget_name, _widget_id, _min, _max, _steps, _step) { ; Reset the view mov xpos (0) mov ypos (0) mov zoom (zoom_min) } callback cb_push_timereset (_widget_name, _widget_id, _min, _max, _steps, _step) { ; Reset the clock clock_set_multiplier (1) widget_step_set (hnd_win_main, "time_warp", [uint] 1) } callback cb_turn_timewarp (_widget_name, _widget_id, _min, _max, _steps, _step) { ; Speed up the universe mov _mul (((_step * _step) * _step) * _step) clock_set_multiplier (_mul) } ; ; Menu item callbacks ; callback cb_file_exit (_item, _position, _tag, _flag) { jmp "cb_destroy_main" } callback cb_object_render (_item, _position, _tag, _flag) { mov _msg ("Not implemented, use widgets instead") dump _msg } callback cb_object_print (_item, _position, _tag, _flag) { mov _msg ("Not implemented, use widgets instead") dump _msg } callback cb_object_save (_item, _position, _tag, _flag) { mov _msg ("Not implemented, use widgets instead") dump _msg } callback cb_time_reset (_item, _position, _tag, _flag) { mov _msg ("Not implemented, use widgets instead") dump _msg } callback cb_time_set (_item, _position, _tag, _flag) { mov _msg ("Not implemented, use widgets instead") dump _msg }
; ; Copyright (c) 2016-2023, Jani Salonen <salojan at goto10 piste co> ; All rights reserved. ; ; @WIDGET_USE_BOUNDING_BOXES no ; window "1" { set "0" { widget "background" { name "background" state enable image "examples/datafiles/background.tga" } widget "label" { name "help" state enable position x = 20, y = 580 label "LMB + mouse to move view, wheel to zoom, enter to select, backspace to previous view", \ charset = UTF-8, size = 8, \ color = rgb:#ffffff, \ justification = left } widget "pushbutton_2" name "render_object" state enable type 3 position x = 40, y = 100 title "Render object", \ charset = UTF-8, size = 10, \ color = rgb:#ffffff, \ justification = center, \ position = above, x = 0, y = -10 sticky no action push = cb_push_renderobject } widget "pushbutton_2" { name "print_object" state enable type 3 position x = 160, y = 100 title "Print object", \ charset = UTF-8, size = 10, \ color = rgb:#ffffff, \ justification = center, \ position = above, x = 0, y = -10 sticky no action push = cb_push_printobject } widget "pushbutton_2" { name "save_object" state enable type 3 position x = 280, y = 100 title "Save object", \ charset = UTF-8, size = 10, \ color = rgb:#ffffff, \ justification = center, \ position = above, x = 0, y = -10 sticky no action push = cb_push_saveobject } widget "pushbutton_2" { name "view_reset" state enable type 1 position x = 440, y = 100 title "View reset", \ charset = UTF-8, size = 10, \ color = rgb:#ffffff, \ justification = center, \ position = above, x = 0, y = -10 sticky no action push = cb_push_viewreset } widget "pushbutton_2" { name "time_reset" state enable type 1 position x = 560, y = 100 title "Time reset", \ charset = UTF-8, size = 10, \ color = rgb:#ffffff, \ justification = center, \ position = above, x = 0, y = -10 sticky no action push = cb_push_timereset } widget "turnswitch" { name "time_warp" state enable type 1 position x = 670, y = 60 angle min = 5, max = 355 steps start = 1, total = 1000 title "Time warp", \ charset = UTF-8, size = 10, \ color = rgb:#ffffff, \ justification = center, \ position = above, x = 0, y = -5 trigger constant action turn = cb_turn_timewarp } } }
; ; Copyright (c) 2016-2023, Jani Salonen <salojan at goto10 piste co> ; All rights reserved. ; ; ; container_type "name" { ; window "1" { ; ; menu "name" { optional_icon ; menu "File" { examples/datafiles/vesmir_menu_1.tga ; ; type "name", id, callback_func, flags, optional_icon ; item "Exit", 1, cb_file_exit, none, none } menu "Object" { item "Render", 10, cb_object_render, none, none item "Print", 11, cb_object_print, none, none item "Save", 12, cb_object_save, none, none } menu "Time" { item "Reset", 20, cb_time_reset, none, none delim radio "Increase 10%", 30, cb_time_set, none, none radio "Increase 20%", 30, cb_time_set, none, none radio "Increase 30%", 30, cb_time_set, none, none radio "Increase 40%", 30, cb_time_set, none, none radio "Increase 50%", 30, cb_time_set, none, none radio "Increase 60%", 30, cb_time_set, none, none radio "Increase 70%", 30, cb_time_set, none, none radio "Increase 80%", 30, cb_time_set, none, none radio "Increase 90%", 30, cb_time_set, none, none radio "Increase 100%", 30, cb_time_set, none, none } }
Copyright © 2023, Jani Salonen <salojan at goto10 piste co>. Piste is finnish word and means dot. All rights reserved.