Skip to content

Commit 6960cf4

Browse files
authored
Merge pull request #1918 from nicolasnoble/psyqo-lua
Creating the psyqo-lua directory.
2 parents 24deb16 + 08d07c0 commit 6960cf4

File tree

11 files changed

+886
-2
lines changed

11 files changed

+886
-2
lines changed

.github/filter-mips/filter.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ cd $CWD
1010

1111
# Need to delete submodules actively.
1212
# Done in two passes for speed.
13-
git filter-branch -f --tree-filter 'find third_party -depth -not -name uC-sdk -and -not -path third_party/EABase -and -not -path third_party/EABase/\* -and -not -path third_party/EASTL -and -not -path third_party/EASTL/\* -delete || true' --tag-name-filter cat --prune-empty
14-
git filter-branch -f --tree-filter 'find third_party -depth -not -name uC-sdk -and -not -path third_party/EABase -and -not -path third_party/EABase/\* -and -not -path third_party/EASTL -and -not -path third_party/EASTL/\* -exec git rm -f {} \; || true' --tag-name-filter cat --prune-empty
13+
git filter-branch -f --tree-filter 'find third_party -depth -not -name uC-sdk -and -not -path third_party/psxlua -and -not -path third_party/EABase -and -not -path third_party/EABase/\* -and -not -path third_party/EASTL -and -not -path third_party/EASTL/\* -delete || true' --tag-name-filter cat --prune-empty
14+
git filter-branch -f --tree-filter 'find third_party -depth -not -name uC-sdk -and -not -path third_party/psxlua -and -not -path third_party/EABase -and -not -path third_party/EABase/\* -and -not -path third_party/EASTL -and -not -path third_party/EASTL/\* -exec git rm -f {} \; || true' --tag-name-filter cat --prune-empty
1515

1616
# Shuffle files around.
1717
git filter-branch -f --tree-filter 'mkdir -p src/mips ; git mv third_party src/mips ; mv .gitmodules src/mips ; mv docker* src/mips || true' --tag-name-filter cat --prune-empty
@@ -33,5 +33,9 @@ git filter-branch -f --tree-filter "find . -name Makefile -exec sed 's|\.\./\.\.
3333
git filter-branch -f --tree-filter "find . -name '*.mk' -exec sed 's|\.\./\.\./\.\./third_party/EABase/|../third_party/EABase/|' -i {} \;" --tag-name-filter cat --prune-empty
3434
git filter-branch -f --tree-filter "find . -name '*.mk' -exec sed 's|\.\./\.\./\.\./third_party/EASTL/|../third_party/EASTL/|' -i {} \;" --tag-name-filter cat --prune-empty
3535

36+
# Adjust paths for psxlua
37+
git filter-branch -f --tree-filter "find . -name Makefile -exec sed 's|\.\./\.\./\.\./third_party/psxlua/|../third_party/psxlua/|' -i {} \;" --tag-name-filter cat --prune-empty
38+
git filter-branch -f --tree-filter "find . -name '*.mk' -exec sed 's|\.\./\.\./\.\./third_party/psxlua/|../third_party/psxlua/|' -i {} \;" --tag-name-filter cat --prune-empty
39+
3640
# Delete unwanted files
3741
git filter-branch -f --tree-filter 'find . -name compile_flags.txt -or -name Doxyfile -delete || true' --tag-name-filter cat --prune-empty

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,6 @@
9797
[submodule "third_party/PEGTL"]
9898
path = third_party/PEGTL
9999
url = https://github.com/taocpp/PEGTL.git
100+
[submodule "third_party/psxlua"]
101+
path = third_party/psxlua
102+
url = https://github.com/grumpycoders/psxlua.git

src/mips/psyqo-lua/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
PSYQOLUADIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
2+
3+
TARGET = psyqo-lua
4+
TYPE = library
5+
6+
SRCS = \
7+
src/lua.cpp \
8+
9+
CPPFLAGS += -I$(PSYQOLUADIR)../../../third_party/psxlua/src
10+
11+
EXTRA_DEPS += $(PSYQOLUADIR)Makefile
12+
13+
include ../psyqo/psyqo.mk

src/mips/psyqo-lua/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# PSYQo Lua
2+
3+
PSYQo Lua is a component of the PCSX-Redux project that integrates the Lua scripting language with PSYQo applications. It provides a streamlined way to leverage Lua's powerful scripting capabilities in your PlayStation applications.
4+
5+
## Features
6+
7+
### Automatic Lua VM Integration
8+
9+
PSYQo Lua automatically links the Lua virtual machine into your project, handling all the necessary build configurations and dependencies, while setting up the necessary glue between the Lua VM and the rest of PSYQo.
10+
11+
### C++ Wrapper for Lua API
12+
13+
The library provides an idiomatic C++ wrapper around the standard Lua C API, offering a modern C++ interfaces that reduce boilerplate code typically associated with Lua scripting.
14+
15+
### Example Implementation
16+
17+
A complete working example is provided in the [examples/hello](examples/hello) folder, demonstrating:
18+
19+
- How to initialize the Lua environment
20+
- Loading and executing Lua scripts
21+
- Exchanging data between C++ and Lua
22+
- Registering C++ functions for use in Lua scripts
23+
24+
## Getting Started
25+
26+
To use PSYQo Lua in your project:
27+
28+
1. Include the PSYQo Lua library in your Makefile:
29+
```makefile
30+
include path/to/psyqo-lua/psyqo-lua.mk
31+
```
32+
33+
1. Include the necessary headers:
34+
```cpp
35+
#include "psyqo-lua/lua.hh"
36+
```
37+
38+
2. Create a Lua VM in your application:
39+
```cpp
40+
psyqo::Lua L;
41+
```
42+
43+
3. Start using Lua in your PlayStation application with the C++ wrapper:
44+
```cpp
45+
L.loadBuffer("print('Hello, PSYQo Lua!')");
46+
L.pcall(0, 0);
47+
```
48+
49+
See the example in [examples/hello](examples/hello) for a more detailed implementation.

src/mips/psyqo-lua/compile_flags.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-m32
2+
-std=c++20
3+
-fcoroutines-ts
4+
-I.
5+
-I..
6+
-I../../../third_party/EASTL/include
7+
-I../../../third_party/EABase/include/Common
8+
-I../../../third_party/psxlua/src
9+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
TARGET = hello
2+
TYPE = ps-exe
3+
4+
SRCS = \
5+
hello.cpp \
6+
7+
ifeq ($(TEST),true)
8+
CPPFLAGS = -Werror
9+
endif
10+
CXXFLAGS = -std=c++20
11+
12+
include ../../psyqo-lua.mk
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
3+
MIT License
4+
5+
Copyright (c) 2025 PCSX-Redux authors
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
*/
26+
27+
#include "EASTL/string.h"
28+
#include "common/syscalls/syscalls.h"
29+
#include "psyqo-lua/lua.hh"
30+
#include "psyqo/application.hh"
31+
#include "psyqo/font.hh"
32+
#include "psyqo/gpu.hh"
33+
#include "psyqo/scene.hh"
34+
35+
namespace {
36+
37+
// Simple Lua script for demonstration
38+
constexpr const char DEMO_SCRIPT[] = R"(
39+
-- Simple Lua script to show psyqo::Lua functionality
40+
function factorial(n)
41+
if n <= 1 then
42+
return 1
43+
else
44+
return n * factorial(n - 1)
45+
end
46+
end
47+
48+
-- Calculate some values
49+
results = {
50+
factorial = factorial(5),
51+
message = 'Hello from Lua!',
52+
number = 42,
53+
table = {1, 2, 3, 'testing'}
54+
}
55+
56+
-- Call our C++ function
57+
greet 'Lua script'
58+
59+
return results
60+
)";
61+
62+
// C++ function to be called from Lua
63+
int luaGreet(psyqo::Lua L) {
64+
// Get the name parameter from Lua
65+
const char* name = L.checkString(1);
66+
67+
// Print to debug output (if available)
68+
ramsyscall_printf("Greeting from C++: Hello, %s!\n", name);
69+
70+
// No return values
71+
return 0;
72+
}
73+
74+
class LuaExample final : public psyqo::Application {
75+
void prepare() override;
76+
void createScene() override;
77+
78+
public:
79+
psyqo::Font<> m_font;
80+
psyqo::Lua L;
81+
82+
// Results from Lua execution
83+
eastl::string m_luaMessage;
84+
int m_luaNumber = 0;
85+
int m_luaFactorial = 0;
86+
bool m_luaSuccess = false;
87+
};
88+
89+
class LuaExampleScene final : public psyqo::Scene {
90+
void frame() override;
91+
};
92+
93+
LuaExample luaExample;
94+
LuaExampleScene luaExampleScene;
95+
96+
} // namespace
97+
98+
void LuaExample::prepare() {
99+
psyqo::GPU::Configuration config;
100+
config.set(psyqo::GPU::Resolution::W320)
101+
.set(psyqo::GPU::VideoMode::AUTO)
102+
.set(psyqo::GPU::ColorMode::C15BITS)
103+
.set(psyqo::GPU::Interlace::PROGRESSIVE);
104+
gpu().initialize(config);
105+
106+
// Initialize Lua and register our functions
107+
L.push(luaGreet);
108+
L.setGlobal("greet");
109+
110+
// Execute our demo script
111+
if (L.loadBuffer(DEMO_SCRIPT, "demo") == 0) {
112+
// Script loaded successfully, now execute it
113+
if (L.pcall(0, 1) == 0) {
114+
// Script executed successfully
115+
m_luaSuccess = true;
116+
117+
// Get the results table
118+
if (L.isTable(-1)) {
119+
// Extract factorial result
120+
L.getField(-1, "factorial");
121+
if (L.isNumber(-1)) {
122+
m_luaFactorial = L.toNumber(-1);
123+
}
124+
L.pop();
125+
126+
// Extract message
127+
L.getField(-1, "message");
128+
if (L.isString(-1)) {
129+
m_luaMessage = L.toString(-1);
130+
}
131+
L.pop();
132+
133+
// Extract number
134+
L.getField(-1, "number");
135+
if (L.isNumber(-1)) {
136+
m_luaNumber = L.toNumber(-1);
137+
}
138+
L.pop();
139+
}
140+
141+
// Clean stack
142+
L.pop();
143+
} else {
144+
// Script execution failed, get error message
145+
m_luaMessage = "Error: ";
146+
m_luaMessage += L.isString(-1) ? L.toString(-1) : "Unknown error";
147+
L.pop();
148+
}
149+
} else {
150+
// Script loading failed, get error message
151+
m_luaMessage = "Error loading script: ";
152+
m_luaMessage += L.isString(-1) ? L.toString(-1) : "Unknown error";
153+
L.pop();
154+
}
155+
}
156+
157+
void LuaExample::createScene() {
158+
m_font.uploadSystemFont(gpu());
159+
pushScene(&luaExampleScene);
160+
}
161+
162+
void LuaExampleScene::frame() {
163+
auto& gpu = luaExample.gpu();
164+
auto& font = luaExample.m_font;
165+
psyqo::Color textColor = {.r = 255, .g = 255, .b = 255};
166+
167+
// Clear the screen with a nice background color
168+
gpu.clear({{.r = 0, .g = 64, .b = 91}});
169+
170+
// Display title
171+
font.print(gpu, "PSYQo Lua Example", {{.x = 16, .y = 32}}, textColor);
172+
173+
if (luaExample.m_luaSuccess) {
174+
// Display results from Lua execution
175+
font.print(gpu, "Lua script executed successfully!", {{.x = 16, .y = 64}}, textColor);
176+
font.printf(gpu, {{.x = 16, .y = 80}}, textColor, "Message from Lua: %s", luaExample.m_luaMessage.c_str());
177+
font.printf(gpu, {{.x = 16, .y = 96}}, textColor, "Number from Lua: %d", luaExample.m_luaNumber);
178+
font.printf(gpu, {{.x = 16, .y = 112}}, textColor, "Factorial(5) from Lua: %d", luaExample.m_luaFactorial);
179+
180+
// Example of calling Lua function from C++
181+
luaExample.L.getGlobal("factorial");
182+
luaExample.L.pushNumber(7); // Calculate factorial of 7
183+
if (luaExample.L.pcall(1, 1) != 0) {
184+
// Error occurred
185+
font.print(gpu, "Error calling factorial(7):", {{.x = 16, .y = 128}}, textColor);
186+
font.print(gpu, luaExample.L.toString(-1), {{.x = 16, .y = 144}}, textColor);
187+
} else {
188+
int factorial7 = luaExample.L.toNumber(-1);
189+
font.printf(gpu, {{.x = 16, .y = 144}}, textColor, "Calling factorial(7) from C++: %d", factorial7);
190+
}
191+
luaExample.L.pop();
192+
} else {
193+
// Display error message
194+
font.print(gpu, "Lua script execution failed:", {{.x = 16, .y = 64}}, textColor);
195+
font.print(gpu, luaExample.m_luaMessage.c_str(), {{.x = 16, .y = 80}}, textColor);
196+
}
197+
}
198+
199+
int main() { return luaExample.run(); }

0 commit comments

Comments
 (0)