Browse Source

Comm software package alpha

cuu 5 years ago
parent
commit
be872d0536

+ 1 - 1
.gitignore

@@ -11,4 +11,4 @@ sys.py/.lang
 !**/Jobs/.gitkeep
 !**/Jobs/00_lowpower.sh
 !**/Jobs/00_lowpower.alias
-
+.done

+ 5 - 0
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

+ 8 - 0
Menu/GameShell/50_PICO-8/Post-Up.sh

@@ -0,0 +1,8 @@
+#!/bin/bash
+
+mkdir ~/.lexaloffle
+
+cp -rf pico-8 ~/.lexaloffle
+
+touch .done
+

+ 0 - 136
Menu/GameShell/50_PICO-8/__init__.py

@@ -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)

+ 9 - 0
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" 
+}

+ 0 - 2
Menu/GameShell/50_PICO-8/md5sum.log

@@ -1,2 +0,0 @@
-a3f2995cf117499f880bd964d6a0e1f2  pico-8_0.1.11g_raspi.zip
-6726141c784afd4a41be6b7414c1b932  pico-8_0.1.11g_amd64.zip

+ 99 - 0
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
+

+ 90 - 0
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

+ 1 - 0
Menu/GameShell/50_PICO-8/pico-8/sdl_controllers.txt

@@ -0,0 +1 @@
+// add SDL2 game controller mappings to this file

BIN
skin/default/Menu/GameShell/PICO-8.png


BIN
skin/default/sys.py/gameshell/icons/pico8_md5_err.png


BIN
skin/default/sys.py/gameshell/icons/pico8_notfound.png


+ 342 - 0
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)
+                

+ 1 - 1
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

+ 19 - 0
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:

+ 20 - 2
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()
 

+ 4 - 1
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')
             

+ 33 - 4
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()

+ 3 - 1
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):

+ 15 - 12
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)