Skip to content

Commit

Permalink
feat: add support HTTP to ginga (#28)
Browse files Browse the repository at this point in the history
* feat: turn HTTP asyncronous

* feat: improve event loop ginga

* feat: start http_ginga

* feat: ginga http protocol working

* feat: error when 3xx https in ginga

* feat: improve http and test in ginga

* feat: http ginga requests context

* fix: ginga without bit lib support colors

* tests: http_ginga protocol

* feat: improve launcher

* fix: launcher example running in blocking http

* docs: hidden functions in example laucnher

* change: small adjusts in the ginga/launcher

* fix: lua 5.1 compatibility

* feat: cmd run default core is love

* tests: ginga test_http_simultaneous_requests

* feat: improve ginga_http flow

* feat: http ginga support redirects

* change: dequeue requests in fixed loop

* feat: improve responsive in html5 cores

* style: improve responsive on mobile

* feat: add support to samsung #21

* feat: standardize http
  • Loading branch information
RodrigoDornelles authored Aug 7, 2024
1 parent c2d67f9 commit 3a51c47
Show file tree
Hide file tree
Showing 25 changed files with 1,762 additions and 328 deletions.
2 changes: 2 additions & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ EXTENSION_MAPPING = .lua=C++
INPUT = README.md SUPPORT.md src examples
USE_MDFILE_AS_MAINPAGE = README.md
MARKDOWN_ID_STYLE = GITHUB
ALIASES += startjson=@startuml{json}
ALIASES += endjson=@enduml
ALIASES += startebnf=@startuml{ebnf}
ALIASES += endebnf=@enduml
# Theme: https://jothepro.github.io/doxygen-awesome-css/
Expand Down
266 changes: 206 additions & 60 deletions examples/launcher/game.lua
Original file line number Diff line number Diff line change
@@ -1,99 +1,245 @@
local function init(std, game)
if game.multi_state == 4 then
game.application.callbacks.init(std, game)
return
--! @file examples/launcher/game.lua
--!
--! @startuml
--! hide empty description
--! skinparam State {
--! FontColor white
--! }
--! state 1 as "boot" #sienna
--! state 2 as "download csv" #darkblue
--! state 3 as "parse csv" #darkgreen
--! state 4 as "menu launcher" #gray
--! state 5 as "download game" #blue
--! state 6 as "load game" #green
--! state 7 as "run game" #black
--! state 8 as "exit game" #brown
--! state 9 as "http failed" #orange
--! state 10 as "error" #red
--!
--! [*] --> 1
--! 1 --> 2
--! 2 --> 3
--! 3 --> 4
--! 4 --> 5
--! 5 --> 6
--! 6 --> 7
--! 7 --> 8
--! 8 --> 4
--! 2 --> 9
--! 5 --> 9
--! 1 -[dotted]-> 10
--! 2 -[dotted]-> 10
--! 3 -[dotted]-> 10
--! 4 -[dotted]-> 10
--! 5 -[dotted]-> 10
--! 6 -[dotted]-> 10
--! 7 -[dotted]-> 10
--! 8 -[dotted]-> 10
--! 10 --> [*]
--! 9 --> [*]
--! @enduml

--! @cond
local function next_state(game, new_state)
if game._state + 1 == new_state then
game._state = new_state
end
if game._state == 2 and new_state == 9 then
game._state = new_state
end
if game._state == 5 and new_state == 9 then
game._state = new_state
end
if game._state == 8 and new_state == 4 then
game._state = new_state
end
local registry = 'gist.githubusercontent.com/RodrigoDornelles/7ee1ac926b76442d6c303c3a291037c4/raw/c3597529459e487eadccd8597fb1dc72e5034096/games.csv'
game.multi_text = 'booting...'
game.multi_state = 1
game.multi_menu = 1
game.multi_menu_time = game.milis
game.multi_list = {}
std.http.get(registry):run()
end

local function http(std, game)
if std.http.ok and game.multi_state == 1 then
std.csv(std.http.body, game.multi_list)
game.multi_state = 2
elseif std.http.ok and game.multi_state == 3 then
game.multi_state = 1
game.application = load(std.http.body)
game.application = game.application and game.application()
if game.application then
game.multi_state = 4
std.game.exit = function()
game.multi_menu_time = game.milis
game.multi_state = 2
end
game.application.callbacks.init(std, game)
game.menu_time = game.milis
local function halt_state(game)
return function (func)
local ok, message = pcall(func)
if not ok then
game._state = 10
game._error = message
end
else
game.multi_state = 1
game.multi_text = std.http.body or std.http.error
end
end
--! @endcond

local function loop(std, game)
if game.multi_state == 2 then
local key = std.key.press.down - std.key.press.up
if key ~= 0 and game.milis > game.multi_menu_time + 250 then
game.multi_menu = std.math.clamp2(game.multi_menu + key, 1, 2)
game.multi_menu_time = game.milis
local function init(std, game)
if not game._state then
game._state = 0
game._menu = 1
game._csv = ''
game._list = {}
game._source = ''
game._menu_time = game.milis
game._want_leave = false
std.game.exit = function ()
game._want_leave = true
end
end
if game._state == 7 then
halt_state(game)(function()
game._app.callbacks.init(std, game)
end)
end
end

local function http(std, game)
halt_state(game)(function ()
if std.http.error then
error(std.http.error)
end
if not std.http.ok then
next_state(game, 9)
game._status = std.http.status
game._error = std.http.body
end
if std.http.body and #std.http.body == 0 then
next_state(game, 9)
game._status = std.http.status
game._error = '<empty>'
end
if game._state == 2 then
game._csv = std.http.body
end
if std.key.press.enter == 1 and game.milis > game.multi_menu_time + 250 then
game.multi_state = 3
game.multi_menu_time = game.milis
std.http.get(game.multi_list[game.multi_menu].raw_url):run()
if game._state == 5 then
game._source = std.http.body
end
elseif game.multi_state == 4 then
game.application.callbacks.loop(std, game)
end)
end

local function loop(std, game)
if game._state == 0 then
next_state(game, 1)
elseif game._state == 1 then
halt_state(game)(function()
next_state(game, 2)
std.http.get('http://gh.dornelles.me/games.csv'):run()
end)
elseif game._state == 2 and #game._csv > 0 then
next_state(game, 3)
elseif game._state == 3 then
halt_state(game)(function()
std.csv(game._csv, game._list)
game._csv = ''
next_state(game, 4)
end)
elseif game._state == 4 then
halt_state(game)(function()
local key = std.key.press.down - std.key.press.up
if key ~= 0 and game.milis > game._menu_time + 250 then
game._menu = std.math.clamp2(game._menu + key, 1, #game._list)
game._menu_time = game.milis
end
if std.key.press.enter == 1 and game.milis > game._menu_time + 250 then
game._menu_time = game.milis
next_state(game, 5)
std.http.get(game._list[game._menu].raw_url):run()
end
end)
elseif game._state == 5 and #game._source > 0 then
next_state(game, 6)
elseif game._state == 6 then
halt_state(game)(function()
game._app = std.game.load(game._source)
game._app.callbacks.init(std, game)
game._source = ''
next_state(game, 7)
end)
elseif game._state == 7 then
halt_state(game)(function()
if not game._want_leave then
game._app.callbacks.loop(std, game)
else
game._app.callbacks.exit(std, game)
game._want_leave = false
next_state(game, 8)
end
end)
elseif game._state == 8 then
halt_state(game)(function()
game._menu_time = game.milis
game._app.callbacks.exit(std, game)
next_state(game, 4)
end)
end
end

local function draw(std, game)
if game.multi_state == 1 then
std.draw.clear(std.color.red)
if game._state == 1 then
std.draw.clear(std.color.darkbrown)
std.draw.color(std.color.white)
std.draw.text(8, 8, game.multi_text)
elseif game.multi_state == 3 then
std.draw.clear(std.color.blue)
std.draw.text(8, 8, 'booting...')
elseif game._state == 2 then
std.draw.clear(std.color.darkblue)
std.draw.color(std.color.white)
std.draw.text(8, 8, 'loading...')
elseif game.multi_state == 2 then
std.draw.text(8, 8, 'downloading csv...')
elseif game._state == 3 then
std.draw.clear(std.color.darkgreen)
std.draw.color(std.color.white)
std.draw.text(8, 8, 'parsing csv...')
elseif game._state == 4 then
local s = 0
std.draw.clear(std.color.darkgray)
std.draw.color(std.color.white)
local index = 1
while index <= #game.multi_list do
std.draw.text(16, 8 + (index * 14), game.multi_list[index].title)
std.draw.text(100, 8 + (index * 14), game.multi_list[index].version)
s=std.math.max(std.draw.text(200, 8 + (index * 12), game.multi_list[index].author), s)
while index <= #game._list do
std.draw.text(16, 8 + (index * 14), game._list[index].title)
std.draw.text(100, 8 + (index * 14), game._list[index].version)
s=std.math.max(std.draw.text(200, 8 + (index * 12), game._list[index].author), s)
index = index + 1
end
std.draw.color(std.color.red)
std.draw.rect(1, 16, 5 + (game.multi_menu * 16), 200 + s, 14)
elseif game.multi_state == 4 then
game.application.callbacks.draw(std, game)
std.draw.rect(1, 16, 5 + (game._menu * 16), 200 + s, 14)
elseif game._state == 5 then
std.draw.clear(std.color.blue)
std.draw.color(std.color.white)
std.draw.text(8, 8, 'download game...')
elseif game._state == 6 then
std.draw.clear(std.color.green)
std.draw.color(std.color.white)
std.draw.text(8, 8, 'loading game...')
elseif game._state == 7 then
halt_state(game)(function()
game._app.callbacks.draw(std, game)
end)
elseif game._state == 8 then
std.draw.clear(std.color.gold)
std.draw.color(std.color.white)
std.draw.text(8, 8, 'exiting game...')
elseif game._state == 9 then
std.draw.clear(std.color.orange)
std.draw.color(std.color.white)
std.draw.text(8, 8, 'HTTP ERROR:')
std.draw.text(200, 8, game._status)
std.draw.text(8, 32, game._error)
elseif game._state == 10 then
std.draw.clear(std.color.red)
std.draw.color(std.color.white)
std.draw.text(8, 8, 'FATAL ERROR:')
std.draw.text(8, 32, game._error)
end
end

local function exit(std, game)
if game.multi_state == 4 then
game.application.callbacks.exit(std, game)
if game._state == 7 then
halt_state(game)(function()
game._app.callbacks.exit(std, game)
end)
end
end

local P = {
meta={
title='Launcher Games',
description='a online multi game list',
description='online multi game list',
author='Rodrigo Dornelles',
version='1.0.0'
},
config={
require='http random math csv'
require='http random math csv load'
},
callbacks={
init=init,
Expand Down
3 changes: 3 additions & 0 deletions src/cli/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ local core_list = {
}

if command == 'run' then
if not zeebo_args.get(arg, 'core') then
core = 'love'
end
if not core_list[core] or not core_list[core].exe then
print('this core cannot be runned!')
os.exit(1)
Expand Down
20 changes: 15 additions & 5 deletions src/engine/core/ginga/draw.lua
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
local bit = require('bit32')
local math = require('math')

--! @cond
local canvas = nil
local game = nil
--! @endcond

local function color(c)
local R = bit.band(bit.rshift(c, 24), 0xFF)
local G = bit.band(bit.rshift(c, 16), 0xFF)
local B = bit.band(bit.rshift(c, 8), 0xFF)
local A = bit.band(bit.rshift(c, 0), 0xFF)
local R = math.floor(c/0x1000000)
local G = math.floor(c/0x10000) - (R * 0x100)
local B = math.floor(c/0x100) - (R * 0x10000) - (G * 0x100)
local A = c - (R * 0x1000000) - (G * 0x10000) - (B * 0x100)
canvas:attrColor(R, G, B, A)
end

Expand Down Expand Up @@ -48,6 +48,16 @@ local function install(std, lgame, application, ginga)
std.draw.text=text
std.draw.font=font
std.draw.line=line
local index = #application.internal.fixed_loop + 1
application.internal.fixed_loop[index] = function ()
canvas:attrColor(0, 0, 0, 0)
canvas:clear()
application.callbacks.draw(std, game)
if game.fps_show and game.fps_show >= 0 and std.draw.fps then
std.draw.fps(game.fps_show, 8, 8)
end
canvas:flush()
end
return std.draw
end

Expand Down
Loading

0 comments on commit 3a51c47

Please sign in to comment.