From be872d0536d4f8422a0987410fd2f4aafb9d034c Mon Sep 17 00:00:00 2001 From: cuu Date: Thu, 17 Jan 2019 00:56:40 +0800 Subject: [PATCH] Comm software package alpha --- .gitignore | 2 +- Menu/GameShell/50_PICO-8/PICO-8.sh | 5 + Menu/GameShell/50_PICO-8/Post-Up.sh | 8 + Menu/GameShell/50_PICO-8/__init__.py | 136 ------- Menu/GameShell/50_PICO-8/compkginfo.json | 9 + Menu/GameShell/50_PICO-8/md5sum.log | 2 - Menu/GameShell/50_PICO-8/pico-8/config.txt | 99 +++++ Menu/GameShell/50_PICO-8/pico-8/log.txt | 90 +++++ .../50_PICO-8/pico-8/sdl_controllers.txt | 1 + skin/default/Menu/GameShell/PICO-8.png | Bin 1174 -> 1987 bytes .../sys.py/gameshell/icons/pico8_md5_err.png | Bin 0 -> 3685 bytes .../sys.py/gameshell/icons/pico8_notfound.png | Bin 0 -> 3732 bytes .../UI/CommercialSoftwarePackage/__init__.py | 342 ++++++++++++++++++ sys.py/UI/constants.py | 2 +- sys.py/UI/icon_item.py | 19 + sys.py/UI/icon_pool.py | 22 +- sys.py/UI/lang_manager.py | 5 +- sys.py/UI/main_screen.py | 37 +- sys.py/UI/page.py | 4 +- sys.py/UI/text_bulletinboard.py | 27 +- 20 files changed, 650 insertions(+), 160 deletions(-) create mode 100755 Menu/GameShell/50_PICO-8/PICO-8.sh create mode 100755 Menu/GameShell/50_PICO-8/Post-Up.sh delete mode 100644 Menu/GameShell/50_PICO-8/__init__.py create mode 100644 Menu/GameShell/50_PICO-8/compkginfo.json delete mode 100644 Menu/GameShell/50_PICO-8/md5sum.log create mode 100644 Menu/GameShell/50_PICO-8/pico-8/config.txt create mode 100644 Menu/GameShell/50_PICO-8/pico-8/log.txt create mode 100644 Menu/GameShell/50_PICO-8/pico-8/sdl_controllers.txt create mode 100644 skin/default/sys.py/gameshell/icons/pico8_md5_err.png create mode 100644 skin/default/sys.py/gameshell/icons/pico8_notfound.png create mode 100644 sys.py/UI/CommercialSoftwarePackage/__init__.py diff --git a/.gitignore b/.gitignore index 3e20d37..e812c3b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ sys.py/.lang !**/Jobs/.gitkeep !**/Jobs/00_lowpower.sh !**/Jobs/00_lowpower.alias - +.done diff --git a/Menu/GameShell/50_PICO-8/PICO-8.sh b/Menu/GameShell/50_PICO-8/PICO-8.sh new file mode 100755 index 0000000..cfbba82 --- /dev/null +++ b/Menu/GameShell/50_PICO-8/PICO-8.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +#SDL_VIDEODRIVER=x11 DISPLAY=:0 ./pico-8/pico8_dyn -splore -draw_rect 32,0,256,240 +cd /home/cpi/games/PICO-8/pico-8 +SDL_VIDEODRIVER=x11 DISPLAY=:0 ./pico8_dyn -draw_rect 32,0,256,240 diff --git a/Menu/GameShell/50_PICO-8/Post-Up.sh b/Menu/GameShell/50_PICO-8/Post-Up.sh new file mode 100755 index 0000000..f2062a3 --- /dev/null +++ b/Menu/GameShell/50_PICO-8/Post-Up.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +mkdir ~/.lexaloffle + +cp -rf pico-8 ~/.lexaloffle + +touch .done + diff --git a/Menu/GameShell/50_PICO-8/__init__.py b/Menu/GameShell/50_PICO-8/__init__.py deleted file mode 100644 index 5c0b610..0000000 --- a/Menu/GameShell/50_PICO-8/__init__.py +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -import pygame -import validators - -from UI.constants import Width,Height,ICON_TYPES,RUNEVT -#from UI.simple_name_space import SimpleNamespace -from UI.page import Page -from UI.label import Label -from UI.fonts import fonts -from UI.icon_item import IconItem -from UI.icon_pool import MyIconPool -from UI.keys_def import CurKeys -from UI.skin_manager import MySkinManager -from UI.lang_manager import MyLangManager -from UI.text_bulletinboard import Textbulletinboard,Text -from UI.util_funcs import FileExists - - -class NOPICOPage(Page): - _FootMsg = ["Nav","","","Back",""] - - def Init(self): - self._PosX = self._Index*self._Screen._Width - self._Width = self._Screen._Width - self._Height = self._Screen._Height - - self._CanvasHWND = self._Screen._CanvasHWND - - self._Board = Textbulletinboard() - - self._Board._PosX = 4 - self._Board._PosY = 20 - self._Board._Width= self._Width - 4*2 - self._Board._Height = 100 - self._Board._CanvasHWND = self._CanvasHWND - self._Board.Init() - - a = Text("Please Go to \n",None,MyLangManager.TrFont("varela14"),True) - b = Text("https://www.lexaloffle.com/pico-8.php",MySkinManager.GiveColor("URL"),None,True,True) - c = Text("buy a pico-8 raspi and put zip into \n/home/cpi/games/PICO-8") - - d = a.Words()+b.Words()+c.Words() - self._Board.SetAndBlitText(d) - - def KeyDown(self,event): - if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]: - self.ReturnToUpLevelPage() - self._Screen.Draw() - self._Screen.SwapAndShow() - return - - def Draw(self): - self.ClearCanvas() - self._Board.Draw() - - -class PICO8ZipHashErrPage(Page): - _FootMsg = ["Nav","","","Cancel","Continue"] - - def Init(self): - self._PosX = self._Index*self._Screen._Width - self._Width = self._Screen._Width - self._Height = self._Screen._Height - - self._CanvasHWND = self._Screen._CanvasHWND - - self._Board = Textbulletinboard() - - self._Board._PosX = 4 - self._Board._PosY = self._Height/2 - 35 - self._Board._Width= self._Width - 4*2 - self._Board._Height = 100 - self._Board._CanvasHWND = self._CanvasHWND - self._Board._Align = "Center" - self._Board.Init() - - a = Text("Md5sum check error\n",None,MyLangManager.TrFont("varela24")) - b = Text("continue anyway?\n",None,MyLangManager.TrFont("varela24")) - - self._Board.SetAndBlitText(a.Words()+b.Words()) - - def KeyDown(self,event): - if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]: - self.ReturnToUpLevelPage() - self._Screen.Draw() - self._Screen.SwapAndShow() - return - - def Draw(self): - self.ClearCanvas() - self._Board.Draw() - - -class APIOBJ(object): - - _Page = None - _pico8 ="/home/cpi/games/PICO-8/pico-8" - - def __init__(self): - pass - - def CheckPico8(self): - if FileExists(self._pico8): - return True - - def Init(self,main_screen): - self._NOPicoPage = NOPICOPage() - self._NOPicoPage._Name = "Not Found" - self._NOPicoPage._Screen = main_screen - self._NOPicoPage.Init() - - self._HashErrPage = PICO8ZipHashErrPage() - self._HashErrPage._Name = "Md5sum check failed" - self._HashErrPage._Screen = main_screen - self._HashErrPage.Init() - - def API(self,main_screen): - if main_screen !=None: - if self.CheckPico8() == False: - main_screen._MsgBox.SetText("Starting pico-8") - main_screen._MsgBox.Draw() - main_screen.SwapAndShow() - pygame.time.delay(300) - cmdpath = "/home/cpi/games/PICO-8/PICO-8.sh" - pygame.event.post( pygame.event.Event(RUNEVT, message=cmdpath)) - else: - main_screen.PushPage(self._NOPicoPage) - #main_screen.PushPage(self._HashErrPage) - main_screen.Draw() - main_screen.SwapAndShow() - -OBJ = APIOBJ() -def Init(main_screen): - OBJ.Init(main_screen) -def API(main_screen): - OBJ.API(main_screen) diff --git a/Menu/GameShell/50_PICO-8/compkginfo.json b/Menu/GameShell/50_PICO-8/compkginfo.json new file mode 100644 index 0000000..77a86cc --- /dev/null +++ b/Menu/GameShell/50_PICO-8/compkginfo.json @@ -0,0 +1,9 @@ +{ +"GameDir":"/home/cpi/games/PICO-8/", +"InstallDir":"pico-8", +"NotFoundMsg":["Please purchase the PICO-8 \n|None|varela16", +"and copy it to the \"Games\" folder|None|varela16"], + +"MD5":{"pico-8_0.1.11g_raspi.zip":"a3f2995cf117499f880bd964d6a0e1f2","pico-8_0.1.11g_amd64.zip":"6726141c784afd4a41be6b7414c1b932"}, +"Post-Up":"bash Post-Up.sh" +} diff --git a/Menu/GameShell/50_PICO-8/md5sum.log b/Menu/GameShell/50_PICO-8/md5sum.log deleted file mode 100644 index f66e2de..0000000 --- a/Menu/GameShell/50_PICO-8/md5sum.log +++ /dev/null @@ -1,2 +0,0 @@ -a3f2995cf117499f880bd964d6a0e1f2 pico-8_0.1.11g_raspi.zip -6726141c784afd4a41be6b7414c1b932 pico-8_0.1.11g_amd64.zip diff --git a/Menu/GameShell/50_PICO-8/pico-8/config.txt b/Menu/GameShell/50_PICO-8/pico-8/config.txt new file mode 100644 index 0000000..15ea6fc --- /dev/null +++ b/Menu/GameShell/50_PICO-8/pico-8/config.txt @@ -0,0 +1,99 @@ +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Configuration for pico-8 +// +// config.txt is read on startup and saved on exit. +// To generate the default config.txt, delete this file. +// +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// :: Video Settings + +window_size 0 0 // window width, height +screen_size 0 0 // screen width, height (stretched to window) +show_fps 0 // Draw frames per second in the corner + + +// :: Window Settings + +windowed 0 // 1 to start up in windowed mode +window_position -1 -1 // x and y position of window, or -1, -1 to let the window manager decide +frameless 0 // 1 to use a window with no frame +fullscreen_method 1 // 0 maximized window (linux) 1 borderless desktop-sized window 2 fullscreen + + +// :: System Settings + +foreground_sleep_ms 1 // number of milliseconds to sleep each frame. Try 10 to conserve battery power + +background_sleep_ms 20 // number of milliseconds to sleep each frame when running in the background + +sessions 4 // number of times program has been run + +// (scancode) hold this key down and left-click to simulate right-click +rmb_key 0 // 0 for none 226 for LALT + +// 0:off 1: ignore SDL_TEXTINPUT and use SDL_GetKeyboardState instead (mapped to a US layout) +emulate_textinput 1 + +// Desktop for saving screenshots etc. Defaults to $HOME/Desktop +desktop_path + + + +// :: Audio Settings + +sound_volume 256 // 0..256 +music_volume 256 // 0..256 +mix_buffer_size 1024 // usually 1024. Try 2048 if you get choppy sound + + +// :: + +version 0.1.11g + + +// Location of pico-8's root folder +root_path /home/cpi/.lexaloffle/pico-8/carts/ + + +// Location of cartridge save data +cdata_path /home/cpi/.lexaloffle/pico-8/cdata/ + + +// Specify which player index joystick control begins at (0..7) +joystick_index 0 + + +// Custom keyboard scancodes for buttons. player0 0..6, player1 0..5 +button_keys 0 0 0 0 13 14 0 0 0 0 0 0 0 + +// Play notes as they are plotted in frequency mode +live_notes 0 + +// iff 1: when using keyboard cursor, snap to closest pixel / map cel +cursor_snap 0 + +// maximum length of gif in seconds (1..120, default 8) +gif_len 8 + +// 0 classic 1 dark blue background in code editor +gui_theme 0 + +// scale of screenshots and gifs // 2 means 256x256 +screenshot_scale 3 +gif_scale 2 + +// when 1 can enter glyphs using shift-A..Z +shift_glyphs 1 + +// 0 for off. 1 to notify whenever unsaved changes are backed up +show_backup_messages 1 + +// 0 for off. 1 to allow control of a cart's framerate due to host machine's cpu capacity (recommended) +host_framerate_control 1 + +// filter splore content +// 0 for no filter (18+) 1 medium (13+) 2 maximum (kid-friendly) +content_filter 1 + diff --git a/Menu/GameShell/50_PICO-8/pico-8/log.txt b/Menu/GameShell/50_PICO-8/pico-8/log.txt new file mode 100644 index 0000000..3f783a2 --- /dev/null +++ b/Menu/GameShell/50_PICO-8/pico-8/log.txt @@ -0,0 +1,90 @@ +codo_init + platform: Linux + Found config.txt + + 01 window_size 0 0 // window width, height + 02 screen_size 0 0 // screen width, height (stretched to window) + 03 show_fps 0 // Draw frames per second in the corner + 04 windowed 0 // 1 to start up in windowed mode + 05 window_position -1 -1 // x and y position of window, or -1, -1 to let the window manager decide + new window position: -1, -1 + 06 frameless 0 // 1 to use a window with no frame + 07 fullscreen_method 1 // 0 maximized window (linux) 1 borderless desktop-sized window 2 fullscreen + 08 foreground_sleep_ms 1 // number of milliseconds to sleep each frame. Try 10 to conserve battery power + 09 background_sleep_ms 20 // number of milliseconds to sleep each frame when running in the background + 10 sessions 3 // number of times program has been run + 11 rmb_key 0 // 0 for none 226 for LALT + 12 emulate_textinput 1 + 13 desktop_path + 14 sound_volume 256 // 0..256 + 15 music_volume 256 // 0..256 + 16 mix_buffer_size 1024 // usually 1024. Try 2048 if you get choppy sound + 17 version 0.1.11g + 18 root_path /home/cpi/.lexaloffle/pico-8/carts/ + 19 cdata_path /home/cpi/.lexaloffle/pico-8/cdata/ + 20 joystick_index 0 + 21 button_keys 0 0 0 0 0 0 0 0 0 0 0 0 0 + 22 live_notes 0 + 23 cursor_snap 0 + 24 gif_len 8 + 25 gui_theme 0 + 26 screenshot_scale 3 + 27 gif_scale 2 + 28 shift_glyphs 1 + 29 show_backup_messages 1 + 30 host_framerate_control 1 + 31 content_filter 1 + + codo_system_init + Compiled against SDL version: 2.0.7 + Linked against SDL version: 2.0.5 + Built-in video drivers: 0 x11 1 wayland 2 dummy + Current video driver: x11 + Built-in render drivers: + Renderer opengl: + Flags: 0x0000000E ( | | ) + Texture formats (1): ARGB8888 + Renderer opengles2: + Flags: 0x0000000E ( | | ) + Texture formats (4): ARGB8888, ABGR8888, RGB888, BGR888 + Renderer software: + Flags: 0x00000009 ( | ) + Texture formats (8): ARGB8888, ABGR8888, RGBA8888, BGRA8888, RGB888, BGR888, RGB565, RGB555 + codo_reset_timer + codo_gui_init + codo_keys_init + codo_text_init + codo_video_init + codo_mouse_init + codo_joystick_init + Reading controller mappings: /home/cpi/.lexaloffle/pico-8/sdl_controllers.txt + searching for joysticks + found 0 joysticks + ok +ok +codo_load_pod: /home/cpi/apps/Menu/50_PICO-8/pico8.dat ok +codo_set_screen 128 128 8 100 + set pixel_perfect 1 + window size: 640 480 +codo_plat_pi: forcing fullscreen mode +Current renderer: + Renderer opengl: + Flags: 0x0000000A ( | ) + Texture formats (5): ARGB8888, YV12, IYUV, 0x3231564e, 0x3132564e + Max Texture Size: 8192x8192 +codo_sound_init mix_buffer_size: 1024 +codo_sound_init +SDL_INIT_AUDIO ok +SDL_OpenAudio ok +Built-in audio drivers: 0 pulseaudio 1 alsa 2 sndio 3 dsp 4 disk 5 dummy +Current audio driver: alsa +codo_exit + cmusic_stop + codo_main_exit + codo_config_save + codo_sound_exit + codo_video_exit + codo_joystick_exit + codo_system_exit + codo_items_created: 1023 +ok diff --git a/Menu/GameShell/50_PICO-8/pico-8/sdl_controllers.txt b/Menu/GameShell/50_PICO-8/pico-8/sdl_controllers.txt new file mode 100644 index 0000000..d6719d7 --- /dev/null +++ b/Menu/GameShell/50_PICO-8/pico-8/sdl_controllers.txt @@ -0,0 +1 @@ +// add SDL2 game controller mappings to this file diff --git a/skin/default/Menu/GameShell/PICO-8.png b/skin/default/Menu/GameShell/PICO-8.png index 65ef00b91645bc43078a63fb9ba39d6ab5242aaf..26b80d255daf060668f51984df0b78eec987a28b 100644 GIT binary patch delta 1984 zcmV;x2S50h3BwPN8Gi%-001NyIwk-B00Lr5M??VshmXv^00009a7bBm000XU000XU z0RWnu7ytkO2XskIMF-;n5C<_Aal9#0000M6Nkl=aVhxC2FgV;Ih1zLN|Ih@n_JazxGLC5xY=5U%5{!Q+j2(s)oTJo; zr8GuBW;QehqAm1emB~OD96~yAU?chNANOYS_1*_-~H{m@1Aq+xhDxs zN>mmLn8%lyLpGUs@d5z?v~!6T{=>(dl(xx?kT5~8RF-l-rF>}|5C4}24slq%hzp>y zD5Z?$q(|8C8h>@{qCxs&2&lZ2@gr^*X6JpC!Z zXO{$G0H{(a=NYC4Z}jjXhxmYI=?&4#Lm~HYKX;K7ym^^z)Qoq+#|fxb@mppEFHf?E zy>dAM-A`u?-(x}W#(6f#{wM*eTxxj8T=a8*U(2ZpE`P1t`2`PSnahKe%Y{h;s_#%k z1^@%>qf*X}e&TW8zl-hr7Bs$6GUk1A+01G)ZU^P^$I#<@Lc%4poeFbtmI^s)_f#K! z4*l&Gto(~L>Q#190Ax_B7V%^0a%QkX;AQf@!RulZh4y$85jo0yHleY~saKg3093Q_ zu@C@1#ecF@dWfP(k8Gs`KL88ysW}k>s(g--55T(=Ni#7JIZY7<0m$d5%8vk0&8EQ^ zm7P2+9mGhagB9!qU=|JbTC{8ffO>KOsFWwAj~I&d$&>sFfE@m+vc>_Zl6jjv0Jh3z z;vn)ITLH-9PbxXQ27kvl0eFLFiI+Uf9{?y}dw&=}wVHKiY5Y(I;=!hpK?W!@%cVlC z4gsigsWFD-(b#@_!zQ>}e~WzA7@b#DuCoSfxEbi?5&4`ri+s)_bORYiNn-)kDiacH zj*Z<5i`a}_ln<#@Ho=0riL=}SoZ=gH5#FJ{b!FSX_@<`H_4X}0s#5Q82mvnT7uiOS zCx5sdXko5g9~~^L=N4dq$L#~quI%m{`+#72#F0hS|ZrgE#ylfob;vqn-&PF-y20l5>34Z{}44_J5IRLwGi@XlNa+RhvxRi9Dhqqh< z_!d2Ym!*S%0LP`>Eqv0>hXCBC0T%=C9&VC9o5hQzvP_2Rh^qiKO}@(Vm~=#dumM7U zJOP{OBn?>LVIBZyv3XAmOG=evR-nr3(9+YnQ#tK;%LSxY{gWb~(0^kl z_>6AsE_NDhMo#v{NY#*gjAQmKRWm)U_AQBn5!M-sfIN#^0XP@$k1XtdLKEF)p`*N3 z+$MUyW?1OF$TimiUIif2GAY`tt^?F6^ICXat-&-4my3nYxTm|0YzhFK7M;T`-6UFN z0gHB5Yw&*-p8=5LI>4C#T(bBSz<>CYI7-;#1>@m7CS_Bg?Od8b4Vv8RejyT z<35@`t-!t|kT~Vr_68(4i0;xAY4|mFvHZ#fJa@7*iG=8~k0e|lU@Sv*z z9{`|1Z<_uBz`{`HJ@FNl$z1>((tw8v07m+s1ajugK|Fi_dDc4+*jx zRc=HI{E5jF{cP}*WW-66ylD>fUQmURZEKtYiO6wWeMZfK>@#PL%Xm#C#0@Wj*I5QY z&FDfO%f^oD9N`bx5;p~I;rjsi#`>}`fYQwh4srbgmCrP5+=#O#f)pS#Uo zWf@J8*~JLLswT5E{M;>mCoAjZA6mGR3y1x}<_NbeNs~5ml?^PJbG1uBzpT$s2UAMk+#8 z500-ybQU$iO=&-Gvt<$`qMKM5RLXli5rq;_^Xk>S6y+k@pUb|eB$KL>omAipuF=kCoWsvYG=;Kq;pP7VYb99C SuLbD<0000FfWVf*)fgM*UJ z1P*SMLrk5NF?F1+<{ta-!C=|4Wp-;*8(sE&+`swX!zWKzy1Tn8YHN?4J3Jgb*43`9HR_XzLviM?0h*oQaPT1F$IyD(S<;f=%X8JHO^tdVW zurUjDvOM}&akMaNt5n%;Ss<9dE--At>8DzqvV80=fk!T042*0{+bju0+S=NxOuTH& zbNrUeynpvjNvQM0$0J8ra?EBY?K^z<@T5LTNy&qE?#R^G-Jj0V=Cp8F`j5J$we{hvSEtH+|N3>|{{8WR)BToj+`hfN z#42|C)@-32d-lX^XRT+Cj*eEH`>epiz}$TK3U0RM)b)EsvV?Bjzu*7tS=!N$=gytm zmG>!{VDXB@xYr~?q`K`X{wD{tKfB)pRZ{J=Txm&GKZ#wrPjccg~?;m{gMkg&j z-G1%tnKLJ@Zv^@YD6hwV>1K}D(Imm2HT#}aY>a3DCdb@d*Yfi6n}zoOE5unCV`F2x zcGcMNdrq2gHjR-XH#aw6_0<V1n{)f^wB*@m+kgqzb?*K5?f2hLfBf;|$4#GW+m1hOJpTCSryW@zxI>lx s7&UT~D+r2tw6F>#Ho8PmllhNnhC}gfrS2cO!19K{)78&qol`;+0PQdoZU6uP diff --git a/skin/default/sys.py/gameshell/icons/pico8_md5_err.png b/skin/default/sys.py/gameshell/icons/pico8_md5_err.png new file mode 100644 index 0000000000000000000000000000000000000000..8b281a1984c6387aecc9759af93400bb3aae70ad GIT binary patch literal 3685 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 EF9^{^`v3p{ literal 0 HcmV?d00001 diff --git a/sys.py/UI/CommercialSoftwarePackage/__init__.py b/sys.py/UI/CommercialSoftwarePackage/__init__.py new file mode 100644 index 0000000..ba5b066 --- /dev/null +++ b/sys.py/UI/CommercialSoftwarePackage/__init__.py @@ -0,0 +1,342 @@ +# -*- coding: utf-8 -*- + +""" +Package /home/cpi/games/xxx/yyy.zip ,only support in zip + +com_pkg_info /home/cpi/launcher/Menu/GameShell/xxxx/compkginfo.json +use https://jsonlint.com/ to validate first in case syntax err + +``` +{ +"NotFoundMsg":["Please Go to \n|None|varela14|True", +"https://www.lexaloffle.com/pico-8.php|URL|None|True|True", +"buy a pico-8 raspi and put zip into \n/home/cpi/games/PICO-8"] + +"MD5":{"pico-8_0.1.11g_raspi.zip":"a3f2995cf117499f880bd964d6a0e1f2","pico-8_0.1.11g_amd64.zip":"6726141c784afd4a41be6b7414c1b932"} +} + +``` + +""" + +import pygame +#import validators +import os +import commands +from UI.constants import Width,Height,ICON_TYPES,RUNEVT,RESTARTUI +#from UI.simple_name_space import SimpleNamespace +from UI.page import Page +from UI.label import Label +from UI.fonts import fonts +from UI.icon_item import IconItem +from UI.icon_pool import MyIconPool +from UI.keys_def import CurKeys +from UI.skin_manager import MySkinManager +from UI.lang_manager import MyLangManager +from UI.text_bulletinboard import Textbulletinboard,Text +from UI.util_funcs import FileExists + + +class NotFoundPage(Page): + _FootMsg = ["Nav","","","Back",""] + _BG = "pico8_notfound" + _Leader = None + _Padding = pygame.Rect(0,20,0,0) + def Init(self): + self._PosX = self._Index*self._Screen._Width + self._Width = self._Screen._Width + self._Height = self._Screen._Height + + self._CanvasHWND = self._Screen._CanvasHWND + + self._BGpng = IconItem() + self._BGpng._ImgSurf = MyIconPool._Icons[self._BG] + self._BGpng._MyType = ICON_TYPES["STAT"] + self._BGpng._Parent = self + #print( MyIconPool.Width(self._BG),MyIconPool.Height(self._BG) ) + self._BGpng.Adjust(0,0,MyIconPool.Width(self._BG),MyIconPool.Height(self._BG),0) + + self._Board = Textbulletinboard() + + self._Board._PosX = 4 + self._Board._PosY = 100 + self._Board._Width= self._Width - 4*2 + self._Board._Height = 100 + self._Board._CanvasHWND = self._CanvasHWND + self._Board._Align = "Center" + self._Board._RowPitch =30 + self._Board.Init() + + if self._Leader!= None and self._Leader._ComPkgInfo != None: + if "NotFoundMsg" in self._Leader._ComPkgInfo: + d = [] + for i, v in enumerate(self._Leader._ComPkgInfo["NotFoundMsg"]): + Color = None + Font = None + Bold = False + Und = False + Txt = "" + parts = v.split("|") + if len(parts) > 0: + Txt = parts[0] + + if len(parts) == 2: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + elif len(parts) == 3: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + if parts[2] != "None": + Font = MyLangManager.TrFont(parts[2]) + elif len(parts) == 4: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + if parts[2] != "None": + Font = MyLangManager.TrFont(parts[2]) + if parts[3] == "True": + Bold = True + elif len(parts) == 5: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + if parts[2] != "None": + Font = MyLangManager.TrFont(parts[2]) + if parts[3] == "True": + Bold = True + if parts[4] == "True": + Und = True + + a = Text(Txt,Color,Font,Bold,Und) + d = d + a.Words() + + self._Board.SetAndBlitText(d) + + def KeyDown(self,event): + if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]: + self.ReturnToUpLevelPage() + self._Screen.Draw() + self._Screen.SwapAndShow() + return + + def Draw(self): + self.ClearCanvas() + if self._BGpng != None: + self._BGpng.NewCoord((self._Width-self._BGpng._Width)/2,self._Padding.y ) + self._BGpng.DrawTopLeft() + self._Board._PosY = self._BGpng._Height+self._Padding.y + else: + self._Board._PosY = self._Padding.y + + self._Board.Draw() + + +class HashErrPage(Page): + _FootMsg = ["Nav","","","Cancel","Continue"] + _BG ="pico8_md5_err" + + _Leader = None + _Padding = pygame.Rect(0,20,0,0) + + def Init(self): + self._PosX = self._Index*self._Screen._Width + self._Width = self._Screen._Width + self._Height = self._Screen._Height + + self._CanvasHWND = self._Screen._CanvasHWND + + self._BGpng = IconItem() + self._BGpng._ImgSurf = MyIconPool._Icons[self._BG] + self._BGpng._MyType = ICON_TYPES["STAT"] + self._BGpng._Parent = self + self._BGpng.Adjust(0,0,MyIconPool.Width(self._BG),MyIconPool.Height(self._BG),0) + + self._Board = Textbulletinboard() + + self._Board._PosX = 4 + self._Board._PosY = self._Height/2 - 35 + self._Board._Width= self._Width - 4*2 + self._Board._Height = 100 + self._Board._CanvasHWND = self._CanvasHWND + self._Board._RowPitch =30 + self._Board._Align = "Center" + self._Board.Init() + + if self._Leader!= None and self._Leader._ComPkgInfo != None: + if "HashErrMsg" in self._Leader._ComPkgInfo: + d = [] + for i, v in enumerate(self._Leader._ComPkgInfo["HashErrMsg"]): + Color = None + Font = None + Bold = False + Und = False + Txt = "" + parts = v.split("|") + if len(parts) > 0: + Txt = parts[0] + + if len(parts) == 2: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + elif len(parts) == 3: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + if parts[2] != "None": + Font = MyLangManager.TrFont(parts[2]) + elif len(parts) == 4: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + if parts[2] != "None": + Font = MyLangManager.TrFont(parts[2]) + if parts[3] == "True": + Bold = True + elif len(parts) == 5: + if parts[1] != "None": + Color = MySkinManager.GiveColor(parts[1]) + if parts[2] != "None": + Font = MyLangManager.TrFont(parts[2]) + if parts[3] == "True": + Bold = True + if parts[4] == "True": + Und = True + + a = Text(Txt,Color,Font,Bold,Und) + d = d + a.Words() + + self._Board.SetAndBlitText(d) + + else: + a = Text("MD5 check Failed!\n",None,MyLangManager.TrFont("varela16")) + b = Text("Do you want to continue?",None,MyLangManager.TrFont("varela16")) + self._Board.SetAndBlitText(a.Words()+b.Words()) + + def KeyDown(self,event): + if event.key == CurKeys["A"] or event.key == CurKeys["Menu"]: + self.ReturnToUpLevelPage() + self._Screen.Draw() + self._Screen.SwapAndShow() + return + + if event.key == CurKeys["B"]: + self._Leader.InstallPackage(self._Screen) + return + + def OnLoadCb(self): + pass + + def Draw(self): + self.ClearCanvas() + if self._BGpng != None: + self._BGpng.NewCoord((self._Width-self._BGpng._Width)/2,self._Padding.y) + self._BGpng.DrawTopLeft() + self._Board._PosY = self._BGpng._Height+self._Padding.y + else: + self._Board._PosY = self._Padding.y + + self._Board.Draw() + + +class MyCommercialSoftwarePackage(object): + _ComPkgInfo = None + _Done = "" + _InvokeDir = "" + + def __init__(self): + pass + + def InstallPackage(self,main_screen): + main_screen._MsgBox.SetText("Installing the package") + main_screen._MsgBox.Draw() + main_screen.SwapAndShow() + json_config = self._ComPkgInfo + cur_dir = os.getcwd() + + os.chdir(json_config["GameDir"]) + for i,v in enumerate(json_config["MD5"]): + os.system("unzip -o %s" %v) ## auto overwrite + + if "Post-Up" in json_config: + if FileExists(self._InvokeDir): + os.chdir(self._InvokeDir) + + os.system(json_config["Post-Up"]) + + + os.chdir(cur_dir) + pygame.time.delay(1000) + + main_screen._MsgBox.SetText("Package Installed") + main_screen._MsgBox.Draw() + main_screen.SwapAndShow() + pygame.time.delay(500) + + pygame.event.post( pygame.event.Event(RESTARTUI, message="")) + + def VerifyPackage(self,main_screen): + ## do unzip and check md5sum once + + main_screen._MsgBox.SetText("Verify the package") + main_screen._MsgBox.Draw() + main_screen.SwapAndShow() + pygame.time.delay(400) + + Checked = False + + json_config = self._ComPkgInfo + if json_config == None: + return + + if "MD5" in json_config: + for i,v in enumerate(json_config["MD5"]): + print(i,v) + if FileExists( os.path.join(json_config["GameDir"], v )): + print( os.path.join(json_config["GameDir"],v )) + out = commands.getstatusoutput("md5sum %s" % os.path.join(json_config["GameDir"],v)) + ret = out[1] + ret = ret.split(" ") + print(ret) + if ret[0] == json_config["MD5"][v]: + print("md5 is ok") + Checked = True + + return Checked + + return Checked + + def Init(self,main_screen): + self._Page1 = NotFoundPage() + self._Page1._Name = "Not Found" + self._Page1._Screen = main_screen + self._Page1._Leader = self + self._Page1.Init() + + self._Page2 = HashErrPage() + self._Page2._Name = "Md5sum check failed" + self._Page2._Screen = main_screen + self._Page2._Leader = self + self._Page2.Init() + + + def API(self,main_screen): + if main_screen !=None: + if self._Done != "": + main_screen._MsgBox.SetText("Starting") + main_screen._MsgBox.Draw() + main_screen.SwapAndShow() + pygame.time.delay(300) + #### + + pygame.event.post( pygame.event.Event(RUNEVT, message=self._Done)) + #### + else: + print(self._ComPkgInfo) + if FileExists( os.path.join(self._ComPkgInfo["GameDir"],self._ComPkgInfo["InstallDir"] )) == False: + main_screen.PushPage(self._Page1) + main_screen.Draw() + main_screen.SwapAndShow() + else: + if self.VerifyPackage(main_screen) == False: + main_screen.PushPage(self._Page2) + main_screen.Draw() + main_screen.SwapAndShow() + else: + self.InstallPackage(main_screen) + diff --git a/sys.py/UI/constants.py b/sys.py/UI/constants.py index c6b8574..6aab244 100644 --- a/sys.py/UI/constants.py +++ b/sys.py/UI/constants.py @@ -24,7 +24,7 @@ icon_height = 80 icon_ext = ".sh" -ICON_TYPES={"Emulator":7,"FILE":6,"STAT":5,"NAV":4,"LETTER":3,"FUNC":2,"DIR":1,"EXE":0,"None":-1} # FUNC is like UI widget's function,DIR contains child page,EXE just execute a binary +ICON_TYPES={"Commercial":8,"Emulator":7,"FILE":6,"STAT":5,"NAV":4,"LETTER":3,"FUNC":2,"DIR":1,"EXE":0,"None":-1} # FUNC is like UI widget's function,DIR contains child page,EXE just execute a binary ## H=horizontal ,V=vertical S=Single Line #SLeft start from left, single line diff --git a/sys.py/UI/icon_item.py b/sys.py/UI/icon_item.py index 8edea09..237f3d1 100644 --- a/sys.py/UI/icon_item.py +++ b/sys.py/UI/icon_item.py @@ -81,7 +81,26 @@ class IconItem(Widget): def Clear(self): pass + + def DrawTopLeft(self): + if self._Align==ALIGN["VCenter"]: #default + if self._Label != None: + self._Label._PosX = self._PosX - self._Label._Width/2 + self._Parent._PosX + self._Label._PosY = self._PosY + self._Height/2 +6 + self._Parent._PosY + + elif self._Align ==ALIGN["HLeft"]: + if self._Label != None: + self._Label._PosX = self._PosX + self._Width/2 + 3 + self._Parent._PosX + self._Label._PosY = self._PosY - self._Label._Height/2 + self._Parent._PosY + if self._Label!=None: + self._Label.Draw() + + if self._ImgSurf != None: + self._Parent._CanvasHWND.blit(self._ImgSurf,pygame.Rect(self._PosX+self._Parent._PosX, + self._PosY+self._Parent._PosY, + self._Width, + self._Height)) def Draw(self): if self._Align==ALIGN["VCenter"]: #default if self._Label != None: diff --git a/sys.py/UI/icon_pool.py b/sys.py/UI/icon_pool.py index f08058c..dc04b1c 100644 --- a/sys.py/UI/icon_pool.py +++ b/sys.py/UI/icon_pool.py @@ -13,6 +13,7 @@ class IconPool(object): _GameShellIconPath = SkinMap("gameshell/icons/") _Icons = {} + _Sizes = {} def __init__(self): self._Icons= {} @@ -23,7 +24,24 @@ class IconPool(object): if os.path.isfile(self._GameShellIconPath+"/"+i) and i.endswith(".png"): keyname = i.split(".")[0] self._Icons[keyname] = pygame.image.load(self._GameShellIconPath+"/"+i).convert_alpha() - + self._Sizes[keyname] = self._Icons[keyname].get_size() + + def Width(self,keyname): + if keyname in self._Sizes: + return self._Sizes[keyname][0] + + def Height(self,keyname): + if keyname in self._Sizes: + return self._Sizes[keyname][1] + +##global Handler +MyIconPool = None + +def InitMyIconPool(): + global MyIconPool + if MyIconPool == None: + MyIconPool = IconPool() + +InitMyIconPool() -MyIconPool = IconPool() diff --git a/sys.py/UI/lang_manager.py b/sys.py/UI/lang_manager.py index 0a1de09..5a027e7 100644 --- a/sys.py/UI/lang_manager.py +++ b/sys.py/UI/lang_manager.py @@ -89,7 +89,10 @@ class LangManager(object): return english_key_str def TrFont(self,orig_font_str): - font_size_number = int(filter(str.isdigit, orig_font_str)) + try: + font_size_number = int(filter(str.isdigit, orig_font_str)) + except TypeError: + font_size_number = int(filter(unicode.isdigit, orig_font_str)) if font_size_number > 120: raise Exception('font string format error') diff --git a/sys.py/UI/main_screen.py b/sys.py/UI/main_screen.py index 3a12a0e..f390b8d 100644 --- a/sys.py/UI/main_screen.py +++ b/sys.py/UI/main_screen.py @@ -5,7 +5,7 @@ from pygame.locals import * from sys import exit import os import sys - +import json from operator import itemgetter from libs import easing @@ -25,6 +25,7 @@ from keys_def import CurKeys from label import Label from untitled_icon import UntitledIcon from Emulator import MyEmulator +from CommercialSoftwarePackage import MyCommercialSoftwarePackage from skin_manager import MySkinManager from lang_manager import MyLangManager @@ -120,6 +121,7 @@ class MessageBox(Label): python_package_flag = "__init__.py" emulator_flag = "action.config" +commercialsoftware_flag = "compkginfo.json" ##Abstract object for manage Pages ,not the pygame's physic screen class MainScreen(Widget): @@ -383,7 +385,14 @@ class MainScreen(Widget): if i.endswith(emulator_flag): return True return False - + + def IsCommercialPackage(self,dirname): + files = os.listdir(dirname) + for i in sorted(files): + if i.endswith(commercialsoftware_flag): + return True + return False + def IsPythonPackage(self,dirname): files = os.listdir(dirname) for i in sorted(files): @@ -435,6 +444,7 @@ class MainScreen(Widget): def ReadTheDirIntoPages(self,_dir,pglevel,cur_page): + global commercialsoftware_flag if FileExists(_dir) == False and os.path.isdir(_dir) == False: return @@ -523,11 +533,30 @@ class MainScreen(Widget): iconitem._MyType = ICON_TYPES["Emulator"] cur_page._Icons.append(iconitem) - elif self.IsExecPackage(_dir+"/"+i): + elif self.IsCommercialPackage( os.path.join(_dir,i)): + data = None + em = MyCommercialSoftwarePackage() + if FileExists( _dir+"/"+i+"/.done"): + print(_dir+"/"+i+"/.done") + em._Done = os.path.realpath(_dir+"/"+i+"/"+i2+".sh") + else: + with open(os.path.join(_dir,i) +"/"+commercialsoftware_flag) as f: + data = json.load(f) + em._ComPkgInfo = data + em._Done = "" + + em._InvokeDir = os.path.realpath( os.path.join(_dir,i)) + em.Init(self) + + iconitem._CmdPath = em + iconitem._MyType = ICON_TYPES["Commercial"] + cur_page._Icons.append(iconitem) + + elif self.IsExecPackage(_dir+"/"+i): ## ExecPackage is the last one to check iconitem._MyType = ICON_TYPES["EXE"] iconitem._CmdPath = os.path.realpath(_dir+"/"+i+"/"+i2+".sh") MakeExecutable(iconitem._CmdPath) - cur_page._Icons.append(iconitem) + cur_page._Icons.append(iconitem) else: iconitem._MyType = ICON_TYPES["DIR"] iconitem._LinkPage = Page() diff --git a/sys.py/UI/page.py b/sys.py/UI/page.py index 8e2c1ab..b734c0e 100644 --- a/sys.py/UI/page.py +++ b/sys.py/UI/page.py @@ -98,6 +98,8 @@ class Page(Widget): _SelectedIconTopOffset=20 _EasingDur = 30 + _Padding = pygame.Rect(0,0,0,0)# x,y,w,h + _Margin = pygame.Rect(0,0,0,0) def __init__(self): self._Icons = [] @@ -519,7 +521,7 @@ class Page(Widget): if api_cb != None: if callable(api_cb): cur_icon._CmdPath.API(self._Screen) - elif cur_icon._MyType == ICON_TYPES["Emulator"]: + elif cur_icon._MyType == ICON_TYPES["Emulator"] or cur_icon._MyType == ICON_TYPES["Commercial"]: cur_icon._CmdPath.API(self._Screen) def ReturnToUpLevelPage(self): diff --git a/sys.py/UI/text_bulletinboard.py b/sys.py/UI/text_bulletinboard.py index 2892272..017458c 100644 --- a/sys.py/UI/text_bulletinboard.py +++ b/sys.py/UI/text_bulletinboard.py @@ -112,12 +112,12 @@ class Textbulletinboard(Textarea): _TextLimit = 200 _BackgroundColor = MySkinManager.GiveColor("White") _Align = "Left" ## Left or Center + _RowPitch = -1 def SetAndBlitText(self,words):# words => [] if self._TextFull != True: self._MyWords = words - #self.BlitText() self._TextIndex = len(self._MyWords) else: print("is Full %s" % "".join(str(self._MyWords))) @@ -130,13 +130,15 @@ class Textbulletinboard(Textarea): x = self._PosX+xmargin linenumber = 0 cursor_row = 0 - + + #print(self._MyWords) for i, v in enumerate(self._MyWords): if str(v) == "\n": w = 0 x = self._PosX+xmargin - linenumber+=1 - blit_rows.append([]) + linenumber+=2 + blit_rows.append([]) + blit_rows.append([]) else: t = v.Render() t_width = t.get_width() @@ -153,8 +155,7 @@ class Textbulletinboard(Textarea): w = 0 linenumber += 1 blit_rows.append([]) - - + self._BlitWords = blit_rows self._BlitIndex = self._TextIndex @@ -171,10 +172,13 @@ class Textbulletinboard(Textarea): self._TextFull = len(self._MyWords) > self._TextLimit last_height = 0 - for row_idx, row in enumerate(self._BlitWords): - + for row_idx, row in enumerate(self._BlitWords): if len(row) == 0: - y = y + 16 + if self._RowPitch > 0: + y = y + self._RowPitch + else: + y = y + 16 + w = 0 continue @@ -194,6 +198,7 @@ class Textbulletinboard(Textarea): last_height = 0 total_row_width = 0 x = start_x + y = y + last_height for i,v in enumerate(row): t = v.Render() total_row_width += t.get_width() @@ -208,9 +213,7 @@ class Textbulletinboard(Textarea): self._CanvasHWND.blit(t, (x,y)) x += t.get_width() - - y = y + last_height - + def Draw(self): #aa_round_rect(self._CanvasHWND, (4,24.5+6,312,60),self._BackgroundColor,4,0,self._BackgroundColor)