diff --git a/Dockerfile b/Dockerfile index 01ab6ebf..01aed7e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,11 +6,12 @@ WORKDIR /go/src/github.com/giongto35/cloud-game # Install server dependencies RUN apt-get update -#RUN apt-get install portaudio19-dev -y -RUN apt-get install libvpx-dev -y -RUN go get github.com/pion/webrtc + #RUN go get github.com/gordonklaus/portaudio -RUN go get github.com/gorilla/mux +#RUN apt-get install portaudio19-dev -y + +RUN apt-get install pkg-config libvpx-dev -y +RUN go get github.com/pion/webrtc RUN go get github.com/gorilla/websocket RUN go install github.com/giongto35/cloud-game diff --git a/main.go b/main.go index ab5d40c3..376a2ab7 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "os" "encoding/json" "fmt" "image" @@ -19,22 +20,21 @@ import ( pionRTC "github.com/pion/webrtc" ) -const gameboyIndex = "./static/gameboy.html" -const wsIndex = "./static/index_ws.html" +const ( + width = 256 + height = 240 + scale = 3 + title = "NES" + gameboyIndex = "./static/gameboy.html" + debugIndex = "./static/index_ws.html" +) -var width = 256 -var height = 240 -var indexFN string = gameboyIndex -var service string = "ws" +var indexFN = gameboyIndex // Time allowed to write a message to the peer. var readWait = 30 * time.Second var writeWait = 30 * time.Second -type IndexPageData struct { - Service string -} - var upgrader = websocket.Upgrader{} type WSPacket struct { @@ -53,11 +53,20 @@ type Room struct { closedChannel chan bool rtcSessions []*webrtc.WebRTC + + director *ui.Director } var rooms map[string]*Room func main() { + fmt.Println("Usage: ./game [debug]") + if len(os.Args) > 1 { + // debug + indexFN = debugIndex + fmt.Println("Use debug version") + } + rand.Seed(time.Now().UTC().UnixNano()) fmt.Println("http://localhost:8000") rooms = map[string]*Room{} @@ -71,9 +80,6 @@ func main() { http.ListenAndServe(":8000", nil) } -func startGame(path string, roomID string, imageChannel chan *image.RGBA, inputChannel chan int, closedChannel chan bool) { - ui.Run([]string{path}, roomID, imageChannel, inputChannel, closedChannel) -} func getWeb(w http.ResponseWriter, r *http.Request) { bs, err := ioutil.ReadFile(indexFN) @@ -92,14 +98,20 @@ func initRoom(roomID, gameName string) string { imageChannel := make(chan *image.RGBA, 100) inputChannel := make(chan int, 100) closedChannel := make(chan bool) + + // create director + director := ui.NewDirector(roomID, imageChannel, inputChannel, closedChannel) + rooms[roomID] = &Room{ imageChannel: imageChannel, inputChannel: inputChannel, closedChannel: closedChannel, rtcSessions: []*webrtc.WebRTC{}, + director: director, } + go fanoutScreen(imageChannel, roomID) - go startGame("games/"+gameName, roomID, imageChannel, inputChannel, closedChannel) + go director.Start([]string{"games/" + gameName}) return roomID } @@ -140,12 +152,12 @@ func startSession(webRTC *webrtc.WebRTC, gameName string, roomID string, playerI func ws(w http.ResponseWriter, r *http.Request) { c, err := upgrader.Upgrade(w, r, nil) if err != nil { - log.Print("upgrade:", err) + log.Print("[!] WS upgrade:", err) return } defer c.Close() - log.Println("New Connection") + log.Println("New ws connection") webRTC := webrtc.NewWebRTC() // streaming game @@ -207,10 +219,40 @@ func ws(w http.ResponseWriter, r *http.Request) { case "start": log.Println("Starting game") + roomID = startSession(webRTC, gameName, roomID, playerIndex) res.ID = "start" - res.RoomID = startSession(webRTC, gameName, roomID, playerIndex) + res.RoomID = roomID - isDone = true + // maybe we wont close websocket + // isDone = true + + case "save": + log.Println("Saving game state") + res.ID = "save" + res.Data = "ok" + if roomID != "" { + err = rooms[roomID].director.SaveGame() + if err != nil { + log.Println("[!] Cannot save game state: ", err) + res.Data = "error" + } + } else { + res.Data = "error" + } + + case "load": + log.Println("Loading game state") + res.ID = "load" + res.Data = "ok" + if roomID != "" { + err = rooms[roomID].director.LoadGame() + if err != nil { + log.Println("[!] Cannot load game state: ", err) + res.Data = "error" + } + } else { + res.Data = "error" + } } stRes, err := json.Marshal(res) @@ -274,9 +316,9 @@ func faninInput(inputChannel chan int, webRTC *webrtc.WebRTC, playerIndex int) { // encode frame if webRTC.IsConnected() { input := <-webRTC.InputChannel - // the first 10 bits belong to player 1 - // the next 10 belongs to player 2 ... - // We standardize and put it to inputChannel (20 bits) + // the first 8 bits belong to player 1 + // the next 8 belongs to player 2 ... + // We standardize and put it to inputChannel (16 bits) input = input << ((uint(playerIndex) - 1) * ui.NumKeys) inputChannel <- input } diff --git a/static/css/gameboy.css b/static/css/gameboy.css index bef93b84..766ff69e 100644 --- a/static/css/gameboy.css +++ b/static/css/gameboy.css @@ -6,7 +6,7 @@ body { background-repeat: no-repeat; /*Prevent showing multiple background images*/ } -#loading-screen { +#game-screen { width: 100%; height: 100%; display: none; @@ -58,9 +58,9 @@ body { -webkit-transform:translateX(50%); transform:translateX(50%); /* Apply animation to this element */ - -moz-animation: horizontally 1s linear infinite alternate; - -webkit-animation: horizontally 1s linear infinite alternate; - animation: horizontally 1s linear infinite alternate; + -moz-animation: horizontally 5s linear infinite alternate; + -webkit-animation: horizontally 5s linear infinite alternate; + animation: horizontally 5s linear infinite alternate; } /* Move it (define the animation) */ @-moz-keyframes horizontally { @@ -154,11 +154,6 @@ body { -#colors { - position: fixed; - bottom: 0px; -} - @import url(https://fonts.googleapis.com/css?family=Asap:400italic,700italic); @import url(https://fonts.googleapis.com/css?family=Oxygen:700,300); * { @@ -176,7 +171,7 @@ body { width: 340px; height: 570px; /*overflow: hidden;*/ - top: 25%; + top: 17%; margin: auto; line-height: 1; @@ -283,8 +278,8 @@ body { right: 0; border-radius: 15px 15px 170px 170px / 15px 15px 35px 35px; background-color: #b0b0b0; - -webkit-animation: canvas 1s linear; - animation: canvas 1s linear; + -webkit-animation: canvas 8s linear; + animation: canvas 8s linear; z-index: 1; } @-moz-keyframes border { @@ -425,8 +420,8 @@ body { border: 4px #808080 solid; border-radius: 15px 15px 170px 170px / 15px 15px 35px 35px; z-index: 2; - -webkit-animation: border 1s linear; - animation: border 1s linear; + -webkit-animation: border 8s linear; + animation: border 8s linear; } #border-top, #border-bottom { @@ -497,8 +492,8 @@ body { #border-top { top: 20px; right: 11px; - -webkit-animation: border-top 1s linear; - animation: border-top 1s linear; + -webkit-animation: border-top 8s linear; + animation: border-top 8s linear; } @-moz-keyframes border-left { 0% { @@ -552,8 +547,8 @@ body { left: 11px; top: 20px; width: 20px; - -webkit-animation: border-left 1s linear; - animation: border-left 1s linear; + -webkit-animation: border-left 8s linear; + animation: border-left 8s linear; } @-moz-keyframes border-bottom { 0% { @@ -607,8 +602,8 @@ body { top: 516px; left: 11px; height: 30px; - -webkit-animation: border-bottom 1s linear; - animation: border-bottom 1s linear; + -webkit-animation: border-bottom 8s linear; + animation: border-bottom 8s linear; } @-moz-keyframes border-right { 0% { @@ -680,8 +675,8 @@ body { right: 11px; top: 26px; width: 8px; - -webkit-animation: border-right 1s linear; - animation: border-right 1s linear; + -webkit-animation: border-right 8s linear; + animation: border-right 8s linear; } .screw { border-radius: 100%; @@ -761,8 +756,8 @@ body { } #screw-small-right { right: 25px; - -webkit-animation: screw-small-right 1s linear; - animation: screw-small-right 1s linear; + -webkit-animation: screw-small-right 8s linear; + animation: screw-small-right 8s linear; } @-moz-keyframes screw-small-left { 0% { @@ -826,8 +821,8 @@ body { } #screw-small-left { left: 25px; - -webkit-animation: screw-small-left 1s linear; - animation: screw-small-left 1s linear; + -webkit-animation: screw-small-left 8s linear; + animation: screw-small-left 8s linear; } @-moz-keyframes screw-large-right { 0% { @@ -891,8 +886,8 @@ body { } #screw-large-right { right: 3px; - -webkit-animation: screw-large-right 1s linear; - animation: screw-large-right 1s linear; + -webkit-animation: screw-large-right 8s linear; + animation: screw-large-right 8s linear; } @-moz-keyframes screw-large-left { 0% { @@ -956,8 +951,8 @@ body { } #screw-large-left { left: 3px; - -webkit-animation: screw-large-left 1s linear; - animation: screw-large-left 1s linear; + -webkit-animation: screw-large-left 8s linear; + animation: screw-large-left 8s linear; } @-moz-keyframes backboard { 0% { @@ -1051,8 +1046,8 @@ body { left: 60px; bottom: 340px; background-color: #222222; - -webkit-animation: backboard 1s linear; - animation: backboard 1s linear; + -webkit-animation: backboard 8s linear; + animation: backboard 8s linear; } @-moz-keyframes motherboard { 0% { @@ -1231,8 +1226,8 @@ body { top: 75px; overflow: hidden; background-color: #4ca879; - -webkit-animation: motherboard 1s linear; - animation: motherboard 1s linear; + -webkit-animation: motherboard 8s linear; + animation: motherboard 8s linear; } #motherboard::before { content: ""; @@ -1242,8 +1237,8 @@ body { height: 100%; background-color: #66947d; box-shadow: -6px 0 #66947d, 9px 0 #66947d; - -webkit-animation: motherboard-before 1s linear; - animation: motherboard-before 1s linear; + -webkit-animation: motherboard-before 8s linear; + animation: motherboard-before 8s linear; } .chip { z-index: 4; @@ -1360,8 +1355,8 @@ body { height: 400px; top: 75px; right: 35px; - -webkit-animation: chip-tall 1s linear; - animation: chip-tall 1s linear; + -webkit-animation: chip-tall 8s linear; + animation: chip-tall 8s linear; } #chip-tall::before { content: ""; @@ -1371,8 +1366,8 @@ body { width: 4px; height: 100%; background-color: #267146; - -webkit-animation: chip-tall-before 1s linear; - animation: chip-tall-before 1s linear; + -webkit-animation: chip-tall-before 8s linear; + animation: chip-tall-before 8s linear; } #chip-tall::after { content: ""; @@ -1382,8 +1377,8 @@ body { width: 4px; height: 100%; background-color: #267146; - -webkit-animation: chip-tall-after 1s linear; - animation: chip-tall-after 1s linear; + -webkit-animation: chip-tall-after 8s linear; + animation: chip-tall-after 8s linear; } @-moz-keyframes chip-short { 0% { @@ -1552,8 +1547,8 @@ body { height: 140px; top: 75px; right: 35px; - -webkit-animation: chip-short 1s linear; - animation: chip-short 1s linear; + -webkit-animation: chip-short 8s linear; + animation: chip-short 8s linear; } #chip-short::before { content: ""; @@ -1564,8 +1559,8 @@ body { position: absolute; left: 36px; box-shadow: 6px 0 #66947d; - -webkit-animation: chip-details 1s linear; - animation: chip-details 1s linear; + -webkit-animation: chip-details 8s linear; + animation: chip-details 8s linear; } #chip-short::after { content: ""; @@ -1575,8 +1570,8 @@ body { position: absolute; left: -14px; box-shadow: 6px 0 #66947d; - -webkit-animation: chip-details 1s linear; - animation: chip-details 1s linear; + -webkit-animation: chip-details 8s linear; + animation: chip-details 8s linear; } @-moz-keyframes chip-diagonal { 0% { @@ -1630,8 +1625,8 @@ body { transform-origin: 0 100%; -webkit-transform: rotateZ(-40deg); transform: rotateZ(-40deg); - -webkit-animation: chip-diagonal 1s linear; - animation: chip-diagonal 1s linear; + -webkit-animation: chip-diagonal 8s linear; + animation: chip-diagonal 8s linear; } #chip-diagonal::before { content: ""; @@ -1642,8 +1637,8 @@ body { left: -11px; top: -9px; box-shadow: 5px 4px #66947d; - -webkit-animation: chip-details-diagonal 1s linear; - animation: chip-details-diagonal 1s linear; + -webkit-animation: chip-details-diagonal 8s linear; + animation: chip-details-diagonal 8s linear; } .capacitors { position: absolute; @@ -1717,8 +1712,8 @@ body { #chip-capacitors { left: 240px; top: 130px; - -webkit-animation: chip-capacitors 1s linear; - animation: chip-capacitors 1s linear; + -webkit-animation: chip-capacitors 8s linear; + animation: chip-capacitors 8s linear; } @-moz-keyframes motherboard-capacitors { 0% { @@ -1785,8 +1780,8 @@ body { top: 265px; -webkit-transform: rotateZ(-90deg); transform: rotateZ(-90deg); - -webkit-animation: motherboard-capacitors 1s linear; - animation: motherboard-capacitors 1s linear; + -webkit-animation: motherboard-capacitors 8s linear; + animation: motherboard-capacitors 8s linear; } @-moz-keyframes contrast-knob { 0% { @@ -1934,8 +1929,8 @@ body { width: 28px; height: 28px; background-color: #808080; - -webkit-animation: contrast-knob 1s linear; - animation: contrast-knob 1s linear; + -webkit-animation: contrast-knob 8s linear; + animation: contrast-knob 8s linear; } #contrast-knob:before { content: ''; @@ -1946,8 +1941,8 @@ body { height: 32px; border-radius: 50%; background-color: #303030; - -webkit-animation: contrast-knob-before 1s linear; - animation: contrast-knob-before 1s linear; + -webkit-animation: contrast-knob-before 8s linear; + animation: contrast-knob-before 8s linear; } @-moz-keyframes link-port { 0% { @@ -2026,8 +2021,8 @@ body { width: 34px; height: 34px; background-color: #ffffff; - -webkit-animation: link-port 1s linear; - animation: link-port 1s linear; + -webkit-animation: link-port 8s linear; + animation: link-port 8s linear; } .circuit { z-index: 4; @@ -2160,16 +2155,16 @@ body { left: 155px; -webkit-transform: rotateZ(-90deg); transform: rotateZ(-90deg); - -webkit-animation: circuit-bottom 1s linear; - animation: circuit-bottom 1s linear; + -webkit-animation: circuit-bottom 8s linear; + animation: circuit-bottom 8s linear; } #circuit-bottom::before { - -webkit-animation: circuit-bottom-before 1s linear; - animation: circuit-bottom-before 1s linear; + -webkit-animation: circuit-bottom-before 8s linear; + animation: circuit-bottom-before 8s linear; } #circuit-bottom::after { - -webkit-animation: circuit-bottom-after 1s linear; - animation: circuit-bottom-after 1s linear; + -webkit-animation: circuit-bottom-after 8s linear; + animation: circuit-bottom-after 8s linear; } @-moz-keyframes circuit-top { 0% { @@ -2275,16 +2270,16 @@ body { height: 80px; top: 100px; left: 70px; - -webkit-animation: circuit-top 1s linear; - animation: circuit-top 1s linear; + -webkit-animation: circuit-top 8s linear; + animation: circuit-top 8s linear; } #circuit-top::before { - -webkit-animation: circuit-top-before 1s linear; - animation: circuit-top-before 1s linear; + -webkit-animation: circuit-top-before 8s linear; + animation: circuit-top-before 8s linear; } #circuit-top::after { - -webkit-animation: circuit-top-after 1s linear; - animation: circuit-top-after 1s linear; + -webkit-animation: circuit-top-after 8s linear; + animation: circuit-top-after 8s linear; } @-moz-keyframes transistors { 0% { @@ -2356,8 +2351,8 @@ body { border-radius: 50%; background-color: #303030; box-shadow: 16px 0, 32px 0, 48px 0; - -webkit-animation: transistors 1s linear; - animation: transistors 1s linear; + -webkit-animation: transistors 8s linear; + animation: transistors 8s linear; } @-moz-keyframes processor { 0% { @@ -2498,8 +2493,8 @@ body { letter-spacing: 3px; font-weight: 700; font-family: 'Oxygen', Helvetica, arial, sans-serif; - -webkit-animation: processor 1s linear; - animation: processor 1s linear; + -webkit-animation: processor 8s linear; + animation: processor 8s linear; } #processor::before { content: "llllll"; @@ -2513,8 +2508,8 @@ body { transform-origin: 0 0; left: 48px; bottom: -9px; - -webkit-animation: processor-before 1s linear; - animation: processor-before 1s linear; + -webkit-animation: processor-before 8s linear; + animation: processor-before 8s linear; } #processor::after { content: "llllll"; @@ -2528,8 +2523,8 @@ body { transform-origin: 0 0; left: 7px; top: 50px; - -webkit-animation: processor-after 1s linear; - animation: processor-after 1s linear; + -webkit-animation: processor-after 8s linear; + animation: processor-after 8s linear; } @-moz-keyframes component { 0% { @@ -2626,8 +2621,8 @@ body { border-bottom-right-radius: 3px; width: 14px; height: 55px; - -webkit-animation: component 1s linear; - animation: component 1s linear; + -webkit-animation: component 8s linear; + animation: component 8s linear; } @-moz-keyframes controller { 0% { @@ -2805,8 +2800,8 @@ body { top: 390px; left: 68px; background-color: #9d9d9d; - -webkit-animation: controller 1s linear; - animation: controller 1s linear; + -webkit-animation: controller 8s linear; + animation: controller 8s linear; } #controller::before { content: ""; @@ -2816,8 +2811,8 @@ body { height: 6px; left: -18px; bottom: 25px; - -webkit-animation: controller-before 1s linear; - animation: controller-before 1s linear; + -webkit-animation: controller-before 8s linear; + animation: controller-before 8s linear; } #controller::after { content: ""; @@ -2827,8 +2822,8 @@ body { bottom: -24px; left: 45px; background-color: #303030; - -webkit-animation: controller-after 1s linear; - animation: controller-after 1s linear; + -webkit-animation: controller-after 8s linear; + animation: controller-after 8s linear; } @-moz-keyframes speaker { 0% { @@ -2917,8 +2912,8 @@ body { bottom: 24px; border-radius: 100%; background-color: #222222; - -webkit-animation: speaker 1s linear; - animation: speaker 1s linear; + -webkit-animation: speaker 8s linear; + animation: speaker 8s linear; } #speaker::after { content: ""; @@ -3029,8 +3024,8 @@ body { left: 76px; background-color: #ffffff; border: 5px #808080 solid; - -webkit-animation: whitescreen 1s linear; - animation: whitescreen 1s linear; + -webkit-animation: whitescreen 8s linear; + animation: whitescreen 8s linear; } @-moz-keyframes screen { 0% { @@ -3158,8 +3153,8 @@ body { bottom: 278px; border-radius: 10px 10px 50% 50% / 10px 10px 20px 20px; background-color: #222222; - -webkit-animation: screen 1s linear; - animation: screen 1s linear; + -webkit-animation: screen 8s linear; + animation: screen 8s linear; } @-moz-keyframes glass-gameboy-text { 0% { @@ -3210,8 +3205,8 @@ body { white-space: nowrap; -webkit-transform: skew(-5deg); transform: skew(-5deg); - -webkit-animation: glass-gameboy-text 1s linear; - animation: glass-gameboy-text 1s linear; + -webkit-animation: glass-gameboy-text 8s linear; + animation: glass-gameboy-text 8s linear; } @-moz-keyframes glass-color-text { 0% { @@ -3352,8 +3347,8 @@ body { font-size: 23px; letter-spacing: -2px; font-weight: 700; - -webkit-animation: glass-color-text 1s linear; - animation: glass-color-text 1s linear; + -webkit-animation: glass-color-text 8s linear; + animation: glass-color-text 8s linear; } #glass-color-text::before { content: "L"; @@ -3367,8 +3362,8 @@ body { border-radius: 50%; width: 7px; height: 7px; - -webkit-animation: glass-color-text-before 1s linear; - animation: glass-color-text-before 1s linear; + -webkit-animation: glass-color-text-before 8s linear; + animation: glass-color-text-before 8s linear; } #glass-color-text::after { content: "R"; @@ -3382,8 +3377,8 @@ body { border-radius: 50%; width: 7px; height: 7px; - -webkit-animation: glass-color-text-after 1s linear; - animation: glass-color-text-after 1s linear; + -webkit-animation: glass-color-text-after 8s linear; + animation: glass-color-text-after 8s linear; } @-moz-keyframes glass { 0% { @@ -3498,8 +3493,8 @@ body { left: 80px; top: 60px; background-color: #f0f0f0; - -webkit-animation: glass 1s linear; - animation: glass 1s linear; + -webkit-animation: glass 8s linear; + animation: glass 8s linear; } @-moz-keyframes screen-gameboy-text { 0% { @@ -3667,8 +3662,8 @@ body { background-position: 130px; -webkit-background-clip: text; -webkit-text-fill-color: transparent; - -webkit-animation: screen-gameboy-text 1s linear; - animation: screen-gameboy-text 1s linear; + -webkit-animation: screen-gameboy-text 8s linear; + animation: screen-gameboy-text 8s linear; } @-moz-keyframes screen-nintendo-text { 0% { @@ -3730,8 +3725,8 @@ body { font-family: Arial Black, sans-serif; font-weight: 700; font-size: 13px; - -webkit-animation: screen-nintendo-text 1s linear; - animation: screen-nintendo-text 1s linear; + -webkit-animation: screen-nintendo-text 8s linear; + animation: screen-nintendo-text 8s linear; } @-moz-keyframes joystick-pad { 0% { @@ -3861,8 +3856,8 @@ body { background-color: #f0f0f0; left: 11px; bottom: 130px; - -webkit-animation: joystick-pad 1s linear; - animation: joystick-pad 1s linear; + -webkit-animation: joystick-pad 8s linear; + animation: joystick-pad 8s linear; } @-moz-keyframes joystick { 0% { @@ -4060,8 +4055,8 @@ body { line-height: 44px; text-indent: 43px; color: #222222; - -webkit-animation: joystick 1s linear; - animation: joystick 1s linear; + -webkit-animation: joystick 8s linear; + animation: joystick 8s linear; } #joystick::before, #joystick::after { @@ -4083,8 +4078,8 @@ body { text-align: center; font-size: 16px; color: #222222; - -webkit-animation: joystick-control 1s linear; - animation: joystick-control 1s linear; + -webkit-animation: joystick-control 8s linear; + animation: joystick-control 8s linear; } #joystick::after { -webkit-transform: rotateZ(-90deg); @@ -4235,8 +4230,8 @@ body { box-shadow: 0 3px; -webkit-transform: rotate(-18deg); transform: rotate(-18deg); - -webkit-animation: control 1s linear; - animation: control 1s linear; + -webkit-animation: control 8s linear; + animation: control 8s linear; } .control-button { position: absolute; @@ -4332,8 +4327,8 @@ body { color: white; right: 97px; bottom: 156px; - -webkit-animation: control-b 1s linear; - animation: control-b 1s linear; + -webkit-animation: control-b 8s linear; + animation: control-b 8s linear; } @-moz-keyframes control-a { 0% { @@ -4414,8 +4409,8 @@ body { color: white; right: 34px; bottom: 176px; - -webkit-animation: control-a 1s linear; - animation: control-a 1s linear; + -webkit-animation: control-a 8s linear; + animation: control-a 8s linear; } @-moz-keyframes start-select-box { 0% { @@ -4550,8 +4545,8 @@ body { bottom: 85px; left: 120px; background-color: #f0f0f0; - -webkit-animation: start-select-box 1s linear; - animation: start-select-box 1s linear; + -webkit-animation: start-select-box 8s linear; + animation: start-select-box 8s linear; } #start-select-box::before { content: ""; @@ -4564,8 +4559,8 @@ body { background-color: #9d9d9d; left: 5px; box-shadow: 50px 0 #9d9d9d; - -webkit-animation: start-select-pad 1s linear; - animation: start-select-pad 1s linear; + -webkit-animation: start-select-pad 8s linear; + animation: start-select-pad 8s linear; } @-moz-keyframes start-select-button { 0% { @@ -4637,8 +4632,8 @@ body { background-color: #303030; border-radius: 80% / 100%; box-shadow: 50px 0 #303030; - -webkit-animation: start-select-button 1s linear; - animation: start-select-button 1s linear; + -webkit-animation: start-select-button 8s linear; + animation: start-select-button 8s linear; } #cover-vertical { position: absolute; @@ -4787,8 +4782,8 @@ body { } #gameboy.transparent #cover-vertical { background-color: rgba(140, 46, 217, 0.125); - -webkit-animation: cover-vertical-transparent 1s linear; - animation: cover-vertical-transparent 1s linear; + -webkit-animation: cover-vertical-transparent 8s linear; + animation: cover-vertical-transparent 8s linear; box-shadow: 34px 0 rgba(140, 46, 217, 0.125), 68px 0 rgba(140, 46, 217, 0.125), 102px 0 rgba(140, 46, 217, 0.125), 136px 0 rgba(140, 46, 217, 0.125), 170px 0 rgba(140, 46, 217, 0.125), 204px 0 rgba(140, 46, 217, 0.125), 238px 0 rgba(140, 46, 217, 0.125), 272px 0 rgba(140, 46, 217, 0.125), 306px 0 rgba(140, 46, 217, 0.125); } @-moz-keyframes cover-vertical-teal { @@ -4931,8 +4926,8 @@ body { } #gameboy.teal #cover-vertical { background-color: #01b4dd; - -webkit-animation: cover-vertical-teal 1s linear; - animation: cover-vertical-teal 1s linear; + -webkit-animation: cover-vertical-teal 8s linear; + animation: cover-vertical-teal 8s linear; box-shadow: 34px 0 #01b4dd, 68px 0 #01b4dd, 102px 0 #01b4dd, 136px 0 #01b4dd, 170px 0 #01b4dd, 204px 0 #01b4dd, 238px 0 #01b4dd, 272px 0 #01b4dd, 306px 0 #01b4dd; } @-moz-keyframes cover-vertical-yellow { @@ -5075,8 +5070,8 @@ body { } #gameboy.yellow #cover-vertical { background-color: #f9e52e; - -webkit-animation: cover-vertical-yellow 1s linear; - animation: cover-vertical-yellow 1s linear; + -webkit-animation: cover-vertical-yellow 8s linear; + animation: cover-vertical-yellow 8s linear; box-shadow: 34px 0 #f9e52e, 68px 0 #f9e52e, 102px 0 #f9e52e, 136px 0 #f9e52e, 170px 0 #f9e52e, 204px 0 #f9e52e, 238px 0 #f9e52e, 272px 0 #f9e52e, 306px 0 #f9e52e; } @-moz-keyframes cover-vertical-green { @@ -5219,8 +5214,8 @@ body { } #gameboy.green #cover-vertical { background-color: #85e367; - -webkit-animation: cover-vertical-green 1s linear; - animation: cover-vertical-green 1s linear; + -webkit-animation: cover-vertical-green 8s linear; + animation: cover-vertical-green 8s linear; box-shadow: 34px 0 #85e367, 68px 0 #85e367, 102px 0 #85e367, 136px 0 #85e367, 170px 0 #85e367, 204px 0 #85e367, 238px 0 #85e367, 272px 0 #85e367, 306px 0 #85e367; } @-moz-keyframes cover-vertical-purple { @@ -5363,8 +5358,8 @@ body { } #gameboy.purple #cover-vertical { background-color: #5151dd; - -webkit-animation: cover-vertical-purple 1s linear; - animation: cover-vertical-purple 1s linear; + -webkit-animation: cover-vertical-purple 8s linear; + animation: cover-vertical-purple 8s linear; box-shadow: 34px 0 #5151dd, 68px 0 #5151dd, 102px 0 #5151dd, 136px 0 #5151dd, 170px 0 #5151dd, 204px 0 #5151dd, 238px 0 #5151dd, 272px 0 #5151dd, 306px 0 #5151dd; } @-moz-keyframes cover-vertical-red { @@ -5507,8 +5502,8 @@ body { } #gameboy.red #cover-vertical { background-color: #ff0151; - -webkit-animation: cover-vertical-red 1s linear; - animation: cover-vertical-red 1s linear; + -webkit-animation: cover-vertical-red 8s linear; + animation: cover-vertical-red 8s linear; box-shadow: 34px 0 #ff0151, 68px 0 #ff0151, 102px 0 #ff0151, 136px 0 #ff0151, 170px 0 #ff0151, 204px 0 #ff0151, 238px 0 #ff0151, 272px 0 #ff0151, 306px 0 #ff0151; } #cover-horizontal { @@ -5704,8 +5699,8 @@ body { } #gameboy.transparent #cover-horizontal { background-color: rgba(140, 46, 217, 0.125); - -webkit-animation: cover-horizontal-transparent 1s linear; - animation: cover-horizontal-transparent 1s linear; + -webkit-animation: cover-horizontal-transparent 8s linear; + animation: cover-horizontal-transparent 8s linear; box-shadow: 0 -38px rgba(140, 46, 217, 0.125), 0 -76px rgba(140, 46, 217, 0.125), 0 -114px rgba(140, 46, 217, 0.125), 0 -152px rgba(140, 46, 217, 0.125), 0 -190px rgba(140, 46, 217, 0.125), 0 -228px rgba(140, 46, 217, 0.125), 0 -266px rgba(140, 46, 217, 0.125), 0 -304px rgba(140, 46, 217, 0.125), 0 -342px rgba(140, 46, 217, 0.125), 0 -380px rgba(140, 46, 217, 0.125), 0 -418px rgba(140, 46, 217, 0.125), 0 -456px rgba(140, 46, 217, 0.125), 0 -494px rgba(140, 46, 217, 0.125), 0 -532px rgba(140, 46, 217, 0.125); } @-moz-keyframes cover-horizontal-teal { @@ -5893,8 +5888,8 @@ body { } #gameboy.teal #cover-horizontal { background-color: #01b4dd; - -webkit-animation: cover-horizontal-teal 1s linear; - animation: cover-horizontal-teal 1s linear; + -webkit-animation: cover-horizontal-teal 8s linear; + animation: cover-horizontal-teal 8s linear; box-shadow: 0 -38px #01b4dd, 0 -76px #01b4dd, 0 -114px #01b4dd, 0 -152px #01b4dd, 0 -190px #01b4dd, 0 -228px #01b4dd, 0 -266px #01b4dd, 0 -304px #01b4dd, 0 -342px #01b4dd, 0 -380px #01b4dd, 0 -418px #01b4dd, 0 -456px #01b4dd, 0 -494px #01b4dd, 0 -532px #01b4dd; } @-moz-keyframes cover-horizontal-yellow { @@ -6082,8 +6077,8 @@ body { } #gameboy.yellow #cover-horizontal { background-color: #f9e52e; - -webkit-animation: cover-horizontal-yellow 1s linear; - animation: cover-horizontal-yellow 1s linear; + -webkit-animation: cover-horizontal-yellow 8s linear; + animation: cover-horizontal-yellow 8s linear; box-shadow: 0 -38px #f9e52e, 0 -76px #f9e52e, 0 -114px #f9e52e, 0 -152px #f9e52e, 0 -190px #f9e52e, 0 -228px #f9e52e, 0 -266px #f9e52e, 0 -304px #f9e52e, 0 -342px #f9e52e, 0 -380px #f9e52e, 0 -418px #f9e52e, 0 -456px #f9e52e, 0 -494px #f9e52e, 0 -532px #f9e52e; } @-moz-keyframes cover-horizontal-green { @@ -6271,8 +6266,8 @@ body { } #gameboy.green #cover-horizontal { background-color: #85e367; - -webkit-animation: cover-horizontal-green 1s linear; - animation: cover-horizontal-green 1s linear; + -webkit-animation: cover-horizontal-green 8s linear; + animation: cover-horizontal-green 8s linear; box-shadow: 0 -38px #85e367, 0 -76px #85e367, 0 -114px #85e367, 0 -152px #85e367, 0 -190px #85e367, 0 -228px #85e367, 0 -266px #85e367, 0 -304px #85e367, 0 -342px #85e367, 0 -380px #85e367, 0 -418px #85e367, 0 -456px #85e367, 0 -494px #85e367, 0 -532px #85e367; } @-moz-keyframes cover-horizontal-purple { @@ -6460,8 +6455,8 @@ body { } #gameboy.purple #cover-horizontal { background-color: #5151dd; - -webkit-animation: cover-horizontal-purple 1s linear; - animation: cover-horizontal-purple 1s linear; + -webkit-animation: cover-horizontal-purple 8s linear; + animation: cover-horizontal-purple 8s linear; box-shadow: 0 -38px #5151dd, 0 -76px #5151dd, 0 -114px #5151dd, 0 -152px #5151dd, 0 -190px #5151dd, 0 -228px #5151dd, 0 -266px #5151dd, 0 -304px #5151dd, 0 -342px #5151dd, 0 -380px #5151dd, 0 -418px #5151dd, 0 -456px #5151dd, 0 -494px #5151dd, 0 -532px #5151dd; } @-moz-keyframes cover-horizontal-red { @@ -6649,8 +6644,8 @@ body { } #gameboy.red #cover-horizontal { background-color: #ff0151; - -webkit-animation: cover-horizontal-red 1s linear; - animation: cover-horizontal-red 1s linear; + -webkit-animation: cover-horizontal-red 8s linear; + animation: cover-horizontal-red 8s linear; box-shadow: 0 -38px #ff0151, 0 -76px #ff0151, 0 -114px #ff0151, 0 -152px #ff0151, 0 -190px #ff0151, 0 -228px #ff0151, 0 -266px #ff0151, 0 -304px #ff0151, 0 -342px #ff0151, 0 -380px #ff0151, 0 -418px #ff0151, 0 -456px #ff0151, 0 -494px #ff0151, 0 -532px #ff0151; } @-moz-keyframes gloss { @@ -6713,8 +6708,8 @@ body { left: 54px; border-bottom-left-radius: 116px 20px; border-bottom-right-radius: 116px 20px; - -webkit-animation: gloss 1s linear; - animation: gloss 1s linear; + -webkit-animation: gloss 8s linear; + animation: gloss 8s linear; } #gameboy.transparent #gloss { background-color: rgba(242, 232, 251, 0.43125); @@ -6777,8 +6772,8 @@ body { z-index: 14; border-radius: 50%; box-shadow: 9.5px 8px #222222, 19px 16px #222222, 0px -19px #222222, 9.5px -11px #222222, 19px -3px #222222, 28.5px 5px #222222, 38px 13px #222222, 0px -38px #222222, 9.5px -30px #222222, 19px -22px #222222, 28.5px -14px #222222, 38px -6px #222222, 47.5px 2px #222222, 57px 10px #222222, 9.5px -49px #222222, 19px -41px #222222, 28.5px -33px #222222, 38px -25px #222222, 47.5px -17px #222222, 57px -9px #222222, 66.5px -1px #222222, 28px -52px #222222, 37.5px -44px #222222, 47px -36px #222222, 56.5px -28px #222222, 66px -20px #222222, 47px -56px #222222, 56.5px -48px #222222, 66px -40px #222222; - -webkit-animation: speaker-holes 1s linear; - animation: speaker-holes 1s linear; + -webkit-animation: speaker-holes 8s linear; + animation: speaker-holes 8s linear; } @-moz-keyframes power { 0% { @@ -6865,14 +6860,18 @@ body { border-radius: 50%; background-color: #ff0151; box-shadow: 5px 0 #222222, 8px 0 #b0b0b0, 12px 0 #222222, 15px 0 #b0b0b0, 19px 0 #222222, 22px 0 #b0b0b0; - -webkit-animation: power 1s linear; - animation: power 1s linear; + -webkit-animation: power 8s linear; + animation: power 8s linear; } #colors { + position: fixed; + bottom: 0px; + right: 20px; + font-family: 'Oxygen', Helvetica, arial, sans-serif; font-weight: 300; - width: 100%; - margin: 0 auto 40px; + /* width: 100%; */ + margin: 0 auto 20px; text-align: center; } #colors span { @@ -6919,4 +6918,4 @@ body { a { color: lightblue; -} +} \ No newline at end of file diff --git a/static/gameboy.html b/static/gameboy.html index 54aa6c8f..5f7684a7 100644 --- a/static/gameboy.html +++ b/static/gameboy.html @@ -37,7 +37,7 @@