From faa449003593e8cfeca2cdfc63e2c6cddea09b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Abdelkader=20Mart=C3=ADnez=20P=C3=A9rez?= Date: Sun, 7 Jun 2020 03:23:25 +0200 Subject: [PATCH] feat: load games from the web (missing some platforms) --- src/Makefile | 2 +- src/srv/main.go | 2 +- src/web/build/assets/scripts/load.lua | 182 ++++++++++++++------------ src/web/src/Main.elm | 171 ++++++++++++++++++++---- 4 files changed, 250 insertions(+), 107 deletions(-) diff --git a/src/Makefile b/src/Makefile index 51c460c..fc77683 100644 --- a/src/Makefile +++ b/src/Makefile @@ -29,7 +29,7 @@ deploy-with-log: webmenu.sh ssh ${MISTER_USER}@${MISTER_HOST} '${MISTER_SCRIPTS}/webmenu.sh' develop-all: - find . -type f -name '*.elm' -or -name '*.go' -or -name '*.html' -or -name '*.sh' | entr -cd make deploy-with-log + find . -type f -name '*.lua' -or -name '*.elm' -or -name '*.go' -or -name '*.html' -or -name '*.sh' | entr -cd make deploy-with-log develop-web: cd web && elm-live src/Main.elm -h 0.0.0.0 --open -d build --start-page="index.html" -- --output="build/elm.min.js" diff --git a/src/srv/main.go b/src/srv/main.go index 0ddfbb1..e6dee94 100644 --- a/src/srv/main.go +++ b/src/srv/main.go @@ -537,7 +537,7 @@ func LUAMount(L *lua.LState) int { func LUAMatch(L *lua.LState) int { exp := L.ToString(1) s := L.ToString(2) - matched, err := regexp.Match(exp, []byte(s)) + matched, err := regexp.Match("(?i)"+exp, []byte(s)) if err != nil { L.RaiseError(err.Error()) } diff --git a/src/web/build/assets/scripts/load.lua b/src/web/build/assets/scripts/load.lua index 9b91850..d820bdb 100644 --- a/src/web/build/assets/scripts/load.lua +++ b/src/web/build/assets/scripts/load.lua @@ -1,3 +1,5 @@ +require "string" + local KEY_ENTER = 28 local KEY_ESC = 1 local KEY_F10 = 68 @@ -11,36 +13,36 @@ cores={ ["Amstrad"]={ ["^.*\.dsk$"]={ ["dir"]="Amstrad", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.e..$"]={ ["dir"]="Amstrad", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, ["^.*\.cdt$"]={ ["dir"]="Amstrad", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} }, ["ao486"]={ ["^.*\.img$"]={ ["dir"]="AO486", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.vhd$"]={ ["dir"]="AO486", - ["keys"]={KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}} }, ["Apogee"]={ ["^.*\.rka$|^.*\.rkr$|^.*\.gam$"]={ ["dir"]="APOGEE", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Apple-I"]={ ["^.*\.txt$"]={ ["dir"]="Apple-I", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, }, ["Apple-II"]={ ["^.*\.nib$|^.*\.dsk$|^.*\.do^.*\.po$"]={ ["dir"]="Apple-II", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Aquarius"]={ ["^.*\.bin$"]={["dir"]="AQUARIUS"}}, @@ -49,71 +51,71 @@ cores={ ["Atari800"]={ ["^.*\.atr$|^.*\.xex$|^.*\.xfd$|^.*\.atx$"]={ ["dir"]="ATARI800", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.car$|^.*\.rom$|^.*\.bin$"]={ ["dir"]="ATARI800", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, }, ["AtariST"]={ [""]={["dir"]=nil}}, -- TODO ["BBCMicro"]={ ["^.*\.vhd$"]={ ["dir"]="BBCMicro", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["BK0011M"]={ ["^.*\.bin$"]={ ["dir"]="BK0011M", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.dsk$"]={ ["dir"]="BK0011M", - ["keys"]={KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}}, ["^.*\.vhd$"]={ ["dir"]="BK0011M", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} }, ["C16"]={ ["^.*\.prg$"]={ ["dir"]="C16", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.bin$"]={ ["dir"]="C16", - ["keys"]={KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}}, ["^.*\.d64$"]={ ["dir"]="C16", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, ["^.*\.tap$"]={ ["dir"]="C16", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} }, ["C64"]={ ["^.*\.d64$|^.*\.t64$"]={ ["dir"]="C64", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.prg$"]={ ["dir"]="C64", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}}, ["^.*\.crt$"]={ ["dir"]="C64", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}}, ["^.*\.tap$"]={ ["dir"]="C64", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} }, ["Galaksija"]={ ["^.*\.tap$"]={ ["dir"]=nil, -- TODO - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["ht1080z"]={ ["^.*\.cas$"]={ ["dir"]="HT1080Z", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Jupiter"]={ ["^.*\.ace$"]={ ["dir"]="Jupiter", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["MacPlus"]={ [""]={["dir"]="MACPLUS"}}, -- TODO @@ -122,204 +124,209 @@ cores={ ["MSX"]={ ["^.*\.vhd$"]={ ["dir"]="MSX", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["MultiComp"]={ [""]={["dir"]=nil}}, -- TODO ["ORAO"]={ ["^.*\.tap$"]={ ["dir"]="ORAO", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Oric"]={ [""]={["dir"]=nil}}, -- TODO ["PDP1"]={ ["^.*\.pdp$|^.*\.rim$|^.*\.bin$"]={ ["dir"]="PDP1", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["PET2001"]={ ["^.*\.tap$|^.*\.prg$"]={ ["dir"]="PET2001", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["QL"]={ ["^.*\.mvd$"]={ ["dir"]="QL", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["SAMCoupe"]={ ["^.*\.dsk$|^.*\.mgt$|^.*\.img$"]={ ["dir"]="SAMCOUPE", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["SharpMZ"]={ [""]={["dir"]="SHARP MZ SERIES"}}, -- TODO ["Specialist"]={ ["^.*\.rks$"]={ ["dir"]="SPMX", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.od1$"]={ ["dir"]="SPMX", - ["keys"]={KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}}, }, ["Ti994a"]={ ["^.*\.bin$"]={ ["dir"]="TI-99_4A", - ["keys"]={KEY_ENTER}} -- XXX: Multiple .bin + ["open_filemanager_keys"]={KEY_ENTER}} -- XXX: Multiple .bin }, ["TRS-80"]={ [""]={["dir"]=nil}}, -- TODO ["TSConf"]={ ["^.*\.vhd$"]={ ["dir"]="TSConf", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Vector-06C"]={ ["^.*\.rom$|^.*\.com$|^.*\.c00$|^.*\.edd$"]={ ["dir"]="VECTOR06", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.fdd$"]={ ["dir"]="VECTOR06", - ["keys"]={KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}} }, ["VIC20"]={ ["^.*\.prg$"]={ ["dir"]="VIC20", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.crt$"]={ ["dir"]="VIC20", - ["keys"]={KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}}, ["^.*\.ct.$"]={ ["dir"]="VIC20", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, ["^.*\.d64$"]={ ["dir"]="VIC20", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}}, ["^.*\.tap$"]={ ["dir"]="VIC20", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} }, ["X68000"]={ [""]={["dir"]="X68000"}}, -- TODO ["ZX81"]={ ["^.*\.o$|^.*\.p$"]={ ["dir"]="ZX81", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["ZX-Spectrum"]={ ["^.*\.trd$|^.*\.img$|^.*\.dsk$|^.*\.mgt$"]={ ["dir"]="Spectrum", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}, + ["post_rom_load_keys"]={KEY_F10}}, ["^.*\.tap$|^.*\.csw$|^.*\.tzx$"]={ ["dir"]="Spectrum", - ["keys"]={KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}, + ["post_rom_load_keys"]={KEY_F10}}, ["^.*\.z80$"]={ ["dir"]="Spectrum", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_ENTER}} }, -- Console ["Astrocade"]={ ["^.*\.bin$"]={ ["dir"]="Astrocade", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Atari2600"]={ [".*$"]={ ["dir"]="ATARI2600", - ["keys"]={KEY_ENTER}} + ["core_load_time"]=500, + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Atari5200"]={ ["^.*\.car$|^.*\.a52$|^.*\.bin$|^.*\.rom$"]={ ["dir"]="ATARI5200", - ["keys"]={KEY_ENTER}} + ["core_load_time"]=4000, + ["open_filemanager_keys"]={KEY_ENTER}} }, ["AY-3-8500"]={ }, ["ColecoVision"]={ ["^.*\.col$|^.*\.bin$|^.*\.rom$"]={ ["dir"]="Coleco", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.sg$"]={ ["dir"]="Coleco", - ["keys"]={KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}} }, ["Gameboy"]={ ["^.*\.gbc$|^.*\.gb$"]={ ["dir"]="GAMEBOY", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["GBA"]={ ["^.*\.gba$"]={ ["dir"]="GBA", - ["load_time"]=6000, - ["keys"]={KEY_ENTER}} + ["core_load_time"]=6000, + ["open_filemanager_keys"]={KEY_ENTER}} }, ["Genesis"]={ ["^.*\.bin$|^.*\.gen$|^.*\.md$"]={ ["dir"]="Genesis", - ["keys"]={KEY_ENTER}} + ["core_load_time"]=4000, + ["open_filemanager_keys"]={KEY_ENTER}} }, ["MegaCD"]={ ["^.*\.cue$"]={ ["dir"]="MegaCD", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.bin$|^.*\.gen$|^.*\.md$"]={ ["dir"]="MegaCD", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, }, ["NeoGeo"]={ [".*$"]={ ["dir"]="NeoGeo", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["NES"]={ ["^.*\.nes$|^.*\.fds$|^.*\.nsf$"]={ ["dir"]="NES", - ["keys"]={KEY_ENTER}}, + ["core_load_time"]=4000, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.bin$"]={ ["dir"]="NES", - ["keys"]={KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}} }, ["Odyssey2"]={ ["^.*\.bin$"]={ ["dir"]="ODYSSEY2", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["SMS"]={ ["^.*\.sms$|^.*\.sg$"]={ ["dir"]="SMS", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.gg$"]={ ["dir"]="SMS", - ["keys"]={KEY_DOWN, KEY_ENTER}} + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}} }, ["SNES"]={ ["^.*\.sfc$|^.*\.smc$|^.*\.bin$"]={ ["dir"]="SNES", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} }, ["TurboGrafx16"]={ ["^.*\.pce$|^.*\.bin$"]={ ["dir"]="TGFX16", - ["keys"]={KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_ENTER}}, ["^.*\.sgx$"]={ ["dir"]="TGFX16", - ["keys"]={KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_ENTER}}, ["^.*\.cue$"]={ ["dir"]="TGFX16-CD", - ["keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, + ["open_filemanager_keys"]={KEY_DOWN, KEY_DOWN, KEY_ENTER}}, }, ["Vectrex"]={ ["^.*\.vec$|^.*\.bin$|^.*\.rom$"]={ ["dir"]="VECTREX", - ["keys"]={KEY_ENTER}} + ["open_filemanager_keys"]={KEY_ENTER}} } } function press(key) - print("Key", key) key_press(key) sleep(500) end @@ -327,41 +334,52 @@ end if method =="boot" then error("Method not implemented yet") elseif method == "rload" then - -- Must have "core" + -- Must have "core_codename" + -- Must have "core_path" -- Must have "rom" - if cores[core] == nil then + if cores[core_codename] == nil then error("Unknown core") end dir = nil - load_time = nil - keys = nil - for exp, config in pairs(cores[core]) do + for exp, config in pairs(cores[core_codename]) do if match(exp, rom) then dir = config["dir"] - load_time = config["load_time"] - keys = config["keys"] + core_load_time = config["core_load_time"] or 5000 + rom_load_time = config["rom_load_time"] or 5000 + open_filenamager_keys = config["open_filemanager_keys"] or {} + post_rom_load_keys = config["post_rom_load_keys"] or {} break end end - if dir == nil or keys == nil then + if dir == nil then error("Config not found for core") end + if is_zip then + rom = string.gsub(rom, "\/[^\/]+$", "", 1) + end dir = "/media/fat/" .. dir + print(rom, dir) + load_core(core_path) + sleep(core_load_time) mount(rom, dir, function () - print(rom, dir) - load_core(core_path) - sleep(load_time == nil and load_time or 4000) press(KEY_ESC) -- Sometimes the menu will popup others won't press(KEY_F12) - for _, key in pairs(keys) do + for _, key in pairs(open_filenamager_keys) do press(key) end + if is_zip then + press(KEY_DOWN) + press(KEY_ENTER) + end press(KEY_DOWN) press(KEY_ENTER) - sleep(4000) + for _, key in pairs(post_rom_load_keys) do + press(key) + end + sleep(rom_load_time) end) else error("Unknown method") diff --git a/src/web/src/Main.elm b/src/web/src/Main.elm index c17bada..7ebbd06 100644 --- a/src/web/src/Main.elm +++ b/src/web/src/Main.elm @@ -36,6 +36,7 @@ import Html.Events exposing (on, onClick, onInput) import Html.Keyed as Keyed import Http import Json.Decode as Decode exposing (Decoder) +import Json.Encode as Encode exposing (Value) import List.Extra exposing (getAt, greedyGroupsOf, last, stripPrefix) import Process import Result.Extra @@ -133,6 +134,22 @@ apiRoot = "" +systemToCoreCodename : Dict String String +systemToCoreCodename = + Dict.fromList + [ ( "Sinclair - ZX Spectrum", "ZX-Spectrum" ) + , ( "Atari - 2600", "Atari2600" ) + , ( "Atari - 5200", "Atari5200" ) + , ( "Sega - Mega Drive - Genesis", "Genesis" ) + , ( "Nintendo - Nintendo Entertainment System", "NES" ) + , ( "Nintendo - Super Nintendo Entertainment System", "SNES" ) + , ( "Nintendo - Game Boy Advance", "GBA" ) + , ( "Nintendo - Game Boy", "Gameboy" ) + , ( "Nintendo - Game Boy Color", "Gameboy" ) + , ( "NEC - PC Engine - TurboGrafx 16", "TurboGrafx16" ) + ] + + coreImages : Dict String String coreImages = Dict.fromList @@ -404,6 +421,16 @@ type alias CoreFolder = } +type alias ContentLoadInfo = + { script : String + , method : String + , coreCodeName : String + , corePath : String + , rom : String + , isZip : Bool + } + + init : Flags -> Url -> Navigation.Key -> ( Model, Cmd Msg ) init flags url key = let @@ -461,6 +488,7 @@ type Msg | GameFolderScanFinished (Result Http.Error ()) | GameScanFinished (Result Http.Error ()) | LoadCores + | LoadContent ContentLoadInfo | ScanCores Bool | ScanGameFolders | ScanGames String @@ -984,6 +1012,19 @@ update msg model = , loadGameFolders ) + LoadContent info -> + case model.gameLoaderScript of + Just script -> + ( { model + | waiting = model.waiting + 1 + , modalVisibility = Modal.hidden + } + , loadContent { info | script = script } + ) + + Nothing -> + ( model, Cmd.none ) + initLoadedGameFolders : GameTree -> List ( String, Bool ) initLoadedGameFolders tree = @@ -1309,6 +1350,15 @@ loadCore lpath = } +loadContent : ContentLoadInfo -> Cmd Msg +loadContent info = + Http.post + { url = relative [ "api", "script", "run" ] [] + , body = Http.jsonBody (loadScriptEncoder info) + , expect = Http.expectWhatever GameLoaded + } + + urlUpdate : Url -> Model -> ( Model, Cmd Msg ) urlUpdate url model = case decode url of @@ -2172,7 +2222,7 @@ pageGamesPageContent model = waitForSync GameFoldersLoaded games -> - pageGamesLoadedContent games + pageGamesLoadedContent model.cores games gameSearch : Maybe String -> Html Msg @@ -2210,8 +2260,8 @@ filterGameByPath path game = String.startsWith path (gamePath game) -pageGamesLoadedContent : GameInfo -> Html Msg -pageGamesLoadedContent games = +pageGamesLoadedContent : CoreState -> GameInfo -> Html Msg +pageGamesLoadedContent cs games = let byPath = case games.folder of @@ -2257,7 +2307,7 @@ pageGamesLoadedContent games = [ gameSearch games.filter , Html.map GameTreeViewMsg (TV.view games.tree) ] - , Grid.col [ Col.sm9 ] (paginationBlock ++ (List.concat <| List.map (gameFolderContent games) pageWithSections) ++ paginationBlock) + , Grid.col [ Col.sm9 ] (paginationBlock ++ (List.concat <| List.map (gameFolderContent cs games) pageWithSections) ++ paginationBlock) ] ] @@ -2282,19 +2332,19 @@ gameBrFromPath path = List.map (\x -> Breadcrumb.item [] [ text x ]) (String.split "/" path) -gameFolderContent : GameInfo -> ( String, List Game ) -> List (Html Msg) -gameFolderContent m ( path, cs ) = - [ gameBrFromPath path ] ++ gameContent m cs +gameFolderContent : CoreState -> GameInfo -> ( String, List Game ) -> List (Html Msg) +gameFolderContent cs m ( path, gs ) = + [ gameBrFromPath path ] ++ gameContent cs m gs -gameKeyAndCard : GameInfo -> Game -> ( String, Card.Config Msg ) -gameKeyAndCard m g = - ( gamePath g ++ "/" ++ gameFilename g, gameCard m g ) +gameKeyAndCard : CoreState -> GameInfo -> Game -> ( String, Card.Config Msg ) +gameKeyAndCard cs m g = + ( gamePath g ++ "/" ++ gameFilename g, gameCard cs m g ) -gameContent : GameInfo -> List Game -> List (Html Msg) -gameContent m cs = - List.map Card.keyedDeck (partition 3 ( "", emptyCard ) (List.map (gameKeyAndCard m) cs)) +gameContent : CoreState -> GameInfo -> List Game -> List (Html Msg) +gameContent cs m gs = + List.map Card.keyedDeck (partition 3 ( "", emptyCard ) (List.map (gameKeyAndCard cs m) gs)) getFilename : String -> Maybe String @@ -2375,8 +2425,31 @@ ifNotGameMissing m s = s -gameCard : GameInfo -> Game -> Card.Config Msg -gameCard model game = +isCoreByCodeName : String -> Core -> Maybe String +isCoreByCodeName codeName = + coreBiMap + (always Nothing) + (\rbf -> + if rbf.codename == codeName then + Just rbf.path + + else + Nothing + ) + + +getCoreByCodeName : List Core -> String -> Maybe String +getCoreByCodeName cs codeName = + List.head <| List.filterMap (isCoreByCodeName codeName) cs + + +isZip : String -> Bool +isZip filename = + String.contains ".zip/" (String.toLower filename) + + +gameCard : CoreState -> GameInfo -> Game -> Card.Config Msg +gameCard cores model game = let titleText = gameName game @@ -2390,8 +2463,45 @@ gameCard model game = UnrecognizedGame _ -> "" - loadEv = - ShowModal "Are you sure?" ("You are about to launch " ++ titleText ++ ". Any running game will be stopped immediately!") (LoadCore "") + contentLoadInfo = + case ( cores, game ) of + ( CoresLoaded cs, RecognizedGame g ) -> + case Dict.get g.system systemToCoreCodename of + Just coreCodeName -> + case getCoreByCodeName cs coreCodeName of + Just corePath -> + Just + { method = "rload" + , coreCodeName = coreCodeName + , corePath = corePath + , rom = gamePath game ++ "/" ++ gameFilename game + , script = "" -- To be filled + , isZip = isZip (gameFilename game) + } + + _ -> + Nothing + + _ -> + Nothing + + _ -> + Nothing + + runButtonAttrs = + case contentLoadInfo of + Nothing -> + [ class "bg-secondary" + , class "text-center" + ] + + Just info -> + [ class "bg-primary" + , class "text-center" + , class "text-white" + , class "runbutton" + , on "click" (Decode.succeed (ShowModal "Are you sure?" ("You are about to launch " ++ titleText ++ ". Any running game will be stopped immediately!") (LoadContent info))) + ] body = Block.text [] @@ -2450,12 +2560,7 @@ gameCard model game = ] [ body ] |> Card.footer - [ class "bg-primary" - , class "text-center" - , class "text-white" - , class "runbutton" - , on "click" (Decode.succeed loadEv) - ] + runButtonAttrs [ text "Run" ] @@ -2553,3 +2658,23 @@ gameFolderElement scanningOn name scanned = ) ] ) + + +loadScriptEncoder : ContentLoadInfo -> Value +loadScriptEncoder info = + scriptCallEncoder + [ ( "method", Encode.string info.method ) + , ( "core_codename", Encode.string info.coreCodeName ) + , ( "core_path", Encode.string info.corePath ) + , ( "rom", Encode.string info.rom ) + , ( "is_zip", Encode.bool info.isZip ) + ] + info.script + + +scriptCallEncoder : List ( String, Value ) -> String -> Value +scriptCallEncoder params source = + Encode.object + [ ( "params", Encode.object params ) + , ( "source", Encode.string source ) + ]