├── screenshot.png
├── textures
├── w.png
├── laptop_bat.png
├── laptop_crt.png
├── laptop_fan.png
├── laptop_gpu.png
├── laptop_lcd.png
├── laptop_psu.png
├── laptop_tnt.png
├── laptop_usb.png
├── laptop_boom.png
├── laptop_case.png
├── laptop_cpu_c6.png
├── laptop_cs_bos.png
├── laptop_go_web.png
├── laptop_k_back.png
├── laptop_k_left.png
├── laptop_k_top.png
├── laptop_m_back.png
├── laptop_m_left.png
├── laptop_m_top.png
├── laptop_mail.png
├── laptop_p_back.png
├── laptop_p_left.png
├── laptop_p_top.png
├── laptop_t_back.png
├── laptop_t_left.png
├── laptop_t_top.png
├── laptop_wa_web.png
├── laptop_ad1_web.png
├── laptop_browser.png
├── laptop_cpu_d75a.png
├── laptop_diskette.png
├── laptop_home_web.png
├── laptop_k_bottom.png
├── laptop_k_front.png
├── laptop_k_right.png
├── laptop_m_bottom.png
├── laptop_m_front.png
├── laptop_m_right.png
├── laptop_p_bottom.png
├── laptop_p_front.png
├── laptop_p_right.png
├── laptop_painting.png
├── laptop_t_bottom.png
├── laptop_t_front.png
├── laptop_t_right.png
├── laptop_background.png
├── laptop_calculator.png
├── laptop_cpu_65536.png
├── laptop_cpu_jetcore.png
├── laptop_crt_amber.png
├── laptop_crt_green.png
├── laptop_email_edit.png
├── laptop_email_new.png
├── laptop_email_reply.png
├── laptop_email_trash.png
├── laptop_fruit_base.png
├── laptop_harddrive.png
├── laptop_lcd_fruit.png
├── laptop_m_front_on.png
├── laptop_mail_button.png
├── laptop_mail_read.png
├── laptop_motherboard.png
├── laptop_notes_pad.png
├── laptop_opti_kb_top.png
├── laptop_opti_ms_top.png
├── laptop_opti_pc_top.png
├── laptop_printer_top.png
├── laptop_removable.png
├── laptop_t_front_on.png
├── laptop_tetris_icon.png
├── laptop_welcome_web.png
├── laptop_email_forward.png
├── laptop_email_letter.png
├── laptop_lap_base_item.png
├── laptop_lap_car_item.png
├── laptop_lcd_fruit_on.png
├── laptop_mail_received.png
├── laptop_mail_sentbox.png
├── laptop_opti_kb_back.png
├── laptop_opti_kb_front.png
├── laptop_opti_kb_left.png
├── laptop_opti_kb_right.png
├── laptop_opti_lcb_back.png
├── laptop_opti_lcb_left.png
├── laptop_opti_lcb_top.png
├── laptop_opti_lcd_back.png
├── laptop_opti_lcd_left.png
├── laptop_opti_lcd_top.png
├── laptop_opti_lcp_back.png
├── laptop_opti_lcp_left.png
├── laptop_opti_lcp_top.png
├── laptop_opti_ms_back.png
├── laptop_opti_ms_front.png
├── laptop_opti_ms_left.png
├── laptop_opti_ms_right.png
├── laptop_opti_pc_back.png
├── laptop_opti_pc_front.png
├── laptop_opti_pc_left.png
├── laptop_opti_pc_right.png
├── laptop_printed_paper.png
├── laptop_printer_back.png
├── laptop_printer_front.png
├── laptop_printer_left.png
├── laptop_printer_right.png
├── laptop_settings_web.png
├── laptop_tetris_block.png
├── laptop_cube_monitor_top.png
├── laptop_cube_tower_back.png
├── laptop_cube_tower_front.png
├── laptop_cube_tower_left.png
├── laptop_cube_tower_right.png
├── laptop_cube_tower_top.png
├── laptop_fruit_lcd_back.png
├── laptop_fruit_stand_top.png
├── laptop_lap_car_bottom.png
├── laptop_lap_car_open_top.png
├── laptop_lap_sc_open_back.png
├── laptop_mail_read_button.png
├── laptop_opti_kb_bottom.png
├── laptop_opti_lcb_front.png
├── laptop_opti_lcb_right.png
├── laptop_opti_lcd_bottom.png
├── laptop_opti_lcd_front.png
├── laptop_opti_lcd_right.png
├── laptop_opti_lcp_front.png
├── laptop_opti_lcp_right.png
├── laptop_opti_ms_bottom.png
├── laptop_opti_pc_bottom.png
├── laptop_opti_pc_on_front.png
├── laptop_printer_bottom.png
├── laptop_printer_button.png
├── laptop_printer_front_on.png
├── laptop_setting_wrench.png
├── laptop_cube_monitor_back.png
├── laptop_cube_monitor_front.png
├── laptop_cube_monitor_left.png
├── laptop_cube_monitor_right.png
├── laptop_cube_tower_bottom.png
├── laptop_lap_base_open_back.png
├── laptop_lap_base_open_left.png
├── laptop_lap_base_open_top.png
├── laptop_lap_car_closed_top.png
├── laptop_lap_car_open_back.png
├── laptop_lap_car_open_front.png
├── laptop_lap_car_open_left.png
├── laptop_lap_car_open_right.png
├── laptop_lap_sc_open_bottom.png
├── laptop_lap_sc_open_front.png
├── laptop_opti_lcd_on_front.png
├── laptop_printer_front_off.png
├── laptop_realchess_chess_bg.png
├── laptop_theme_basic_button.png
├── laptop_theme_minor_button.png
├── laptop_cube_monitor_bottom.png
├── laptop_cube_monitor_front_on.png
├── laptop_cube_tower_front_on.png
├── laptop_lap_base_closed_back.png
├── laptop_lap_base_closed_front.png
├── laptop_lap_base_closed_left.png
├── laptop_lap_base_closed_right.png
├── laptop_lap_base_closed_top.png
├── laptop_lap_base_open_bottom.png
├── laptop_lap_base_open_front.png
├── laptop_lap_base_open_on_top.png
├── laptop_lap_base_open_right.png
├── laptop_lap_car_closed_back.png
├── laptop_lap_car_closed_front.png
├── laptop_lap_car_closed_left.png
├── laptop_lap_car_closed_right.png
├── laptop_lap_car_open_on_top.png
├── laptop_lap_car_sc_open_front.png
├── laptop_lap_sc_open_on_front.png
├── laptop_realchess_king_black.png
├── laptop_realchess_king_white.png
├── laptop_realchess_pawn_black.png
├── laptop_realchess_pawn_white.png
├── laptop_realchess_queen_black.png
├── laptop_realchess_queen_white.png
├── laptop_realchess_rook_black.png
├── laptop_realchess_rook_white.png
├── laptop_theme_red_back_button.png
├── laptop_theme_red_exit_button.png
├── laptop_lap_base_closed_bottom.png
├── laptop_lap_car_sc_open_bottom.png
├── laptop_launcher_insert_floppy.png
├── laptop_realchess_bishop_black.png
├── laptop_realchess_bishop_white.png
├── laptop_realchess_knight_black.png
├── laptop_realchess_knight_white.png
├── laptop_theme_blue_back_button.png
├── laptop_theme_blue_exit_button.png
├── laptop_theme_blue_major_button.png
├── laptop_theme_boing_back_button.png
├── laptop_theme_boing_exit_button.png
├── laptop_theme_cubic_back_button.png
├── laptop_theme_cubic_exit_button.png
├── laptop_theme_magma_back_button.png
├── laptop_theme_magma_exit_button.png
├── laptop_theme_red_major_button.png
├── laptop_theme_shell_back_button.png
├── laptop_theme_shell_exit_button.png
├── laptop_lap_car_sc_open_on_front.png
├── laptop_realchess_chessboard_icon.png
├── laptop_theme_ambershell_email_new.png
├── laptop_theme_ambershell_mail_icon.png
├── laptop_theme_ambershell_tnt_icon.png
├── laptop_theme_argyle_exit_button.png
├── laptop_theme_argyle_major_button.png
├── laptop_theme_basic_app_background.png
├── laptop_theme_blue_app_background.png
├── laptop_theme_boing_app_background.png
├── laptop_theme_boing_major_button.png
├── laptop_theme_circuit_back_button.png
├── laptop_theme_circuit_exit_button.png
├── laptop_theme_circuit_major_button.png
├── laptop_theme_cubic_app_background.png
├── laptop_theme_cubic_major_button.png
├── laptop_theme_freedom_back_button.png
├── laptop_theme_freedom_exit_button.png
├── laptop_theme_freedom_major_button.png
├── laptop_theme_greenshell_email_new.png
├── laptop_theme_greenshell_mail_icon.png
├── laptop_theme_greenshell_tnt_icon.png
├── laptop_theme_magma_app_background.png
├── laptop_theme_magma_major_button.png
├── laptop_theme_printos_major_button.png
├── laptop_theme_printos_minor_button.png
├── laptop_theme_red_app_background.png
├── laptop_theme_shell_app_background.png
├── laptop_theme_shell_major_button.png
├── laptop_theme_shell_minor_button.png
├── laptop_theme_ambershell_back_button.png
├── laptop_theme_ambershell_cs_bos_icon.png
├── laptop_theme_ambershell_email_edit.png
├── laptop_theme_ambershell_email_read.png
├── laptop_theme_ambershell_email_reply.png
├── laptop_theme_ambershell_email_trash.png
├── laptop_theme_ambershell_exit_button.png
├── laptop_theme_ambershell_laptop_boom.png
├── laptop_theme_ambershell_mail_button.png
├── laptop_theme_ambershell_tetris_icon.png
├── laptop_theme_argyle_app_background.png
├── laptop_theme_circuit_app_background.png
├── laptop_theme_clouds_app_background.png
├── laptop_theme_freedom_app_background.png
├── laptop_theme_greenshell_back_button.png
├── laptop_theme_greenshell_cs_bos_icon.png
├── laptop_theme_greenshell_email_edit.png
├── laptop_theme_greenshell_email_read.png
├── laptop_theme_greenshell_email_reply.png
├── laptop_theme_greenshell_email_trash.png
├── laptop_theme_greenshell_exit_button.png
├── laptop_theme_greenshell_laptop_boom.png
├── laptop_theme_greenshell_mail_button.png
├── laptop_theme_greenshell_tetris_icon.png
├── laptop_theme_red_desktop_background.png
├── laptop_theme_snowpines_exit_button.png
├── laptop_theme_snowpines_major_button.png
├── laptop_theme_snowpines_minor_button.png
├── laptop_theme_ambershell_app_background.png
├── laptop_theme_ambershell_email_forward.png
├── laptop_theme_ambershell_mail_received.png
├── laptop_theme_ambershell_mail_sentbox.png
├── laptop_theme_ambershell_major_button.png
├── laptop_theme_ambershell_minor_button.png
├── laptop_theme_ambershell_notepad_icon.png
├── laptop_theme_ambershell_printer_button.png
├── laptop_theme_ambershell_removable_icon.png
├── laptop_theme_ambershell_settings_icon.png
├── laptop_theme_argyle_desktop_background.png
├── laptop_theme_basic_desktop_background.png
├── laptop_theme_blue_desktop_background.png
├── laptop_theme_blue_desktop_icon_button.png
├── laptop_theme_boing_desktop_background.png
├── laptop_theme_clouds_desktop_background.png
├── laptop_theme_cubic_desktop_background.png
├── laptop_theme_cubic_desktop_icon_button.png
├── laptop_theme_fruit_desktop_background.png
├── laptop_theme_greenshell_app_background.png
├── laptop_theme_greenshell_email_forward.png
├── laptop_theme_greenshell_mail_received.png
├── laptop_theme_greenshell_mail_sentbox.png
├── laptop_theme_greenshell_major_button.png
├── laptop_theme_greenshell_minor_button.png
├── laptop_theme_greenshell_notepad_icon.png
├── laptop_theme_greenshell_printer_button.png
├── laptop_theme_greenshell_removable_icon.png
├── laptop_theme_greenshell_settings_icon.png
├── laptop_theme_magma_desktop_background.png
├── laptop_theme_magma_desktop_icon_button.png
├── laptop_theme_red_desktop_icon_button.png
├── laptop_theme_shell_desktop_background.png
├── laptop_theme_snowpines_app_background.png
├── laptop_theme_ambershell_calculator_icon.png
├── laptop_theme_ambershell_email_letter_new.png
├── laptop_theme_bubbles_desktop_background.png
├── laptop_theme_circuit_desktop_background.png
├── laptop_theme_freedom_desktop_background.png
├── laptop_theme_freedom_desktop_icon_button.png
├── laptop_theme_greenshell_calculator_icon.png
├── laptop_theme_greenshell_email_letter_new.png
├── laptop_theme_ambershell_desktop_background.png
├── laptop_theme_desktop_icon_label_button_grey.png
├── laptop_theme_greenshell_desktop_background.png
├── laptop_theme_snowpines_desktop_background.png
├── laptop_theme_clouds_desktop_icon_label_button.png
├── laptop_theme_desktop_icon_label_button_black.png
├── laptop_theme_shell_desktop_icon_label_button.png
├── laptop_theme_ambershell_desktop_icon_label_button.png
├── laptop_theme_ambershell_realchess_chessboard_icon.png
└── laptop_theme_greenshell_desktop_icon_label_button.png
├── themes
├── fruit_theme.lua
├── magma_theme.lua
├── bubbles_theme.lua
├── red_theme.lua
├── blue_theme.lua
├── freedom_theme.lua
├── basic_theme.lua
├── circuit_theme.lua
├── clouds_theme.lua
├── cubic_theme.lua
├── argyle_theme.lua
├── printer_theme.lua
├── boing_theme.lua
├── snowpines_theme.lua
├── shell_theme.lua
├── ambershell_theme.lua
└── greenshell_theme.lua
├── mod.conf
├── .gitattributes
├── init.lua
├── LICENSE.txt
├── MTBOX.md
├── README-LICENSE.txt
├── apps
├── shell-os_app.lua
├── launcher_settings_app.lua
├── removable_app.lua
├── launcher_app.lua
├── stickynote_app.lua
├── os_dialogs_app.lua
├── browser_app.lua
├── calculator_app.lua
├── TNTsweeper_app.lua
├── painting_app.lua
├── tetris_app.lua
├── mail_app.lua
└── os_print_app.lua
├── app_fw.lua
├── README.md
├── recipe_compat.lua
├── themes.lua
├── block_devices.lua
├── craftitems.lua
└── hardware_fw.lua
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/screenshot.png
--------------------------------------------------------------------------------
/textures/w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/w.png
--------------------------------------------------------------------------------
/textures/laptop_bat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_bat.png
--------------------------------------------------------------------------------
/textures/laptop_crt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_crt.png
--------------------------------------------------------------------------------
/textures/laptop_fan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_fan.png
--------------------------------------------------------------------------------
/textures/laptop_gpu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_gpu.png
--------------------------------------------------------------------------------
/textures/laptop_lcd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lcd.png
--------------------------------------------------------------------------------
/textures/laptop_psu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_psu.png
--------------------------------------------------------------------------------
/textures/laptop_tnt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_tnt.png
--------------------------------------------------------------------------------
/textures/laptop_usb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_usb.png
--------------------------------------------------------------------------------
/textures/laptop_boom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_boom.png
--------------------------------------------------------------------------------
/textures/laptop_case.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_case.png
--------------------------------------------------------------------------------
/textures/laptop_cpu_c6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cpu_c6.png
--------------------------------------------------------------------------------
/textures/laptop_cs_bos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cs_bos.png
--------------------------------------------------------------------------------
/textures/laptop_go_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_go_web.png
--------------------------------------------------------------------------------
/textures/laptop_k_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_k_back.png
--------------------------------------------------------------------------------
/textures/laptop_k_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_k_left.png
--------------------------------------------------------------------------------
/textures/laptop_k_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_k_top.png
--------------------------------------------------------------------------------
/textures/laptop_m_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_m_back.png
--------------------------------------------------------------------------------
/textures/laptop_m_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_m_left.png
--------------------------------------------------------------------------------
/textures/laptop_m_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_m_top.png
--------------------------------------------------------------------------------
/textures/laptop_mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_mail.png
--------------------------------------------------------------------------------
/textures/laptop_p_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_p_back.png
--------------------------------------------------------------------------------
/textures/laptop_p_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_p_left.png
--------------------------------------------------------------------------------
/textures/laptop_p_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_p_top.png
--------------------------------------------------------------------------------
/textures/laptop_t_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_t_back.png
--------------------------------------------------------------------------------
/textures/laptop_t_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_t_left.png
--------------------------------------------------------------------------------
/textures/laptop_t_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_t_top.png
--------------------------------------------------------------------------------
/textures/laptop_wa_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_wa_web.png
--------------------------------------------------------------------------------
/textures/laptop_ad1_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_ad1_web.png
--------------------------------------------------------------------------------
/textures/laptop_browser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_browser.png
--------------------------------------------------------------------------------
/textures/laptop_cpu_d75a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cpu_d75a.png
--------------------------------------------------------------------------------
/textures/laptop_diskette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_diskette.png
--------------------------------------------------------------------------------
/textures/laptop_home_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_home_web.png
--------------------------------------------------------------------------------
/textures/laptop_k_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_k_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_k_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_k_front.png
--------------------------------------------------------------------------------
/textures/laptop_k_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_k_right.png
--------------------------------------------------------------------------------
/textures/laptop_m_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_m_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_m_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_m_front.png
--------------------------------------------------------------------------------
/textures/laptop_m_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_m_right.png
--------------------------------------------------------------------------------
/textures/laptop_p_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_p_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_p_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_p_front.png
--------------------------------------------------------------------------------
/textures/laptop_p_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_p_right.png
--------------------------------------------------------------------------------
/textures/laptop_painting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_painting.png
--------------------------------------------------------------------------------
/textures/laptop_t_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_t_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_t_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_t_front.png
--------------------------------------------------------------------------------
/textures/laptop_t_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_t_right.png
--------------------------------------------------------------------------------
/textures/laptop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_background.png
--------------------------------------------------------------------------------
/textures/laptop_calculator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_calculator.png
--------------------------------------------------------------------------------
/textures/laptop_cpu_65536.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cpu_65536.png
--------------------------------------------------------------------------------
/textures/laptop_cpu_jetcore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cpu_jetcore.png
--------------------------------------------------------------------------------
/textures/laptop_crt_amber.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_crt_amber.png
--------------------------------------------------------------------------------
/textures/laptop_crt_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_crt_green.png
--------------------------------------------------------------------------------
/textures/laptop_email_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_email_edit.png
--------------------------------------------------------------------------------
/textures/laptop_email_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_email_new.png
--------------------------------------------------------------------------------
/textures/laptop_email_reply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_email_reply.png
--------------------------------------------------------------------------------
/textures/laptop_email_trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_email_trash.png
--------------------------------------------------------------------------------
/textures/laptop_fruit_base.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_fruit_base.png
--------------------------------------------------------------------------------
/textures/laptop_harddrive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_harddrive.png
--------------------------------------------------------------------------------
/textures/laptop_lcd_fruit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lcd_fruit.png
--------------------------------------------------------------------------------
/textures/laptop_m_front_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_m_front_on.png
--------------------------------------------------------------------------------
/textures/laptop_mail_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_mail_button.png
--------------------------------------------------------------------------------
/textures/laptop_mail_read.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_mail_read.png
--------------------------------------------------------------------------------
/textures/laptop_motherboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_motherboard.png
--------------------------------------------------------------------------------
/textures/laptop_notes_pad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_notes_pad.png
--------------------------------------------------------------------------------
/textures/laptop_opti_kb_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_kb_top.png
--------------------------------------------------------------------------------
/textures/laptop_opti_ms_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_ms_top.png
--------------------------------------------------------------------------------
/textures/laptop_opti_pc_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_pc_top.png
--------------------------------------------------------------------------------
/textures/laptop_printer_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_top.png
--------------------------------------------------------------------------------
/textures/laptop_removable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_removable.png
--------------------------------------------------------------------------------
/textures/laptop_t_front_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_t_front_on.png
--------------------------------------------------------------------------------
/textures/laptop_tetris_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_tetris_icon.png
--------------------------------------------------------------------------------
/textures/laptop_welcome_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_welcome_web.png
--------------------------------------------------------------------------------
/textures/laptop_email_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_email_forward.png
--------------------------------------------------------------------------------
/textures/laptop_email_letter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_email_letter.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_item.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_item.png
--------------------------------------------------------------------------------
/textures/laptop_lcd_fruit_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lcd_fruit_on.png
--------------------------------------------------------------------------------
/textures/laptop_mail_received.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_mail_received.png
--------------------------------------------------------------------------------
/textures/laptop_mail_sentbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_mail_sentbox.png
--------------------------------------------------------------------------------
/textures/laptop_opti_kb_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_kb_back.png
--------------------------------------------------------------------------------
/textures/laptop_opti_kb_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_kb_front.png
--------------------------------------------------------------------------------
/textures/laptop_opti_kb_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_kb_left.png
--------------------------------------------------------------------------------
/textures/laptop_opti_kb_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_kb_right.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcb_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcb_back.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcb_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcb_left.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcb_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcb_top.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcd_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcd_back.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcd_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcd_left.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcd_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcd_top.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcp_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcp_back.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcp_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcp_left.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcp_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcp_top.png
--------------------------------------------------------------------------------
/textures/laptop_opti_ms_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_ms_back.png
--------------------------------------------------------------------------------
/textures/laptop_opti_ms_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_ms_front.png
--------------------------------------------------------------------------------
/textures/laptop_opti_ms_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_ms_left.png
--------------------------------------------------------------------------------
/textures/laptop_opti_ms_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_ms_right.png
--------------------------------------------------------------------------------
/textures/laptop_opti_pc_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_pc_back.png
--------------------------------------------------------------------------------
/textures/laptop_opti_pc_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_pc_front.png
--------------------------------------------------------------------------------
/textures/laptop_opti_pc_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_pc_left.png
--------------------------------------------------------------------------------
/textures/laptop_opti_pc_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_pc_right.png
--------------------------------------------------------------------------------
/textures/laptop_printed_paper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printed_paper.png
--------------------------------------------------------------------------------
/textures/laptop_printer_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_back.png
--------------------------------------------------------------------------------
/textures/laptop_printer_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_front.png
--------------------------------------------------------------------------------
/textures/laptop_printer_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_left.png
--------------------------------------------------------------------------------
/textures/laptop_printer_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_right.png
--------------------------------------------------------------------------------
/textures/laptop_settings_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_settings_web.png
--------------------------------------------------------------------------------
/textures/laptop_tetris_block.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_tetris_block.png
--------------------------------------------------------------------------------
/textures/laptop_cube_monitor_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_monitor_top.png
--------------------------------------------------------------------------------
/textures/laptop_cube_tower_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_tower_back.png
--------------------------------------------------------------------------------
/textures/laptop_cube_tower_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_tower_front.png
--------------------------------------------------------------------------------
/textures/laptop_cube_tower_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_tower_left.png
--------------------------------------------------------------------------------
/textures/laptop_cube_tower_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_tower_right.png
--------------------------------------------------------------------------------
/textures/laptop_cube_tower_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_tower_top.png
--------------------------------------------------------------------------------
/textures/laptop_fruit_lcd_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_fruit_lcd_back.png
--------------------------------------------------------------------------------
/textures/laptop_fruit_stand_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_fruit_stand_top.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_open_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_open_top.png
--------------------------------------------------------------------------------
/textures/laptop_lap_sc_open_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_sc_open_back.png
--------------------------------------------------------------------------------
/textures/laptop_mail_read_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_mail_read_button.png
--------------------------------------------------------------------------------
/textures/laptop_opti_kb_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_kb_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcb_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcb_front.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcb_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcb_right.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcd_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcd_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcd_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcd_front.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcd_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcd_right.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcp_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcp_front.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcp_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcp_right.png
--------------------------------------------------------------------------------
/textures/laptop_opti_ms_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_ms_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_opti_pc_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_pc_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_opti_pc_on_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_pc_on_front.png
--------------------------------------------------------------------------------
/textures/laptop_printer_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_printer_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_button.png
--------------------------------------------------------------------------------
/textures/laptop_printer_front_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_front_on.png
--------------------------------------------------------------------------------
/textures/laptop_setting_wrench.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_setting_wrench.png
--------------------------------------------------------------------------------
/textures/laptop_cube_monitor_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_monitor_back.png
--------------------------------------------------------------------------------
/textures/laptop_cube_monitor_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_monitor_front.png
--------------------------------------------------------------------------------
/textures/laptop_cube_monitor_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_monitor_left.png
--------------------------------------------------------------------------------
/textures/laptop_cube_monitor_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_monitor_right.png
--------------------------------------------------------------------------------
/textures/laptop_cube_tower_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_tower_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_open_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_open_back.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_open_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_open_left.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_open_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_open_top.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_closed_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_closed_top.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_open_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_open_back.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_open_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_open_front.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_open_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_open_left.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_open_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_open_right.png
--------------------------------------------------------------------------------
/textures/laptop_lap_sc_open_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_sc_open_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_lap_sc_open_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_sc_open_front.png
--------------------------------------------------------------------------------
/textures/laptop_opti_lcd_on_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_opti_lcd_on_front.png
--------------------------------------------------------------------------------
/textures/laptop_printer_front_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_printer_front_off.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_chess_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_chess_bg.png
--------------------------------------------------------------------------------
/textures/laptop_theme_basic_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_basic_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_minor_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_minor_button.png
--------------------------------------------------------------------------------
/textures/laptop_cube_monitor_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_monitor_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_cube_monitor_front_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_monitor_front_on.png
--------------------------------------------------------------------------------
/textures/laptop_cube_tower_front_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_cube_tower_front_on.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_closed_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_closed_back.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_closed_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_closed_front.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_closed_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_closed_left.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_closed_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_closed_right.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_closed_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_closed_top.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_open_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_open_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_open_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_open_front.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_open_on_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_open_on_top.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_open_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_open_right.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_closed_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_closed_back.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_closed_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_closed_front.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_closed_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_closed_left.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_closed_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_closed_right.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_open_on_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_open_on_top.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_sc_open_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_sc_open_front.png
--------------------------------------------------------------------------------
/textures/laptop_lap_sc_open_on_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_sc_open_on_front.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_king_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_king_black.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_king_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_king_white.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_pawn_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_pawn_black.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_pawn_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_pawn_white.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_queen_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_queen_black.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_queen_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_queen_white.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_rook_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_rook_black.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_rook_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_rook_white.png
--------------------------------------------------------------------------------
/textures/laptop_theme_red_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_red_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_red_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_red_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_lap_base_closed_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_base_closed_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_sc_open_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_sc_open_bottom.png
--------------------------------------------------------------------------------
/textures/laptop_launcher_insert_floppy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_launcher_insert_floppy.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_bishop_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_bishop_black.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_bishop_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_bishop_white.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_knight_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_knight_black.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_knight_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_knight_white.png
--------------------------------------------------------------------------------
/textures/laptop_theme_blue_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_blue_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_blue_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_blue_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_blue_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_blue_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_boing_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_boing_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_boing_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_boing_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_cubic_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_cubic_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_cubic_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_cubic_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_magma_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_magma_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_magma_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_magma_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_red_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_red_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_shell_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_shell_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_shell_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_shell_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_lap_car_sc_open_on_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_lap_car_sc_open_on_front.png
--------------------------------------------------------------------------------
/textures/laptop_realchess_chessboard_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_realchess_chessboard_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_email_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_email_new.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_mail_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_mail_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_tnt_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_tnt_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_argyle_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_argyle_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_argyle_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_argyle_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_basic_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_basic_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_blue_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_blue_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_boing_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_boing_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_boing_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_boing_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_circuit_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_circuit_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_circuit_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_circuit_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_circuit_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_circuit_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_cubic_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_cubic_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_cubic_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_cubic_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_freedom_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_freedom_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_freedom_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_freedom_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_freedom_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_freedom_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_email_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_email_new.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_mail_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_mail_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_tnt_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_tnt_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_magma_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_magma_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_magma_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_magma_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_printos_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_printos_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_printos_minor_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_printos_minor_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_red_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_red_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_shell_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_shell_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_shell_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_shell_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_shell_minor_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_shell_minor_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_cs_bos_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_cs_bos_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_email_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_email_edit.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_email_read.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_email_read.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_email_reply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_email_reply.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_email_trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_email_trash.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_laptop_boom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_laptop_boom.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_mail_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_mail_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_tetris_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_tetris_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_argyle_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_argyle_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_circuit_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_circuit_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_clouds_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_clouds_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_freedom_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_freedom_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_back_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_back_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_cs_bos_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_cs_bos_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_email_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_email_edit.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_email_read.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_email_read.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_email_reply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_email_reply.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_email_trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_email_trash.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_laptop_boom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_laptop_boom.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_mail_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_mail_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_tetris_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_tetris_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_red_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_red_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_snowpines_exit_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_snowpines_exit_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_snowpines_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_snowpines_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_snowpines_minor_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_snowpines_minor_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_email_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_email_forward.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_mail_received.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_mail_received.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_mail_sentbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_mail_sentbox.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_minor_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_minor_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_notepad_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_notepad_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_printer_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_printer_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_removable_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_removable_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_settings_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_settings_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_argyle_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_argyle_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_basic_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_basic_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_blue_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_blue_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_blue_desktop_icon_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_blue_desktop_icon_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_boing_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_boing_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_clouds_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_clouds_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_cubic_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_cubic_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_cubic_desktop_icon_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_cubic_desktop_icon_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_fruit_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_fruit_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_email_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_email_forward.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_mail_received.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_mail_received.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_mail_sentbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_mail_sentbox.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_major_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_major_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_minor_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_minor_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_notepad_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_notepad_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_printer_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_printer_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_removable_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_removable_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_settings_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_settings_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_magma_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_magma_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_magma_desktop_icon_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_magma_desktop_icon_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_red_desktop_icon_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_red_desktop_icon_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_shell_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_shell_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_snowpines_app_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_snowpines_app_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_calculator_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_calculator_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_email_letter_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_email_letter_new.png
--------------------------------------------------------------------------------
/textures/laptop_theme_bubbles_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_bubbles_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_circuit_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_circuit_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_freedom_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_freedom_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_freedom_desktop_icon_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_freedom_desktop_icon_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_calculator_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_calculator_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_email_letter_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_email_letter_new.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_desktop_icon_label_button_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_desktop_icon_label_button_grey.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_snowpines_desktop_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_snowpines_desktop_background.png
--------------------------------------------------------------------------------
/textures/laptop_theme_clouds_desktop_icon_label_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_clouds_desktop_icon_label_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_desktop_icon_label_button_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_desktop_icon_label_button_black.png
--------------------------------------------------------------------------------
/textures/laptop_theme_shell_desktop_icon_label_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_shell_desktop_icon_label_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_desktop_icon_label_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_desktop_icon_label_button.png
--------------------------------------------------------------------------------
/textures/laptop_theme_ambershell_realchess_chessboard_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_ambershell_realchess_chessboard_icon.png
--------------------------------------------------------------------------------
/textures/laptop_theme_greenshell_desktop_icon_label_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gerold55/laptop/HEAD/textures/laptop_theme_greenshell_desktop_icon_label_button.png
--------------------------------------------------------------------------------
/themes/fruit_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Fruit", {
2 | desktop_background = "laptop_theme_fruit_desktop_background.png",
3 | app_background = "laptop_theme_blue_app_background.png",
4 | os_min_version = '6.33',
5 | })
6 |
--------------------------------------------------------------------------------
/mod.conf:
--------------------------------------------------------------------------------
1 | name = laptop
2 | title = Laptop
3 | description = Adds laptops/computers to your MT world.
4 | depends = default
5 | optional_depends = mesecons_materials, mesecons_gates, mesecons_fpga, mesecons_delayer, mesecons_luacontroller, mesecons_lightstone, homedecor, basic_materials, technic, power_generators
6 |
7 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/themes/magma_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Magma", {
2 | desktop_background = "laptop_theme_magma_desktop_background.png",
3 | app_background = "laptop_theme_magma_app_background.png",
4 | major_button = "laptop_theme_magma_major_button.png",
5 | back_button = "laptop_theme_magma_back_button.png",
6 | exit_button = "laptop_theme_magma_exit_button.png",
7 | desktop_icon_button = "laptop_theme_magma_desktop_icon_button.png",
8 | os_min_version = '7.00',
9 | })
10 |
--------------------------------------------------------------------------------
/themes/bubbles_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Bubbles", {
2 | desktop_background = "laptop_theme_bubbles_desktop_background.png",
3 | app_background = "laptop_theme_blue_app_background.png",
4 | major_button = "laptop_theme_blue_major_button.png",
5 | desktop_icon_label_textcolor = "#0000FF",
6 | desktop_icon_label_button = "laptop_theme_desktop_icon_label_button_grey.png",
7 | table_highlight_bgcolor='#7294ff',
8 | table_highlight_textcolor='#000000',
9 | os_min_version = '5.00',
10 | })
11 |
--------------------------------------------------------------------------------
/init.lua:
--------------------------------------------------------------------------------
1 | laptop = {}
2 | laptop.class_lib = {}
3 | dofile(minetest.get_modpath('laptop')..'/themes.lua')
4 | dofile(minetest.get_modpath('laptop')..'/block_devices.lua')
5 | dofile(minetest.get_modpath('laptop')..'/app_fw.lua')
6 | dofile(minetest.get_modpath('laptop')..'/mtos.lua')
7 | dofile(minetest.get_modpath('laptop')..'/hardware_fw.lua')
8 | dofile(minetest.get_modpath('laptop')..'/recipe_compat.lua')
9 | dofile(minetest.get_modpath('laptop')..'/hardware_nodes.lua')
10 | dofile(minetest.get_modpath('laptop')..'/craftitems.lua')
11 |
--------------------------------------------------------------------------------
/themes/red_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Red", {
2 | desktop_background = "laptop_theme_red_desktop_background.png",
3 | app_background = "laptop_theme_red_app_background.png",
4 | major_button = "laptop_theme_red_major_button.png",
5 | back_button = "laptop_theme_red_back_button.png",
6 | exit_button = "laptop_theme_red_exit_button.png",
7 | desktop_icon_button = "laptop_theme_red_desktop_icon_button.png",
8 | table_highlight_bgcolor='#FF6666',
9 | table_highlight_textcolor='#000000',
10 | os_min_version = '7.00',
11 | })
12 |
--------------------------------------------------------------------------------
/themes/blue_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Blue", {
2 | desktop_background = "laptop_theme_blue_desktop_background.png",
3 | app_background = "laptop_theme_blue_app_background.png",
4 | major_button = "laptop_theme_blue_major_button.png",
5 | back_button = "laptop_theme_blue_back_button.png",
6 | exit_button = "laptop_theme_blue_exit_button.png",
7 | desktop_icon_button = "laptop_theme_blue_desktop_icon_button.png",
8 | table_highlight_bgcolor='#1c3c9e',
9 | table_highlight_textcolor = '#cccccc',
10 | os_min_version = '7.00',
11 | })
12 |
--------------------------------------------------------------------------------
/themes/freedom_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Freedom", {
2 | desktop_background = "laptop_theme_freedom_desktop_background.png",
3 | app_background = "laptop_theme_freedom_app_background.png",
4 | major_button = "laptop_theme_freedom_major_button.png",
5 | back_button = "laptop_theme_freedom_back_button.png",
6 | back_textcolor = "#FFFF00",
7 | exit_button = "laptop_theme_freedom_exit_button.png",
8 | desktop_icon_button = "laptop_theme_freedom_desktop_icon_button.png",
9 | table_highlight_bgcolor='#17863f',
10 | muted_textcolor = "#555555",
11 | })
12 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | ================================================================
2 | License of source code and textures: WTFPL
3 | -----------------------------------------------------------------
4 | This program is free software. It comes without any warranty, to
5 | the extent permitted by applicable law. You can redistribute it
6 | and/or modify it under the terms of the do whatever you want with it.
7 | To Public License, Version 2, as published by Sam Hocevar. See
8 | http://sam.zoy.org/wtfpl/COPYING for more details.
9 | ================================================================
--------------------------------------------------------------------------------
/themes/basic_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Basic", {
2 | desktop_background = "laptop_theme_basic_desktop_background.png",
3 | app_background = "laptop_theme_basic_app_background.png",
4 | major_button = "laptop_theme_basic_button.png",
5 | major_textcolor = "#FFFFFF",
6 | minor_button = "laptop_theme_basic_button.png",
7 | minor_textcolor = "#FFFFFF",
8 | back_button = "blank.png",
9 | exit_button = "blank.png",
10 | desktop_icon_button = "blank.png",
11 | table_highlight_bgcolor='#999999',
12 | table_highlight_textcolor='#000000',
13 | os_min_version = '7.00',
14 | })
15 |
--------------------------------------------------------------------------------
/MTBOX.md:
--------------------------------------------------------------------------------
1 | The Laptop mod is a group collaboration between Bell07, Toby109tt, veNext, Cross_over and Yours truly lol. We aim to make a working laptop inside of MineTest. There is multiple different computers to choose from and to use. There is multiple different apps to run on comupters There is multiple different media to store data There is multiple different themes to personalize computers
2 |
3 | Apps Included So Far:
4 |
5 | -- System --
6 | System settings
7 | Removable media manager
8 |
9 | -- Office --
10 | Calculator
11 | Sticky Notes
12 | Email
13 |
14 | -- Games --
15 | TNTSweeper
16 | Tetris
17 |
18 | V.0.38
19 |
--------------------------------------------------------------------------------
/README-LICENSE.txt:
--------------------------------------------------------------------------------
1 | Laptop created by GamingAssociation39
2 |
3 | ================================================================
4 | License of source code and textures: LGPL v3
5 |
6 | Copyright © 2007 Free Software Foundation, Inc.
7 |
8 | Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
9 |
10 | This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below.
11 | ================================================================
--------------------------------------------------------------------------------
/themes/circuit_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Circuit", {
2 | desktop_background = "laptop_theme_circuit_desktop_background.png",
3 | app_background = "laptop_theme_circuit_app_background.png",
4 | major_button = "laptop_theme_circuit_major_button.png",
5 | back_button = "laptop_theme_circuit_back_button.png",
6 | back_textcolor = "#000000",
7 | exit_button = "laptop_theme_circuit_exit_button.png",
8 | desktop_icon_button = "blank.png",
9 | taskbar_clock_position_and_size = "11,-.38;4,0.7",
10 | exit_character = " ",
11 | titlebar_textcolor = "#000000",
12 | os_max_version = '6.99',
13 | table_highlight_bgcolor = '#cdf7da',
14 | })
15 |
--------------------------------------------------------------------------------
/themes/clouds_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Clouds", {
2 | desktop_background = "laptop_theme_clouds_desktop_background.png",
3 | app_background = "laptop_theme_clouds_app_background.png",
4 | major_button = "laptop_theme_argyle_major_button.png",
5 | minor_button = "laptop_theme_argyle_major_button.png",
6 | back_button = "laptop_theme_argyle_exit_button.png",
7 | back_textcolor= "#000000",
8 | exit_button = "laptop_theme_argyle_exit_button.png",
9 | exit_textcolor = "#000000",
10 | desktop_icon_button = "blank.png",
11 | desktop_icon_label_button = "laptop_theme_clouds_desktop_icon_label_button.png",
12 | os_min_version = '5.00',
13 | })
14 |
--------------------------------------------------------------------------------
/themes/cubic_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Cubic", {
2 | desktop_background = "laptop_theme_cubic_desktop_background.png",
3 | app_background = "laptop_theme_cubic_app_background.png",
4 | major_button = "laptop_theme_cubic_major_button.png",
5 | back_button = "laptop_theme_cubic_back_button.png",
6 | exit_button = "laptop_theme_cubic_exit_button.png",
7 | desktop_icon_button = "laptop_theme_cubic_desktop_icon_button.png",
8 | table_bgcolor = "#555555",
9 | table_highlight_bgcolor='#0c1c4f',
10 | table_highlight_textcolor = '#ffffff',
11 | table_textcolor = "#ffffff",
12 | muted_textcolor = "#cccccc",
13 | os_min_version = '7.00',
14 | })
15 |
--------------------------------------------------------------------------------
/apps/shell-os_app.lua:
--------------------------------------------------------------------------------
1 | laptop.register_app("shell", {
2 | app_name = "Shell",
3 | app_info = "CS-BOS Graphic Shell",
4 | fullscreen = true,
5 | app_icon = "laptop_????.png",
6 | os_min_version = '1.00',
7 | os_max_version = "4.99",
8 | formspec_func = function(...)
9 | --re-use the default launcher screen
10 | return laptop.apps["launcher"].formspec_func(...)
11 | end,
12 | receive_fields_func = function(...)
13 | --re-use the default launcher processing
14 | return laptop.apps["launcher"].receive_fields_func(...)
15 | end,
16 | appwindow_formspec_func = function(...)
17 | --re-use the default launcher theming
18 | return laptop.apps["launcher"].appwindow_formspec_func(...)
19 | end,
20 | })
21 |
--------------------------------------------------------------------------------
/themes/argyle_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Argyle", {
2 | desktop_background = "laptop_theme_argyle_desktop_background.png",
3 | app_background = "laptop_theme_argyle_app_background.png",
4 | major_button = "laptop_theme_argyle_major_button.png",
5 | minor_button = "laptop_theme_argyle_major_button.png",
6 | back_button = "laptop_theme_argyle_exit_button.png",
7 | back_textcolor= "#000000",
8 | exit_button = "blank.png",
9 | desktop_icon_button = "blank.png",
10 | exit_button = "laptop_theme_argyle_exit_button.png",
11 | exit_textcolor = "#000000",
12 | desktop_icon_label_textcolor = "#000000",
13 | desktop_icon_label_button = "laptop_theme_desktop_icon_label_button_grey.png",
14 | os_max_version = '6.99',
15 | })
16 |
--------------------------------------------------------------------------------
/themes/printer_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("PrintOS", {
2 | desktop_background = "laptop_theme_blue_desktop_background.png",
3 | app_background = "laptop_theme_blue_app_background.png",
4 | contrast_background = "laptop_theme_desktop_icon_label_button_grey.png",
5 | contrast_textcolor = "#63a0e4",
6 | titlebar_textcolor = "#63a0e4",
7 | major_button = "laptop_theme_printos_major_button.png",
8 | minor_button = "laptop_theme_printos_minor_button.png",
9 | back_button = "laptop_theme_blue_back_button.png",
10 | exit_button = "laptop_theme_blue_exit_button.png",
11 | desktop_icon_button = "laptop_theme_blue_desktop_icon_button.png",
12 | table_highlight_bgcolor='#1c3c9e',
13 | table_highlight_textcolor = '#cccccc',
14 | os_max_version = "0.01",
15 | })
16 |
--------------------------------------------------------------------------------
/themes/boing_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Boing!", {
2 | desktop_background = "laptop_theme_boing_desktop_background.png",
3 | app_background = "laptop_theme_boing_app_background.png",
4 | major_button = "laptop_theme_boing_major_button.png",
5 | major_textcolor = "#FFFFFF",
6 | minor_button = "laptop_theme_snowpines_minor_button.png",
7 | minor_textcolor = "#FFFFFF",
8 | back_button = "laptop_theme_boing_back_button.png",
9 | back_textcolor = "#000000",
10 | exit_button = "laptop_theme_boing_exit_button.png",
11 | exit_character = " ",
12 | desktop_icon_button = "blank.png",
13 | taskbar_clock_position_and_size = "11,-.25;4,0.4",
14 | desktop_icon_label_button = "laptop_theme_boing_major_button.png",
15 | titlebar_textcolor = "#000000",
16 | os_max_version = '7.99',
17 | })
18 |
--------------------------------------------------------------------------------
/themes/snowpines_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Snow Pines", {
2 | desktop_background = "laptop_theme_snowpines_desktop_background.png",
3 | app_background = "laptop_theme_snowpines_app_background.png",
4 | major_button = "laptop_theme_snowpines_major_button.png",
5 | major_textcolor = "#FFFFFF",
6 | minor_button = "laptop_theme_snowpines_minor_button.png",
7 | minor_textcolor = "#FFFFFF",
8 | back_button = "laptop_theme_snowpines_exit_button.png",
9 | back_textcolor = "#000000",
10 | exit_button = "laptop_theme_snowpines_exit_button.png",
11 | exit_textcolor = "#000000",
12 | contrast_background = "laptop_theme_snowpines_major_button.png",
13 | desktop_icon_button = "blank.png",
14 | taskbar_clock_position_and_size = "5.5,-.31;4,0.7",
15 | table_bgcolor="#FFFFFF",
16 | table_highlight_bgcolor='#888888',
17 | muted_textcolor = "#444444",
18 | table_border = 'true',
19 | os_min_version = '7.00',
20 | })
21 |
--------------------------------------------------------------------------------
/themes/shell_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("CS-BOS Shell", {
2 | desktop_background = "laptop_theme_shell_desktop_background.png",
3 | app_background = "laptop_theme_shell_app_background.png",
4 | major_button = "laptop_theme_shell_major_button.png",
5 | minor_button = "laptop_theme_shell_minor_button.png",
6 | minor_textcolor = "#FFFFFF",
7 | back_button = "laptop_theme_shell_back_button.png",
8 | back_textcolor = "#000000",
9 | exit_button = "laptop_theme_shell_exit_button.png",
10 | exit_character = " ",
11 | -- desktop_icon_button = "blank.png",
12 | taskbar_clock_position_and_size = "9,3.5;4,2",
13 | desktop_icon_label_button = "laptop_theme_shell_desktop_icon_label_button.png",
14 | desktop_icon_label_textcolor = '#000000',
15 | titlebar_textcolor = "#000000",
16 | table_highlight_bgcolor = '#00ffff',
17 | textcolor = "#888888",
18 | texture_replacements = {
19 | ['laptop_removable.png'] = 'laptop_diskette.png',
20 | },
21 | os_max_version = '5.50',
22 | })
23 |
--------------------------------------------------------------------------------
/apps/launcher_settings_app.lua:
--------------------------------------------------------------------------------
1 | laptop.register_app("launcher_settings", {
2 | app_name = "Settings",
3 | app_icon = "laptop_setting_wrench.png",
4 | app_info = "Desktop settings.",
5 | os_min_version = '5.00',
6 | formspec_func = function(app, mtos)
7 | local settings_data = mtos.bdev:get_app_storage('ram', 'launcher_settings')
8 |
9 | -- Change background setting
10 | local current_theme_name = settings_data.selected_theme or mtos:get_theme().name or "default"
11 | local current_theme = mtos:get_theme(current_theme_name)
12 | local current_idx
13 |
14 | settings_data.themes_tab = {}
15 | for name, _ in pairs(laptop.themes) do
16 | if name ~= "default" and mtos:is_theme_compatible(name) then
17 | table.insert(settings_data.themes_tab, name)
18 | end
19 | end
20 | table.sort(settings_data.themes_tab)
21 |
22 |
23 | local formspec = mtos.theme:get_label('0,0.5', "Select theme")
24 |
25 | local formspec = formspec..mtos.theme:get_tableoptions()..
26 | "tablecolumns[text]"..
27 | "table[0,1;5,2;sel_theme;"
28 | for i, theme in ipairs(settings_data.themes_tab) do
29 | if i > 1 then
30 | formspec = formspec..','
31 | end
32 | if theme == current_theme_name then
33 | current_idx = i
34 | end
35 | formspec = formspec..theme
36 | end
37 | if current_idx then
38 | formspec = formspec..";"..current_idx
39 | end
40 | formspec = formspec.."]"
41 |
42 | if current_theme then
43 | formspec = formspec.."image[5.5,1;5,3.75;"..current_theme.desktop_background.."]"
44 | end
45 |
46 | formspec = formspec .. mtos.theme:get_button('0,3.2;2.5,0.6', 'major', 'theme_apply', 'Apply', 'Apply theme')
47 |
48 | return formspec
49 | end,
50 |
51 | receive_fields_func = function(app, mtos, sender, fields)
52 | local settings_data = mtos.bdev:get_app_storage('ram', 'launcher_settings')
53 | if fields.sel_theme then
54 | local event = minetest.explode_table_event(fields.sel_theme)
55 | settings_data.selected_theme = settings_data.themes_tab[event.row]
56 | end
57 |
58 | if fields.theme_apply and settings_data.selected_theme then
59 | mtos:set_theme(settings_data.selected_theme)
60 | settings_data.selected_theme = nil
61 | end
62 | end
63 | })
64 |
--------------------------------------------------------------------------------
/app_fw.lua:
--------------------------------------------------------------------------------
1 | laptop.apps = {}
2 |
3 | local app_class = {}
4 | app_class.__index = app_class
5 | laptop.class_lib.app = app_class
6 |
7 | -- internally used: get current app formspec
8 | function app_class:get_formspec()
9 | local app_result
10 | if self.formspec_func then
11 | app_result = self.formspec_func(self, self.os)
12 | else
13 | app_result = ""
14 | end
15 | if self.fullscreen then
16 | return app_result
17 | end
18 |
19 | if app_result == false then
20 | return false
21 | end
22 |
23 | local launcher = self.os:get_app(self.os.hwdef.custom_launcher or "launcher")
24 | local window_formspec = ""
25 | if launcher.appwindow_formspec_func then
26 | window_formspec = launcher.appwindow_formspec_func(launcher, self, self.os)
27 | end
28 | return window_formspec..app_result
29 | end
30 |
31 | -- internally used: process input
32 | function app_class:receive_data(method, reshow, sender, ...)
33 | local ret
34 |
35 | if self[method] then
36 | ret = self[method](self, self.os, sender, ...)
37 | end
38 |
39 | if method == "receive_fields_func" then
40 | local fields = ...
41 | if fields.os_back then
42 | self:back_app()
43 | elseif fields.os_exit then
44 | self:exit_app()
45 | end
46 | end
47 | return ret
48 | end
49 |
50 | -- Back to previous app in stack
51 | function app_class:back_app(fields, sender)
52 | self.os:set_app('', sender, fields)
53 | if fields then
54 | self.os:pass_to_app('receive_fields_func', true, sender, fields)
55 | end
56 | end
57 |
58 | -- Exit current app and back to launcher
59 | function app_class:exit_app()
60 | self.os:set_app() -- launcher
61 | end
62 |
63 | function app_class:get_timer()
64 | self.os.timer = self.os.timer or minetest.get_node_timer(self.os.pos)
65 | return self.os.timer
66 | end
67 |
68 | -- Register new app
69 | function laptop.register_app(name, def)
70 | def.name = name
71 | laptop.apps[name] = def
72 | end
73 |
74 | -- Register new app
75 | function laptop.register_view(name, def)
76 | def.view = true
77 | laptop.apps[name] = def
78 | end
79 |
80 | -- load all apps
81 | local app_path = minetest.get_modpath('laptop')..'/apps/'
82 | local app_list = minetest.get_dir_list(app_path, false)
83 |
84 | for _, file in ipairs(app_list) do
85 | if file:sub(-8) == '_app.lua' then
86 | dofile(app_path..file)
87 | end
88 | end
89 |
90 | dofile(app_path..'browser_app.lua')
91 | for _, file in ipairs(app_list) do
92 | if file:sub(-8) == '_app.lua' and file ~= 'browser_app.lua'
93 | then
94 | dofile(app_path..file)
95 | end
96 | end
97 |
--------------------------------------------------------------------------------
/apps/removable_app.lua:
--------------------------------------------------------------------------------
1 | laptop.register_app("removable", {
2 | app_name = "Removable Storage",
3 | app_icon = "laptop_removable.png",
4 | app_info = "Interface with Removable Media",
5 | formspec_func = function(app, mtos)
6 | local formspec =
7 | "list[nodemeta:"..mtos.pos.x..','..mtos.pos.y..','..mtos.pos.z..";main;0,0.3;1,1;]" ..
8 | "list[current_player;main;0,4.85;8,1;]" ..
9 | "list[current_player;main;0,6.08;8,3;8]" ..
10 | "listring[nodemeta:"..mtos.pos.x..','..mtos.pos.y..','..mtos.pos.z..";main]" ..
11 | "listring[current_player;main]"..
12 | "background[0,0.3;8,1;".. mtos.theme.contrast_background .. ']'
13 |
14 | mtos.bdev.removable_disk = nil -- force reading
15 | local idata = mtos.bdev:get_removable_disk()
16 | if idata.stack then
17 | -- change label
18 | formspec = formspec .. "field[2,0.65;4,1;label;;"..idata.label.."]"..
19 | mtos.theme:get_button('5.7,0.5;1.5,0.7', 'minor', 'set_label', 'Rename', 'Rename the '..idata.def.description)..
20 | mtos.theme:get_label('0,1.5', idata.def.description)..
21 | mtos.theme:get_label('0,2', "Format: "..idata.os_format)..
22 | -- buttons
23 | mtos.theme:get_button('0,3;1.5,0.7', 'minor', 'format_wipe', 'wipe', 'Wipe all data from disk')..
24 | mtos.theme:get_button('0,4;1.5,0.7', 'minor', 'format_data', 'data', 'Format disk to store data')
25 | if idata.def.groups.laptop_removable_usb then
26 | formspec = formspec .. mtos.theme:get_button('2,3;1.5,0.7', 'minor', 'format_backup', 'backup', 'Store backup to disk')
27 | end
28 | if idata.os_format == "backup" then
29 | formspec = formspec .. mtos.theme:get_button('2,4;1.5,0.7', 'minor', 'restore', 'restore', 'Restore from backup disk')
30 | end
31 |
32 | -- format CS-BOS
33 | if idata.def.groups.laptop_removable_floppy then
34 | formspec = formspec .. mtos.theme:get_button('4,3;1.5,0.7', 'minor', 'format_csbos', 'CS-BOS', 'Format disk to boot CS-BOS ')
35 | end
36 | end
37 | return formspec
38 | end,
39 |
40 | receive_fields_func = function(app, mtos, sender, fields)
41 | local idata = mtos.bdev:get_removable_disk()
42 | if idata.stack then
43 | if fields.set_label then
44 | idata.label = fields.label
45 | elseif fields.format_wipe then
46 | idata:format_disk()
47 | elseif fields.format_data then
48 | idata:format_disk("data", "Data "..idata.def.description)
49 | elseif fields.format_backup then
50 | idata:format_disk("backup", "Backup of "..mtos.hwdef.description.." from "..os.date('%x'))
51 | idata.meta:set_string("backup_data", mtos.meta:get_string('laptop_appdata'))
52 | elseif fields.format_csbos then
53 | idata:format_disk("boot", "CS-BOS Boot Disk")
54 | elseif fields.restore then
55 | mtos.meta:set_string('laptop_appdata', idata.meta:get_string("backup_data"))
56 | mtos.bdev = laptop.get_bdev_handler(mtos)
57 | mtos:power_on() --reboot
58 | end
59 | end
60 | laptop.mtos_cache:sync_and_free(mtos)
61 | end,
62 | })
63 |
--------------------------------------------------------------------------------
/themes/ambershell_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Amber Shell", {
2 | desktop_background = "laptop_theme_ambershell_desktop_background.png",
3 | app_background = "laptop_theme_ambershell_app_background.png",
4 | major_button = "laptop_theme_ambershell_major_button.png",
5 | major_textcolor = "#FFB000",
6 | minor_button = "laptop_theme_ambershell_minor_button.png",
7 | back_button = "laptop_theme_ambershell_back_button.png",
8 | back_textcolor = "#000000",
9 | exit_button = "laptop_theme_ambershell_exit_button.png",
10 | exit_character = " ",
11 | contrast_background = "laptop_theme_ambershell_desktop_icon_label_button.png",
12 | contrast_textcolor = "#000000",
13 | contrast_bgcolor = "#FFB000",
14 | desktop_icon_button = "laptop_theme_desktop_icon_label_button_black.png",
15 | taskbar_clock_position_and_size = "9,3.5;4,2",
16 | desktop_icon_label_textcolor = '#FFB000',
17 | titlebar_textcolor = "#000000",
18 | textcolor = "#FFB000",
19 | monochrome_textcolor = "#FFB000",
20 | table_bgcolor = "#FFB000",
21 | table_highlight_bgcolor = '#a77200',
22 | table_highlight_textcolor = '#000000',
23 | muted_textcolor = "#6b4900",
24 | status_online_textcolor = "#000000",
25 | status_disabled_textcolor = "#a77200",
26 | status_off_textcolor = "#000000",
27 | os_max_version = '5.50',
28 | texture_replacements = {
29 | ['laptop_mail.png'] = 'laptop_theme_ambershell_email_letter_new.png',
30 | ['laptop_mail_received.png'] = 'laptop_theme_ambershell_mail_received.png',
31 | ['laptop_mail_sentbox.png'] = 'laptop_theme_ambershell_mail_sentbox.png',
32 | ['laptop_email_new.png'] = 'laptop_theme_ambershell_email_new.png',
33 | ['laptop_mail_read_button.png'] = 'laptop_theme_ambershell_email_read.png',
34 | ['laptop_email_edit.png'] = 'laptop_theme_ambershell_email_edit.png',
35 | ['laptop_email_reply.png'] = 'laptop_theme_ambershell_email_reply.png',
36 | ['laptop_email_forward.png'] = 'laptop_theme_ambershell_email_forward.png',
37 | ['laptop_email_trash.png'] = 'laptop_theme_ambershell_email_trash.png',
38 | ['laptop_mail_button.png'] = 'laptop_theme_ambershell_mail_button.png',
39 | ['laptop_printer_button.png'] = 'laptop_theme_ambershell_printer_button.png',
40 | ['laptop_boom.png'] = 'laptop_theme_ambershell_laptop_boom.png',
41 | --shell icons
42 | ['laptop_email_letter.png'] = 'laptop_theme_ambershell_mail_icon.png',
43 | ['laptop_removable.png'] = 'laptop_theme_ambershell_removable_icon.png',
44 | ['laptop_tetris_icon.png'] = 'laptop_theme_ambershell_tetris_icon.png',
45 | ['laptop_cs_bos.png'] = 'laptop_theme_ambershell_cs_bos_icon.png',
46 | ['laptop_tnt.png'] = 'laptop_theme_ambershell_tnt_icon.png',
47 | ['laptop_realchess_chessboard_icon.png'] = 'laptop_theme_ambershell_realchess_chessboard_icon.png',
48 | ['laptop_calculator.png'] = 'laptop_theme_ambershell_calculator_icon.png',
49 | ['laptop_notes_pad.png'] = 'laptop_theme_ambershell_notepad_icon.png',
50 | ['laptop_setting_wrench.png'] = 'laptop_theme_ambershell_settings_icon.png',
51 | }
52 | })
53 |
--------------------------------------------------------------------------------
/themes/greenshell_theme.lua:
--------------------------------------------------------------------------------
1 | laptop.register_theme("Green Shell", {
2 | desktop_background = "laptop_theme_greenshell_desktop_background.png",
3 | app_background = "laptop_theme_greenshell_app_background.png",
4 | major_button = "laptop_theme_greenshell_major_button.png",
5 | major_textcolor = "#00FF33",
6 | minor_button = "laptop_theme_greenshell_minor_button.png",
7 | back_button = "laptop_theme_greenshell_back_button.png",
8 | back_textcolor = "#000000",
9 | exit_button = "laptop_theme_greenshell_exit_button.png",
10 | exit_character = " ",
11 | contrast_background = "laptop_theme_greenshell_desktop_icon_label_button.png",
12 | contrast_textcolor = "#000000",
13 | contrast_bgcolor = "#00FF33",
14 | desktop_icon_button = "laptop_theme_desktop_icon_label_button_black.png",
15 | taskbar_clock_position_and_size = "9,3.5;4,2",
16 | table_bgcolor = "#00FF33",
17 | desktop_icon_label_textcolor = '#00FF33',
18 | titlebar_textcolor = "#000000",
19 | textcolor = "#00FF33",
20 | monochrome_textcolor = "#00FF33",
21 | table_highlight_bgcolor = '#00b71a',
22 | table_highlight_textcolor = '#000000',
23 | muted_textcolor = "#00540b",
24 | status_online_textcolor = "#000000",
25 | status_disabled_textcolor = "#a77200",
26 | status_off_textcolor = "#000000",
27 | os_max_version = '5.50',
28 | texture_replacements = {
29 | ['laptop_mail.png'] = 'laptop_theme_greenshell_email_letter_new.png',
30 | ['laptop_mail_received.png'] = 'laptop_theme_greenshell_mail_received.png',
31 | ['laptop_mail_sentbox.png'] = 'laptop_theme_greenshell_mail_sentbox.png',
32 | ['laptop_email_new.png'] = 'laptop_theme_greenshell_email_new.png',
33 | ['laptop_mail_read_button.png'] = 'laptop_theme_greenshell_email_read.png',
34 | ['laptop_email_edit.png'] = 'laptop_theme_greenshell_email_edit.png',
35 | ['laptop_email_reply.png'] = 'laptop_theme_greenshell_email_reply.png',
36 | ['laptop_email_forward.png'] = 'laptop_theme_greenshell_email_forward.png',
37 | ['laptop_email_trash.png'] = 'laptop_theme_greenshell_email_trash.png',
38 | ['laptop_mail_button.png'] = 'laptop_theme_greenshell_mail_button.png',
39 | ['laptop_printer_button.png'] = 'laptop_theme_greenshell_printer_button.png',
40 | ['laptop_boom.png'] = 'laptop_theme_greenshell_laptop_boom.png',
41 | --shell icons
42 | ['laptop_email_letter.png'] = 'laptop_theme_greenshell_mail_icon.png',
43 | ['laptop_removable.png'] = 'laptop_theme_greenshell_removable_icon.png',
44 | ['laptop_tetris_icon.png'] = 'laptop_theme_greenshell_tetris_icon.png',
45 | ['laptop_cs_bos.png'] = 'laptop_theme_greenshell_cs_bos_icon.png',
46 | ['laptop_tnt.png'] = 'laptop_theme_greenshell_tnt_icon.png',
47 | ['laptop_realchess_chessboard_icon.png'] = 'laptop_theme_greenshell_realchess_chessboard_icon.png',
48 | ['laptop_calculator.png'] = 'laptop_theme_greenshell_calculator_icon.png',
49 | ['laptop_notes_pad.png'] = 'laptop_theme_greenshell_notepad_icon.png',
50 | ['laptop_setting_wrench.png'] = 'laptop_theme_greenshell_settings_icon.png',
51 | }
52 | })
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laptop | Computers emulation for Minetest
2 |
3 | The Laptop mod is a group collaboration between bell07, Cross_over, Gerold55, Toby109tt, v-rob, veNext, Grizzly Adam and Yours truly lol.
4 | We aim to make a working laptop inside of MineTest.
5 | There are different computers, apps which run on computers, media to store data and different themes to personalize the appearance.
6 |
7 | 
8 |
9 | An [API.md](https://github.com/Gerold55/minetest-laptop/blob/master/API.md) is given to develop additional components.
10 | The mod includes next components:
11 |
12 | ## Hardware
13 |
14 | | Itemname | Name | Author |
15 | | - | - | - |
16 | | core | CP Core | by Cross_over and Gerold55 |
17 | | printer | Flash Printex | by Cross_over and Gerold55 |
18 | | cube | CUBE PC | by Cross_over and Gerold55 |
19 | | monitor2 | Fruit Zero | by Cross_over and Gerold55 |
20 | | monitor4 | Bell CrossOver | by Cross_over and Gerold55 |
21 | | monitor3 | Pentium 3 | by Cross_over and Gerold55 |
22 | | laptop | laptop v2.0 | by Cross_over and Gerold55 |
23 |
24 | ## Items
25 | | Itemname | Description | Author |
26 | | - | - | - |
27 | | floppy | Boot old computer or just store data | by Toby109tt and Cross_over |
28 | | usbstick | Store data or take full computer backup | by Toby109tt and Cross_over |
29 | | printed_paper | Show printed text on use | by Toby109tt and Cross_over |
30 |
31 | ## Software
32 | ### System
33 | | Name | Description | Author |
34 | | - | - | - |
35 | | mtos/app_fw/bdev | Operating System | by bell07 |
36 | | launcher | Desktop launcher | by bell07, app icons by Toby109tt and Cross_over |
37 | | launcher_settings | Theme selector | by bell07 |
38 | | os_dialogs | Select file dialog | by bell07 |
39 | | os_print | Printer OS and driver | by bell07 |
40 | | removable | Removable storage manager | by bell07 |
41 | | CS-BOS | Text based Operating System | by Grizzly Adam and bell07 |
42 |
43 | ### Office
44 | | Name | Description | Author |
45 | | - | - | - |
46 | | calculator | Calculator | by bell07 |
47 | | mail | Email service | by bell07 |
48 | | stickynote | Text editor | by bell07 |
49 |
50 | ### Games
51 | | Name | Description | Author |
52 | | - | - | - |
53 | | tetris | Tetris clone | by kilbith (Ported from homedecor by bell07) |
54 | | TNTsweeper | Minesweeper clone | by bell07 |
55 | | realchess | Chess game | by kilbith (Ported from realchess by bell07) |
56 |
57 | ## Themes
58 | | Name | Description | Author |
59 | | - | - | - |
60 | | amber shell | | by Grizzly Adam |
61 | | argyle | | by Grizzly Adam |
62 | | basic | | by v-rob |
63 | | blue | | by v-rob |
64 | | boing! | | by Grizzly Adam |
65 | | bubbles | | by veNext |
66 | | Circuit | | by Grizzly Adam |
67 | | clouds | | by Grizzly Adam |
68 | | cubic | | by v-rob |
69 | | fruit | | by veNext |
70 | | green shell | | by Grizzly Adam |
71 | | magma | | by v-rob |
72 | | red | | by v-rob |
73 | | shell | | by Grizzly Adam |
74 | | snow pines | | by Grizzly Adam |
75 |
76 |
77 | V.0.38
78 |
--------------------------------------------------------------------------------
/apps/launcher_app.lua:
--------------------------------------------------------------------------------
1 |
2 | laptop.register_app("launcher", {
3 | app_name = "Main launcher",
4 | app_info = "Desktop Enviroment",
5 | fullscreen = true,
6 | os_min_version = '5.00',
7 | formspec_func = function(launcher_app, mtos)
8 |
9 | -- no system found. Error
10 | if not mtos.sysdata then
11 | local formspec = "size[10,7]background[10,7;0,0;laptop_launcher_insert_floppy.png;true]"..
12 | "listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]"..
13 | "list[nodemeta:"..mtos.pos.x..','..mtos.pos.y..','..mtos.pos.z..";main;2.5,3;1,1;]" ..
14 | "list[current_player;main;0,6.5;8,1;]" ..
15 | "listring[nodemeta:"..mtos.pos.x..','..mtos.pos.y..','..mtos.pos.z..";main]" ..
16 | "listring[current_player;main]"
17 |
18 | local idata = mtos.bdev:get_removable_disk()
19 | if idata.stack then
20 | if idata.os_format ~= "boot" then
21 | formspec = formspec .. "label[0,1.7;Disk found but not formatted to boot]"
22 | end
23 | end
24 | return formspec
25 | end
26 |
27 | local c_row_count = 4
28 |
29 | local i = 0
30 | local out = "size[15,10]"
31 | if mtos.theme.desktop_background then
32 | out = out..'background[15,10;0,0;'..mtos.theme.desktop_background..';true]'
33 | end
34 | local appslist_sorted = {}
35 | for name, def in pairs(laptop.apps) do
36 | if def.app_name and not def.view and def.name ~= launcher_app.name and mtos:is_app_compatible(name)then
37 | table.insert(appslist_sorted, {name = name, def = def})
38 | end
39 | end
40 | table.sort(appslist_sorted, function(a,b) return a.name < b.name end)
41 | for i, e in ipairs(appslist_sorted) do
42 | local x = math.floor((i-1) / c_row_count)*2 + 1
43 | local y = ((i-1) % c_row_count)*2 + 1
44 | out = out .. mtos.theme:get_image_button(x..','..y..';1,1', 'desktop_icon', e.name, mtos.theme:get_texture(e.def.app_icon or 'logo.png'), "", (e.def.app_info or e.name))..
45 | mtos.theme:get_button((x-.5)..','..(y+1.08)..';2,.5', 'desktop_icon_label', e.name, e.def.app_name)
46 | end
47 | out = out..mtos.theme:get_button(mtos.theme.taskbar_clock_position_and_size, "major", "os_clock", os.date("%c"))
48 | return out
49 | end,
50 | appwindow_formspec_func = function(launcher_app, app, mtos)
51 | local formspec = 'size[15,10]'
52 | if mtos.theme.app_background then
53 | formspec = formspec..'background[0,0;15,10;'..mtos.theme.app_background..';true]'
54 | end
55 | if #mtos.sysram.stack > 0 then
56 | formspec = formspec..mtos.theme:get_button('-0.29,-0.31;1.09,0.61', 'back', 'os_back', '<', 'Return to previous screen')
57 | end
58 | if app.app_info then
59 | if #mtos.sysram.stack > 0 then
60 | formspec = formspec..mtos.theme:get_label("0.8,-0.29", app.app_info, "titlebar")
61 | else
62 | formspec = formspec..mtos.theme:get_label("-0.1,-0.29", app.app_info, "titlebar")
63 | end
64 | end
65 | formspec = formspec..mtos.theme:get_button('14.2,-0.31;1.09,0.61', 'exit', 'os_exit', mtos.theme.exit_character, 'Exit app')
66 | return formspec
67 | end,
68 | receive_fields_func = function(launcher_app, mtos, sender, fields)
69 | for name, descr in pairs(fields) do
70 | if laptop.apps[name] then
71 | mtos:set_app(name)
72 | break
73 | end
74 | end
75 | end,
76 | })
77 |
78 |
--------------------------------------------------------------------------------
/recipe_compat.lua:
--------------------------------------------------------------------------------
1 | laptop.recipe_compat = {
2 | -- Init all used vars to avoid crash if missed
3 | tin = '-unknown-', copper = '-unknown-', gold = '-unknown-',
4 | steel = '-unknown-', glass = '-unknown-', diamond = '-unknown-',
5 | silicon = '-unknown-', fiber = '-unknown-',
6 | gates_diode = '-unknown-', gates_and = '-unknown-', gates_or = '-unknown-',
7 | gates_nand = '-unknown-', gates_xor = '-unknown-', gates_not = '-unknown-',
8 | fpga = '-unknown-', programmer = '-unknown-', delayer = '-unknown-',
9 | controller = '-unknown-', light_red = '-unknown-', light_green = '-unknown-',
10 | light_blue = '-unknown-',
11 | plastic = '-unknown-', motor = '-unknown-',
12 | battery = '-unknown-', lv_transformer = '-unknown-',
13 | }
14 |
15 | local rc = laptop.recipe_compat
16 |
17 | -- Fallback values from default mod
18 | if minetest.get_modpath('default') then
19 | rc.tin = 'default:tin_ingot'
20 | rc.copper = 'default:copper_ingot'
21 | rc.gold = 'default:gold_ingot'
22 | rc.steel = 'default:steel_ingot'
23 | rc.glass = 'default:glass'
24 | rc.diamond = 'default:diamond'
25 | rc.plastic = 'default:steel_ingot'
26 | rc.motor = 'default:steel_ingot'
27 | rc.battery = 'default:steel_ingot'
28 | rc.lv_transformer = 'default:copper_ingot'
29 | end
30 |
31 | if minetest.get_modpath('homedecor') then
32 | rc.gates_diode = 'homedecor:paraffin'
33 | rc.gates_and = 'homedecor:power_crystal'
34 | rc.gates_or = 'homedecor:steel_strip'
35 | rc.gates_nand = 'homedecor:steel_wire'
36 | rc.gates_xor = 'homedecor:copper_wire'
37 | rc.gates_not = 'homedecor:copper_strip'
38 | rc.fpga = 'homedecor:ic'
39 | rc.programmer = 'homedecor:heating_element'
40 | rc.controller = 'homedecor:motor'
41 | rc.motor = 'homedecor:motor'
42 | end
43 |
44 | if minetest.get_modpath('mesecons_materials') then
45 | rc.silicon = 'mesecons_materials:silicon'
46 | rc.fiber = 'mesecons_materials:fiber'
47 | end
48 |
49 | if minetest.get_modpath('mesecons_gates') then
50 | rc.gates_diode = 'mesecons_gates:diode_off'
51 | rc.gates_and = 'mesecons_gates:and_off'
52 | rc.gates_or = 'mesecons_gates:or_off'
53 | rc.gates_nand = 'mesecons_gates:nand_off'
54 | rc.gates_xor = 'mesecons_gates:xor_off'
55 | rc.gates_not = 'mesecons_gates:not_off'
56 | end
57 |
58 | if minetest.get_modpath('mesecons_fpga') then
59 | rc.fpga = 'mesecons_fpga:fpga0000'
60 | rc.programmer = 'mesecons_fpga:programmer'
61 | end
62 |
63 | if minetest.get_modpath('mesecons_delayer') then
64 | rc.delayer = 'mesecons_delayer:delayer_off_1'
65 | end
66 |
67 | if minetest.get_modpath('mesecons_luacontroller') then
68 | rc.controller = 'mesecons_luacontroller:luacontroller0000'
69 | end
70 |
71 | if minetest.get_modpath('mesecons_lightstone') then
72 | rc.light_red = 'mesecons_lightstone:lightstone_red_off'
73 | rc.light_green = 'mesecons_lightstone:lightstone_green_off'
74 | rc.light_blue = 'mesecons_lightstone:lightstone_blue_off'
75 | end
76 |
77 | if minetest.get_modpath('basic_materials') then
78 | rc.plastic = 'basic_materials:plastic_sheet'
79 | rc.motor = 'basic_materials:motor'
80 | end
81 |
82 | if minetest.get_modpath('technic') then
83 | rc.battery = 'technic:battery'
84 | rc.lv_transformer = 'technic:lv_transformer'
85 | rc.silicon = 'technic:doped_silicon_wafer'
86 | end
87 |
88 |
--------------------------------------------------------------------------------
/apps/stickynote_app.lua:
--------------------------------------------------------------------------------
1 | local store_area = 'stickynote:files'
2 |
3 | laptop.register_app("stickynote", {
4 | app_name = "Notepad",
5 | app_icon = "laptop_notes_pad.png",
6 | app_info = "Write Text Documents",
7 | formspec_func = function(app, mtos)
8 | local data = mtos.bdev:get_app_storage('system', 'stickynote')
9 | data.files = data.files or {}
10 | data.text = data.text or ""
11 |
12 | if data.selected_disk_name and data.selected_file_name then
13 | app.app_info = app.app_info..' - Open File: '..data.selected_disk_name..' / '..data.selected_file_name
14 | end
15 |
16 | -- cache sorted files list
17 | if not data.fileslist_sorted then
18 | data.fileslist_sorted = {}
19 | for filename,_ in pairs(data.files) do
20 | table.insert(data.fileslist_sorted, filename)
21 | end
22 | table.sort(data.fileslist_sorted)
23 | end
24 |
25 | local formspec = "background[0,1.35;15.2,8.35;"..mtos.theme.contrast_background.."]"..
26 | "textarea[0.35,1.35;15.08,9.5;text;;"..minetest.formspec_escape(data.text).."]"..
27 | mtos.theme:get_button('0,0.5;1.5,0.8', 'minor', 'clear', 'New', 'New file')..
28 | mtos.theme:get_button('2,0.5;1.5,0.8', 'minor', 'load', 'Load', 'Load file')..
29 | mtos.theme:get_button('4,0.5;1.5,0.8', 'minor', 'save', 'Save', 'Save file')..
30 | mtos.theme:get_button('8,0.5;1.5,0.8', 'minor', 'print', 'Print', 'Print file')
31 | return formspec
32 | end,
33 | receive_fields_func = function(app, mtos, sender, fields)
34 | local data = mtos.bdev:get_app_storage('system', 'stickynote')
35 | if fields.text then
36 | data.text = fields.text
37 | end
38 |
39 | if fields.load then
40 | mtos:select_file_dialog({
41 | mode = 'open',
42 | allowed_disks = {'hdd', 'removable'},
43 | selected_disk_name = data.selected_disk_name,
44 | selected_file_name = data.selected_file_name,
45 | store_name = store_area,
46 | prefix = 'open_',
47 | })
48 | elseif fields.open_selected_disk and fields.open_selected_file then
49 | data.selected_disk_name = fields.open_selected_disk
50 | data.selected_file_name = fields.open_selected_file
51 | local store = mtos.bdev:get_app_storage(data.selected_disk_name, store_area)
52 | if store then
53 | data.text = store[data.selected_file_name].content
54 | end
55 | elseif fields.save then
56 | mtos:select_file_dialog({
57 | mode = 'save',
58 | allowed_disks = {'hdd', 'removable'},
59 | selected_disk_name = data.selected_disk_name,
60 | selected_file_name = data.selected_file_name,
61 | store_name = store_area,
62 | prefix = 'save_',
63 | })
64 | elseif fields.save_selected_disk and fields.save_selected_file then
65 | data.selected_disk_name = fields.save_selected_disk
66 | data.selected_file_name = fields.save_selected_file
67 | local store = mtos.bdev:get_app_storage(data.selected_disk_name, store_area)
68 | if store then
69 | store[data.selected_file_name] = { content = data.text, ctime = os.time(), owner = sender:get_player_name() }
70 | end
71 | elseif fields.clear then
72 | data.selected_disk_name = nil
73 | data.selected_file_name = nil
74 | data.text = ""
75 | elseif fields.print then
76 | mtos:print_file_dialog({
77 | label = data.selected_file_name,
78 | text = data.text,
79 | })
80 | end
81 | end
82 | })
83 |
--------------------------------------------------------------------------------
/themes.lua:
--------------------------------------------------------------------------------
1 | laptop.themes = {
2 | default = { --Fallback theme
3 | desktop_background = "blank.png",
4 | desktop_icon_button = "blank.png",
5 | desktop_icon_label_button = "laptop_theme_desktop_icon_label_button_black.png",
6 | desktop_icon_label_textcolor = '#FFFFFF',
7 | app_background = "blank.png",
8 | titlebar_textcolor = "#FFFFFF",
9 | back_button = "laptop_theme_blue_back_button.png",
10 | back_textcolor = "#FFFF00",
11 | exit_button = "laptop_theme_blue_exit_button.png",
12 | exit_textcolor = "#FF0000",
13 | exit_character = "X",
14 | major_button = "laptop_theme_blue_major_button.png",
15 | major_textcolor = "#000000",
16 | minor_button = "laptop_theme_minor_button.png",
17 | minor_textcolor = "#000000",
18 | contrast_background = "gui_formbg.png",
19 | contrast_bgcolor = "#000000",
20 | contrast_textcolor = "#FFFFFF",
21 | toolbar_button = "laptop_theme_basic_button.png",
22 | toolbar_textcolor = "#000000",
23 | status_online_textcolor = "#00FF00",
24 | status_disabled_textcolor = "#FF0000",
25 | status_off_textcolor = "#888888",
26 | table_bgcolor = "#ffffff",
27 | table_textcolor = "#000000",
28 | table_highlight_bgcolor = '#cde6f7',
29 | table_highlight_textcolor = '#000000',
30 | muted_textcolor = "#666666",
31 | -- monochrome_textcolor = nil, -- If set, some colorizing is applied using this color
32 |
33 | textcolor = "#000000",
34 |
35 | taskbar_clock_position_and_size = "11,9.8;4,0.7",
36 | node_color = 0,
37 | table_border = 'yes',
38 | texture_replacements = {}, -- No replacements in default theme
39 | -- os_min_version = nil,
40 | -- os_max_version = nil,
41 |
42 | -- used in browser app
43 | url_dark_textcolor = "#6495ED",
44 | url_dark_button = "laptop_theme_desktop_icon_label_button_black.png",
45 | url_bright_textcolor = "#000080",
46 | url_bright_button = "laptop_fruit_base.png",
47 | },
48 | }
49 |
50 | function laptop.register_theme(name, def)
51 | laptop.themes[name] = def
52 | end
53 |
54 | -- load all themes
55 | local theme_path = minetest.get_modpath('laptop')..'/themes/'
56 | local theme_list = minetest.get_dir_list(theme_path, false)
57 |
58 | for _, file in ipairs(theme_list) do
59 | if file:sub(-10) == '_theme.lua' then
60 | dofile(theme_path..file)
61 | end
62 | end
63 |
64 | local theme_class = {}
65 | theme_class.__index = theme_class
66 |
67 | -- get prepared button textures
68 | function theme_class:get_button(area, prefix, code, text, tooltip)
69 | local formspec = 'image_button['..area..';'..self[prefix.."_button"]..';'..code..';'.. minetest.colorize(self[prefix.."_textcolor"] or self.textcolor,minetest.formspec_escape(text))..']'
70 | if tooltip then
71 | formspec = formspec.."tooltip["..code..";"..minetest.formspec_escape(tooltip).."]"
72 | end
73 | return formspec
74 | end
75 |
76 | -- get prepared button textures
77 | function theme_class:get_image_button(area, prefix, code, image, text, tooltip)
78 | local formspec = 'image_button['..area..';'..self[prefix.."_button"]..'^'..self:get_texture(image)..';'..code..';'.. minetest.colorize(self[prefix.."_textcolor"] or self.textcolor,minetest.formspec_escape(text))..']'
79 | if tooltip then
80 | formspec = formspec.."tooltip["..code..";"..minetest.formspec_escape(tooltip).."]"
81 | end
82 | return formspec
83 | end
84 |
85 |
86 | -- Get themed label
87 | function theme_class:get_label(area, label, color_prefix)
88 | if color_prefix then
89 | return 'label['..area..';'..minetest.colorize(self[color_prefix.."_textcolor"] or self.textcolor, minetest.formspec_escape(label))..']'
90 | else
91 | return 'label['..area..';'..minetest.colorize(self.textcolor, minetest.formspec_escape(label))..']'
92 | end
93 | end
94 |
95 | -- Get themed texture name
96 | function theme_class:get_texture(texture_name)
97 | return self.texture_replacements[texture_name] or texture_name
98 | end
99 |
100 | function theme_class:get_bgcolor_box(area, color_prefix)
101 | return 'box['..area..';'..(self[color_prefix.."_bgcolor"] or self.bgcolor)..']'
102 | end
103 |
104 | function theme_class:get_tableoptions(show_select_bar)
105 | if show_select_bar == false then
106 | return "tableoptions[background="..self.table_bgcolor..
107 | ";color="..self.table_textcolor..
108 | ";highlight="..self.table_bgcolor..
109 | ";highlight_text="..self.table_textcolor..
110 | ";border="..self.table_border.."]"
111 | else
112 | return "tableoptions[background="..self.table_bgcolor..
113 | ";color="..self.table_textcolor..
114 | ";highlight="..self.table_highlight_bgcolor..
115 | ";highlight_text="..self.table_highlight_textcolor..
116 | ";border="..self.table_border.."]"
117 | end
118 | end
119 |
120 |
121 | function laptop.get_theme(theme_name)
122 | theme_name = theme_name or "Freedom"
123 | local self = setmetatable({}, theme_class)
124 | for k, v in pairs(laptop.themes.default) do
125 | self[k] = v
126 | end
127 | if theme_name and laptop.themes[theme_name] then
128 | for k,v in pairs(laptop.themes[theme_name]) do
129 | self[k] = v
130 | end
131 | self.name = theme_name
132 | else
133 | self.name = "default"
134 | end
135 | return self
136 | end
137 |
--------------------------------------------------------------------------------
/apps/os_dialogs_app.lua:
--------------------------------------------------------------------------------
1 | -- Tool to get data
2 | local function get_file(key, value)
3 | if not value then
4 | return { name = key }
5 | elseif type(value) == 'string' then
6 | return { name = key, content = value }
7 | else
8 | return {
9 | name = key,
10 | -- content = value.content or value,
11 | owner = value.owner,
12 | ctime = value.ctime,
13 | }
14 | end
15 | end
16 |
17 | laptop.register_view('os:power_off', {
18 | fullscreen = true,
19 | })
20 |
21 |
22 | laptop.register_view('os:select_file', {
23 | formspec_func = function(app, mtos)
24 | local param = mtos.bdev:get_app_storage('ram', 'os:select_file').param
25 | local allowed_disks = param.allowed_disks or { 'system' }
26 | local selected_disk
27 | if param.selected_disk_name then
28 | selected_disk = mtos.bdev:get_app_storage(param.selected_disk_name, param.store_name)
29 | end
30 |
31 | -- Get all available storage and check the storage_list
32 | local storage_list = {}
33 | for idx, disk in ipairs(allowed_disks) do
34 | local dev_exists = mtos.bdev:get_app_storage(disk, param.store_name)
35 | if dev_exists then
36 | if not selected_disk then
37 | selected_disk = dev_exists
38 | param.selected_disk_name = disk
39 | end
40 | table.insert(storage_list, disk)
41 | end
42 | end
43 |
44 | -- Get sorted files list
45 | param.files_list = {}
46 | if selected_disk then
47 | for key, value in pairs(selected_disk) do
48 | table.insert(param.files_list, get_file(key, value))
49 | end
50 | end
51 | table.sort(param.files_list, function(a,b) return a.name 1 then
91 | formspec = formspec..','
92 | end
93 | formspec = formspec..file.name..','..(file.owner or '')..','
94 | if file.ctime then
95 | formspec = formspec..os.date("%c", file.ctime)
96 | end
97 | if file.name == param.selected_file_name then
98 | selected_idx = idx
99 | end
100 | end
101 | formspec = formspec .. ";"..selected_idx.."]"
102 |
103 | -- Buttons
104 | if param.mode == 'save' then
105 | formspec = formspec .. mtos.theme:get_bgcolor_box('1.5,8.8;11,1.2', 'contrast')..
106 | mtos.theme:get_label("1.6,9.1", "File name:", "contrast").."field[3.2,9.3;5.5,0.8;filename;;"..(param.selected_file_name or "").."]"
107 | else
108 | formspec = formspec .. mtos.theme:get_label('1.5, 9.3', "Selected file: "..(param.selected_file_name or ""))
109 | end
110 | if param.selected_file_name and param.selected_file_name ~= "" and
111 | selected_disk and selected_disk[param.selected_file_name] then
112 | formspec = formspec .. mtos.theme:get_button('10.2,8.9;1.5,1', 'minor', 'delete', 'Delete')
113 | formspec = formspec .. mtos.theme:get_button('8.5,8.9;1.5,1', 'major', 'select', param.button_txt)
114 | elseif param.mode == 'save' then
115 | formspec = formspec .. mtos.theme:get_button('8.5,8.9;1.5,1', 'major', 'select', param.button_txt)
116 | end
117 |
118 | return formspec
119 | end,
120 |
121 | -- Input processing
122 | receive_fields_func = function(app, mtos, sender, fields)
123 | local st = mtos.bdev:get_app_storage('ram', 'os:select_file')
124 | local param = st.param
125 |
126 | if fields.filename then
127 | param.selected_file_name = fields.filename
128 | end
129 |
130 | for field, value in pairs(fields) do
131 | if field:sub(1,7) == 'disksel' then
132 | param.selected_disk_name = field:sub(9,-1)
133 | break
134 | end
135 | end
136 |
137 | if fields.mount then
138 | mtos:set_app("removable")
139 |
140 | elseif fields.filesel then
141 | local event = minetest.explode_table_event(fields.filesel)
142 | if param.files_list[event.row] then
143 | param.selected_file_name = param.files_list[event.row].name
144 | end
145 |
146 | elseif fields.select and param.selected_file_name and param.selected_file_name ~= ""
147 | and param.selected_disk_name and param.selected_disk_name ~= "" then
148 | param.prefix = param.prefix or ""
149 | local pass_fields = {
150 | [param.prefix..'selected_disk'] = param.selected_disk_name,
151 | [param.prefix..'selected_file'] = param.selected_file_name,
152 | }
153 | app:back_app(pass_fields, sender)
154 | st.param = nil
155 | elseif fields.delete and param.selected_disk_name and param.selected_file_name then
156 | local store = mtos.bdev:get_app_storage(param.selected_disk_name, param.store_name)
157 | if store then
158 | store[param.selected_file_name] = nil
159 | end
160 | end
161 | end
162 | })
163 |
--------------------------------------------------------------------------------
/apps/browser_app.lua:
--------------------------------------------------------------------------------
1 | laptop.browser_api = {} -- Be useable from other mods
2 |
3 |
4 | -- Helper function - navigate to page
5 | function laptop.browser_api.navigate(app, mtos, pagename)
6 | local page_prep = minetest.strip_colors(pagename)
7 | if page_prep == "" then
8 | return
9 | end
10 |
11 | local page_prep = page_prep:lower()
12 | local page = laptop.apps[page_prep]
13 | if page and page.browser_page then
14 | mtos:set_app(page_prep)
15 | else
16 | mtos:set_app("error.404")
17 | end
18 | end
19 |
20 | --- Navigation bar - Shown on each page - needs to be included to each page
21 | function laptop.browser_api.header_formspec_func(app, mtos)
22 | local currentpage = ""
23 | if app.browser_page then
24 | currentpage = app.name
25 | end
26 | local formspec = "field[.2,.5;13,1;input_field;;"..currentpage.."]field_close_on_enter[input_field;false]"..
27 | mtos.theme:get_image_button('12.9,.3;.8,.8', 'toolbar', 'go_button', 'laptop_go_web.png', '', 'Go') ..
28 | mtos.theme:get_image_button('13.6,.3;.8,.8', 'toolbar', 'home_button', 'laptop_home_web.png', '', 'Home') ..
29 | mtos.theme:get_image_button('14.3,.3;.8,.8', 'toolbar', 'settings_button', 'laptop_settings_web.png', '', 'Settings')
30 | return formspec
31 | end
32 |
33 | -- Page header / Navigation bar buttons processing. Needs to be included to each page
34 | function laptop.browser_api.header_receive_fields_func(app, mtos, sender, fields)
35 | if (fields.key_enter and fields.key_enter_field == "input_field") or fields.go_button then
36 | laptop.browser_api.navigate(app, mtos, fields.input_field)
37 | elseif fields.home_button then
38 | mtos:set_app("browser")
39 | elseif fields.settings_button then
40 | mtos:set_app("browser:settings")
41 | elseif fields.page_link then
42 | laptop.browser_api.navigate(app, mtos, fields.page_link)
43 | end
44 | end
45 |
46 | --------------------------------------------
47 | -- Browser home page
48 | --------------------------------------------
49 | laptop.register_app("browser", {
50 | app_name = "MineBrowse",
51 | app_icon = "laptop_browser.png",
52 | app_info = "Web Browser",
53 | os_min_version = "5.51",
54 | formspec_func = function(app, mtos)
55 | local formspec = laptop.browser_api.header_formspec_func(app, mtos) ..
56 | --"image[.1,1.3;18,1.6;laptop_header_web.png]"..
57 | "image[0,1.3;18,1.6;laptop_welcome_web.png]"..
58 | mtos.theme:get_label('.1,2.7', 'MineBrowse is a working web browser powered by formspecs. It is community driven,', 'contrast') ..
59 | mtos.theme:get_label('.1,3', 'which means websites are created by the community. If you like to add your own site', 'contrast') ..
60 | mtos.theme:get_label('.1,3.3', 'visit submit.official for further details.', 'contrast') ..
61 | "background[0,1.2;15,9;laptop_background.png]"..
62 | mtos.theme:get_button('11.3,9.3;3,.8', 'url_bright', 'page_link', 'submit.official') ..
63 | "image[11,2.8;4,8.1;laptop_ad1_web.png]"..
64 | "image[.1,3.8;12,1.2;laptop_wa_web.png]"
65 |
66 | -- Prepare / Generate Pages list
67 | local c_row_count = 12
68 |
69 | local pageslist_sorted = {}
70 | for name, def in pairs(laptop.apps) do
71 | if def.browser_page and mtos:is_app_compatible(name) then
72 | table.insert(pageslist_sorted, {name = name, def = def})
73 | end
74 | end
75 | table.sort(pageslist_sorted, function(a,b) return a.name < b.name end)
76 | for i, e in ipairs(pageslist_sorted) do
77 | local x = math.floor((i-1) / c_row_count)*5 + 0.3
78 | local y = ((i-1) % c_row_count)*0.4 + 4.7
79 | formspec = formspec .. mtos.theme:get_button(x..','..y..';3,.5', 'url_dark', "page_link", e.name)..
80 | mtos.theme:get_label((x+3)..','..y, e.def.app_info, 'contrast')
81 | end
82 |
83 | return formspec
84 | end,
85 | receive_fields_func = function(app, mtos, sender, fields)
86 | laptop.browser_api.header_receive_fields_func(app, mtos, sender, fields)
87 | end
88 | })
89 |
90 | --------------------------------------------
91 | -- Error 404 - Page not found
92 | --------------------------------------------
93 | laptop.register_view("error.404", {
94 | app_info = "Page not found",
95 | formspec_func = function(app, mtos)
96 | local formspec = laptop.browser_api.header_formspec_func(app, mtos) ..
97 | mtos.theme:get_label('.3,1.1','Error 404 - Page not found')
98 | return formspec
99 | end,
100 | receive_fields_func = function(app, mtos, sender, fields)
101 | laptop.browser_api.header_receive_fields_func(app, mtos, sender, fields)
102 | end
103 | })
104 |
105 | --------------------------------------------
106 | -- Settings
107 | --------------------------------------------
108 | laptop.register_view("browser:settings", {
109 | app_info = "Browser settings",
110 | formspec_func = function(app, mtos)
111 | local formspec = mtos.theme:get_label('.3,1.1','Settings')
112 | return formspec
113 | end,
114 | receive_fields_func = function(app, mtos, sender, fields)
115 | laptop.browser_api.header_receive_fields_func(app, mtos, sender, fields)
116 | end
117 | })
118 |
119 | --------------------------------------------
120 | -- Submit informations
121 | --------------------------------------------
122 | laptop.register_view("submit.official", {
123 | app_info = "Contribute to Minetest Laptop Mod",
124 | browser_page = true,
125 | formspec_func = function(app, mtos)
126 | local formspec = laptop.browser_api.header_formspec_func(app, mtos) ..
127 | mtos.theme:get_label('.1,2.8', 'You can help create many more websites that people can explore!', 'contrast') ..
128 | mtos.theme:get_label('.1,3.1', 'Each website can have multiple pages.', 'contrast') ..
129 | mtos.theme:get_label('.1,3.4', 'Please submit your website/webpages to:', 'contrast') ..
130 | mtos.theme:get_label('.1,3.7', 'https://github.com/Gerold55/MineBrowse-Sites', 'contrast') ..
131 | "background[0,1.2;15,9;laptop_background.png]"
132 | return formspec
133 | end,
134 | receive_fields_func = function(app, mtos, sender, fields)
135 | laptop.browser_api.header_receive_fields_func(app, mtos, sender, fields)
136 | end
137 | })
--------------------------------------------------------------------------------
/apps/calculator_app.lua:
--------------------------------------------------------------------------------
1 | laptop.register_app("calculator", {
2 | app_name = "Calculator",
3 | app_icon = "laptop_calculator.png",
4 | app_info = "Perform Mathematical Calculations",
5 | formspec_func = function(app, mtos)
6 | local data = mtos.bdev:get_app_storage('ram', 'calculator')
7 |
8 | if not data.tab then
9 | data.tab = {}
10 | end
11 | if not data.tab[1] then
12 | table.insert(data.tab, {})
13 | end
14 |
15 | local formspec = mtos.theme:get_tableoptions(false).."tablecolumns[" ..
16 | "text,align=right,padding=1.5,width=10;".. -- first value
17 | "text,align=right,padding=1.5;".. -- operator
18 | "text,align=right,padding=1.5,width=10]".. -- last value
19 | "table[3.9,0.8;7,2;tab;"
20 |
21 | for idx,entry in ipairs(data.tab) do
22 | if idx > 1 then
23 | formspec = formspec..','
24 | end
25 | formspec = formspec..(entry.var1 or "")..","..(entry.operator or "")..","..(entry.var2 or "")
26 | end
27 |
28 | formspec = formspec .. ";"..#data.tab.."]"..
29 | mtos.theme:get_button('4,3;1,1', "minor", 'number', '1') ..
30 | mtos.theme:get_button('5,3;1,1', "minor", 'number', '2') ..
31 | mtos.theme:get_button('6,3;1,1', "minor", 'number', '3') ..
32 | mtos.theme:get_button('4,4;1,1', "minor", 'number', '4') ..
33 | mtos.theme:get_button('5,4;1,1', "minor", 'number', '5') ..
34 | mtos.theme:get_button('6,4;1,1', "minor", 'number', '6') ..
35 | mtos.theme:get_button('4,5;1,1', "minor", 'number', '7') ..
36 | mtos.theme:get_button('5,5;1,1', "minor", 'number', '8') ..
37 | mtos.theme:get_button('6,5;1,1', "minor", 'number', '9') ..
38 | mtos.theme:get_button('4,6;1,1', "minor", 'number', '0') ..
39 | mtos.theme:get_button('5,6;1,1', "minor", 'number', '.') ..
40 | mtos.theme:get_button('6,6;1,1', "minor", 'minus', '+/-') ..
41 |
42 | mtos.theme:get_button('4,7;1,1',"minor", 'constant_pi', "PI")..
43 | mtos.theme:get_button('5,7;1,1', "minor", 'constant_e', "e")..
44 | mtos.theme:get_button('6,7;1,1', "minor", 'rnd', "RND")..
45 |
46 | mtos.theme:get_button('8,3;1,1', "minor", 'operator', '+') ..
47 | mtos.theme:get_button('8,4;1,1', "minor", 'operator', '-') ..
48 | mtos.theme:get_button('8,5;1,1', "minor", 'operator', '/') ..
49 | mtos.theme:get_button('8,6;1,1', "minor", 'operator', '*') ..
50 | mtos.theme:get_button('8,7;1,1', "minor", 'operator', '^') ..
51 | mtos.theme:get_button('9,6;2,1', "minor", 'operator', '=') ..
52 |
53 | mtos.theme:get_button('9,3;2,1', "minor", 'del_char', 'DEL-1') ..
54 | mtos.theme:get_button('9,4;2,1', "minor", 'del_line', 'DEL-L') ..
55 | mtos.theme:get_button('9,5;2,1', "minor", 'del_all', 'DEL-A')
56 | return formspec
57 | end,
58 |
59 | receive_fields_func = function(app, mtos, sender, fields)
60 | local data = mtos.bdev:get_app_storage('ram', 'calculator')
61 | local entry = data.tab[#data.tab]
62 |
63 | if fields.number then
64 | -- simple number entry. With check for valid value
65 | local new_val = (entry.var2 or "")..minetest.strip_colors(fields.number)
66 | if tonumber(new_val) then
67 | entry.var2 = new_val
68 | end
69 | elseif fields.minus then
70 | if entry.var2 then
71 | entry.var2 = tostring(-tonumber(entry.var2))
72 | else
73 | entry.var2 = '-0'
74 | end
75 | elseif fields.constant_pi then
76 | entry.var2 = tostring(math.pi)
77 | elseif fields.constant_e then
78 | entry.var2 = tostring(math.exp(1))
79 | elseif fields.rnd then
80 | entry.var2 = tostring(math.random())
81 | elseif fields.del_char then
82 | -- delete char
83 | if entry.var2 then
84 | -- remove char from current number
85 | entry.var2 = entry.var2:sub(1, -2)
86 | if not tonumber(entry.var2) then
87 | entry.var2 = nil
88 | end
89 | else
90 | -- get previous number
91 | if #data.tab > 1 then
92 | -- go back to previous line if exists
93 | table.remove(data.tab, #data.tab)
94 | else
95 | -- get from left site if first entry
96 | entry.var2 = entry.var1
97 | entry.operator = nil
98 | entry.var1 = nil
99 | end
100 | end
101 | elseif fields.del_line then
102 | -- just delete full number if exists
103 | if entry.var2 then
104 | entry.var2 = nil
105 | else
106 | -- go back to previous line and delete the full number if exists
107 | table.remove(data.tab, #data.tab)
108 | if #data.tab > 0 then
109 | entry = data.tab[#data.tab]
110 | entry.var2 = nil
111 | end
112 | end
113 | elseif fields.del_all then
114 | data.tab = nil
115 | elseif fields.operator then
116 | fields.operator = minetest.strip_colors(fields.operator)
117 | -- no previous operator
118 | if not entry.operator then
119 | if fields.operator == '=' and (entry.var1 or entry.var2) then
120 | table.insert(data.tab, {}) -- add empty line
121 | elseif entry.var2 then
122 | -- move to the left
123 | entry.var1 = entry.var2
124 | entry.operator = fields.operator
125 | entry.var2 = nil
126 | end
127 | -- process previous operator
128 | else
129 | local result
130 | if entry.var2 then
131 | -- both values available
132 | if entry.operator == '+' then
133 | result = tonumber(entry.var1) + tonumber(entry.var2)
134 | elseif entry.operator == '-' then
135 | result = tonumber(entry.var1) - tonumber(entry.var2)
136 | elseif entry.operator == '/' then
137 | result = tonumber(entry.var1) / tonumber(entry.var2)
138 | elseif entry.operator == '*' then
139 | result = tonumber(entry.var1) * tonumber(entry.var2)
140 | elseif entry.operator == '^' then
141 | result = tonumber(entry.var1) ^ tonumber(entry.var2)
142 | elseif entry.operator == '=' then
143 | result = tonumber(entry.var2)
144 | end
145 | else
146 | if entry.operator == '-' then
147 | result = - tonumber(entry.var1)
148 | end
149 | end
150 | if result then
151 | if fields.operator == '=' then
152 | table.insert(data.tab, {var2 = tostring(result)})
153 | else
154 | table.insert(data.tab, {var1 = tostring(result), operator = fields.operator})
155 | end
156 | end
157 | end
158 | end
159 | end
160 | })
161 |
--------------------------------------------------------------------------------
/block_devices.lua:
--------------------------------------------------------------------------------
1 | local mod_storage = minetest.get_mod_storage()
2 |
3 | local bdev = {}
4 |
5 | -- Check hardware capabilities { "hdd", "floppy", "usb", "net", "liveboot" }
6 | function bdev:is_hw_capability(hw_cap)
7 | for i, cap in ipairs(self.os.hwdef.hw_capabilities) do
8 | if cap == hw_cap or cap == hw_cap:sub(18, -1) then --"laptop_removable_*"then
9 | return cap
10 | end
11 | end
12 | return false
13 | end
14 |
15 | -- Get RAM
16 | function bdev:get_ram_disk()
17 | if not self.ram_disk then
18 | self.ram_disk = minetest.deserialize(self.os.meta:get_string('laptop_ram')) or {}
19 | end
20 | return self.ram_disk
21 | end
22 |
23 | function bdev:free_ram_disk()
24 | self.ram_disk = {}
25 | self:sync()
26 | end
27 |
28 |
29 | -- Get HDD if exists
30 | function bdev:get_hard_disk()
31 | if self.hard_disk == nil then
32 | if self:is_hw_capability('hdd') then
33 | self.hard_disk = minetest.deserialize(self.os.meta:get_string('laptop_appdata')) or {}
34 | else
35 | self.hard_disk = false
36 | end
37 | end
38 | return self.hard_disk
39 | end
40 |
41 | -- Get Removable disk if exists
42 | function bdev:get_removable_disk(removable_type)
43 | if self.removable_disk == nil then
44 | local data = { bdev = self }
45 | data.inv = self.os.meta:get_inventory()
46 | data.inv:set_size("main", 1) -- 1 disk supported
47 | function data:reload(stack)
48 | -- self.inv unchanged
49 | -- self.rtype unchanged (assumption
50 | stack = stack or self.inv:get_stack("main", 1)
51 | if stack then
52 | local def = stack:get_definition()
53 | if def and def.name ~= "" then
54 | self.stack = stack
55 | self.def = def
56 | self.meta = stack:get_meta()
57 | self.os_format = self.meta:get_string("os_format")
58 | if self.os_format == "" then
59 | self.os_format = "none"
60 | end
61 | self.label = self.meta:get_string("description")
62 | if self.label == "" then
63 | self.label = self.def.description
64 | end
65 | for group, _ in pairs(self.def.groups) do
66 | local rtype_chk = self.bdev:is_hw_capability(group)
67 | if not removable_type or removable_type == rtype_chk then
68 | self.rtype = rtype_chk
69 | break
70 | end
71 | end
72 | self.storage = minetest.deserialize(self.meta:get_string("os_storage")) or {}
73 | end
74 | end
75 | end
76 | function data:eject()
77 | if not self.stack then
78 | return false
79 | end
80 | local p = self.bdev.os.pos
81 | local drop_pos = { x=p.x+math.random()*2-1, y=p.y,z=p.z+math.random()*2-1 }
82 | minetest.item_drop(self.stack, nil, drop_pos)
83 | self.stack = nil
84 | return true
85 | end
86 | function data:format_disk(ftype, label)
87 | self.stack = ItemStack(self.def.name)
88 | self.meta = self.stack:get_meta()
89 | self.meta:set_string("os_format", ftype or "")
90 | self.os_format = ftype
91 | self.label = label or ""
92 | end
93 |
94 | data:reload()
95 | self.removable_disk = data
96 | end
97 | return self.removable_disk
98 | end
99 |
100 | -- Connect to cloud
101 | function bdev:get_cloud_disk(store_name)
102 | if self.cloud_disk == nil or (self.cloud_disk ~= false and not self.cloud_disk[store_name]) then
103 | if self:is_hw_capability('net') then
104 | self.cloud_disk = self.cloud_disk or {}
105 | self.cloud_disk[store_name] = minetest.deserialize(mod_storage:get_string(store_name)) or {}
106 | else
107 | self.cloud_disk = false
108 | return false
109 | end
110 | end
111 | return self.cloud_disk[store_name]
112 | end
113 |
114 | -- Get device to boot
115 | function bdev:get_boot_disk()
116 | if self:is_hw_capability('liveboot') then
117 | local drive = self:get_removable_disk()
118 | if drive.stack and drive.os_format == 'boot' then
119 | return 'removable'
120 | end
121 | end
122 | return 'hdd'
123 | end
124 |
125 | -- Get app related object from storage "disk_type"
126 | function bdev:get_app_storage(disk_type, store_name)
127 | if disk_type == 'ram' then
128 | local store = self:get_ram_disk()
129 | store[store_name] = store[store_name] or {}
130 | return store[store_name]
131 | elseif disk_type == 'hdd' then
132 | local store = self:get_hard_disk()
133 | if store then
134 | store[store_name] = store[store_name] or {}
135 | return store[store_name]
136 | else
137 | return nil
138 | end
139 | elseif disk_type == 'removable' then
140 | local store = self:get_removable_disk()
141 | if store.stack and (store.os_format == 'data' or store.os_format == 'boot') then
142 | store.storage[store_name] = store.storage[store_name] or {}
143 | return store.storage[store_name]
144 | else
145 | return nil
146 | end
147 | elseif disk_type == 'system' then
148 | local runtime = self:get_app_storage("ram", "os")
149 | runtime.booted_from = runtime.booted_from or self:get_boot_disk()
150 | return self:get_app_storage(runtime.booted_from, store_name)
151 | elseif disk_type == 'cloud' then
152 | return self:get_cloud_disk(store_name) or nil
153 | end
154 | end
155 |
156 |
157 | -- Save all data if used
158 | function bdev:sync()
159 | -- save RAM
160 | self.os.meta:set_string('laptop_ram', minetest.serialize(self.ram_disk))
161 | self.os.meta:mark_as_private('laptop_ram')
162 |
163 | -- save HDD
164 | if self.hard_disk then
165 | self.os.meta:set_string('laptop_appdata', minetest.serialize(self.hard_disk))
166 | self.os.meta:mark_as_private('laptop_appdata')
167 | end
168 |
169 | -- save removable
170 | if self.removable_disk then
171 | if self.removable_disk.stack then
172 | if self.removable_disk.def and self.removable_disk.label ~= self.removable_disk.def.description then
173 | self.removable_disk.meta:set_string("description", self.removable_disk.label)
174 | end
175 | if self.removable_disk.storage and next(self.removable_disk.storage) then
176 | self.removable_disk.meta:set_string("os_storage", minetest.serialize(self.removable_disk.storage))
177 | end
178 | end
179 | self.removable_disk.inv:set_stack("main", 1, self.removable_disk.stack)
180 | end
181 | end
182 |
183 | -- Save all data if used
184 | function bdev:sync_cloud()
185 | -- Modmeta (Cloud)
186 | if self.cloud_disk then
187 | for store, value in pairs(self.cloud_disk) do
188 | mod_storage:set_string(store, minetest.serialize(value))
189 | end
190 | end
191 | end
192 |
193 | -- Get handler
194 | function laptop.get_bdev_handler(mtos)
195 | local bdevobj = {}
196 | for k,v in pairs(bdev) do
197 | bdevobj[k] = v
198 | end
199 | bdevobj.os = mtos
200 | return bdevobj
201 | end
202 |
203 |
204 |
205 |
--------------------------------------------------------------------------------
/apps/TNTsweeper_app.lua:
--------------------------------------------------------------------------------
1 | local level_config = {
2 | ['Small'] = { w = 9, h = 9, bomb = 10, icon_size = 0.9 },
3 | ['Small hard'] = { w = 9, h = 9, bomb = 35, icon_size = 0.9},
4 | ['Midsize'] = { w = 16, h = 16, bomb = 40, icon_size = 0.7 },
5 | ['Midsize hard'] = { w = 16, h = 16, bomb = 99, icon_size = 0.7},
6 | ['Big'] = { w = 24, h = 20, bomb = 99, icon_size = 0.58 },
7 | ['Big hard'] = { w = 24, h = 20, bomb = 170, icon_size = 0.58},
8 | }
9 |
10 |
11 | local sweeper_class = {}
12 | sweeper_class.__index = sweeper_class
13 |
14 | function sweeper_class:init(level)
15 | self.data.level = level
16 | if not level_config[level] then print('ERROR: WRONG LEVEL', level) end
17 | local config = level_config[level]
18 | -- build board
19 | self.data.board = {}
20 | self.data.open_all = config.w * config.h - config.bomb
21 | self.data.open_count = 0
22 | self.data.bomb_all = config.bomb
23 | self.data.bomb_count = 0
24 |
25 | local board = self.data.board
26 | for w = 1, config.w do
27 | board[w] = {}
28 | for h = 1, config.h do
29 | board[w][h] = { count = 0, is_bomb = false, is_revealed = false }
30 | end
31 | end
32 |
33 | -- fill board with bombs
34 | local placed = 0
35 | while placed < config.bomb do
36 | local rnd_w = math.random(config.w)
37 | local rnd_h = math.random(config.h)
38 | local rndfield = board[rnd_w][rnd_h]
39 | if not rndfield.is_bomb then
40 | rndfield.is_bomb = true
41 | placed = placed + 1
42 | for w = rnd_w - 1, rnd_w + 1 do
43 | for h = rnd_h - 1, rnd_h + 1 do
44 | if board[w] and board[w][h] then
45 | board[w][h].count = board[w][h].count + 1
46 | end
47 | end
48 | end
49 | end
50 | end
51 | end
52 |
53 | function sweeper_class:get(sel_w, sel_h)
54 | local board = self.data.board
55 | if board[sel_w] then
56 | return board[sel_w][sel_h]
57 | end
58 | end
59 |
60 | function sweeper_class:reveal(sel_w, sel_h)
61 | local board = self.data.board
62 | local sel = self:get(sel_w, sel_h)
63 |
64 | -- unmark bomb
65 | if sel.bomb_marked then
66 | self:toggle_bomb_mark(sel_w, sel_h)
67 | end
68 |
69 | sel.is_revealed = true
70 | if sel.is_bomb then
71 | -- Bomb found
72 | self.data.bomb_count = self.data.bomb_count + 1
73 | else
74 | -- No bomb, count empty fields
75 | self.data.open_count = self.data.open_count + 1
76 | if sel.count == 0 then
77 | for w = sel_w - 1, sel_w + 1 do
78 | for h = sel_h - 1, sel_h + 1 do
79 | local chk_sel = self:get(w,h)
80 | if chk_sel and
81 | not chk_sel.is_revealed and
82 | not chk_sel.bomb_marked then
83 | self:reveal(w,h)
84 | end
85 | end
86 | end
87 | end
88 | end
89 | end
90 |
91 | function sweeper_class:toggle_bomb_mark(sel_w, sel_h)
92 | local sel = self:get(sel_w, sel_h)
93 | if sel.bomb_marked then
94 | self.data.bomb_count = self.data.bomb_count - 1
95 | sel.bomb_marked = nil
96 | else
97 | self.data.bomb_count = self.data.bomb_count + 1
98 | sel.bomb_marked = true
99 | end
100 | end
101 |
102 | local function get_sweeper(data)
103 | local self = setmetatable({}, sweeper_class)
104 | self.data = data
105 | return self
106 | end
107 |
108 |
109 | laptop.register_app("tntsweeper", {
110 | app_name = "TNT Sweeper",
111 | app_icon = "laptop_tnt.png",
112 | app_info = "Avoid hitting TNT",
113 | formspec_func = function(app, mtos)
114 | local data = mtos.bdev:get_app_storage('ram', 'tntsweeper')
115 | local sweeper = get_sweeper(data)
116 |
117 | if not sweeper.data.level then
118 | sweeper:init('Midsize')
119 | end
120 | local config = level_config[sweeper.data.level]
121 | local formspec = ""
122 |
123 | for w = 1, config.w do
124 | for h = 1, config.h do
125 | local pos = (w*config.icon_size*0.8)..','..(h*config.icon_size*0.85)
126 | local field = sweeper.data.board[w][h]
127 | if not field.is_revealed then
128 | if field.bomb_marked then
129 | formspec = formspec .. "image_button["..pos..";"..config.icon_size..","..config.icon_size..";"..mtos.theme.minor_button.."^"..mtos.theme:get_texture("laptop_tnt.png")..";field:"..w..":"..h..";]"
130 | else
131 | formspec = formspec .. "image_button["..pos..";"..config.icon_size..","..config.icon_size..";"..mtos.theme.minor_button..";field:"..w..":"..h..";]"
132 | end
133 | elseif field.is_bomb then
134 | formspec = formspec .. "image["..pos..";"..config.icon_size..","..config.icon_size..";"..mtos.theme:get_texture("laptop_boom.png").."]"
135 | elseif field.count > 0 then
136 | local lbpos = ((w+0.4)*config.icon_size*0.8)..','..((h+0.1)*config.icon_size*0.85)
137 | formspec = formspec .. mtos.theme:get_label(lbpos, field.count)
138 | end
139 | end
140 | end
141 |
142 | formspec = formspec .. "background[12,0.5;3,1;"..mtos.theme.contrast_background..']'..
143 | mtos.theme:get_label("12,0.5", "Open fields: "..sweeper.data.open_count.."/"..sweeper.data.open_all, "contrast")..
144 | mtos.theme:get_label("12,1", "Bomb: "..sweeper.data.bomb_count.."/"..sweeper.data.bomb_all, "contrast")..
145 | mtos.theme:get_button('12.5,2;1.5,0.8', 'major', 'reset', 'Small')..
146 | mtos.theme:get_button('12.5,3;1.5,0.8', 'major', 'reset', 'Small hard')..
147 | mtos.theme:get_button('12.5,4;1.5,0.8', 'major', 'reset', 'Midsize')..
148 | mtos.theme:get_button('12.5,5;1.5,0.8', 'major', 'reset', 'Midsize hard')..
149 | mtos.theme:get_button('12.5,6;1.5,0.8', 'major', 'reset', 'Big')..
150 | mtos.theme:get_button('12.5,7;1.5,0.8', 'major', 'reset', 'Big hard')
151 | if data.mark_mode then
152 | formspec = formspec .. mtos.theme:get_button('12.5,9;1.5,0.8', 'minor', 'mark_mode', 'mark', 'change to reveal mode')
153 | else
154 | formspec = formspec .. mtos.theme:get_button('12.5,9;1.5,0.8', 'minor', 'mark_mode', 'reveal', 'change to mark mode')
155 | end
156 | return formspec
157 | end,
158 |
159 | receive_fields_func = function(app, mtos, sender, fields)
160 | local data = mtos.bdev:get_app_storage('ram', 'tntsweeper')
161 | local sweeper = get_sweeper(data)
162 | local config = level_config[sweeper.data.level]
163 | for field, _ in pairs(fields) do
164 | if field:sub(1,6) == 'field:' then
165 | local sel_w, sel_h
166 | for str in field:gmatch("([^:]+)") do
167 | if str ~= 'field' then
168 | if not sel_w then
169 | sel_w = tonumber(str)
170 | else
171 | sel_h = tonumber(str)
172 | end
173 | end
174 | end
175 |
176 | --if sender:get_player_control().sneak then -- TODO: test if https://github.com/minetest/minetest/issues/6353
177 | if data.mark_mode then
178 | sweeper:toggle_bomb_mark(sel_w, sel_h)
179 | else
180 | sweeper:reveal(sel_w, sel_h)
181 | end
182 | end
183 | end
184 |
185 | if fields.reset then
186 | sweeper:init(minetest.strip_colors(fields.reset))
187 | elseif fields.mark_mode then
188 | if data.mark_mode then
189 | data.mark_mode = nil
190 | else
191 | data.mark_mode = true
192 | end
193 | end
194 | end
195 | })
196 |
--------------------------------------------------------------------------------
/apps/painting_app.lua:
--------------------------------------------------------------------------------
1 | local store_area = 'painting:files'
2 |
3 | local have_painting = minetest.get_modpath("painting")
4 |
5 | local hexcolors = {
6 | black = "000000",
7 | maroon = "800000",
8 | green = "008000",
9 | olive = "808000",
10 | navy = "000080",
11 | purple = "800080",
12 | teal = "008080",
13 | silver = "C0C0C0",
14 |
15 | gray = "808080",
16 | red = "FF0000",
17 | lime = "00FF00",
18 | yellow = "FFFF00",
19 | blue = "0000FF",
20 | fuchsia = "FF00FF",
21 | aqua = "00FFFF",
22 | white = "FFFFFF",
23 | }
24 | local colors = {
25 | "black", "maroon", "green", "olive", "navy", "purple", "teal", "silver",
26 | "gray", "red", "lime", "yellow", "blue", "fuchsia", "aqua", "white",
27 | }
28 |
29 | local butcolors = {}
30 | for color, hex in pairs(hexcolors) do
31 | butcolors["color_"..color] = hex
32 | end
33 |
34 | laptop.register_app("painting", {
35 | app_name = "Painting",
36 | app_icon = "laptop_painting.png",
37 | app_info = "Show/Edit Pictures",
38 | formspec_func = function(app, mtos)
39 | local data = mtos.bdev:get_app_storage('system', 'painting')
40 | data.files = data.files or {}
41 | if not data.brush_color then
42 | data.brush_color = "000000"
43 | end
44 | if not data.resolution then
45 | data.resolution = 16
46 | end
47 | if not data.grid then
48 | data.grid = {}
49 | for y = 1,data.resolution do
50 | data.grid[y] = {}
51 | for x = 1,data.resolution do
52 | data.grid[y][x] = "FFFFFFFF"
53 | end
54 | end
55 | end
56 |
57 | if data.selected_disk_name and data.selected_file_name then
58 | app.app_info = app.app_info..' - Open File: '..data.selected_disk_name..' / '..data.selected_file_name
59 | end
60 |
61 | -- cache sorted files list
62 | if not data.fileslist_sorted then
63 | data.fileslist_sorted = {}
64 | for filename,_ in pairs(data.files) do
65 | table.insert(data.fileslist_sorted, filename)
66 | end
67 | table.sort(data.fileslist_sorted)
68 | end
69 |
70 | local formspec = "background[0,3.35;7.2,6.35;"..mtos.theme.contrast_background.."]"..
71 | mtos.theme:get_button('0,0.5;1.5,0.8', 'minor', 'new_16', 'New 16', 'New picture with resolution 16x16')..
72 | mtos.theme:get_button('2,0.5;1.5,0.8', 'minor', 'new_32', 'New 32', 'New picture with resolution 32x32')..
73 | mtos.theme:get_button('4,0.5;1.5,0.8', 'minor', 'load', 'Load', 'Load picture')..
74 | mtos.theme:get_button('6,0.5;1.5,0.8', 'minor', 'save', 'Save', 'Save picture')
75 | --if have_painting then
76 | if false then
77 | formspec = formspec .. mtos.theme:get_button('12,0.5;1.5,0.8', 'minor', 'print', 'Print', 'Print file')
78 | end
79 | formspec = formspec .. "field[0.3,1.8;1.5,0.8;hex_color;;000000]"
80 | formspec = formspec .. mtos.theme:get_button('1.5,1.5;1.5,0.8', 'minor', 'set_hex', 'Set', 'Set hex color')
81 | formspec = formspec .. mtos.theme:get_image_button('0,2.5;0.8,0.8', 'minor', 'brush_color', 'w.png^[colorize:#'..data.brush_color, '', 'Brush color')
82 | for index,color in pairs(colors) do
83 | local xoff = 3.5 + 0.8 * ((index-1)%8)
84 | local yoff = 1.5
85 | if index>8 then
86 | yoff = 2.5
87 | end
88 | formspec = formspec .. mtos.theme:get_image_button(xoff..','..yoff..';0.8,0.8', 'minor', 'color_'..color, 'w.png^[colorize:#'..hexcolors[color], '', 'Color '..color)
89 | end
90 | local resolution = data.resolution
91 | local xsize = 0.1979+6.3333/resolution
92 | local ysize = 0.1771+5.6667/resolution
93 | local xyoff = 6/resolution
94 | for y = 1,resolution do
95 | for x = 1,resolution do
96 | local xoff = 0.012369*resolution + x*xyoff
97 | local yoff = 2.9+0.011069*resolution + y*xyoff
98 | local hex = data.grid[y] or {}
99 | hex = hex[x] or "FFFFFF"
100 | formspec = formspec .. mtos.theme:get_image_button(xoff..','..yoff..';'..xsize..','..ysize, 'minor', 'pixel_'..y..'_'..x, 'w.png^[colorize:#'..hex, '', 'Pixel '..x..'x'..y)
101 | end
102 | end
103 | return formspec
104 | end,
105 | receive_fields_func = function(app, mtos, sender, fields)
106 | local data = mtos.bdev:get_app_storage('system', 'painting')
107 | if fields.text then
108 | data.text = fields.text
109 | end
110 |
111 | if fields.load then
112 | mtos:select_file_dialog({
113 | mode = 'open',
114 | allowed_disks = {'hdd', 'removable'},
115 | selected_disk_name = data.selected_disk_name,
116 | selected_file_name = data.selected_file_name,
117 | store_name = store_area,
118 | prefix = 'open_',
119 | })
120 | elseif fields.open_selected_disk and fields.open_selected_file then
121 | data.selected_disk_name = fields.open_selected_disk
122 | data.selected_file_name = fields.open_selected_file
123 | local store = mtos.bdev:get_app_storage(data.selected_disk_name, store_area)
124 | if store then
125 | data.grid = store[data.selected_file_name].content
126 | data.resolution = #data.grid
127 | end
128 | elseif fields.save then
129 | mtos:select_file_dialog({
130 | mode = 'save',
131 | allowed_disks = {'hdd', 'removable'},
132 | selected_disk_name = data.selected_disk_name,
133 | selected_file_name = data.selected_file_name,
134 | store_name = store_area,
135 | prefix = 'save_',
136 | })
137 | elseif fields.save_selected_disk and fields.save_selected_file then
138 | data.selected_disk_name = fields.save_selected_disk
139 | data.selected_file_name = fields.save_selected_file
140 | local store = mtos.bdev:get_app_storage(data.selected_disk_name, store_area)
141 | if store then
142 | store[data.selected_file_name] = { content = data.grid, ctime = os.time(), owner = sender:get_player_name() }
143 | end
144 | elseif fields.new_16 then
145 | data.selected_disk_name = nil
146 | data.selected_file_name = nil
147 | data.resolution = 16
148 | data.grid = nil
149 | elseif fields.new_32 then
150 | data.selected_disk_name = nil
151 | data.selected_file_name = nil
152 | data.resolution = 32
153 | data.grid = nil
154 | elseif fields.print then
155 | mtos:print_picture_dialog({
156 | label = data.selected_file_name,
157 | text = data.text,
158 | })
159 | elseif fields.set_hex then
160 | local color = {
161 | r = tonumber("00"..fields.hex_color:sub(1,2),16),
162 | g = tonumber("00"..fields.hex_color:sub(3,4),16),
163 | b = tonumber("00"..fields.hex_color:sub(5,6),16),
164 | a = fields.hex_color:sub(7,8),
165 | }
166 | if color.a=="" then
167 | color.a = 255
168 | else
169 | color.a = tonumber(color.a, 16)
170 | end
171 | if color.a==255 then
172 | data.brush_color = string.format("%02x%02x%02x", color.r, color.g, color.b)
173 | else
174 | data.brush_color = string.format("%02x%02x%02x%02x", color.r, color.g, color.b, color.a)
175 | end
176 | else
177 | -- check for pixel click
178 | for y = 1,data.resolution do
179 | for x = 1,data.resolution do
180 | local key = "pixel_"..y.."_"..x
181 | if fields[key] then
182 | local line = data.grid[y] or {}
183 | line[x] = data.brush_color..""
184 | return
185 | end
186 | end
187 | end
188 | -- check for color select click
189 | for index,color in pairs(colors) do
190 | local key = "color_"..color
191 | if fields[key] then
192 | data.brush_color = hexcolors[color]
193 | return
194 | end
195 | end
196 | end
197 | end
198 | })
199 |
--------------------------------------------------------------------------------
/craftitems.lua:
--------------------------------------------------------------------------------
1 | local rc = laptop.recipe_compat -- Recipe items from other mods
2 |
3 | ----------------------------
4 | ---------PROCESSORS---------
5 | ----------------------------
6 |
7 | minetest.register_craftitem("laptop:cpu_c6", {
8 | description = 'Ziram c6 Processor',
9 | inventory_image = "laptop_cpu_c6.png",
10 | })
11 |
12 | minetest.register_craft({
13 | output = 'laptop:cpu_c6',
14 | recipe = {
15 | {'', '', ''},
16 | {rc.silicon, rc.gates_diode, rc.tin},
17 | {rc.gates_and, rc.gates_or, rc.gates_nand},
18 | }
19 | })
20 |
21 | minetest.register_craftitem("laptop:cpu_d75a", {
22 | description = 'Interlink D75A Processor',
23 | inventory_image = "laptop_cpu_d75a.png",
24 | })
25 |
26 | minetest.register_craft({
27 | output = 'laptop:cpu_d75a',
28 | recipe = {
29 | {rc.silicon, rc.silicon, rc.silicon},
30 | {rc.gates_xor, rc.copper, rc.gates_nand},
31 | {rc.fpga, rc.programmer, rc.fpga},
32 | }
33 | })
34 |
35 | minetest.register_craftitem("laptop:cpu_jetcore", {
36 | description = 'Interlink jetCore Processor',
37 | inventory_image = "laptop_cpu_jetcore.png",
38 | })
39 |
40 | minetest.register_craft({
41 | output = 'laptop:cpu_jetcore',
42 | recipe = {
43 | {rc.silicon, rc.silicon, rc.silicon},
44 | {rc.fiber, rc.gold, rc.delayer},
45 | {rc.fpga, rc.controller, rc.programmer},
46 | }
47 | })
48 |
49 | minetest.register_craftitem("laptop:cpu_65536", {
50 | description = 'Transpose 65536 Processor',
51 | inventory_image = "laptop_cpu_65536.png",
52 | })
53 |
54 | minetest.register_craft({
55 | output = 'laptop:cpu_65536',
56 | recipe = {
57 | {'', '', ''},
58 | {rc.silicon, rc.copper, rc.silicon},
59 | {rc.gates_not, rc.fpga, rc.delayer},
60 | }
61 | })
62 |
63 | minetest.register_craftitem("laptop:bat", {
64 | description = 'Battery',
65 | inventory_image = "laptop_bat.png",
66 | })
67 |
68 | minetest.register_craft({
69 | output = 'laptop:bat',
70 | recipe = {
71 | {rc.steel, rc.battery, rc.steel},
72 | {rc.battery, rc.gates_diode, rc.battery},
73 | {rc.steel, rc.battery, rc.steel},
74 | }
75 | })
76 |
77 | minetest.register_craftitem("laptop:case", {
78 | description = 'Case',
79 | inventory_image = "laptop_case.png",
80 | })
81 |
82 | minetest.register_craft({
83 | output = 'laptop:case',
84 | recipe = {
85 | {rc.steel, rc.steel, rc.steel},
86 | {rc.steel, '', rc.steel},
87 | {rc.steel, rc.steel, rc.steel},
88 | }
89 | })
90 |
91 | minetest.register_craftitem("laptop:crt", {
92 | description = 'CRT Screen',
93 | inventory_image = "laptop_crt.png",
94 | })
95 |
96 | minetest.register_craft({
97 | output = 'laptop:crt',
98 | recipe = {
99 | {rc.glass, rc.glass, rc.glass},
100 | {rc.light_red , rc.light_green, rc.light_blue},
101 | {rc.steel, rc.controller, rc.steel},
102 | }
103 | })
104 |
105 | minetest.register_craftitem("laptop:crt_amber", {
106 | description = 'Amber CRT Screen',
107 | inventory_image = "laptop_crt_amber.png",
108 | })
109 |
110 | minetest.register_craft({
111 | output = 'laptop:crt_amber',
112 | recipe = {
113 | {rc.glass, 'dye:orange', rc.glass},
114 | {rc.light_red , rc.light_green, rc.light_blue},
115 | {rc.steel, rc.controller, rc.steel},
116 | }
117 | })
118 |
119 | minetest.register_craftitem("laptop:crt_green", {
120 | description = 'Green CRT Screen',
121 | inventory_image = "laptop_crt_green.png",
122 | })
123 |
124 | minetest.register_craft({
125 | output = 'laptop:crt_green',
126 | recipe = {
127 | {rc.glass, 'dye:green', rc.glass},
128 | {rc.light_red , rc.light_green, rc.light_blue},
129 | {rc.steel, rc.controller, rc.steel},
130 | }
131 | })
132 |
133 | minetest.register_craftitem("laptop:lcd", {
134 | description = 'LCD Screen',
135 | inventory_image = "laptop_lcd.png",
136 | })
137 |
138 | minetest.register_craft({
139 | output = 'laptop:lcd',
140 | recipe = {
141 | {rc.light_red , rc.light_green, rc.light_blue},
142 | {'dye:black', rc.controller, 'dye:black'},
143 | {rc.steel, rc.diamond, rc.steel},
144 | }
145 | })
146 |
147 | minetest.register_craftitem("laptop:gpu", {
148 | description = 'GPU',
149 | inventory_image = "laptop_gpu.png",
150 | })
151 |
152 | minetest.register_craft({
153 | output = 'laptop:gpu',
154 | recipe = {
155 | {rc.steel, rc.silicon, rc.steel},
156 | {'laptop:fan', rc.fpga, 'laptop:fan'},
157 | {rc.steel, rc.silicon, rc.steel},
158 | }
159 | })
160 |
161 | minetest.register_craftitem("laptop:HDD", {
162 | description = 'Hard Drive',
163 | inventory_image = "laptop_harddrive.png",
164 | })
165 |
166 | minetest.register_craft({
167 | output = 'laptop:HDD',
168 | recipe = {
169 | {rc.steel, rc.steel, rc.steel},
170 | {rc.steel, rc.controller, rc.steel},
171 | {rc.steel, rc.steel, rc.steel},
172 | }
173 | })
174 |
175 | minetest.register_craftitem("laptop:motherboard", {
176 | description = 'Motherboard',
177 | inventory_image = "laptop_motherboard.png",
178 | })
179 |
180 | minetest.register_craft({
181 | output = 'laptop:motherboard',
182 | recipe = {
183 | {rc.controller, rc.fpga, rc.gates_nand},
184 | {'dye:dark_green', 'dye:dark_green', 'dye:dark_green'},
185 | {rc.steel, rc.copper, rc.steel},
186 | }
187 | })
188 |
189 | minetest.register_craftitem("laptop:fan", {
190 | description = 'Fan',
191 | inventory_image = "laptop_fan.png",
192 | })
193 |
194 | minetest.register_craft({
195 | output = 'laptop:fan',
196 | recipe = {
197 | {'', rc.plastic, ''},
198 | {rc.plastic, rc.motor, rc.plastic},
199 | {'', rc.plastic, ''},
200 | }
201 | })
202 |
203 | minetest.register_craftitem("laptop:psu", {
204 | description = 'PSU',
205 | inventory_image = "laptop_psu.png",
206 | })
207 |
208 | minetest.register_craft({
209 | output = 'laptop:psu',
210 | recipe = {
211 | {rc.steel, rc.lv_transformer, rc.steel},
212 | {rc.controller, rc.fpga, 'laptop:fan'},
213 | {rc.steel, rc.lv_transformer, rc.steel},
214 | }
215 | })
216 |
217 | minetest.register_craftitem("laptop:floppy", {
218 | description = 'High density floppy',
219 | inventory_image = "laptop_diskette.png",
220 | groups = {laptop_removable_floppy = 1},
221 | stack_max = 1,
222 | })
223 |
224 | minetest.register_craft({
225 | output = 'laptop:floppy',
226 | recipe = {
227 | {rc.plastic, rc.plastic, rc.plastic},
228 | {rc.plastic, rc.programmer, rc.plastic},
229 | {rc.plastic, rc.plastic, rc.plastic},
230 | }
231 | })
232 |
233 | minetest.register_craftitem("laptop:usbstick", {
234 | description = 'USB storage stick',
235 | inventory_image = "laptop_usb.png",
236 | groups = {laptop_removable_usb = 1},
237 | stack_max = 1,
238 | })
239 |
240 | minetest.register_craft({
241 | output = 'laptop:usbstick',
242 | recipe = {
243 | {'', rc.silicon, ''},
244 | {'', rc.programmer, ''},
245 | {'', rc.plastic, ''},
246 | }
247 | })
248 |
249 | minetest.register_craftitem("laptop:printed_paper", {
250 | description = 'Printed paper',
251 | inventory_image = "laptop_printed_paper.png",
252 | groups = {not_in_creative_inventory = 1},
253 | stack_max = 1,
254 | on_use = function(itemstack, user)
255 | local meta = itemstack:get_meta()
256 | local data = meta:to_table().fields
257 | local formspec = "size[8,8]" .. default.gui_bg .. default.gui_bg_img ..
258 | "label[0,0;" .. minetest.formspec_escape(data.title or "unnamed") ..
259 | " by " .. (data.author or "unknown") .. " from " .. os.date("%c", data.timestamp) .. "]"..
260 | "textarea[0.5,1;7.5,7;;" ..
261 | minetest.formspec_escape(data.text or "test text") .. ";]"
262 | minetest.show_formspec(user:get_player_name(), "laptop:printed_paper", formspec)
263 | return itemstack
264 | end
265 |
266 | })
267 |
--------------------------------------------------------------------------------
/apps/tetris_app.lua:
--------------------------------------------------------------------------------
1 | -- Based on https://github.com/minetest-mods/homedecor_modpack/blob/master/computer/tetris.lua
2 |
3 | local shapes = {
4 | { { x = {0, 1, 0, 1}, y = {0, 0, 1, 1} } },
5 |
6 | { { x = {1, 1, 1, 1}, y = {0, 1, 2, 3} },
7 | { x = {0, 1, 2, 3}, y = {1, 1, 1, 1} } },
8 |
9 | { { x = {0, 0, 1, 1}, y = {0, 1, 1, 2} },
10 | { x = {1, 2, 0, 1}, y = {0, 0, 1, 1} } },
11 |
12 | { { x = {1, 0, 1, 0}, y = {0, 1, 1, 2} },
13 | { x = {0, 1, 1, 2}, y = {0, 0, 1, 1} } },
14 |
15 | { { x = {1, 2, 1, 1}, y = {0, 0, 1, 2} },
16 | { x = {0, 1, 2, 2}, y = {1, 1, 1, 2} },
17 | { x = {1, 1, 0, 1}, y = {0, 1, 2, 2} },
18 | { x = {0, 0, 1, 2}, y = {0, 1, 1, 1} } },
19 |
20 | { { x = {1, 1, 1, 2}, y = {0, 1, 2, 2} },
21 | { x = {0, 1, 2, 0}, y = {1, 1, 1, 2} },
22 | { x = {0, 1, 1, 1}, y = {0, 0, 1, 2} },
23 | { x = {0, 1, 2, 2}, y = {1, 1, 1, 0} } },
24 |
25 | { { x = {1, 0, 1, 2}, y = {0, 1, 1, 1} },
26 | { x = {1, 1, 1, 2}, y = {0, 1, 2, 1} },
27 | { x = {0, 1, 2, 1}, y = {1, 1, 1, 2} },
28 | { x = {0, 1, 1, 1}, y = {1, 0, 1, 2} } } }
29 |
30 | local base_color_texture = "laptop_tetris_block.png"
31 | local base_color_alpha = '128'
32 | local colors = { base_color_texture.."^[colorize:#00FFFF:"..base_color_alpha, base_color_texture.."^[colorize:#FF00FF:"..base_color_alpha, base_color_texture.."^[colorize:#FF0000:"..base_color_alpha,
33 | base_color_texture.."^[colorize:#0000FF:"..base_color_alpha, base_color_texture.."^[colorize:#00FF00:"..base_color_alpha, base_color_texture.."^[colorize:#FF4500:"..base_color_alpha,
34 | base_color_texture.."^[colorize:#FFFF00:"..base_color_alpha }
35 |
36 | local boardx, boardy = 0, 0
37 | local sizex, sizey, size = 0.42, 0.44, 0.47
38 |
39 | local comma = ","
40 | local semi = ";"
41 | local close = "]"
42 |
43 | local concat = table.concat
44 | local insert = table.insert
45 |
46 | local tetris_class = {}
47 | tetris_class.__index = tetris_class
48 |
49 | local function get_tetris(app, data)
50 | local self = setmetatable({}, tetris_class)
51 | self.data = data
52 | self.app = app
53 | return self
54 | end
55 |
56 |
57 | function tetris_class:new_game()
58 | local nex = math.random(7)
59 | self.data.t = {
60 | board = {},
61 | boardstring = "",
62 | previewstring = self:draw_shape(nex, 0, 0, 1, 6.5, 0.8),
63 | score = 0,
64 | cur = math.random(7),
65 | nex = nex,
66 | x=4, y=0, rot=1
67 | }
68 | self.app:get_timer():start(0.3)
69 | end
70 |
71 |
72 | function tetris_class:update_boardstring()
73 | local scr = {}
74 | local ins = #scr
75 | local fixed_color
76 | if self.app.os.theme.monochrome_textcolor then
77 | fixed_color = base_color_texture.."^[colorize:"..
78 | self.app.os.theme.monochrome_textcolor..
79 | ":"..base_color_alpha
80 | end
81 | for i, line in pairs(self.data.t.board) do
82 | for _, tile in pairs(line) do
83 | local tmp = { "image[",
84 | tile[1]*sizex+boardx, comma,
85 | i*sizey+boardy, semi,
86 | size, comma, size, semi,
87 | fixed_color or colors[tile[2]], close }
88 |
89 | ins = ins + 1
90 | scr[ins] = concat(tmp)
91 | end
92 | end
93 | self.data.t.boardstring = concat(scr)
94 | end
95 |
96 |
97 | function tetris_class:add()
98 | local t = self.data.t
99 | local d = shapes[t.cur][t.rot]
100 | for i=1,4 do
101 | local l = d.y[i] + t.y
102 | if not t.board[l] then t.board[l] = {} end
103 | insert(t.board[l], {d.x[i] + t.x, t.cur})
104 | end
105 | end
106 |
107 | function tetris_class:scroll(l)
108 | for i=l, 1, -1 do
109 | self.data.t.board[i] = self.data.t.board[i-1] or {}
110 | end
111 | end
112 |
113 | function tetris_class:check_lines()
114 | for i, line in pairs(self.data.t.board) do
115 | if #line >= 10 then
116 | self:scroll(i)
117 | self.data.t.score = self.data.t.score + 20
118 | end
119 | end
120 | end
121 |
122 | function tetris_class:check_position(x, y, rot)
123 | local d = shapes[self.data.t.cur][rot]
124 | for i=1,4 do
125 | local cx, cy = d.x[i]+x, d.y[i]+y
126 | if cx < 0 or cx > 9 or cy < 0 or cy > 19 then
127 | return false
128 | end
129 | for _, tile in pairs(self.data.t.board[ cy ] or {}) do
130 | if tile[1] == cx then return false end
131 | end
132 | end
133 | return true
134 | end
135 |
136 | function tetris_class:stuck()
137 | local t = self.data.t
138 | if self:check_position(t.x, t.y+1, t.rot) then
139 | return false
140 | else
141 | return true
142 | end
143 | end
144 |
145 | function tetris_class:tick()
146 | local t = self.data.t
147 | if self:stuck() then
148 | if t.y <= 0 then
149 | return false
150 | end
151 | self:add()
152 | self:check_lines()
153 | self:update_boardstring()
154 | t.cur, t.nex = t.nex, math.random(7)
155 | t.x, t.y, t.rot = 4, 0, 1
156 | t.previewstring = self:draw_shape(t.nex, 0, 0, 1, 6.5, 0.8)
157 | else
158 | t.y = t.y + 1
159 | end
160 | return true
161 | end
162 |
163 | function tetris_class:move(dx, dy)
164 | local t = self.data.t
165 | local newx, newy = t.x+dx, t.y+dy
166 | if not self:check_position(newx, newy, t.rot) then
167 | return
168 | end
169 | t.x, t.y = newx, newy
170 | end
171 |
172 | function tetris_class:rotate(dr)
173 | local t = self.data.t
174 | local no = #(shapes[t.cur])
175 | local newrot = (t.rot+dr) % no
176 |
177 | if newrot<1 then newrot = newrot+no end
178 | if not self:check_position(t.x, t.y, newrot) then
179 | return
180 | end
181 | t.rot = newrot
182 | end
183 |
184 | function tetris_class:key(fields)
185 | local t = self.data.t
186 | if fields.left then
187 | self:move(-1, 0)
188 | end
189 | if fields.rotateleft then
190 | self:rotate(-1)
191 | end
192 | if fields.down then
193 | t.score = t.score + 1
194 | self:move(0, 1)
195 | end
196 | if fields.drop then
197 | while not self:stuck() do
198 | t.score = t.score + 2
199 | self:move(0, 1)
200 | end
201 | end
202 | if fields.rotateright then
203 | self:rotate(1)
204 | end
205 | if fields.right then
206 | self:move(1, 0)
207 | end
208 | end
209 |
210 | function tetris_class:draw_shape(id, x, y, rot, posx, posy)
211 | local d = shapes[id][rot]
212 | local scr = {}
213 | local ins = #scr
214 | local color = colors[id]
215 | if self.app.os.theme.monochrome_textcolor then
216 | color = base_color_texture.."^[colorize:"..
217 | self.app.os.theme.monochrome_textcolor..
218 | ":"..base_color_alpha
219 | end
220 | for i=1,4 do
221 | local tmp = { "image[",
222 | (d.x[i]+x)*sizex+posx, comma,
223 | (d.y[i]+y)*sizey+posy, semi,
224 | size, comma, size, semi,
225 | color, close }
226 |
227 | ins = ins + 1
228 | scr[ins] = concat(tmp)
229 | end
230 | return concat(scr)
231 | end
232 |
233 |
234 | laptop.register_app("tetris", {
235 | app_name = "Tetris",
236 | app_icon = "laptop_tetris_icon.png",
237 | app_info = "Falling Tile Game",
238 |
239 | formspec_func = function(app, mtos)
240 | local data = mtos.bdev:get_app_storage('ram', 'tetris')
241 | local tetris = get_tetris(app, data)
242 | if not data.t then
243 | return mtos.theme:get_button('2,4;2,2', 'major', 'new', 'New Game', 'Start a new game')
244 | end
245 |
246 | local buttons = mtos.theme:get_button('6,6;1,1', 'minor', 'left', '<')..
247 | mtos.theme:get_button('6,5;1,1', 'minor', 'rotateleft', 'L')..
248 | mtos.theme:get_button('7,5;1,1', 'minor', 'down', 'v')..
249 | mtos.theme:get_button('7,6;1,1', 'minor', 'drop', 'V')..
250 | mtos.theme:get_button('8,5;1,1', 'minor', 'rotateright', 'R')..
251 | mtos.theme:get_button('8,6;1,1', 'minor', 'right', '>')..
252 | mtos.theme:get_button('6,3.5;3,1', 'major', 'new', 'New Game', 'Start a new game')
253 |
254 | local t = tetris.data.t
255 | return 'container[3,1]background[0,-0.05;4.35,9;'.. mtos.theme.contrast_background .. ']' ..
256 | t.boardstring .. t.previewstring ..
257 | tetris:draw_shape(t.cur, t.x, t.y, t.rot, boardx, boardy) ..
258 | mtos.theme:get_label('6.5,0.1', 'Next...') ..
259 | mtos.theme:get_label('6.5,2.7', 'Score:...'..t.score) ..
260 | buttons .. 'container_end[]'
261 | end,
262 |
263 | receive_fields_func = function(app, mtos, sender, fields)
264 | local data = mtos.bdev:get_app_storage('ram', 'tetris')
265 | local tetris = get_tetris(app, data)
266 | if fields.new then
267 | tetris:new_game()
268 | elseif fields.continue then
269 | app:get_timer():start(0.3)
270 | else
271 | tetris:key(fields)
272 | end
273 | end,
274 |
275 | on_timer = function(app, mtos)
276 | local data = mtos.bdev:get_app_storage('ram', 'tetris')
277 | if not data.t then
278 | return false
279 | else
280 | return get_tetris(app, data):tick()
281 | end
282 | end,
283 | })
284 |
285 |
--------------------------------------------------------------------------------
/apps/mail_app.lua:
--------------------------------------------------------------------------------
1 | -- based on https://github.com/cheapie/mail
2 |
3 | laptop.register_app("mail", {
4 | app_name = "Mail",
5 | app_icon = "laptop_email_letter.png",
6 | app_info = "Send Electronic Mail",
7 | formspec_func = function(app, mtos)
8 | local cloud = mtos.bdev:get_app_storage('cloud', 'mail')
9 | if not cloud then
10 | mtos:set_app("mail:nonet")
11 | return false
12 | end
13 | if not mtos.sysram.current_player then
14 | mtos:set_app() -- no player. Back to launcher
15 | return false
16 | end
17 |
18 | if not cloud[mtos.sysram.current_player] then
19 | mtos:set_app("mail:newplayer")
20 | return false
21 | end
22 | local account = cloud[mtos.sysram.current_player]
23 | account.selected_box = account.selected_box or "inbox"
24 | account.selected_index = nil -- will be new determinated by selectedmessage
25 | local box = account[account.selected_box] -- inbox or outbox
26 |
27 | app.app_info = app.app_info.." - Welcome "..mtos.sysram.current_player
28 | local formspec =
29 | mtos.theme:get_tableoptions()..
30 | "tablecolumns[" ..
31 | "image,align=center,1="..mtos.theme:get_texture('laptop_mail.png')..",2="..mtos.theme:get_texture('laptop_mail_read.png')..";".. --icon column
32 | "color;".. -- subject and date color
33 | "text;".. -- subject
34 | "text,padding=1.5;".. -- sender
35 | "text,padding=1.5,align=right]".. -- date
36 | "table[0,0.5;7.5,8.2;message;"
37 |
38 | if box and box[1] then
39 | for idx,message in ipairs(box) do
40 | if idx > 1 then
41 | formspec = formspec..','
42 | end
43 | -- set read/unread status
44 | if account.selected_box == "sentbox" then
45 | formspec = formspec .. "2,"..mtos.theme.muted_textcolor.."," -- sent are always read
46 | elseif not message.is_read then
47 | formspec = formspec .. "1,"..mtos.theme.table_textcolor.."," -- unread
48 | else
49 | formspec = formspec .. "2,"..mtos.theme.muted_textcolor.."," -- read
50 | end
51 |
52 | -- set subject
53 | if not message.subject or message.subject == "" then
54 | formspec = formspec .. "(No Subject),"
55 | elseif string.len(message.subject) > 30 then
56 | formspec = formspec .. minetest.formspec_escape(string.sub(message.subject,1,27)) .. "...,"
57 | else
58 | formspec = formspec .. minetest.formspec_escape(message.subject) .. ","
59 | end
60 |
61 | -- set sender or receiver
62 | if account.selected_box == "inbox" then
63 | formspec = formspec..minetest.formspec_escape(message.sender or "") .."," -- body
64 | else
65 | formspec = formspec..minetest.formspec_escape(message.receiver or "") .."," -- body
66 | end
67 |
68 | -- set date
69 | formspec = formspec .. os.date("%c", message.time) -- timestamp
70 |
71 | -- handle marked line
72 | if account.selectedmessage and
73 | message.sender == account.selectedmessage.sender and
74 | message.subject == account.selectedmessage.subject and
75 | message.time == account.selectedmessage.time and
76 | message.body == account.selectedmessage.body then
77 | account.selected_index = idx
78 | end
79 | end
80 | formspec = formspec .. ";"..(account.selected_index or "").."]"
81 | else
82 | formspec = formspec .. ",,No Mail :(]"
83 | end
84 |
85 | -- toggle inbox/sentbox
86 | if account.selected_box == "inbox" then
87 | formspec = formspec .. mtos.theme:get_image_button('0,9;1,1', 'minor', 'switch_sentbox', 'laptop_mail_sentbox.png', '', 'Show Sent Messages')
88 | else
89 | formspec = formspec .. mtos.theme:get_image_button('0,9;1,1', 'minor', 'switch_inbox', 'laptop_mail_received.png', '', 'Show Received Messages')
90 | end
91 |
92 | formspec = formspec .. mtos.theme:get_image_button('1.7,9;1,1', 'minor', 'new', 'laptop_email_new.png', '', 'New Message')
93 | if account.newmessage then
94 | formspec = formspec .. mtos.theme:get_image_button('2.7,9;1,1', 'minor', 'continue', 'laptop_email_edit.png', '', 'Continue Last Message')
95 | end
96 |
97 | if account.selectedmessage then
98 | formspec = formspec ..
99 | mtos.theme:get_image_button('3.7,9;1,1', 'minor', 'reply', 'laptop_email_reply.png', '', 'Reply')..
100 | mtos.theme:get_image_button('4.7,9;1,1', 'minor', 'forward', 'laptop_email_forward.png', '', 'Forward')..
101 | mtos.theme:get_image_button('5.7,9;1,1', 'minor', 'delete', 'laptop_email_trash.png', '', 'Delete')
102 | if account.selected_box == "inbox" then
103 | if not account.selectedmessage.is_read then
104 | formspec = formspec .. mtos.theme:get_image_button('6.7,9;1,1', 'minor', 'markread', 'laptop_mail_read_button.png', '', 'Mark Message as Read')
105 | else
106 | formspec = formspec .. mtos.theme:get_image_button('6.7,9;1,1', 'minor', 'markunread', 'laptop_mail_button.png', '', 'Mark Message as Unread')
107 | end
108 | end
109 | formspec = formspec .. mtos.theme:get_image_button('8,9;1,1', 'minor', 'print', 'laptop_printer_button.png', '', 'Print Email')
110 | if account.selected_box == "inbox" then
111 | formspec = formspec .. mtos.theme:get_label('8,0.5', "From: "..(account.selectedmessage.sender or ""))
112 | else
113 | formspec = formspec .. mtos.theme:get_label('8,0.5', "To: "..(account.selectedmessage.receiver or ""))
114 | end
115 |
116 | formspec = formspec .. mtos.theme:get_label('8,1', "Subject: "..(account.selectedmessage.subject or ""))..
117 | mtos.theme:get_tableoptions(false).."tablecolumns[text]table[8,1.55;6.85,7.15;preview_bg;]"..
118 | "textarea[8.35,1.6;6.8,8.25;;"..minetest.colorize(mtos.theme.table_textcolor, minetest.formspec_escape(account.selectedmessage.body) or "")..";]"
119 | end
120 | return formspec
121 | end,
122 | receive_fields_func = function(app, mtos, sender, fields)
123 | if mtos.sysram.current_player ~= mtos.sysram.last_player then
124 | mtos:set_app() -- wrong player. Back to launcher
125 | return
126 | end
127 |
128 | local cloud = mtos.bdev:get_app_storage('cloud', 'mail')
129 | local account = cloud[mtos.sysram.current_player]
130 | if not account then
131 | mtos:set_app() -- wrong player. Back to launcher
132 | return
133 | end
134 | account.selected_box = account.selected_box or "inbox"
135 | local box = account[account.selected_box] -- inbox or outbox
136 |
137 | -- Set read status if 2 seconds selected
138 | if account.selected_index and account.selectedmessage and account.selected_box == "inbox" and
139 | account.selected_timestamp and (os.time() - account.selected_timestamp) > 1 then
140 | account.selectedmessage.is_read = true
141 | end
142 |
143 | -- process input
144 | if fields.message then
145 | local event = minetest.explode_table_event(fields.message)
146 | account.selectedmessage = box[event.row]
147 | if account.selectedmessage then
148 | account.selected_index = event.row
149 | account.selected_timestamp = os.time()
150 | else
151 | account.selected_index = nil
152 | end
153 | elseif fields.new then
154 | account.newmessage = {}
155 | mtos:set_app("mail:compose")
156 | elseif fields.continue then
157 | mtos:set_app("mail:compose")
158 | elseif fields.switch_sentbox then
159 | account.selected_box = "sentbox"
160 | account.selectedmessage = nil
161 | elseif fields.switch_inbox then
162 | account.selected_box = "inbox"
163 | account.selectedmessage = nil
164 | elseif account.selected_index then
165 | if fields.delete then
166 | table.remove(box, account.selected_index)
167 | account.selectedmessage = nil
168 | elseif fields.reply then
169 | account.newmessage = {}
170 | account.newmessage.receiver = account.selectedmessage.sender
171 | account.newmessage.subject = "Re: "..(account.selectedmessage.subject or "")
172 | account.newmessage.body = "Type your reply here."..string.char(10)..string.char(10).."--Original message follows--"..string.char(10)..(account.selectedmessage.body or "")
173 | mtos:set_app("mail:compose")
174 | elseif fields.forward then
175 | account.newmessage = {}
176 | account.newmessage.subject = "Fw: "..(account.selectedmessage.subject or "")
177 | account.newmessage.body = "Type your reply here."..string.char(10)..string.char(10).."--Original message follows--"..string.char(10)..(account.selectedmessage.body or "")
178 | mtos:set_app("mail:compose")
179 | elseif fields.markread then
180 | account.selectedmessage.is_read = true
181 | elseif fields.markunread then
182 | account.selectedmessage.is_read = false
183 | account.selected_timestamp = nil
184 | elseif fields.print then
185 | mtos:print_file_dialog({
186 | label = account.selectedmessage.subject,
187 | author = account.selectedmessage.sender,
188 | timestamp = account.selectedmessage.time,
189 | text = account.selectedmessage.body,
190 | })
191 | end
192 | end
193 | end
194 | })
195 |
196 | laptop.register_view("mail:newplayer", {
197 | formspec_func = function(app, mtos)
198 | return mtos.theme:get_label('1,3', "No mail account for player "..mtos.sysram.current_player.. " found. Do you like to create a new account?")..
199 | mtos.theme:get_button('1,4;3,1', 'major', 'create', 'Create Account')
200 | end,
201 | receive_fields_func = function(app, mtos, sender, fields)
202 | if mtos.sysram.current_player ~= mtos.sysram.last_player then
203 | mtos:set_app() -- wrong player. Back to launcher
204 | return
205 | end
206 | if fields.create then
207 | local cloud = mtos.bdev:get_app_storage('cloud', 'mail')
208 | cloud[mtos.sysram.current_player] = {
209 | inbox = {},
210 | sentbox = {}
211 | }
212 | app:back_app()
213 | elseif fields.os_back then
214 | app:exit_app()
215 | end
216 | end
217 | })
218 |
219 | laptop.register_view("mail:nonet", {
220 | formspec_func = function(app, mtos)
221 | return mtos.theme:get_label('1,3', "NO NETWORK CONNECTION")
222 | end,
223 | receive_fields_func = function(app, mtos, sender, fields)
224 | app:exit_app()
225 | end
226 | })
227 |
228 | -- Write new mail
229 | laptop.register_view("mail:compose", {
230 | formspec_func = function(app, mtos)
231 | local cloud = mtos.bdev:get_app_storage('cloud', 'mail')
232 | local account = cloud[mtos.sysram.current_player]
233 | account.newmessage = account.newmessage or {}
234 | local message = account.newmessage
235 |
236 | local formspec = "background[0,0.4;8,2.4;"..mtos.theme.contrast_background.."]"..
237 | mtos.theme:get_label("0.25,2", "Subject:", "contrast").."field[2.7,2;5,1;subject;;"..minetest.formspec_escape(message.subject or "").."]"..
238 | "background[0,3.05;7.95,3.44;"..mtos.theme.contrast_background.."]"..
239 | "textarea[0.25,3;8,4;body;;"..minetest.formspec_escape(message.body or "").."]"..
240 | mtos.theme:get_button("0,8;2,1", "major", "send", "Send message")..
241 | mtos.theme:get_label("0.25,0.75", "Receiver:", "contrast").."dropdown[2.4,0.75;5.2,1;receiver;"
242 |
243 | local sortedtab = {}
244 | for playername,_ in pairs(cloud) do
245 | table.insert(sortedtab, playername)
246 | end
247 | table.sort(sortedtab)
248 |
249 | local selected_idx
250 | for idx, playername in ipairs(sortedtab) do
251 | formspec = formspec..',' .. minetest.formspec_escape(playername)
252 | if playername == message.receiver then
253 | selected_idx = idx+1 -- +1 because of empty entry
254 | end
255 | end
256 | formspec = formspec .. ";"..(selected_idx or "").."]"
257 |
258 | if message.receiver and not cloud[message.receiver] then
259 | formspec = formspec..mtos.theme:get_label('2.3,8', "invalid receiver player")
260 | end
261 | return formspec
262 | end,
263 | receive_fields_func = function(app, mtos, sender, fields)
264 | if mtos.sysram.current_player ~= mtos.sysram.last_player then
265 | mtos:set_app() -- wrong player. Back to launcher
266 | return
267 | end
268 |
269 | local cloud = mtos.bdev:get_app_storage('cloud', 'mail')
270 | local account = cloud[mtos.sysram.current_player]
271 | account.newmessage = account.newmessage or {}
272 | local message = account.newmessage
273 |
274 | message.receiver = fields.receiver or message.receiver
275 | message.sender = mtos.sysram.current_player
276 | message.time = os.time()
277 | message.subject = fields.subject or message.subject
278 | message.body = fields.body or message.body
279 |
280 | if fields.send and message.receiver and cloud[message.receiver] then
281 | table.insert(cloud[message.receiver].inbox, message)
282 | table.insert(account.sentbox, table.copy(message))
283 | account.newmessage = nil
284 | app:back_app()
285 | end
286 | end
287 | })
288 |
--------------------------------------------------------------------------------
/apps/os_print_app.lua:
--------------------------------------------------------------------------------
1 | local printer_range = 10
2 |
3 | local function trigger_queue(app, mtos)
4 | -- Check print requirements
5 | if mtos.sysdata.selected_view ~= 'output' or
6 | mtos.sysdata.out_stack_save or
7 | not mtos.sysdata.paper_count or mtos.sysdata.paper_count == 0 or
8 | not mtos.sysdata.dye_count or mtos.sysdata.dye_count == 0 or
9 | not mtos.sysdata.print_queue or
10 | not mtos.sysdata.print_queue[1] then
11 | mtos.sysdata.print_progress = 0
12 | return false
13 | end
14 |
15 | -- timer done
16 | if mtos.sysdata.print_progress >= 5 then
17 | mtos.sysdata.print_progress = 0
18 | mtos.sysdata.paper_count = mtos.sysdata.paper_count - 1
19 | mtos.sysdata.dye_count = mtos.sysdata.dye_count - 0.1
20 | mtos.bdev.removable_disk = nil -- force reading
21 | local idata = mtos.bdev:get_removable_disk()
22 | local stack = ItemStack("laptop:printed_paper")
23 | local print_data = mtos.sysdata.print_queue[1]
24 | stack:get_meta():from_table({ fields = print_data})
25 | table.remove(mtos.sysdata.print_queue, 1)
26 | idata:reload(stack)
27 | idata.label = print_data.title
28 | mtos.bdev:sync()
29 | end
30 |
31 | local timer = app:get_timer()
32 | if not timer:is_started() then
33 | timer:start(1)
34 | end
35 | return true
36 | end
37 |
38 | local function sync_stack_values(mtos)
39 | mtos.sysdata.paper_count = mtos.sysdata.paper_count or 0
40 | mtos.sysdata.dye_count = mtos.sysdata.dye_count or 0
41 | mtos.sysdata.print_progress = mtos.sysdata.print_progress or 0
42 | mtos.bdev.removable_disk = nil -- force reading
43 | local idata = mtos.bdev:get_removable_disk()
44 | -- store old stack values
45 | if mtos.sysdata.selected_view == 'paper' then
46 | if idata.stack then
47 | mtos.sysdata.paper_count = idata.stack:get_count()
48 | else
49 | mtos.sysdata.paper_count = 0
50 | end
51 | elseif mtos.sysdata.selected_view == 'dye' then
52 | if idata.stack then
53 | mtos.sysdata.dye_count = mtos.sysdata.dye_count - math.floor(mtos.sysdata.dye_count) + idata.stack:get_count()
54 | else
55 | mtos.sysdata.dye_count = mtos.sysdata.dye_count - math.floor(mtos.sysdata.dye_count)
56 | end
57 | elseif mtos.sysdata.selected_view == 'output' then
58 | if idata.stack then
59 | mtos.sysdata.out_stack_save = idata.stack:to_string()
60 | else
61 | mtos.sysdata.out_stack_save = nil
62 | end
63 | end
64 | end
65 |
66 | laptop.register_app("printer_launcher", {
67 | app_name = "Printer firmware",
68 | view = true, -- to be hidden in "usual" OS
69 | fullscreen = true,
70 | formspec_func = function(launcher_app, mtos)
71 | mtos.sysdata.print_queue = mtos.sysdata.print_queue or {}
72 | mtos.sysdata.selected_view = mtos.sysdata.selected_view or 'output'
73 | sync_stack_values(mtos)
74 | trigger_queue(launcher_app, mtos)
75 | mtos.bdev:sync()
76 | -- inventory fields
77 | local formspec = "size[9,8]"..
78 | "list[current_player;main;0.3,3.85;8,1;]" ..
79 | "list[current_player;main;0.3,5.08;8,3;8]" ..
80 | "listring[nodemeta:"..mtos.pos.x..','..mtos.pos.y..','..mtos.pos.z..";main]" ..
81 | "listring[current_player;main]"..
82 | mtos.theme:get_label('0,0', mtos.hwdef.description, 'titlebar')
83 |
84 | -- queue
85 | formspec = formspec .. mtos.theme:get_tableoptions()..
86 | "tablecolumns[" ..
87 | "text;".. -- label
88 | "text;".. -- author
89 | "text]".. -- timestamp
90 | "table[0,0.5;5,2.42;printers;"
91 | for idx, file in ipairs(mtos.sysdata.print_queue) do
92 | if idx > 1 then
93 | formspec = formspec..','
94 | end
95 | formspec = formspec .. minetest.formspec_escape(file.title or "")..','..
96 | (file.author or "")..','..os.date("%c", file.timestamp)
97 | end
98 | formspec = formspec .. ";]"
99 |
100 | local out_button = 'minor'
101 | local paper_button = 'minor'
102 | local dye_button = 'minor'
103 | if mtos.sysdata.selected_view == 'paper' then
104 | paper_button = 'major'
105 | formspec = formspec .."background[6.2,0.8;2.5,0.7;"..mtos.theme.contrast_background..']'
106 | elseif mtos.sysdata.selected_view == 'dye' then
107 | dye_button = 'major'
108 | formspec = formspec .."background[6.2,1.5;2.5,0.7;"..mtos.theme.contrast_background..']'
109 | elseif mtos.sysdata.selected_view == 'output' then
110 | out_button = 'major'
111 | formspec = formspec .."background[6.2,2.2;2.5,0.7;"..mtos.theme.contrast_background..']'
112 | end
113 |
114 | formspec = formspec .."background[5.2,0.55;1.5,2.45;"..mtos.theme.contrast_background..']'..
115 | mtos.theme:get_label('5.3,0.8', 'Paper: '..mtos.sysdata.paper_count, 'contrast')..
116 | mtos.theme:get_label('5.3,1.3', 'Dye: '..mtos.sysdata.dye_count, 'contrast')..
117 | mtos.theme:get_button('6.8,0.8;1.5,0.7', paper_button, 'view_paper', 'Paper tray', 'Insert paper')..
118 | mtos.theme:get_button('6.8,1.5;1.5,0.7', dye_button, 'view_dye', 'Dye tray', 'Insert black dye')..
119 | mtos.theme:get_button('6.8,2.2;1.5,0.7', out_button, 'view_out', 'Output tray', 'Get printed paper')..
120 | "list[nodemeta:"..mtos.pos.x..','..mtos.pos.y..','..mtos.pos.z..";main;5.4,1.8;1,1;]"..
121 | mtos.theme:get_button('0.3,3;1.5,0.7', 'minor', 'reset', 'Reset', 'Reset printer queue')..
122 | mtos.theme:get_button('2,3;1.5,0.7', 'minor', 'delete', 'Delete', 'Delete job')..
123 | "background[3.7,3.1;"..(mtos.sysdata.print_progress)..",0.5;laptop_theme_red_back_button.png]"
124 | return formspec
125 | end,
126 |
127 | appwindow_formspec_func = function(launcher_app, app, mtos)
128 | local formspec = 'size[10,7]'
129 | return formspec
130 | end,
131 |
132 | allow_metadata_inventory_put = function(app, mtos, player, listname, index, stack)
133 | if mtos.sysdata.selected_view == 'output' then
134 | -- nothing
135 | elseif mtos.sysdata.selected_view == 'paper' and stack:get_name() == 'default:paper' then
136 | return stack:get_stack_max()
137 | elseif mtos.sysdata.selected_view == 'dye' and stack:get_name() == 'dye:black' then
138 | return stack:get_stack_max()
139 | end
140 | return 0
141 | end,
142 |
143 | allow_metadata_inventory_take = function(app, mtos, player, listname, index, stack)
144 | -- removal allways possible
145 | return stack:get_count()
146 | end,
147 |
148 | receive_fields_func = function(app, mtos, sender, fields)
149 | sync_stack_values(mtos)
150 | local idata = mtos.bdev:get_removable_disk()
151 | if fields.view_out then
152 | mtos.sysdata.selected_view = 'output'
153 | idata.stack = ItemStack(mtos.sysdata.out_stack_save or "")
154 | elseif fields.view_paper then
155 | mtos.sysdata.selected_view = 'paper'
156 | idata.stack = ItemStack('default:paper')
157 | idata.stack:set_count(mtos.sysdata.paper_count)
158 | elseif fields.view_dye then
159 | mtos.sysdata.selected_view = 'dye'
160 | idata.stack = ItemStack('dye:black')
161 | idata.stack:set_count(math.floor(mtos.sysdata.dye_count))
162 | elseif fields.reset then
163 | mtos.sysdata.print_queue = {}
164 | mtos.sysdata.print_progress = 0
165 | elseif fields.delete then
166 | table.remove(mtos.sysdata.print_queue, 1)
167 | mtos.sysdata.print_progress = 0
168 | end
169 | idata:reload(idata.stack)
170 | trigger_queue(app, mtos)
171 | mtos.bdev:sync()
172 | end,
173 |
174 | on_timer = function(app, mtos)
175 | mtos.sysdata.print_progress = mtos.sysdata.print_progress + 1
176 | mtos.bdev.removable_disk = nil -- force reading
177 | return trigger_queue(app, mtos)
178 | end,
179 | })
180 |
181 |
182 |
183 | local function get_printer_info(pos)
184 | local hw_os = laptop.os_get(pos)
185 | local printer
186 | if hw_os then
187 | printer = {
188 | pos = pos,
189 | name = hw_os.hwdef.description,
190 | nodename = hw_os.node.name,
191 | }
192 | if not minetest.registered_items[hw_os.node.name].groups.laptop_printer then
193 | printer.status = 'off'
194 | -- printer.status_color = '#FF0000'
195 | elseif not hw_os.sysram.current_app or hw_os.sysram.current_app == 'os:power_off' then
196 | printer.status = 'disabled'
197 | -- printer.status_color = '#FF0000'
198 | else
199 | printer.status = 'online'
200 | -- printer.status_color = '#00FF00'
201 | end
202 | end
203 | return printer
204 | end
205 |
206 | laptop.register_view("printer:app", {
207 | app_info = "Print file",
208 | formspec_func = function(app, mtos)
209 | local store = mtos.bdev:get_app_storage('ram', 'printer:app')
210 | local param = store.param
211 | local sysstore = mtos.bdev:get_app_storage('system', 'printer:app')
212 | sysstore.printers = sysstore.printers or {}
213 |
214 | local formspec = mtos.theme:get_label('0.5,1', "Selected Printer:")
215 | if sysstore.selected_printer then
216 | local printer = get_printer_info(sysstore.selected_printer.pos)
217 | if not printer then
218 | printer = sysstore.selected_printer
219 | printer.status = 'removed'
220 | else
221 | sysstore.selected_printer = printer
222 | end
223 | local status_color = mtos.theme["status_"..printer.status.."_textcolor"] or mtos.theme.textcolor
224 | formspec = formspec .. 'item_image[0.5,1.5;1,1;'..printer.nodename..']'..
225 | mtos.theme:get_label('1.5,1.7', minetest.formspec_escape(printer.name)..' '..
226 | minetest.pos_to_string(printer.pos)..' '.. minetest.colorize(status_color, printer.status))
227 | end
228 |
229 | formspec = formspec .. mtos.theme:get_tableoptions()..
230 | "tablecolumns[" ..
231 | "text;".. -- Printer name
232 | "text;".. -- Printer position
233 | "color;"..-- Status color
234 | "text]".. -- Printer status
235 | "table[0.5,2.5;6.5,4.2;printers;"
236 | if sysstore.printers[1] then
237 | local sel_idx = ""
238 | for idx, printer in ipairs(sysstore.printers) do
239 | if idx > 1 then
240 | formspec = formspec..','
241 | end
242 | local pos_string = minetest.pos_to_string(printer.pos)
243 | local status_color = mtos.theme["status_"..printer.status.."_textcolor"] or mtos.theme.textcolor
244 | formspec = formspec..minetest.formspec_escape(printer.name)..','..
245 | minetest.formspec_escape(minetest.pos_to_string(printer.pos))..','..
246 | status_color..','..printer.status
247 | if sysstore.selected_printer and vector.distance(printer.pos, sysstore.selected_printer.pos) == 0 then
248 | sel_idx = idx
249 | end
250 | end
251 | formspec = formspec .. ";"..sel_idx.."]"
252 | else
253 | formspec = formspec .. "No printer found :(]"
254 | end
255 |
256 | formspec = formspec .. mtos.theme:get_button('2.7,9;2,0.7', 'minor', 'scan', 'Search', 'Scan for printers')
257 | if sysstore.selected_printer and sysstore.selected_printer.status == 'online' then
258 | formspec = formspec .. mtos.theme:get_button('10,9;2,0.7', 'major', 'print', 'Print', 'Print file')
259 | end
260 |
261 | param.label = param.label or ""
262 |
263 | formspec = formspec .. mtos.theme:get_bgcolor_box("7.15,0.4;7.6,1","contrast")..
264 | mtos.theme:get_label('7.3,0.6','Heading:','contrast').."field[9.7,0.7;5,1;label;;"..minetest.formspec_escape(param.label or "").."]"..
265 | mtos.theme:get_label('9.7,1.7'," by "..(mtos.sysram.current_player or ""))..
266 | mtos.theme:get_tableoptions(false).."tablecolumns[text]table[7.15,2.5;7.6,6.0;preview_bg;]"..
267 | "textarea[7.5,2.5;7.5,7;;"..minetest.colorize(mtos.theme.table_textcolor, (minetest.formspec_escape(param.text) or ""))..";]"
268 |
269 | return formspec
270 | end,
271 | receive_fields_func = function(app, mtos, sender, fields)
272 | local store = mtos.bdev:get_app_storage('ram', 'printer:app')
273 | local param = store.param
274 | local sysstore = mtos.bdev:get_app_storage('system', 'printer:app')
275 | sysstore.printers = sysstore.printers or {}
276 |
277 | if fields.scan then
278 | sysstore.printers = {}
279 | local nodes = minetest.find_nodes_in_area({x = mtos.pos.x-printer_range, y= mtos.pos.y-printer_range, z = mtos.pos.z-printer_range},
280 | {x = mtos.pos.x+printer_range, y= mtos.pos.y+printer_range, z = mtos.pos.z+printer_range}, {"group:laptop_printer"})
281 | for _, pos in ipairs(nodes) do
282 | local printer = get_printer_info(pos)
283 | if printer then
284 | printer.printer_os = nil -- do not store whole OS
285 | table.insert(sysstore.printers, printer)
286 | end
287 | end
288 | table.sort(sysstore.printers, function(a,b) return vector.distance(a.pos, mtos.pos) < vector.distance(b.pos, mtos.pos) end)
289 | end
290 |
291 | if fields.printers then
292 | local event = minetest.explode_table_event(fields.printers)
293 | sysstore.selected_printer = sysstore.printers[event.row] or sysstore.selected_printer
294 | end
295 |
296 | if fields.label then
297 | param.label = fields.label
298 | end
299 |
300 | if fields.print and sysstore.selected_printer then
301 | local hw_os = laptop.os_get(sysstore.selected_printer.pos)
302 | if hw_os and minetest.registered_items[hw_os.node.name].groups.laptop_printer then
303 | hw_os.sysdata.print_queue = hw_os.sysdata.print_queue or {}
304 | sync_stack_values(hw_os)
305 | table.insert(hw_os.sysdata.print_queue, { title = param.label, text = param.text, author = param.author or sender:get_player_name(), timestamp = param.timestamp or os.time() })
306 | hw_os:set_app() --update page
307 | app:back_app()
308 | end
309 | end
310 | end,
311 | })
312 |
--------------------------------------------------------------------------------
/hardware_fw.lua:
--------------------------------------------------------------------------------
1 |
2 | laptop.node_config = {}
3 |
4 | local have_technic = minetest.get_modpath("technic")
5 | local have_generator = minetest.get_modpath("power_generators")
6 |
7 | local function on_construct(pos)
8 | laptop.mtos_cache:free(pos)
9 | local mtos = laptop.os_get(pos)
10 | local node = minetest.get_node(pos)
11 | local hwdef = laptop.node_config[node.name]
12 | if hwdef.custom_theme then -- initial only
13 | mtos:set_theme(hwdef.custom_theme)
14 | end
15 | if hwdef.hw_state then
16 | mtos[hwdef.hw_state](mtos)
17 | else
18 | mtos:power_off()
19 | end
20 | end
21 |
22 | local function on_punch(pos, node, puncher)
23 | local mtos = laptop.os_get(pos)
24 |
25 | local punch_item = puncher:get_wielded_item()
26 | local is_compatible = false
27 | if punch_item then
28 | local def = punch_item:get_definition()
29 | for group, _ in pairs(def.groups) do
30 | if mtos.bdev:is_hw_capability(group) then
31 | is_compatible = true
32 | end
33 | end
34 | end
35 |
36 | if is_compatible then
37 | local slot = mtos.bdev:get_removable_disk()
38 | -- swap
39 | puncher:set_wielded_item(slot.stack)
40 | -- reload OS
41 | slot:reload(punch_item)
42 | laptop.mtos_cache:sync_and_free(mtos)
43 | for k,v in pairs(laptop.os_get(mtos.pos)) do
44 | mtos[k] = v
45 | end
46 | mtos:pass_to_app("punched_by_removable", true, puncher, punch_item)
47 | return
48 | end
49 |
50 | local hwdef = laptop.node_config[node.name]
51 | if hwdef.next_node then
52 | local hwdef_next = laptop.node_config[hwdef.next_node]
53 | if hwdef_next.hw_state then
54 | mtos[hwdef_next.hw_state](mtos, hwdef.next_node)
55 | else
56 | mtos:swap_node(hwdef.next_node)
57 | mtos:save()
58 | end
59 | end
60 | end
61 |
62 | local function on_receive_fields(pos, formname, fields, sender)
63 | local mtos = laptop.os_get(pos)
64 | mtos:pass_to_app("receive_fields_func", true, sender, fields)
65 | end
66 |
67 | local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
68 | local mtos = laptop.os_get(pos)
69 | return mtos:pass_to_app("allow_metadata_inventory_move", false, player, from_list, from_index, to_list, to_index, count) or 0
70 | end
71 |
72 | local function allow_metadata_inventory_put(pos, listname, index, stack, player)
73 | local mtos = laptop.os_get(pos)
74 | local def = stack:get_definition()
75 | local allowed_stacksize = 0
76 | if def then
77 | for group, _ in pairs(def.groups) do
78 | if mtos.bdev:is_hw_capability(group) then
79 | allowed_stacksize = 1
80 | end
81 | end
82 | end
83 | return mtos:pass_to_app("allow_metadata_inventory_put", false, player, listname, index, stack) or allowed_stacksize
84 | end
85 |
86 | local function allow_metadata_inventory_take(pos, listname, index, stack, player)
87 | local mtos = laptop.os_get(pos)
88 | return mtos:pass_to_app("allow_metadata_inventory_take", false, player, listname, index, stack) or 1 -- by default removal allowed
89 | end
90 |
91 | local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
92 | local mtos = laptop.os_get(pos)
93 | mtos:pass_to_app("on_metadata_inventory_move", true, player, from_list, from_index, to_list, to_index, count)
94 | end
95 |
96 | local function on_metadata_inventory_put(pos, listname, index, stack, player)
97 | local mtos = laptop.os_get(pos)
98 | mtos:pass_to_app("on_metadata_inventory_put", true, player, listname, index, stack)
99 | end
100 |
101 | local function on_metadata_inventory_take(pos, listname, index, stack, player)
102 | local mtos = laptop.os_get(pos)
103 | mtos:pass_to_app("on_metadata_inventory_take", true, player, listname, index, stack)
104 | end
105 |
106 | local function on_timer(pos, elapsed)
107 | local mtos = laptop.os_get(pos)
108 | return mtos:pass_to_app("on_timer", true, nil, elapsed)
109 | end
110 |
111 | local function after_place_node(pos, placer, itemstack, pointed_thing)
112 | local save = minetest.deserialize(itemstack:get_meta():get_string("laptop_metadata"))
113 | if not save then
114 | return
115 | end
116 |
117 | -- Backwards compatibility code
118 | if save.fields then
119 | laptop.mtos_cache:free(pos)
120 | local meta = minetest.get_meta(pos)
121 | meta:from_table({fields = save.fields})
122 | for invname, inv in pairs(save.invlist) do
123 | meta:get_inventory():set_list(invname, inv)
124 | end
125 | itemstack:clear()
126 | return
127 | end
128 | -- Backwards compatibility code end
129 |
130 | local mtos = laptop.os_get(pos)
131 | mtos.bdev.ram_disk = save.ram_disk or mtos.bdev.ram_disk
132 | mtos.bdev.hard_disk = save.hard_disk or mtos.bdev.hard_disk
133 |
134 | if save.removable_disk then
135 | local removable = mtos.bdev:get_removable_disk()
136 | removable:reload(ItemStack(save.removable_disk))
137 | end
138 |
139 | -- battery support
140 | if have_technic or have_generator then
141 | local node = minetest.get_node(pos)
142 | local hwdef = laptop.node_config[node.name]
143 | if hwdef.battery_capacity then
144 | local metadata = minetest.deserialize(itemstack:get_metadata())
145 | if metadata and metadata.charge then
146 | local meta = minetest.get_meta(pos)
147 | meta:set_int("battery", metadata.charge)
148 | end
149 | end
150 | end
151 |
152 | mtos.bdev:sync()
153 | itemstack:clear()
154 | end
155 |
156 | local function preserve_metadata(pos, oldnode, oldmetadata, drops)
157 | local mtos = laptop.os_get(pos)
158 | if not mtos then
159 | return
160 | end
161 |
162 | laptop.mtos_cache:sync_and_free(mtos)
163 |
164 | local removable = mtos.bdev:get_removable_disk()
165 |
166 | local save = {
167 | laptop_ram = mtos.bdev:get_ram_disk(),
168 | hard_disk = mtos.bdev:get_hard_disk(),
169 | removable_disk = removable.stack and removable.stack:to_string()
170 | }
171 |
172 | local item_name = minetest.registered_items[oldnode.name].drop or oldnode.name
173 | for _, stack in pairs(drops) do
174 | if stack:get_name() == item_name then
175 | stack:get_meta():set_string("laptop_metadata", minetest.serialize(save))
176 | if have_technic or have_generator then
177 | local hwdef = laptop.node_config[oldnode.name]
178 | if hwdef.battery_capacity then
179 | stack:set_metadata(minetest.serialize({charge=tonumber(oldmetadata.battery or "0")}))
180 | -- calculate wear manually for support power_generators without technic
181 | local wear = 65534*(oldmetadata.battery or 0)/hwdef.battery_capacity
182 | if wear<1 then
183 | wear = 1
184 | end
185 | if wear>65534 then
186 | wear = 65534
187 | end
188 | stack:set_wear(65534-wear)
189 | end
190 | end
191 | end
192 | end
193 | end
194 |
195 | local function laptop_run(pos, node, mtos)
196 | local meta = minetest.get_meta(pos)
197 | local hwdef = mtos.hwdef
198 | local demand = hwdef.eu_demand or 0
199 | -- support both technic and power_generators, demand should be always same, supply should be active only one
200 | local supply = meta:get_int("LV_EU_input") + meta:get_int("generator_input")
201 |
202 | if have_generator and (supply>0) then
203 | meta:set_int("generator_input", 0)
204 | end
205 |
206 | -- powered off, nothing to do
207 | if (demand==0) then
208 | return
209 | end
210 |
211 | if (supply0) then
212 | local power_off = true
213 |
214 | if hwdef.battery_capacity then
215 | local battery = meta:get_int("battery")
216 | if (battery>(demand-supply)) then
217 | meta:set_int("battery", battery - (demand - supply))
218 | power_off = false
219 | else
220 | meta:set_int("battery", 0)
221 | end
222 | end
223 |
224 | if power_off then
225 | local hwdef = laptop.node_config[node.name]
226 | if hwdef.power_off_node then
227 | local hwdef_next = laptop.node_config[hwdef.power_off_node]
228 | if hwdef_next.hw_state then
229 | mtos[hwdef_next.hw_state](mtos, hwdef.power_off_node)
230 | else
231 | mtos:power_off(hwdef.power_off_node)
232 | mtos:save()
233 | end
234 | end
235 | end
236 | elseif (demand>0) then
237 | local hwdef = laptop.node_config[node.name]
238 | if hwdef.battery_capacity then
239 | local battery = meta:get_int("battery")
240 | battery = battery+(hwdef.battery_charge or 400)
241 | battery = math.min(battery, hwdef.battery_capacity)
242 | meta:set_int("battery", battery)
243 | end
244 | end
245 |
246 | end
247 |
248 | local function technic_run(pos, node)
249 | local mtos = laptop.os_get(pos)
250 | if not mtos then
251 | return
252 | end
253 |
254 | laptop_run(pos, node, mtos)
255 | end
256 |
257 | local function technic_on_disable(pos, node)
258 | local mtos = laptop.os_get(pos)
259 | -- fix infotext for technic mod enable
260 | mtos:set_infotext(mtos.hwdef.infotext)
261 |
262 | laptop_run(pos, node, mtos)
263 | end
264 |
265 | local tubelib2_side = {
266 | right = "R",
267 | left = "L",
268 | front = "F",
269 | back = "B",
270 | top = "U",
271 | bottom = "D",
272 | }
273 |
274 | function laptop.register_hardware(name, hwdef)
275 | local default_nodename = name.."_"..hwdef.sequence[1]
276 | for idx, variant in ipairs(hwdef.sequence) do
277 | local nodename = name.."_"..variant
278 | local def = table.copy(hwdef.node_defs[variant])
279 | def.description = hwdef.description
280 |
281 | -- drop the item visible in inventory
282 | if def.groups then
283 | def.groups = table.copy(def.groups)
284 | else
285 | def.groups = {choppy=2, oddly_breakably_by_hand=2, dig_immediate = 2, laptop = 1}
286 | end
287 | if have_technic then
288 | def.groups.technic_machine = 1
289 | def.groups.technic_lv = 1
290 | end
291 | if have_generator then
292 | if def._eu_demand then
293 | def.groups.laptop_generator_powered = 1
294 | end
295 | end
296 | if def.connect_sides then
297 | def.connect_sides = table.copy(def.connect_sides)
298 | else
299 | def.connect_sides = {"back"}
300 | end
301 | def._generator_connect_sides = def.connect_sides
302 | def._generator_powered_valid_sides = {}
303 | for _,side in pairs(def.connect_sides) do
304 | def._generator_powered_valid_sides[tubelib2_side[side]] = true
305 | end
306 | if nodename ~= default_nodename then
307 | def.drop = default_nodename
308 | def.groups.not_in_creative_inventory = 1
309 | end
310 | if def.paramtype2 == "colorfacedir" and not def.palette then
311 | def.palette = "unifieddyes_palette_redviolets.png" --TODO: Replace by own laptop specific PNG file
312 | end
313 |
314 | -- needed to transfer content to item if place or dig laptop
315 | def.stack_max = 1
316 | def.after_place_node = after_place_node
317 | def.preserve_metadata = preserve_metadata
318 | def.on_punch = on_punch
319 | def.on_construct = on_construct
320 | def.on_receive_fields = on_receive_fields
321 | def.allow_metadata_inventory_move = allow_metadata_inventory_move
322 | def.allow_metadata_inventory_put = allow_metadata_inventory_put
323 | def.allow_metadata_inventory_take = allow_metadata_inventory_take
324 | def.on_metadata_inventory_move = on_metadata_inventory_move
325 | def.on_metadata_inventory_put = on_metadata_inventory_put
326 | def.on_metadata_inventory_take = on_metadata_inventory_take
327 | def.on_timer = on_timer
328 | def.technic_run = technic_run
329 | def.technic_on_disable = technic_on_disable
330 | if have_technic or have_generator then
331 | if hwdef.battery_capacity then
332 | def.groups.not_in_creative_inventory = 1
333 | def.drop = name.."_item"
334 | end
335 | end
336 | minetest.register_node(nodename, def)
337 |
338 | if have_technic then
339 | technic.register_machine("LV", nodename, technic.receiver)
340 | end
341 | if have_generator then
342 | local cable = power_generators.electric_cable
343 | local sides = {}
344 | for _,side in pairs(def._generator_connect_sides) do
345 | table.insert(sides, tubelib2_side[side])
346 | end
347 | cable:add_secondary_node_names({nodename})
348 | cable:set_valid_sides(nodename, sides)
349 | end
350 |
351 | -- set node configuration for hooks
352 | local merged_hwdef = table.copy(hwdef)
353 | merged_hwdef.name = name
354 | merged_hwdef.nodename = nodename
355 | for k,v in pairs(hwdef.node_defs[variant]) do
356 | merged_hwdef[k] = v
357 | end
358 | local next_seq = hwdef.sequence[idx+1] or hwdef.sequence[1]
359 | local next_node = name.."_"..next_seq
360 | if next_node ~= nodename then
361 | merged_hwdef.next_node = next_node
362 | end
363 |
364 | -- power off node
365 | if def._power_off_seq then
366 | local power_off_node = name.."_"..def._power_off_seq
367 | if power_off_node ~= nodename then
368 | merged_hwdef.power_off_node = power_off_node
369 | end
370 | end
371 | -- battery charge
372 | if def._battery_charge then
373 | merged_hwdef.battery_charge = def._battery_charge
374 | end
375 | -- eu demand
376 | if def._eu_demand then
377 | merged_hwdef.eu_demand = def._eu_demand
378 | end
379 |
380 | -- Defaults
381 | merged_hwdef.hw_capabilities = merged_hwdef.hw_capabilities or {"hdd", "floppy", "usb", "net", "liveboot"}
382 | laptop.node_config[nodename] = merged_hwdef
383 | end
384 |
385 | if hwdef.battery_capacity then
386 | if have_technic or have_generator then
387 | local on_refill = nil
388 | if have_technic then
389 | technic.register_power_tool(name.."_item", hwdef.battery_capacity)
390 | on_refill = technic.refill_RE_charge
391 | end
392 |
393 | minetest.register_tool(name.."_item", {
394 | description = hwdef.description,
395 | inventory_image = hwdef.inventory_image,
396 | stack_max = 1,
397 | wear_represents = "technic_RE_charge",
398 | on_refill = on_refill,
399 | on_place = function(itemstack, placer, pointed_thing)
400 | itemstack:set_name(default_nodename)
401 | minetest.item_place_node(itemstack, placer, pointed_thing)
402 | itemstack:clear()
403 | return itemstack
404 | end,
405 |
406 | })
407 | else
408 | minetest.register_alias(name.."_item", default_nodename)
409 | end
410 | end
411 | end
412 |
413 | if have_generator and (not have_technic) then
414 | minetest.register_abm({
415 | label = "Update running laptops power.",
416 | nodenames = {"group:laptop_generator_powered"},
417 | interval = 1,
418 | chance = 1,
419 | action = function(pos, node)
420 | local def = minetest.registered_nodes[node.name]
421 | def.technic_run(pos, node)
422 | end,
423 | })
424 | end
425 |
426 |
--------------------------------------------------------------------------------