Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f21626136 | |||
| 50a9070d2d | |||
| 8ed34abb83 | |||
| f6ebd079f5 | |||
| 0f7083aa5b | |||
| 9baad8199a | |||
| 5eafc0bdba | |||
| c3c649dcdc | |||
| 1c4a84dffa | |||
| f727dae150 | |||
| 9b24ea3bb6 | |||
| 586180764e | |||
| a329ea73cc | |||
| 5418e28b73 | |||
| d773173ece | |||
| aa21baaaf2 | |||
| 0c0fcd697f | |||
| e07cfc502a | |||
| ab08a385a6 | |||
| 8642959d70 | |||
| 19ae6de1c7 | |||
| c40558bd54 | |||
| 700e878e61 | |||
| 9ee1df81e6 | |||
| 22ecaffe1b | |||
| 26285c54e9 | |||
| a52e2bec0e | |||
| 5583c7bc92 | |||
| b8e5309119 | |||
| fdc5450181 | |||
| 39a962c59b | |||
| b84bd99059 | |||
| caa0fd4db3 | |||
| daee3b4971 | |||
| 02a23cd415 | |||
| c2e653c059 | |||
| 676ac34ec3 | |||
| e229b34ad3 | |||
| 67f70f80d8 | |||
| 1e046d9dda | |||
| 383cdb3675 | |||
| 795910de69 | |||
| b344fd4141 | |||
| b3ff38af06 | |||
| 19c673767c | |||
| 15a2dbb854 | |||
| f4f527b877 | |||
| ce4e2f663f | |||
| 7736f00d71 | |||
| 878adf5dbb | |||
| d2da130771 | |||
| 588f45e870 | |||
| b19d4f42f5 | |||
| ea5849095e | |||
| e2790d93b6 | |||
| 7401926202 | |||
| 200a68e219 | |||
| 699e5f0ff5 | |||
| e63ae14792 | |||
| 87b983153a | |||
| cab934763f | |||
| 20d2291a88 | |||
| 4f6e55c0b0 | |||
| fbcb38d37a | |||
| a25594b95c | |||
| 86c0ab74f1 | |||
| 17d2d93d45 | |||
| f546604ba3 | |||
| d196290a3f | |||
| 481ccd0cf9 | |||
| e3726600fd | |||
| 8b8500a1c9 | |||
| 789c795c14 | |||
| a0be9022ff | |||
| 77c6702f80 | |||
| d54cba9e58 | |||
| 958ddb4ab7 | |||
| edff3a85d5 | |||
| 165cc4221e | |||
| cc42bbf56b | |||
| a340540d55 | |||
| d790349ab9 | |||
| 0cecbf0a7d | |||
| f46b058ecf | |||
| c833f93db2 | |||
| 6dc73982f9 |
@@ -0,0 +1,69 @@
|
|||||||
|
name: Official build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: h4570/tyra
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt install -y git make wget
|
||||||
|
|
||||||
|
- name: Set git safe directory
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Compile engine
|
||||||
|
run: |
|
||||||
|
make clean all -C engine
|
||||||
|
|
||||||
|
- name: Compile tutorials
|
||||||
|
run: |
|
||||||
|
make clean all -C tutorials/01-hello
|
||||||
|
make clean all -C tutorials/02-sprite
|
||||||
|
make clean all -C tutorials/03-minecraft
|
||||||
|
make clean all -C tutorials/04-de_dust2
|
||||||
|
make clean all -C tutorials/05-animation
|
||||||
|
make clean all -C tutorials/06-audio
|
||||||
|
make clean all -C tutorials/07-lighting
|
||||||
|
make clean all -C tutorials/08-skybox-debug
|
||||||
|
make clean all -C tutorials/09-manual-mode
|
||||||
|
make clean all -C tutorials/10-sprite-sheet
|
||||||
|
|
||||||
|
- name: Compile demo
|
||||||
|
run: |
|
||||||
|
make clean all -C demo
|
||||||
|
|
||||||
|
- name: Upload tutorials
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: tutorials-elf
|
||||||
|
path: |
|
||||||
|
tutorials/01-hello/bin
|
||||||
|
tutorials/02-sprite/bin
|
||||||
|
tutorials/03-minecraft/bin
|
||||||
|
tutorials/04-de_dust2/bin
|
||||||
|
tutorials/05-animation/bin
|
||||||
|
tutorials/06-audio/bin
|
||||||
|
tutorials/07-lighting/bin
|
||||||
|
tutorials/08-skybox-debug/bin
|
||||||
|
tutorials/09-manual-mode/bin
|
||||||
|
tutorials/10-sprite-sheet/bin
|
||||||
|
|
||||||
|
- name: Upload demo
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: demo-elf
|
||||||
|
path: |
|
||||||
|
demo/bin
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
name: PR build check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: h4570/tyra
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt install -y git make wget
|
||||||
|
|
||||||
|
- name: Set git safe directory
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Compile engine
|
||||||
|
run: |
|
||||||
|
make clean all -C engine
|
||||||
|
|
||||||
|
- name: Compile tutorials
|
||||||
|
run: |
|
||||||
|
make clean all -C tutorials/01-hello
|
||||||
|
make clean all -C tutorials/02-sprite
|
||||||
|
make clean all -C tutorials/03-minecraft
|
||||||
|
make clean all -C tutorials/04-de_dust2
|
||||||
|
make clean all -C tutorials/05-animation
|
||||||
|
make clean all -C tutorials/06-audio
|
||||||
|
make clean all -C tutorials/07-lighting
|
||||||
|
make clean all -C tutorials/08-skybox-debug
|
||||||
|
make clean all -C tutorials/09-manual-mode
|
||||||
|
make clean all -C tutorials/10-sprite-sheet
|
||||||
|
|
||||||
|
- name: Compile demo
|
||||||
|
run: |
|
||||||
|
make clean all -C demo
|
||||||
|
|
||||||
|
- name: Get short SHA
|
||||||
|
id: slug
|
||||||
|
run: |
|
||||||
|
echo "SHA8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Get branch
|
||||||
|
id: branch
|
||||||
|
run: |
|
||||||
|
BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | sed 's/refs\///g' | sed 's/\//_/g')
|
||||||
|
echo "BRANCH=${BRANCH_NAME}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: binaries-${{ env.SHA8 }}-${{ env.BRANCH }}
|
||||||
|
path: |
|
||||||
|
tutorials/01-hello/bin
|
||||||
|
tutorials/02-sprite/bin
|
||||||
|
tutorials/03-minecraft/bin
|
||||||
|
tutorials/04-de_dust2/bin
|
||||||
|
tutorials/05-animation/bin
|
||||||
|
tutorials/06-audio/bin
|
||||||
|
tutorials/07-lighting/bin
|
||||||
|
tutorials/08-skybox-debug/bin
|
||||||
|
tutorials/09-manual-mode/bin
|
||||||
|
tutorials/10-sprite-sheet/bin
|
||||||
|
demo/bin
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#This is a modified version of the clang format check used on Open-PS2-Loader
|
||||||
|
name: PR C++ format check
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- '**.hpp'
|
||||||
|
- '**.cpp'
|
||||||
|
- '**.'
|
||||||
|
- '**.h'
|
||||||
|
- './engine/inc/tyra'
|
||||||
|
- '.github/workflows/check-format.yml'
|
||||||
|
- '.clang-format'
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '**.hpp'
|
||||||
|
- '**.cpp'
|
||||||
|
- '**.'
|
||||||
|
- '**.h'
|
||||||
|
- './engine/inc/tyra'
|
||||||
|
- '.github/workflows/check-format.yml'
|
||||||
|
- '.clang-format'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-format:
|
||||||
|
name: Check clang format
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: DoozyX/clang-format-lint-action@v0.12
|
||||||
|
with:
|
||||||
|
source: '.'
|
||||||
|
extensions: 'hpp, cpp, h'
|
||||||
|
clangFormatVersion: 12
|
||||||
|
inplace: False
|
||||||
@@ -4,3 +4,4 @@
|
|||||||
/c_cpp_properties.json
|
/c_cpp_properties.json
|
||||||
/tasks.json
|
/tasks.json
|
||||||
/settings.json
|
/settings.json
|
||||||
|
/ps2dev-intellisense
|
||||||
+1
-1
@@ -42,7 +42,7 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"cwd": "${config:buildDirectory}"
|
"cwd": "${config:buildDirectory}"
|
||||||
},
|
},
|
||||||
"command": "./run.ps1"
|
"command": "Start-Job { ./run.ps1 } | Receive-Job -Wait"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ IRXEMBEDDEDEXT := irx-em
|
|||||||
CFLAGS += -D_EE -Wall -O3
|
CFLAGS += -D_EE -Wall -O3
|
||||||
LINKFLAGS += -O3 -Wl,-zmax-page-size=128
|
LINKFLAGS += -O3 -Wl,-zmax-page-size=128
|
||||||
ASFLAGS += -O3
|
ASFLAGS += -O3
|
||||||
LIB += -lstdc++ -ldma -lpacket2 -lgraph -ldraw -lmath3d -lpng -lz -lpad -laudsrv -lpatches -lcdvd
|
LIB += -lstdc++ -ldma -lpacket2 -lgraph -ldraw -lmath3d -lpng -ldebug -lz -lpad -laudsrv -lpatches -lcdvd
|
||||||
INC += -I$(PS2DEV)/ps2sdk/ee/include -I$(PS2DEV)/ps2sdk/common/include -I$(PS2DEV)/ps2sdk/ports/include
|
INC += -I$(PS2DEV)/ps2sdk/ee/include -I$(PS2DEV)/ps2sdk/common/include -I$(PS2DEV)/ps2sdk/ports/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -7,14 +7,16 @@
|
|||||||
<br />
|
<br />
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/h4570/tyra">
|
<a href="https://github.com/h4570/tyra">
|
||||||
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/github-splash.png" alt="Logo" width="100%" height="auto">
|
<img src="https://raw.githubusercontent.com/h4570/tyra/master/assets/github-splash.png" alt="Logo" width="100%" height="auto">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<h3 align="center">Tyra - 2.0.0</h3>
|
<h3 align="center">Tyra</h3>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
Open source game engine for PlayStation 2™
|
Open source game engine for PlayStation 2™
|
||||||
<br />
|
<br />
|
||||||
|
<a href="https://www.youtube.com/watch?v=DGR4vWDjkmc"><strong>Showcase video »</strong></a>
|
||||||
|
|
||||||
<a href="https://youtube.com/playlist?list=PLdQVLBcXRRWvtMi-OqccDWLTEFEisD5RH"><strong>YouTube tutorials »</strong></a>
|
<a href="https://youtube.com/playlist?list=PLdQVLBcXRRWvtMi-OqccDWLTEFEisD5RH"><strong>YouTube tutorials »</strong></a>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
@@ -25,15 +27,12 @@
|
|||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[](https://github.com/h4570/tyra/stargazers)
|
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
* [About the project](#about-the-project)
|
* [About the project](#about-the-project)
|
||||||
* [Description](#description)
|
* [Description](#description)
|
||||||
* [Tutorials](#tutorials)
|
* [Tutorials](#tutorials)
|
||||||
* [Features](#features)
|
* [Features](#features)
|
||||||
* [Branches](#branches)
|
|
||||||
* [Contributing](#contributing)
|
* [Contributing](#contributing)
|
||||||
* [Games](#games)
|
* [Games](#games)
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
@@ -43,8 +42,8 @@
|
|||||||
|
|
||||||
## About the Project
|
## About the Project
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/tyra_code.gif" alt="Sample code" width="500" height="auto">
|
<img src="https://raw.githubusercontent.com/h4570/tyra/master/assets/tyra_code.gif" alt="Sample code" width="500" height="auto">
|
||||||
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/showcase.gif " alt="Sample game" width="500" height="auto">
|
<img src="https://raw.githubusercontent.com/h4570/tyra/master/assets/showcase.gif " alt="Sample game" width="500" height="auto">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -56,7 +55,7 @@ Decision was simple - I need to create an engine which will handle 3D file loadi
|
|||||||
|
|
||||||
### Tutorials
|
### Tutorials
|
||||||
* 01 - Setup environment - [Text tutorial](https://github.com/h4570/tyra/tree/master/docs/install) or [Video](https://www.youtube.com/watch?v=9IXOU1SPdzc)
|
* 01 - Setup environment - [Text tutorial](https://github.com/h4570/tyra/tree/master/docs/install) or [Video](https://www.youtube.com/watch?v=9IXOU1SPdzc)
|
||||||
* 02 - Cooking game assets - [Video](https://www.youtube.com/watch?v=LjO71ovPFJs)
|
* 02 - Cooking game assets - [Video](https://www.youtube.com/watch?v=hpVDeTTLyjI)
|
||||||
* 03 - Create a game repository - [Video](https://www.youtube.com/watch?v=DKfIKar3GUM)
|
* 03 - Create a game repository - [Video](https://www.youtube.com/watch?v=DKfIKar3GUM)
|
||||||
* 04 - Run game from USB in PS2 - [Video](https://www.youtube.com/watch?v=ZX8fTQqiNho)
|
* 04 - Run game from USB in PS2 - [Video](https://www.youtube.com/watch?v=ZX8fTQqiNho)
|
||||||
---
|
---
|
||||||
@@ -97,14 +96,10 @@ Decision was simple - I need to create an engine which will handle 3D file loadi
|
|||||||
* `.md2` 3D file support
|
* `.md2` 3D file support
|
||||||
* `.png` Texture file support
|
* `.png` Texture file support
|
||||||
|
|
||||||
### Branches
|
## Contributing
|
||||||
* `master` - stable releases - tested on PS2 & PCSX2.
|
|
||||||
* `develop` - daily builds.
|
|
||||||
|
|
||||||
See the [open issues](https://github.com/h4570/tyra/issues) for a list of proposed features (and known issues).
|
See the [open issues](https://github.com/h4570/tyra/issues) for a list of proposed features (and known issues).
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
||||||
|
|
||||||
1. Fork the Project
|
1. Fork the Project
|
||||||
@@ -118,7 +113,10 @@ Contributions are what make the open source community such an amazing place to b
|
|||||||
List of games developed with Tyra.
|
List of games developed with Tyra.
|
||||||
If you created one, please contact me - I will add it to the list :)
|
If you created one, please contact me - I will add it to the list :)
|
||||||
|
|
||||||
* [Tyracraft](https://github.com/Wellinator/tyracraft)
|
* [Tyracraft](https://github.com/Wellinator/tyracraft) by [Wellinator](https://github.com/Wellinator)
|
||||||
|
* [Game with car](https://github.com/freebytego/gwc-ps2) by [freebytego](https://github.com/freebytego)
|
||||||
|
* [Rock, paper, scissors](https://github.com/GuidoDQR/my-ps2-game) by [GuidoDQR](https://github.com/GuidoDQR)
|
||||||
|
* [TyraTale](https://github.com/Br4k2n/TyraTale) by [Br4k2n](https://github.com/Br4k2n)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
@@ -141,15 +139,14 @@ Distributed under the Apache License 2.0 License. See `LICENSE` for more informa
|
|||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
Without these guys, Tyra would not happen:
|
Without these guys, Tyra would not happen:
|
||||||
* Dr Henry Fortuna - for code sources, PS2 academy tutorials
|
* [Dr Henry Fortuna](http://ps2-edu.tensioncore.com/index.html) - for code sources, PS2 academy tutorials
|
||||||
* Rick Gaiser, fjtrujy - for maintaining PS2DEV
|
* Whole [PS2DEV](https://github.com/ps2dev) team, and specially to [Rick Gaiser](https://github.com/rickgaiser), [fjtrujy](https://github.com/fjtrujy) - for a lot of good tips!
|
||||||
* Wellington Carvalho - for testing, contributing to Tyra and sharing cool ideas!
|
* [Wellington Carvalho](https://github.com/Wellinator), [André Guilheme](https://github.com/Wolf3s), [Matías Israelson](https://github.com/israpps) - for testing, contributing to Tyra and sharing cool ideas!
|
||||||
* Leonardo Ono - for software renderer example (with clipping!)
|
* [Leonardo Ono](https://github.com/leonardo-ono) - for software renderer example (with clipping!)
|
||||||
* Lukasz D.K. - for huge archive of PS2 stuff
|
* [Lukasz D.K.](https://github.com/lukaszdk) - for huge archive of PS2 stuff
|
||||||
* Guilherme Lampert - for code sources
|
* [Guilherme Lampert](https://github.com/glampert) - for code sources
|
||||||
* Jesper Svennevid, Daniel Collin - for openvcl's code samples
|
* [Jesper Svennevid](https://github.com/jsvennevid), [Daniel Collin](https://github.com/emoon) - for openvcl's code samples
|
||||||
* Whole PS2DEV team
|
* [Manieq](https://www.facebook.com/mvnieq) - for nice splash screens!
|
||||||
* Manieq - for nice splash screens!
|
|
||||||
* And so many other guys. Thanks!
|
* And so many other guys. Thanks!
|
||||||
|
|
||||||
Project Link: [https://github.com/h4570/tyra](https://github.com/h4570/tyra)
|
Project Link: [https://github.com/h4570/tyra](https://github.com/h4570/tyra)
|
||||||
@@ -158,7 +155,7 @@ Sandro Sobczyński - sandro.sobczynski@gmail.com
|
|||||||
|
|
||||||
<br />
|
<br />
|
||||||
<a href="https://github.com/h4570/tyra">
|
<a href="https://github.com/h4570/tyra">
|
||||||
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/github-splash2.png" alt="Logo" width="100%" height="auto">
|
<img src="https://raw.githubusercontent.com/h4570/tyra/master/assets/github-splash2.png" alt="Logo" width="100%" height="auto">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
[contributors-shield]: https://img.shields.io/github/contributors/h4570/tyra.svg?style=flat-square
|
[contributors-shield]: https://img.shields.io/github/contributors/h4570/tyra.svg?style=flat-square
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
BIN
Binary file not shown.
@@ -17,9 +17,10 @@
|
|||||||
docker pull h4570/tyra
|
docker pull h4570/tyra
|
||||||
git clone https://github.com/h4570/tyra.git
|
git clone https://github.com/h4570/tyra.git
|
||||||
```
|
```
|
||||||
3. Open `VSCode` and open previously cloned directory.
|
3. Download the [assets.zip](https://github.com/h4570/tyra/releases) file and unzip it into the tyra directory
|
||||||
4. In `VSCode` open `.vscode/configurations/windows-docker` and copy configuration files into `.vscode/`
|
4. Open `VSCode` and open previously cloned directory.
|
||||||
5. In `c_cpp_properties.json` fix all `YOUR-INTELLISENSE-PATH` with path from point 2.
|
5. In `VSCode` open `.vscode/configurations/windows-docker` and copy configuration files into `.vscode/`
|
||||||
6. Click `CTRL+SHIFT+P`, type `Tasks: Run task` and run `Start docker container` - Repeat this step every time you want to start working with Tyra (every reboot)
|
6. In `c_cpp_properties.json` fix all `YOUR-INTELLISENSE-PATH` with path from point 2.
|
||||||
7. Click `CTRL+SHIFT+P`, type `Tasks: Run build task`
|
7. Click `CTRL+SHIFT+P`, type `Tasks: Run task` and run `Start docker container` - Repeat this step every time you want to start working with Tyra (every reboot)
|
||||||
8. Tyra should automatically compile engine, `demo` game and run `PCSX2`. If you want to compile & run tutorials, please change `buildDirectory` in `settings.json` to example `tutorials/01-hello`
|
8. Click `CTRL+SHIFT+P`, type `Tasks: Run build task`
|
||||||
|
9. Tyra should automatically compile engine, `demo` game and run `PCSX2`. If you want to compile & run tutorials, please change `buildDirectory` in `settings.json` to example `tutorials/01-hello`
|
||||||
|
|||||||
+23
-14
@@ -20,6 +20,7 @@
|
|||||||
#else // IF Debug
|
#else // IF Debug
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <debug.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -48,9 +49,7 @@ class TyraDebug {
|
|||||||
(void)expander{0, (void(ss << std::forward<Args>(args)), 0)...};
|
(void)expander{0, (void(ss << std::forward<Args>(args)), 0)...};
|
||||||
|
|
||||||
if (Tyra::Info::writeLogsToFile) {
|
if (Tyra::Info::writeLogsToFile) {
|
||||||
auto* logFile = getLogFile();
|
writeInLogFile(&ss);
|
||||||
*logFile << ss.str();
|
|
||||||
logFile->flush();
|
|
||||||
} else {
|
} else {
|
||||||
printf("%s", ss.str().c_str());
|
printf("%s", ss.str().c_str());
|
||||||
}
|
}
|
||||||
@@ -65,9 +64,7 @@ class TyraDebug {
|
|||||||
ss1 << "|\n";
|
ss1 << "|\n";
|
||||||
|
|
||||||
if (Tyra::Info::writeLogsToFile) {
|
if (Tyra::Info::writeLogsToFile) {
|
||||||
auto* logFile = getLogFile();
|
writeInLogFile(&ss1);
|
||||||
*logFile << ss1.str();
|
|
||||||
logFile->flush();
|
|
||||||
} else {
|
} else {
|
||||||
printf("%s", ss1.str().c_str());
|
printf("%s", ss1.str().c_str());
|
||||||
}
|
}
|
||||||
@@ -80,20 +77,22 @@ class TyraDebug {
|
|||||||
ss2 << "====================================\n\n";
|
ss2 << "====================================\n\n";
|
||||||
|
|
||||||
if (Tyra::Info::writeLogsToFile) {
|
if (Tyra::Info::writeLogsToFile) {
|
||||||
auto* logFile = getLogFile();
|
writeInLogFile(&ss2);
|
||||||
*logFile << ss2.str();
|
|
||||||
logFile->flush();
|
|
||||||
} else {
|
} else {
|
||||||
printf("%s", ss2.str().c_str());
|
printf("%s", ss2.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_scr();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
scr_setXY(20, 10);
|
||||||
|
scr_printf(ss1.str().c_str());
|
||||||
|
writeAssertLinesInScreen(args...);
|
||||||
|
scr_printf(ss2.str().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<std::ofstream> logFile;
|
static void writeInLogFile(std::stringstream* ss);
|
||||||
static std::ofstream* getLogFile();
|
|
||||||
|
|
||||||
template <typename Arg, typename... Args>
|
template <typename Arg, typename... Args>
|
||||||
static void writeAssertLines(Arg&& arg, Args&&... args) {
|
static void writeAssertLines(Arg&& arg, Args&&... args) {
|
||||||
@@ -105,13 +104,23 @@ class TyraDebug {
|
|||||||
0, (void(ss << "| " << std::forward<Args>(args) << "\n"), 0)...};
|
0, (void(ss << "| " << std::forward<Args>(args) << "\n"), 0)...};
|
||||||
|
|
||||||
if (Tyra::Info::writeLogsToFile) {
|
if (Tyra::Info::writeLogsToFile) {
|
||||||
auto* logfile = getLogFile();
|
writeInLogFile(&ss);
|
||||||
*logfile << ss.str();
|
|
||||||
logFile->flush();
|
|
||||||
} else {
|
} else {
|
||||||
printf("%s", ss.str().c_str());
|
printf("%s", ss.str().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Arg, typename... Args>
|
||||||
|
static void writeAssertLinesInScreen(Arg&& arg, Args&&... args) {
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << "| " << std::forward<Arg>(arg) << "\n";
|
||||||
|
using expander = int[];
|
||||||
|
(void)expander{
|
||||||
|
0, (void(ss << "| " << std::forward<Args>(args) << "\n"), 0)...};
|
||||||
|
|
||||||
|
scr_printf(ss.str().c_str());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <syslimits.h>
|
||||||
|
|
||||||
namespace Tyra {
|
namespace Tyra {
|
||||||
|
|
||||||
@@ -42,9 +44,9 @@ class FileUtils {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Argv name+path & just path
|
// Argv name+path & just path
|
||||||
char cwd[255];
|
char cwd[NAME_MAX];
|
||||||
char elfName[255];
|
char elfName[NAME_MAX];
|
||||||
char elfPath[255 - 14];
|
char elfPath[NAME_MAX - 14];
|
||||||
|
|
||||||
void setPathInfo(const char* path);
|
void setPathInfo(const char* path);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Version {
|
|||||||
~Version() {}
|
~Version() {}
|
||||||
|
|
||||||
static const u8 major = 2;
|
static const u8 major = 2;
|
||||||
static const u8 minor = 0;
|
static const u8 minor = 2;
|
||||||
static const u8 patch = 0;
|
static const u8 patch = 0;
|
||||||
|
|
||||||
static std::string toString() {
|
static std::string toString() {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class IrxLoader {
|
|||||||
void loadSio2man(const bool& verbose);
|
void loadSio2man(const bool& verbose);
|
||||||
void loadPadman(const bool& verbose);
|
void loadPadman(const bool& verbose);
|
||||||
void loadLibsd(const bool& verbose);
|
void loadLibsd(const bool& verbose);
|
||||||
|
void loadIO(const bool& verbose);
|
||||||
void loadUsbModules(const bool& verbose);
|
void loadUsbModules(const bool& verbose);
|
||||||
void loadAudsrv(const bool& verbose);
|
void loadAudsrv(const bool& verbose);
|
||||||
|
|
||||||
|
|||||||
@@ -33,4 +33,5 @@ class TextureBuilderData {
|
|||||||
TextureBpp clutBpp;
|
TextureBpp clutBpp;
|
||||||
unsigned char clutGsComponents;
|
unsigned char clutGsComponents;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ class Math {
|
|||||||
static int randomi(const int& min, const int& max);
|
static int randomi(const int& min, const int& max);
|
||||||
static bool equalf(const float& a, const float& b,
|
static bool equalf(const float& a, const float& b,
|
||||||
const float& epsilon = 0.00001F);
|
const float& epsilon = 0.00001F);
|
||||||
|
|
||||||
private:
|
|
||||||
Math();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "debug/debug.hpp"
|
#include "debug/debug.hpp"
|
||||||
#include "renderer/core/2d/sprite/sprite.hpp"
|
#include "renderer/core/2d/sprite/sprite.hpp"
|
||||||
#include "renderer/core/texture/renderer_core_texture_buffers.hpp"
|
#include "renderer/core/texture/renderer_core_texture_buffers.hpp"
|
||||||
|
#include "renderer/3d/pipeline/shared/pipeline_texture_mapping_type.hpp"
|
||||||
#include "renderer/core/texture/models/texture.hpp"
|
#include "renderer/core/texture/models/texture.hpp"
|
||||||
#include "renderer/renderer_settings.hpp"
|
#include "renderer/renderer_settings.hpp"
|
||||||
#include <packet2_utils.h>
|
#include <packet2_utils.h>
|
||||||
@@ -30,6 +31,9 @@ class RendererCore2D {
|
|||||||
void render(const Sprite& sprite,
|
void render(const Sprite& sprite,
|
||||||
const RendererCoreTextureBuffers& texBuffers, Texture* texture);
|
const RendererCoreTextureBuffers& texBuffers, Texture* texture);
|
||||||
|
|
||||||
|
void setTextureMappingType(
|
||||||
|
const PipelineTextureMappingType textureMappingType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setPrim();
|
void setPrim();
|
||||||
void setLod();
|
void setLod();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class Sprite {
|
|||||||
~Sprite();
|
~Sprite();
|
||||||
|
|
||||||
u32 id;
|
u32 id;
|
||||||
Vec2 position, size;
|
Vec2 position, size, offset;
|
||||||
float scale;
|
float scale;
|
||||||
Color color;
|
Color color;
|
||||||
SpriteMode mode;
|
SpriteMode mode;
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ class Texture {
|
|||||||
|
|
||||||
/** Set texture wrapping */
|
/** Set texture wrapping */
|
||||||
void setWrapSettings(const TextureWrap t_horizontal,
|
void setWrapSettings(const TextureWrap t_horizontal,
|
||||||
const TextureWrap t_vertical);
|
const TextureWrap t_vertical, int minu = 0, int minv = 0,
|
||||||
|
int maxu = 0, int maxv = 0);
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// Other
|
// Other
|
||||||
@@ -96,9 +97,10 @@ class Texture {
|
|||||||
void print(const std::string& name) const { print(name.c_str()); }
|
void print(const std::string& name) const { print(name.c_str()); }
|
||||||
std::string getPrint(const char* name = nullptr) const;
|
std::string getPrint(const char* name = nullptr) const;
|
||||||
|
|
||||||
|
void setDefaultWrapSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setPsm();
|
void setPsm();
|
||||||
void setDefaultWrapSettings();
|
|
||||||
|
|
||||||
texwrap_t wrap;
|
texwrap_t wrap;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ class RendererCoreTexture {
|
|||||||
|
|
||||||
RendererCoreTextureBuffers useTexture(const Texture* t_tex);
|
RendererCoreTextureBuffers useTexture(const Texture* t_tex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by user after changing texture wrap settings
|
||||||
|
* Updates texture packet without reallocate it
|
||||||
|
*/
|
||||||
|
RendererCoreTextureBuffers updateTextureInfo(const Texture* t_tex);
|
||||||
|
|
||||||
/** Called by renderer during initialization */
|
/** Called by renderer during initialization */
|
||||||
void init(RendererCoreGS* gs, Path3* path3);
|
void init(RendererCoreGS* gs, Path3* path3);
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "./models/texture.hpp"
|
#include "./models/texture.hpp"
|
||||||
#include "renderer/3d/mesh/mesh.hpp"
|
#include "renderer/3d/mesh/mesh.hpp"
|
||||||
#include "renderer/core/2d/sprite/sprite.hpp"
|
#include "renderer/core/2d/sprite/sprite.hpp"
|
||||||
|
#include "./renderer_core_texture_buffers.hpp"
|
||||||
#include "loaders/texture/base/texture_loader_selector.hpp"
|
#include "loaders/texture/base/texture_loader_selector.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ class TextureRepository {
|
|||||||
TextureRepository();
|
TextureRepository();
|
||||||
~TextureRepository();
|
~TextureRepository();
|
||||||
|
|
||||||
|
void init(std::vector<RendererCoreTextureBuffers>* textureBuffers);
|
||||||
|
|
||||||
/** Returns all repository textures. */
|
/** Returns all repository textures. */
|
||||||
std::vector<Texture*>* getAll() { return &textures; }
|
std::vector<Texture*>* getAll() { return &textures; }
|
||||||
|
|
||||||
@@ -99,6 +102,13 @@ class TextureRepository {
|
|||||||
void freeByMesh(const Mesh& mesh);
|
void freeByMesh(const Mesh& mesh);
|
||||||
void freeByMesh(const Mesh* mesh);
|
void freeByMesh(const Mesh* mesh);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove texture buffer id if exist.
|
||||||
|
* Texture buffer is NOT destructed.
|
||||||
|
* easy way to create another texture buffer.
|
||||||
|
*/
|
||||||
|
int removeBufferId(const u32& t_texId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove texture from repository.
|
* Remove texture from repository.
|
||||||
* Texture is NOT destructed.
|
* Texture is NOT destructed.
|
||||||
@@ -110,6 +120,7 @@ class TextureRepository {
|
|||||||
void removeByIndex(const u32& t_index);
|
void removeByIndex(const u32& t_index);
|
||||||
|
|
||||||
std::vector<Texture*> textures;
|
std::vector<Texture*> textures;
|
||||||
|
std::vector<RendererCoreTextureBuffers>* textureBuffers;
|
||||||
TextureLoaderSelector texLoaderSelector;
|
TextureLoaderSelector texLoaderSelector;
|
||||||
};
|
};
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
# Licensed under Apache License 2.0
|
# Licensed under Apache License 2.0
|
||||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "audio/audio.hpp"
|
#include "audio/audio.hpp"
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
# Licensed under Apache License 2.0
|
# Licensed under Apache License 2.0
|
||||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "audio/audio_adpcm.hpp"
|
#include "audio/audio_adpcm.hpp"
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
# Licensed under Apache License 2.0
|
# Licensed under Apache License 2.0
|
||||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "audio/audio_song.hpp"
|
#include "audio/audio_song.hpp"
|
||||||
@@ -149,6 +148,7 @@ void AudioSong::work() {
|
|||||||
|
|
||||||
if (chunkReadStatus > 0) {
|
if (chunkReadStatus > 0) {
|
||||||
WaitSema(fillbufferSema); // wait until previous chunk wasn't finished
|
WaitSema(fillbufferSema); // wait until previous chunk wasn't finished
|
||||||
|
audsrv_wait_audio(chunkReadStatus);
|
||||||
audsrv_play_audio(chunk, chunkReadStatus);
|
audsrv_play_audio(chunk, chunkReadStatus);
|
||||||
for (u32 i = 0; i < getListenersCount(); i++)
|
for (u32 i = 0; i < getListenersCount(); i++)
|
||||||
songListeners[i]->listener->onAudioTick();
|
songListeners[i]->listener->onAudioTick();
|
||||||
|
|||||||
@@ -10,16 +10,11 @@
|
|||||||
|
|
||||||
#include "debug/debug.hpp"
|
#include "debug/debug.hpp"
|
||||||
|
|
||||||
std::unique_ptr<std::ofstream> TyraDebug::logFile;
|
void TyraDebug::writeInLogFile(std::stringstream* ss) {
|
||||||
|
std::ofstream logFile;
|
||||||
std::ofstream* TyraDebug::getLogFile() {
|
logFile.open(Tyra::FileUtils::fromCwd("log.txt"),
|
||||||
if (logFile) {
|
std::ofstream::out | std::ofstream::app);
|
||||||
return logFile.get();
|
logFile << ss->str();
|
||||||
} else {
|
logFile.flush();
|
||||||
logFile = std::make_unique<std::ofstream>();
|
// logFile.close();
|
||||||
logFile->open(Tyra::FileUtils::fromCwd("log.txt"),
|
}
|
||||||
std::ofstream::out | std::ofstream::app);
|
|
||||||
return logFile.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Tyra
|
|
||||||
|
|||||||
@@ -12,8 +12,7 @@
|
|||||||
#include <tamtypes.h>
|
#include <tamtypes.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <syslimits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "file/file_utils.hpp"
|
#include "file/file_utils.hpp"
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
$PS2SDK/iop/irx/fileXio.irx
|
||||||
|
fileXio_irx
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
$PS2SDK/iop/irx/iomanX.irx
|
||||||
|
iomanX_irx
|
||||||
@@ -20,30 +20,20 @@
|
|||||||
#include "file/file_utils.hpp"
|
#include "file/file_utils.hpp"
|
||||||
|
|
||||||
// external IRX modules
|
// external IRX modules
|
||||||
|
#define EXTERN_IRX(_irx) \
|
||||||
|
extern u8 _irx[]; \
|
||||||
|
extern int size_##_irx
|
||||||
|
|
||||||
extern u8 sio2man_irx[];
|
EXTERN_IRX(sio2man_irx);
|
||||||
extern int size_sio2man_irx;
|
EXTERN_IRX(padman_irx);
|
||||||
|
EXTERN_IRX(audsrv_irx);
|
||||||
extern u8 padman_irx[];
|
EXTERN_IRX(libsd_irx);
|
||||||
extern int size_padman_irx;
|
EXTERN_IRX(fileXio_irx);
|
||||||
|
EXTERN_IRX(iomanX_irx);
|
||||||
extern u8 audsrv_irx[];
|
EXTERN_IRX(bdm_irx);
|
||||||
extern int size_audsrv_irx;
|
EXTERN_IRX(bdmfs_fatfs_irx);
|
||||||
|
EXTERN_IRX(usbd_irx);
|
||||||
extern u8 libsd_irx[];
|
EXTERN_IRX(usbmass_bd_irx);
|
||||||
extern int size_libsd_irx;
|
|
||||||
|
|
||||||
extern u8 bdm_irx[];
|
|
||||||
extern int size_bdm_irx;
|
|
||||||
|
|
||||||
extern u8 bdmfs_fatfs_irx[];
|
|
||||||
extern int size_bdmfs_fatfs_irx;
|
|
||||||
|
|
||||||
extern u8 usbd_irx[];
|
|
||||||
extern int size_usbd_irx;
|
|
||||||
|
|
||||||
extern u8 usbmass_bd_irx[];
|
|
||||||
extern int size_usbmass_bd_irx;
|
|
||||||
|
|
||||||
namespace Tyra {
|
namespace Tyra {
|
||||||
|
|
||||||
@@ -70,6 +60,7 @@ void IrxLoader::loadAll(const bool& withUsb, const bool& isLoggingToFile) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadIO(!isLoggingToFile);
|
||||||
loadSio2man(!isLoggingToFile);
|
loadSio2man(!isLoggingToFile);
|
||||||
loadPadman(!isLoggingToFile);
|
loadPadman(!isLoggingToFile);
|
||||||
loadLibsd(!isLoggingToFile);
|
loadLibsd(!isLoggingToFile);
|
||||||
@@ -116,6 +107,24 @@ void IrxLoader::loadLibsd(const bool& verbose) {
|
|||||||
if (verbose) TYRA_LOG("IRX: Libsd loaded!");
|
if (verbose) TYRA_LOG("IRX: Libsd loaded!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IrxLoader::loadIO(const bool& verbose) {
|
||||||
|
int ret;
|
||||||
|
if (verbose) TYRA_LOG("IRX: Loading iomanX...");
|
||||||
|
|
||||||
|
SifExecModuleBuffer(&iomanX_irx, size_iomanX_irx, 0, nullptr, &ret);
|
||||||
|
TYRA_ASSERT(ret >= 0, "Failed to load module: iomanX_irx");
|
||||||
|
|
||||||
|
if (verbose) TYRA_LOG("IRX: iomanX loaded!");
|
||||||
|
|
||||||
|
if (verbose) TYRA_LOG("IRX: Loading fileXio...");
|
||||||
|
|
||||||
|
SifExecModuleBuffer(&fileXio_irx, size_fileXio_irx, 0, nullptr, &ret);
|
||||||
|
TYRA_ASSERT(ret >= 0, "Failed to load module: fileXio_irx");
|
||||||
|
|
||||||
|
if (verbose) TYRA_LOG("IRX: fileXio_irx loaded!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void IrxLoader::loadUsbModules(const bool& verbose) {
|
void IrxLoader::loadUsbModules(const bool& verbose) {
|
||||||
if (verbose) TYRA_LOG("IRX: Loading usb modules...");
|
if (verbose) TYRA_LOG("IRX: Loading usb modules...");
|
||||||
|
|
||||||
|
|||||||
@@ -211,10 +211,6 @@ void PngLoader::handle8bppPalletized(TextureBuilderData* result,
|
|||||||
auto* pixel = static_cast<unsigned char*>(result->data);
|
auto* pixel = static_cast<unsigned char*>(result->data);
|
||||||
struct PngClut* clut = (struct PngClut*)result->clut;
|
struct PngClut* clut = (struct PngClut*)result->clut;
|
||||||
|
|
||||||
for (int i = numPallete; i < 256; i++) {
|
|
||||||
memset(&clut[i], 0, sizeof(clut[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < numPallete; i++) {
|
for (int i = 0; i < numPallete; i++) {
|
||||||
clut[i].r = palette[i].red;
|
clut[i].r = palette[i].red;
|
||||||
clut[i].g = palette[i].green;
|
clut[i].g = palette[i].green;
|
||||||
@@ -273,10 +269,6 @@ void PngLoader::handle4bppPalletized(TextureBuilderData* result,
|
|||||||
auto* pixel = static_cast<unsigned char*>(result->data);
|
auto* pixel = static_cast<unsigned char*>(result->data);
|
||||||
struct PngClut* clut = (struct PngClut*)result->clut;
|
struct PngClut* clut = (struct PngClut*)result->clut;
|
||||||
|
|
||||||
for (int i = numPallete; i < 16; i++) {
|
|
||||||
memset(&clut[i], 0, sizeof(clut[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < numPallete; i++) {
|
for (int i = 0; i < numPallete; i++) {
|
||||||
clut[i].r = palette[i].red;
|
clut[i].r = palette[i].red;
|
||||||
clut[i].g = palette[i].green;
|
clut[i].g = palette[i].green;
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ void StaticPipeline::render(const StaticMesh* mesh,
|
|||||||
if (frame->bbox->frustumCheck(
|
if (frame->bbox->frustumCheck(
|
||||||
rendererCore->renderer3D.frustumPlanes.getAll(), model) ==
|
rendererCore->renderer3D.frustumPlanes.getAll(), model) ==
|
||||||
CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
|
CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
|
||||||
|
if (options && optionsManuallyAllocated) {
|
||||||
|
delete options;
|
||||||
|
}
|
||||||
|
delete infoBag;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,10 +84,12 @@ void RendererCore2D::render(const Sprite& sprite,
|
|||||||
else if (sizeY > sizeX)
|
else if (sizeY > sizeX)
|
||||||
texS = texMax / (sizeY / sizeX);
|
texS = texMax / (sizeY / sizeX);
|
||||||
|
|
||||||
rect->t0.s = sprite.flipHorizontal ? texS : 0.0F;
|
rect->t0.s =
|
||||||
rect->t0.t = sprite.flipVertical ? texT : 0.0F;
|
sprite.flipHorizontal ? (texS + sprite.offset.x) : sprite.offset.x;
|
||||||
rect->t1.s = sprite.flipHorizontal ? 0.0F : texS;
|
rect->t0.t = sprite.flipVertical ? (texT + sprite.offset.y) : sprite.offset.y;
|
||||||
rect->t1.t = sprite.flipVertical ? 0.0F : texT;
|
rect->t1.s =
|
||||||
|
sprite.flipHorizontal ? sprite.offset.x : (texS + sprite.offset.x);
|
||||||
|
rect->t1.t = sprite.flipVertical ? sprite.offset.y : (texT + sprite.offset.y);
|
||||||
|
|
||||||
rect->color.r = sprite.color.r;
|
rect->color.r = sprite.color.r;
|
||||||
rect->color.g = sprite.color.g;
|
rect->color.g = sprite.color.g;
|
||||||
@@ -131,4 +133,10 @@ void RendererCore2D::render(const Sprite& sprite,
|
|||||||
context = !context;
|
context = !context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererCore2D::setTextureMappingType(
|
||||||
|
const PipelineTextureMappingType textureMappingType) {
|
||||||
|
lod.mag_filter = textureMappingType;
|
||||||
|
lod.min_filter = textureMappingType;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Sprite::Sprite() {
|
|||||||
flipVertical = false;
|
flipVertical = false;
|
||||||
size.set(32.0F, 32.0F);
|
size.set(32.0F, 32.0F);
|
||||||
position.set(100.0F, 100.0F);
|
position.set(100.0F, 100.0F);
|
||||||
|
offset.set(0.0F, 0.0F);
|
||||||
scale = 1.0F;
|
scale = 1.0F;
|
||||||
mode = MODE_REPEAT;
|
mode = MODE_REPEAT;
|
||||||
setDefaultColor();
|
setDefaultColor();
|
||||||
|
|||||||
@@ -65,20 +65,20 @@ void Path3::sendTexture(const Texture* texture,
|
|||||||
const RendererCoreTextureBuffers& texBuffers) {
|
const RendererCoreTextureBuffers& texBuffers) {
|
||||||
packet2_reset(texturePacket, false);
|
packet2_reset(texturePacket, false);
|
||||||
|
|
||||||
int coreWidth = texBuffers.core->width <= 64 ? 64 : texBuffers.core->width;
|
packet2_update(
|
||||||
packet2_update(texturePacket,
|
texturePacket,
|
||||||
draw_texture_transfer(texturePacket->base, texture->core->data,
|
draw_texture_transfer(texturePacket->base, texture->core->data,
|
||||||
texture->getWidth(),
|
texture->getWidth(), texture->getHeight(),
|
||||||
texture->getHeight(), texture->core->psm,
|
texture->core->psm, texBuffers.core->address,
|
||||||
texBuffers.core->address, coreWidth));
|
texBuffers.core->width));
|
||||||
|
|
||||||
if (texBuffers.clut != nullptr) {
|
if (texBuffers.clut != nullptr) {
|
||||||
auto* clut = texture->clut;
|
auto* clut = texture->clut;
|
||||||
int clutWidth = texBuffers.clut->width <= 64 ? 64 : texBuffers.clut->width;
|
packet2_update(
|
||||||
packet2_update(texturePacket,
|
texturePacket,
|
||||||
draw_texture_transfer(texturePacket->next, clut->data,
|
draw_texture_transfer(texturePacket->next, clut->data, clut->width,
|
||||||
clut->width, clut->height, clut->psm,
|
clut->height, clut->psm, texBuffers.clut->address,
|
||||||
texBuffers.clut->address, clutWidth));
|
texBuffers.clut->width));
|
||||||
}
|
}
|
||||||
|
|
||||||
packet2_chain_open_cnt(texturePacket, 0, 0, 0);
|
packet2_chain_open_cnt(texturePacket, 0, 0, 0);
|
||||||
|
|||||||
@@ -19,8 +19,18 @@
|
|||||||
|
|
||||||
namespace Tyra {
|
namespace Tyra {
|
||||||
|
|
||||||
|
namespace TyraTexture {
|
||||||
|
u32 textureCounter = 1;
|
||||||
|
std::vector<u32> deletedIDs;
|
||||||
|
} // namespace TyraTexture
|
||||||
|
|
||||||
Texture::Texture(TextureBuilderData* t_data) {
|
Texture::Texture(TextureBuilderData* t_data) {
|
||||||
id = rand() % 1000000;
|
if (TyraTexture::deletedIDs.empty() == false) {
|
||||||
|
id = TyraTexture::deletedIDs.front();
|
||||||
|
TyraTexture::deletedIDs.erase(TyraTexture::deletedIDs.begin());
|
||||||
|
} else {
|
||||||
|
id = TyraTexture::textureCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
name = t_data->name;
|
name = t_data->name;
|
||||||
|
|
||||||
@@ -50,6 +60,7 @@ Texture::Texture(TextureBuilderData* t_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
|
TyraTexture::deletedIDs.push_back(id);
|
||||||
if (links.size() > 0) links.clear();
|
if (links.size() > 0) links.clear();
|
||||||
if (core) delete core;
|
if (core) delete core;
|
||||||
if (clut) delete clut;
|
if (clut) delete clut;
|
||||||
@@ -167,9 +178,14 @@ void Texture::setDefaultWrapSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setWrapSettings(const TextureWrap t_horizontal,
|
void Texture::setWrapSettings(const TextureWrap t_horizontal,
|
||||||
const TextureWrap t_vertical) {
|
const TextureWrap t_vertical, int minu, int minv,
|
||||||
|
int maxu, int maxv) {
|
||||||
wrap.horizontal = t_horizontal;
|
wrap.horizontal = t_horizontal;
|
||||||
wrap.vertical = t_vertical;
|
wrap.vertical = t_vertical;
|
||||||
|
wrap.minu = minu;
|
||||||
|
wrap.minv = minv;
|
||||||
|
wrap.maxu = maxu;
|
||||||
|
wrap.maxv = maxv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::addLink(const u32& t_id) {
|
void Texture::addLink(const u32& t_id) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ RendererCoreTexture::~RendererCoreTexture() {}
|
|||||||
void RendererCoreTexture::init(RendererCoreGS* t_gs, Path3* t_path3) {
|
void RendererCoreTexture::init(RendererCoreGS* t_gs, Path3* t_path3) {
|
||||||
gs = t_gs;
|
gs = t_gs;
|
||||||
sender.init(t_path3, t_gs);
|
sender.init(t_path3, t_gs);
|
||||||
|
repository.init(¤tAllocations);
|
||||||
path3 = t_path3;
|
path3 = t_path3;
|
||||||
initClut();
|
initClut();
|
||||||
}
|
}
|
||||||
@@ -56,6 +57,17 @@ RendererCoreTextureBuffers RendererCoreTexture::useTexture(
|
|||||||
return newTexBuffer;
|
return newTexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RendererCoreTextureBuffers RendererCoreTexture::updateTextureInfo(
|
||||||
|
const Texture* t_tex) {
|
||||||
|
TYRA_ASSERT(t_tex != nullptr, "Provided nullptr texture!");
|
||||||
|
|
||||||
|
auto allocated = getAllocatedBuffersByTextureId(t_tex->id);
|
||||||
|
TYRA_ASSERT(allocated.id != 0, "Can't update an unallocated texture!");
|
||||||
|
|
||||||
|
path3->sendTexture(t_tex, allocated);
|
||||||
|
return allocated;
|
||||||
|
}
|
||||||
|
|
||||||
RendererCoreTextureBuffers RendererCoreTexture::getAllocatedBuffersByTextureId(
|
RendererCoreTextureBuffers RendererCoreTexture::getAllocatedBuffersByTextureId(
|
||||||
const u32& t_id) {
|
const u32& t_id) {
|
||||||
for (u32 i = 0; i < currentAllocations.size(); i++)
|
for (u32 i = 0; i < currentAllocations.size(); i++)
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ texbuffer_t* RendererCoreTextureSender::allocateTextureCore(
|
|||||||
auto* result = new texbuffer_t;
|
auto* result = new texbuffer_t;
|
||||||
const auto* core = t_texture->core;
|
const auto* core = t_texture->core;
|
||||||
|
|
||||||
result->width = t_texture->getWidth();
|
int coreWidth = core->width <= 64 ? 64 : core->width;
|
||||||
|
|
||||||
|
result->width = coreWidth;
|
||||||
result->psm = core->psm;
|
result->psm = core->psm;
|
||||||
result->info.components = core->components;
|
result->info.components = core->components;
|
||||||
|
|
||||||
@@ -77,7 +79,9 @@ texbuffer_t* RendererCoreTextureSender::allocateTextureClut(
|
|||||||
auto* result = new texbuffer_t;
|
auto* result = new texbuffer_t;
|
||||||
const auto* clut = t_texture->clut;
|
const auto* clut = t_texture->clut;
|
||||||
|
|
||||||
result->width = clut->width;
|
int clutWidth = clut->width <= 64 ? 64 : clut->width;
|
||||||
|
|
||||||
|
result->width = clutWidth;
|
||||||
result->psm = clut->psm;
|
result->psm = clut->psm;
|
||||||
result->info.components = clut->components;
|
result->info.components = clut->components;
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ TextureRepository::~TextureRepository() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureRepository::init(
|
||||||
|
std::vector<RendererCoreTextureBuffers>* t_textureBuffers) {
|
||||||
|
textureBuffers = t_textureBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
Texture* TextureRepository::getBySpriteId(const u32& t_id) const {
|
Texture* TextureRepository::getBySpriteId(const u32& t_id) const {
|
||||||
for (u32 i = 0; i < textures.size(); i++) {
|
for (u32 i = 0; i < textures.size(); i++) {
|
||||||
if (textures[i]->isLinkedWith(t_id)) return textures[i];
|
if (textures[i]->isLinkedWith(t_id)) return textures[i];
|
||||||
@@ -57,10 +62,20 @@ void TextureRepository::removeByIndex(const u32& t_index) {
|
|||||||
textures.erase(textures.begin() + t_index);
|
textures.erase(textures.begin() + t_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TextureRepository::removeBufferId(const u32& t_texId) {
|
||||||
|
for (u32 i = 0; i < textureBuffers->size(); i++)
|
||||||
|
if ((*textureBuffers)[i].id == t_texId) {
|
||||||
|
(*textureBuffers)[i].id = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void TextureRepository::removeById(const u32& t_texId) {
|
void TextureRepository::removeById(const u32& t_texId) {
|
||||||
s32 index = getIndexOf(t_texId);
|
s32 index = getIndexOf(t_texId);
|
||||||
TYRA_ASSERT(index != -1, "Cant remove texture, because it was not found!");
|
TYRA_ASSERT(index != -1, "Cant remove texture, because it was not found!");
|
||||||
removeByIndex(index);
|
removeByIndex(index);
|
||||||
|
removeBufferId(t_texId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureRepository::freeByMesh(const Mesh& mesh) {
|
void TextureRepository::freeByMesh(const Mesh& mesh) {
|
||||||
@@ -93,6 +108,7 @@ void TextureRepository::free(const u32& t_texId) {
|
|||||||
|
|
||||||
TYRA_ASSERT(index != -1, "Cant remove texture, because it was not found!");
|
TYRA_ASSERT(index != -1, "Cant remove texture, because it was not found!");
|
||||||
removeByIndex(index);
|
removeByIndex(index);
|
||||||
|
removeBufferId(t_texId);
|
||||||
|
|
||||||
delete tex;
|
delete tex;
|
||||||
}
|
}
|
||||||
@@ -116,7 +132,7 @@ void TextureRepository::addByMesh(const Mesh* mesh, const char* directory,
|
|||||||
if (dirFixed.back() != '/' && dirFixed.back() != ':') dirFixed += "/";
|
if (dirFixed.back() != '/' && dirFixed.back() != ':') dirFixed += "/";
|
||||||
|
|
||||||
for (u32 i = 0; i < mesh->materials.size(); i++) {
|
for (u32 i = 0; i < mesh->materials.size(); i++) {
|
||||||
if (!mesh->materials[i]->textureName.has_value()) {
|
if (!mesh->materials[i]->textureName.has_value()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"label": "1. Copy source code to docker volume",
|
"label": "1. Copy source code to docker volume",
|
||||||
"command": "docker exec -t tyra-game-compiler sh -c 'rsync -ac --delete --exclude \".git\" --exclude \".vscode\" --exclude \"*obj*/**\" --exclude \"*bin*/**\" /host/ /src/'"
|
"command": "docker exec -t tyra-game-compiler sh -c 'rsync -ac --delete --exclude=\".git\" --exclude=\".vscode\" --exclude=\"*obj*/**\" --exclude=\"*bin*/**\" /host/ /src/'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"label": "3. Copy binaries to host",
|
"label": "3. Copy binaries to host",
|
||||||
"command": "docker exec -t tyra-game-compiler sh -c 'rsync -zac --include=\"*/\" --include=\"*bin*/**\" --exclude=\"*\" /src/ /host/'",
|
"command": "docker exec -t tyra-game-compiler sh -c 'rsync -zac --include=\"*/\" --include=\"*bin*/**\" --exclude=\"*\" /src/ /host/'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
|
|||||||
@@ -1,12 +1,76 @@
|
|||||||
$PCSX2_PATH = "${Env:ProgramFiles(x86)}/PCSX2"
|
# =======================
|
||||||
$PCSX2_EXE = 'pcsx2.exe'
|
$CUSTOM_PCSX2_PATH = "" # "D:/My/Path/To/PCSX2"
|
||||||
|
# =======================
|
||||||
|
|
||||||
function GetTargetELFName {
|
function GetTargetELFName {
|
||||||
return (Select-String -Path './Makefile' -Pattern "[^ ]*.elf").Matches.Value
|
return (Select-String -Path './Makefile' -Pattern "[^ ]*.elf").Matches.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function FindPCSX2Directory {
|
||||||
|
if (-not [string]::IsNullOrEmpty($CUSTOM_PCSX2_PATH)) {
|
||||||
|
return $CUSTOM_PCSX2_PATH
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Try to find in program files
|
||||||
|
$pcsx2Path = "${Env:ProgramFiles}/PCSX2"
|
||||||
|
$pcsx2Pathx86 = "${Env:ProgramFiles(x86)}/PCSX2"
|
||||||
|
|
||||||
|
if (Test-Path -Path $pcsx2Path) {
|
||||||
|
return $pcsx2Path
|
||||||
|
}
|
||||||
|
elseif (Test-Path -Path $pcsx2Pathx86) {
|
||||||
|
return $pcsx2Pathx86
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "PCSX2 directory not found!"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function IsNewQtVersionOfPCSX2 {
|
||||||
|
param (
|
||||||
|
[string]$path
|
||||||
|
)
|
||||||
|
|
||||||
|
return Test-Path -Path "$path/qt.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
function FindPCSX2Executable {
|
||||||
|
param (
|
||||||
|
[string]$directory
|
||||||
|
)
|
||||||
|
|
||||||
|
$pcsx2ExePath = Join-Path -Path $directory -ChildPath 'pcsx2.exe'
|
||||||
|
$pcsx2QtExePath = Join-Path -Path $directory -ChildPath 'pcsx2-qt.exe'
|
||||||
|
|
||||||
|
if (Test-Path -Path $pcsx2ExePath) {
|
||||||
|
return 'pcsx2.exe'
|
||||||
|
}
|
||||||
|
elseif (Test-Path -Path $pcsx2QtExePath) {
|
||||||
|
return 'pcsx2-qt.exe'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "PCSX2 executable not found in: $directory!"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function RunPCSX2 {
|
function RunPCSX2 {
|
||||||
$PCSX2_EXE_WITHOUT_EXT = (Split-Path $PCSX2_EXE -Leaf).Split('.')[0]
|
$dirPath = FindPCSX2Directory
|
||||||
Stop-Process -Name $PCSX2_EXE_WITHOUT_EXT -ErrorAction 'SilentlyContinue'
|
$isNewVersion = IsNewQtVersionOfPCSX2 -path $dirPath
|
||||||
Start-Process -FilePath "$PCSX2_PATH/$PCSX2_EXE" -ArgumentList "--elf=$PWD/bin/$(GetTargetELFName)"
|
$executableName = FindPCSX2Executable -directory $dirPath
|
||||||
}
|
$executableNameWithoutExt = (Split-Path $executableName -Leaf).Split('.')[0]
|
||||||
|
$targetFileName = "$PWD/bin/$(GetTargetELFName)"
|
||||||
|
|
||||||
|
Stop-Process -Name $executableNameWithoutExt -ErrorAction 'SilentlyContinue'
|
||||||
|
|
||||||
|
if ($isNewVersion) {
|
||||||
|
Start-Process -FilePath "$dirPath/$executableName" -ArgumentList "-elf", $targetFileName
|
||||||
|
}
|
||||||
|
else { # Old version of PCSX2
|
||||||
|
Start-Process -FilePath "$dirPath/$executableName" -ArgumentList "--elf=$targetFileName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RunPCSX2
|
||||||
@@ -26,10 +26,10 @@ class Tutorial08 : public Game {
|
|||||||
void loadCupMesh();
|
void loadCupMesh();
|
||||||
void loadSkyboxMesh();
|
void loadSkyboxMesh();
|
||||||
|
|
||||||
Vec4 cameraPosition, cameraLookAt;
|
Vec4 cameraPosition;
|
||||||
|
Vec4 cameraLookAt;
|
||||||
|
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
|
|
||||||
u8 fpsCounter;
|
u8 fpsCounter;
|
||||||
|
|
||||||
StaticPipeline stapip;
|
StaticPipeline stapip;
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
TARGET := tutorial_10.elf
|
||||||
|
ENGINEDIR := ../../engine
|
||||||
|
|
||||||
|
#The Directories, Source, Includes, Objects, Binary and Resources
|
||||||
|
SRCDIR := src
|
||||||
|
INCDIR := inc
|
||||||
|
BUILDDIR := obj
|
||||||
|
TARGETDIR := bin
|
||||||
|
RESDIR := res
|
||||||
|
SRCEXT := cpp
|
||||||
|
VSMEXT := vsm
|
||||||
|
VCLEXT := vcl
|
||||||
|
VCLPPEXT := vclpp
|
||||||
|
DEPEXT := d
|
||||||
|
OBJEXT := o
|
||||||
|
|
||||||
|
#Flags, Libraries and Includes
|
||||||
|
CFLAGS :=
|
||||||
|
LIB :=
|
||||||
|
LIBDIRS :=
|
||||||
|
INC := -I$(INCDIR)
|
||||||
|
INCDEP := -I$(INCDIR)
|
||||||
|
|
||||||
|
include ../Makefile.tutorials-base
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022-2023, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Guido Diego Quispe Robles
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
|
||||||
|
#define FONT_CHAR_SIZE 96
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
class Font {
|
||||||
|
public:
|
||||||
|
Font();
|
||||||
|
void load(TextureRepository& repository, Renderer2D* renderer);
|
||||||
|
void free(TextureRepository& repository);
|
||||||
|
void drawText(const char* text, const int& x, const int& y, Color color);
|
||||||
|
void drawText(const std::string& text, const int& x, const int& y,
|
||||||
|
Color color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const static int chars[FONT_CHAR_SIZE];
|
||||||
|
const static int charWidths[FONT_CHAR_SIZE];
|
||||||
|
|
||||||
|
Renderer2D* renderer2D;
|
||||||
|
Sprite allFont;
|
||||||
|
std::array<Sprite, FONT_CHAR_SIZE> font;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022-2023, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Guido Diego Quispe Robles
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
#include "font_sprite.hpp"
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
class Tutorial10 : public Game {
|
||||||
|
public:
|
||||||
|
explicit Tutorial10(Engine* engine);
|
||||||
|
~Tutorial10();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadTexture();
|
||||||
|
void loadSprite();
|
||||||
|
void handlePad();
|
||||||
|
|
||||||
|
int padTimer;
|
||||||
|
Engine* engine;
|
||||||
|
Pad* pad;
|
||||||
|
Font font;
|
||||||
|
|
||||||
|
Sprite sprite;
|
||||||
|
Sprite spriteFlip;
|
||||||
|
Sprite spriteScale;
|
||||||
|
Sprite spriteStretch;
|
||||||
|
std::string strFilter;
|
||||||
|
|
||||||
|
PipelineTextureMappingType textureFilter;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
$ConfigFile = Join-Path $PSScriptRoot '../../windows-pcsx2.ps1'
|
||||||
|
. $ConfigFile
|
||||||
|
|
||||||
|
RunPCSX2
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022-2023, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Guido Diego Quispe Robles
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "font_sprite.hpp"
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
const int Font::chars[FONT_CHAR_SIZE]{
|
||||||
|
' ', '!', '"', ' ', '$', '%', ' ', '{', '(', ')', ' ', '+', ',', '-',
|
||||||
|
'.', '/', '0', '1', '2', '3', '4', '5', '6', '2', '8', '9', ':', ';',
|
||||||
|
'<', '=', '>', '?', ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
|
||||||
|
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||||
|
'X', 'Y', 'Z', ' ', ' ', ' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e',
|
||||||
|
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
|
||||||
|
't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '}', ']', '~', ' '};
|
||||||
|
|
||||||
|
const int Font::charWidths[FONT_CHAR_SIZE]{
|
||||||
|
0, 1, 3, 0, 5, 9, 0, 9, 3, 3, 0, 5, 2, 2, 1, 4, 4, 2, 4, 4, 5, 4, 4, 4,
|
||||||
|
4, 4, 1, 2, 4, 5, 4, 4, 0, 6, 5, 5, 5, 4, 4, 5, 5, 1, 4, 5, 4, 7, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 6, 7, 5, 5, 4, 0, 0, 0, 0, 0, 0, 5, 4, 4, 4, 4, 3, 4,
|
||||||
|
4, 1, 2, 4, 1, 7, 4, 4, 4, 4, 3, 4, 3, 4, 5, 7, 4, 4, 4, 2, 5, 2, 6, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Font::Font() {}
|
||||||
|
|
||||||
|
void Font::load(TextureRepository& repository, Renderer2D* renderer) {
|
||||||
|
renderer2D = renderer;
|
||||||
|
|
||||||
|
float height = 16.0F;
|
||||||
|
float width = 16.0F;
|
||||||
|
|
||||||
|
allFont.mode = MODE_REPEAT;
|
||||||
|
allFont.size = Vec2(255, 127);
|
||||||
|
|
||||||
|
auto filepath = FileUtils::fromCwd("earthbound-Font.png");
|
||||||
|
auto* texture = repository.add(filepath);
|
||||||
|
texture->addLink(allFont.id);
|
||||||
|
|
||||||
|
int column = 0;
|
||||||
|
int arrow = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < FONT_CHAR_SIZE; i++) {
|
||||||
|
font[i].id = allFont.id;
|
||||||
|
font[i].mode = MODE_REPEAT;
|
||||||
|
font[i].size = Vec2(width, height);
|
||||||
|
font[i].offset = Vec2(width * column, height * arrow);
|
||||||
|
column++;
|
||||||
|
|
||||||
|
if (column == 16) {
|
||||||
|
arrow++;
|
||||||
|
column = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::free(TextureRepository& repository) {
|
||||||
|
repository.freeBySprite(allFont);
|
||||||
|
for (int i = 0; i < FONT_CHAR_SIZE; i++) {
|
||||||
|
repository.freeBySprite(font[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::drawText(const char* text, const int& x, const int& y, Color color) {
|
||||||
|
drawText(std::string(text), x, y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::drawText(const std::string& text, const int& x, const int& y,
|
||||||
|
Color color) {
|
||||||
|
int sizeText = text.size();
|
||||||
|
|
||||||
|
int offsetY = 0;
|
||||||
|
int offsetX = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeText; i++) {
|
||||||
|
int fontPos = text[i];
|
||||||
|
Sprite fontSpr = font[0];
|
||||||
|
|
||||||
|
for (int j = 0; j < FONT_CHAR_SIZE; j++) {
|
||||||
|
if (fontPos == chars[j]) {
|
||||||
|
fontPos = j;
|
||||||
|
fontSpr = font[j];
|
||||||
|
fontSpr.color = color;
|
||||||
|
fontSpr.position = Vec2(x + offsetX, y + offsetY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontPos == '\n') {
|
||||||
|
offsetY += 18;
|
||||||
|
offsetX = 0.0f;
|
||||||
|
} else {
|
||||||
|
if ((fontPos != ' ') && (fontPos != '\t')) {
|
||||||
|
renderer2D->render(fontSpr);
|
||||||
|
offsetX += charWidths[fontPos] + 2;
|
||||||
|
} else {
|
||||||
|
offsetX += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022-2023, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Guido Diego Quispe Robles
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "engine.hpp"
|
||||||
|
#include "tutorial_10.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this tutorial we will learn:
|
||||||
|
* - How works the offset of the sprite
|
||||||
|
* - How works the texture mapping
|
||||||
|
* - How to write text (font)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Tyra::Engine engine;
|
||||||
|
Tyra::Tutorial10 game(&engine);
|
||||||
|
engine.run(&game);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,290 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022-2023, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Guido Diego Quispe Robles
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
#include "tutorial_10.hpp"
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
Tutorial10::Tutorial10(Engine* t_engine)
|
||||||
|
: padTimer(0), engine(t_engine), pad(&t_engine->pad) {}
|
||||||
|
|
||||||
|
Tutorial10::~Tutorial10() {
|
||||||
|
engine->renderer.getTextureRepository().freeBySprite(sprite);
|
||||||
|
engine->renderer.getTextureRepository().freeBySprite(spriteFlip);
|
||||||
|
engine->renderer.getTextureRepository().freeBySprite(spriteScale);
|
||||||
|
engine->renderer.getTextureRepository().freeBySprite(spriteStretch);
|
||||||
|
font.free(engine->renderer.getTextureRepository());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial10::init() {
|
||||||
|
engine->renderer.setClearScreenColor(Color(32.0F, 32.0F, 32.0F));
|
||||||
|
|
||||||
|
/** Load all the sprites of the sprite sheet. */
|
||||||
|
font.load(engine->renderer.getTextureRepository(),
|
||||||
|
&engine->renderer.renderer2D);
|
||||||
|
|
||||||
|
/** Sprite contains rectangle information. */
|
||||||
|
loadSprite();
|
||||||
|
|
||||||
|
/** Texture contains png image. */
|
||||||
|
loadTexture();
|
||||||
|
|
||||||
|
/** Set the texture filtering. */
|
||||||
|
textureFilter = TyraNearest;
|
||||||
|
|
||||||
|
engine->renderer.core.renderer2D.setTextureMappingType(textureFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial10::loop() {
|
||||||
|
auto& renderer = engine->renderer;
|
||||||
|
|
||||||
|
/** Change the texture filtering of the texture.
|
||||||
|
*
|
||||||
|
* The options are:
|
||||||
|
* TyraNearest (Point Sampling):
|
||||||
|
* uses the color of the texel closest to the pixel center for the pixel
|
||||||
|
* color.
|
||||||
|
*
|
||||||
|
* TyraLinear (Bilinear Sampling):
|
||||||
|
* the four nearest texels to the pixel center are sampled
|
||||||
|
* and their colors are combined by weighted average according to distance.
|
||||||
|
*
|
||||||
|
* By default it is linear.
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderer.core.renderer2D.setTextureMappingType(textureFilter);
|
||||||
|
|
||||||
|
handlePad();
|
||||||
|
|
||||||
|
/** Begin frame will clear our screen. */
|
||||||
|
renderer.beginFrame();
|
||||||
|
|
||||||
|
/** Render sprite. */
|
||||||
|
renderer.renderer2D.render(sprite);
|
||||||
|
renderer.core.renderer2D.setTextureMappingType(TyraLinear);
|
||||||
|
renderer.renderer2D.render(spriteFlip);
|
||||||
|
renderer.core.renderer2D.setTextureMappingType(textureFilter);
|
||||||
|
renderer.renderer2D.render(spriteScale);
|
||||||
|
renderer.renderer2D.render(spriteStretch);
|
||||||
|
|
||||||
|
font.drawText("tests with sprite sheet", (512 / 2) - 60, 10,
|
||||||
|
Color(255, 255, 255));
|
||||||
|
font.drawText("Press Cross for nearest filter", (512 / 2) - 70, 50,
|
||||||
|
Color(255, 255, 255));
|
||||||
|
font.drawText("Press Circle for linear filter", (512 / 2) - 65, 70,
|
||||||
|
Color(255, 255, 255));
|
||||||
|
font.drawText("Use left stick for move the offsets of the sprites",
|
||||||
|
(512 / 2) - 110, 90, Color(255, 255, 255));
|
||||||
|
font.drawText("sprite 32x32\n scaled x3", sprite.position.x + 16,
|
||||||
|
sprite.position.y - 40, Color(255, 255, 255));
|
||||||
|
font.drawText("sprite 32x32\nscaled x3 with flip", spriteFlip.position.x + 4,
|
||||||
|
spriteFlip.position.y - 40, Color(255, 255, 255));
|
||||||
|
font.drawText("sprite 96x96 with\n repeat mode", spriteScale.position.x + 6,
|
||||||
|
spriteScale.position.y - 40, Color(255, 255, 255));
|
||||||
|
font.drawText("sprite 96x96 with\n stretch mode",
|
||||||
|
spriteStretch.position.x + 6, spriteStretch.position.y - 40,
|
||||||
|
Color(255, 255, 255));
|
||||||
|
|
||||||
|
if (textureFilter == TyraLinear) {
|
||||||
|
strFilter = "Filter: Linear";
|
||||||
|
} else {
|
||||||
|
strFilter = "Filter: Nearest";
|
||||||
|
}
|
||||||
|
|
||||||
|
int posX1 = sprite.position.x + 16;
|
||||||
|
int posX2 = spriteFlip.position.x + 16;
|
||||||
|
int posX3 = spriteStretch.position.x + 16;
|
||||||
|
int posX4 = spriteScale.position.x + 16;
|
||||||
|
|
||||||
|
int posY1 = sprite.position.y + (sprite.size.y * sprite.scale) + 16;
|
||||||
|
int posY2 =
|
||||||
|
spriteFlip.position.y + (spriteFlip.size.y * spriteFlip.scale) + 16;
|
||||||
|
int posY3 = spriteStretch.position.y +
|
||||||
|
(spriteStretch.size.y * spriteStretch.scale) + 16;
|
||||||
|
int posY4 =
|
||||||
|
spriteScale.position.y + (spriteScale.size.y * spriteScale.scale) + 16;
|
||||||
|
|
||||||
|
font.drawText(strFilter, posX1, posY1, Color(255, 255, 255));
|
||||||
|
font.drawText("Filter: Linear", posX2, posY2, Color(255, 255, 255));
|
||||||
|
font.drawText(strFilter, posX3, posY3, Color(255, 255, 255));
|
||||||
|
font.drawText(strFilter, posX4, posY4, Color(255, 255, 255));
|
||||||
|
|
||||||
|
/** End frame will perform vsync. */
|
||||||
|
renderer.endFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial10::handlePad() {
|
||||||
|
if (engine->pad.getClicked().Cross) {
|
||||||
|
textureFilter = TyraNearest;
|
||||||
|
} else if (engine->pad.getClicked().Circle) {
|
||||||
|
textureFilter = TyraLinear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Move the offset of the sprites.
|
||||||
|
*
|
||||||
|
* The offset of the sprite need to be equal or greater to zero
|
||||||
|
* or a graphical error occurs.
|
||||||
|
*
|
||||||
|
* And the sum of the sprite size and the offset must be less than 1024
|
||||||
|
* or a graphical error occurs.
|
||||||
|
*
|
||||||
|
* Sum with repeat mode:
|
||||||
|
* Max = sprite.size + sprite.offset.
|
||||||
|
*
|
||||||
|
* Sum with strecth mode:
|
||||||
|
* Max = original size of the image + sprite.offset.
|
||||||
|
*
|
||||||
|
* If it continues moving past these values
|
||||||
|
* in a moment it will return to normal but
|
||||||
|
* the error will be repeated with another value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (padTimer <= 0) {
|
||||||
|
if (pad->getLeftJoyPad().v <= 100) { // up
|
||||||
|
sprite.offset -= Vec2(0, 16);
|
||||||
|
spriteFlip.offset -= Vec2(0, 16);
|
||||||
|
spriteScale.offset -= Vec2(0, 16);
|
||||||
|
spriteStretch.offset -= Vec2(0, 16);
|
||||||
|
padTimer = 20;
|
||||||
|
printf("New offset: %f,%f\n", sprite.offset.x, sprite.offset.y);
|
||||||
|
} else if (pad->getLeftJoyPad().v >= 200) { // down
|
||||||
|
sprite.offset += Vec2(0, 16);
|
||||||
|
spriteFlip.offset += Vec2(0, 16);
|
||||||
|
spriteScale.offset += Vec2(0, 16);
|
||||||
|
spriteStretch.offset += Vec2(0, 16);
|
||||||
|
padTimer = 20;
|
||||||
|
printf("New offset: %f,%f\n", sprite.offset.x, sprite.offset.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pad->getLeftJoyPad().h <= 100) { // left
|
||||||
|
sprite.offset -= Vec2(16, 0);
|
||||||
|
spriteFlip.offset -= Vec2(16, 0);
|
||||||
|
spriteScale.offset -= Vec2(16, 0);
|
||||||
|
spriteStretch.offset -= Vec2(16, 0);
|
||||||
|
padTimer = 20;
|
||||||
|
printf("New offset: %f,%f\n", sprite.offset.x, sprite.offset.y);
|
||||||
|
} else if (pad->getLeftJoyPad().h >= 200) { // right
|
||||||
|
sprite.offset += Vec2(16, 0);
|
||||||
|
spriteFlip.offset += Vec2(16, 0);
|
||||||
|
spriteScale.offset += Vec2(16, 0);
|
||||||
|
spriteStretch.offset += Vec2(16, 0);
|
||||||
|
padTimer = 20;
|
||||||
|
printf("New offset: %f,%f\n", sprite.offset.x, sprite.offset.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
padTimer--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial10::loadSprite() {
|
||||||
|
const auto& screenSettings = engine->renderer.core.getSettings();
|
||||||
|
|
||||||
|
int offset = 25;
|
||||||
|
|
||||||
|
sprite.mode = SpriteMode::MODE_REPEAT;
|
||||||
|
|
||||||
|
/** Let's scale it down */
|
||||||
|
sprite.size = Vec2(32.0F, 32.0F);
|
||||||
|
sprite.scale = 3;
|
||||||
|
|
||||||
|
/** Set the position */
|
||||||
|
sprite.position =
|
||||||
|
Vec2(offset, screenSettings.getHeight() / 2.0F - sprite.size.y / 2.0F);
|
||||||
|
|
||||||
|
spriteFlip.mode = SpriteMode::MODE_REPEAT;
|
||||||
|
|
||||||
|
spriteFlip.flipHorizontal = true;
|
||||||
|
spriteFlip.flipVertical = true;
|
||||||
|
|
||||||
|
spriteFlip.size = Vec2(32.0F, 32.0F);
|
||||||
|
|
||||||
|
spriteFlip.scale = 3;
|
||||||
|
|
||||||
|
spriteFlip.position =
|
||||||
|
Vec2(((offset * 2) + (32.0F * 3)),
|
||||||
|
screenSettings.getHeight() / 2.0F - sprite.size.y / 2.0F);
|
||||||
|
|
||||||
|
spriteScale.mode = SpriteMode::MODE_REPEAT;
|
||||||
|
|
||||||
|
spriteScale.size = Vec2(96.0F, 96.0F);
|
||||||
|
|
||||||
|
spriteScale.position =
|
||||||
|
Vec2(((offset * 3) + ((32.0F * 3) * 2)),
|
||||||
|
screenSettings.getHeight() / 2.0F - sprite.size.y / 2.0F);
|
||||||
|
|
||||||
|
spriteStretch.mode = SpriteMode::MODE_STRETCH;
|
||||||
|
|
||||||
|
spriteStretch.size = Vec2(96.0F, 96.0F);
|
||||||
|
|
||||||
|
spriteStretch.position =
|
||||||
|
Vec2(((offset * 4) + ((32.0F * 3) * 3)),
|
||||||
|
screenSettings.getHeight() / 2.0F - sprite.size.y / 2.0F);
|
||||||
|
|
||||||
|
TYRA_LOG("Sprite created!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial10::loadTexture() {
|
||||||
|
/**
|
||||||
|
* Renderer has high layer functions,
|
||||||
|
* which allows to render:
|
||||||
|
* - Sprite (2D)
|
||||||
|
* - Mesh (3D)
|
||||||
|
*
|
||||||
|
* It uses ONLY low layer functions which are in renderer.core
|
||||||
|
*/
|
||||||
|
auto& renderer = engine->renderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TextureRepository is a repository of textures.
|
||||||
|
* It is a singleton class, with all game textures.
|
||||||
|
* We are linking these textures with sprite's (2D) and mesh (3D) materials.
|
||||||
|
*/
|
||||||
|
auto& textureRepository = renderer.getTextureRepository();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Texture is stored in "res" directory.
|
||||||
|
* Content of "res" directory is automatically copied into
|
||||||
|
* "bin" directory, which contains our final game.
|
||||||
|
*
|
||||||
|
* File utils automatically add's device prefix to the path,
|
||||||
|
* based on current working directory.
|
||||||
|
*
|
||||||
|
* In PS2 world:
|
||||||
|
* - USB has a "mass:" prefix
|
||||||
|
* - Our PC in PS2Link has a "host:" prefix
|
||||||
|
* - Our PC in PCSX2 has a "host:" prefix
|
||||||
|
*/
|
||||||
|
auto filepath = FileUtils::fromCwd("atlas.png");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tyra supports following PNG formats:
|
||||||
|
* 32bpp (RGBA)
|
||||||
|
* 24bpp (RGB)
|
||||||
|
* 8bpp, palletized (RGBA)
|
||||||
|
* 4bpp, palletized (RGBA)
|
||||||
|
*
|
||||||
|
* 8bpp and 4bpp are the fastest.
|
||||||
|
* All of these formats can be easily exported via GIMP.
|
||||||
|
*/
|
||||||
|
auto* texture = textureRepository.add(filepath);
|
||||||
|
|
||||||
|
/** Let's assign this texture to sprite. */
|
||||||
|
texture->addLink(sprite.id);
|
||||||
|
|
||||||
|
spriteFlip.id = sprite.id;
|
||||||
|
spriteScale.id = sprite.id;
|
||||||
|
spriteStretch.id = sprite.id;
|
||||||
|
|
||||||
|
TYRA_LOG("Texture loaded!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
TARGET := tutorial_11.elf
|
||||||
|
ENGINEDIR := ../../engine
|
||||||
|
|
||||||
|
#The Directories, Source, Includes, Objects, Binary and Resources
|
||||||
|
SRCDIR := src
|
||||||
|
INCDIR := inc
|
||||||
|
BUILDDIR := obj
|
||||||
|
TARGETDIR := bin
|
||||||
|
RESDIR := res
|
||||||
|
SRCEXT := cpp
|
||||||
|
VSMEXT := vsm
|
||||||
|
VCLEXT := vcl
|
||||||
|
VCLPPEXT := vclpp
|
||||||
|
DEPEXT := d
|
||||||
|
OBJEXT := o
|
||||||
|
|
||||||
|
#Flags, Libraries and Includes
|
||||||
|
CFLAGS :=
|
||||||
|
LIB :=
|
||||||
|
LIBDIRS :=
|
||||||
|
INC := -I$(INCDIR)
|
||||||
|
INCDEP := -I$(INCDIR)
|
||||||
|
|
||||||
|
include ../Makefile.tutorials-base
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2024, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Wellington Carvalho <wellcoj@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
class Tutorial11 : public Game {
|
||||||
|
public:
|
||||||
|
explicit Tutorial11(Engine* engine);
|
||||||
|
~Tutorial11();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setDrawData();
|
||||||
|
void loadBags();
|
||||||
|
|
||||||
|
void setTextureRegionRepeat();
|
||||||
|
void setTextureDefaultWrap();
|
||||||
|
|
||||||
|
const u8 MAX_TILES = 4;
|
||||||
|
u8 TILE_COL = 0;
|
||||||
|
u8 TILE_ROW = 0;
|
||||||
|
|
||||||
|
u8 shouldFlipTextureSettings = false;
|
||||||
|
float limitTimeToFlip = 2.00f;
|
||||||
|
float elapsedTime = 0;
|
||||||
|
|
||||||
|
Engine* engine;
|
||||||
|
|
||||||
|
Vec4 cameraPosition, cameraLookAt;
|
||||||
|
M4x4 translation, rotation, scale, model;
|
||||||
|
Texture* UVCheckerTex;
|
||||||
|
|
||||||
|
std::array<Vec4, 6> vertices;
|
||||||
|
std::array<Color, 6> colors;
|
||||||
|
std::array<Vec4, 6> uvMap;
|
||||||
|
|
||||||
|
StaticPipeline stapip;
|
||||||
|
std::unique_ptr<StaPipBag> bag;
|
||||||
|
std::unique_ptr<StaPipInfoBag> infoBag;
|
||||||
|
std::unique_ptr<StaPipColorBag> colorBag;
|
||||||
|
std::unique_ptr<StaPipTextureBag> texBag;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
$ConfigFile = Join-Path $PSScriptRoot '../../windows-pcsx2.ps1'
|
||||||
|
. $ConfigFile
|
||||||
|
|
||||||
|
RunPCSX2
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2024, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Wellington Carvalho <wellcoj@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "engine.hpp"
|
||||||
|
#include "tutorial_11.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this tutorial we will learn:
|
||||||
|
* - How to use texture in repeate mode of GS
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Tyra::Engine engine;
|
||||||
|
Tyra::Tutorial11 game(&engine);
|
||||||
|
engine.run(&game);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2024, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Wellington Carvalho <wellcoj@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
#include "tutorial_11.hpp"
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
Tutorial11::Tutorial11(Engine* t_engine) : engine(t_engine) {
|
||||||
|
translation = M4x4::Identity;
|
||||||
|
rotation = M4x4::Identity;
|
||||||
|
scale = M4x4::Identity;
|
||||||
|
model = M4x4::Identity;
|
||||||
|
|
||||||
|
rotation.rotateY(Math::PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tutorial11::~Tutorial11() {}
|
||||||
|
|
||||||
|
void Tutorial11::init() {
|
||||||
|
stapip.setRenderer(&engine->renderer.core);
|
||||||
|
|
||||||
|
cameraPosition = Vec4(0.0F, 0.0F, -10.0F);
|
||||||
|
cameraLookAt.unit();
|
||||||
|
|
||||||
|
UVCheckerTex = engine->renderer.getTextureRepository().add(
|
||||||
|
FileUtils::fromCwd("uv_checker.png"));
|
||||||
|
|
||||||
|
setDrawData();
|
||||||
|
loadBags();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial11::loop() {
|
||||||
|
const auto deltaTime =
|
||||||
|
std::min(1.0f / static_cast<float>(engine->info.getFps()),
|
||||||
|
static_cast<float>(1.0 / 60.0f));
|
||||||
|
elapsedTime += deltaTime;
|
||||||
|
|
||||||
|
if (elapsedTime > limitTimeToFlip) {
|
||||||
|
elapsedTime -= limitTimeToFlip;
|
||||||
|
shouldFlipTextureSettings = !shouldFlipTextureSettings;
|
||||||
|
shouldFlipTextureSettings ? setTextureRegionRepeat()
|
||||||
|
: setTextureDefaultWrap();
|
||||||
|
|
||||||
|
// Update texture packet info after change wrap settings
|
||||||
|
engine->renderer.core.texture.updateTextureInfo(UVCheckerTex);
|
||||||
|
}
|
||||||
|
|
||||||
|
model = translation * rotation * scale;
|
||||||
|
|
||||||
|
engine->renderer.beginFrame(CameraInfo3D(&cameraPosition, &cameraLookAt));
|
||||||
|
{
|
||||||
|
engine->renderer.renderer3D.usePipeline(stapip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets draw manually via "bags".
|
||||||
|
* You can do the same thing with dynamic pipeline.
|
||||||
|
*/
|
||||||
|
stapip.core.render(bag.get());
|
||||||
|
}
|
||||||
|
engine->renderer.endFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial11::setDrawData() {
|
||||||
|
vertices = {
|
||||||
|
// Tri 1
|
||||||
|
Vec4(-3.0F, -3.0F, 0.0F),
|
||||||
|
Vec4(3.0F, -3.0F, 0.0F),
|
||||||
|
Vec4(-3.0F, 3.0F, 0.0F),
|
||||||
|
|
||||||
|
// Tri 2
|
||||||
|
Vec4(3.0F, -3.0F, 0.0F),
|
||||||
|
Vec4(-3.0F, 3.0F, 0.0F),
|
||||||
|
Vec4(3.0F, 3.0F, 0.0F),
|
||||||
|
};
|
||||||
|
|
||||||
|
colors = {
|
||||||
|
Color(128.0F, 128.0F, 128.0F), Color(128.0F, 128.0F, 128.0F),
|
||||||
|
Color(128.0F, 128.0F, 128.0F), Color(128.0F, 128.0F, 128.0F),
|
||||||
|
Color(128.0F, 128.0F, 128.0F), Color(128.0F, 128.0F, 128.0F),
|
||||||
|
};
|
||||||
|
|
||||||
|
setTextureDefaultWrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial11::setTextureDefaultWrap() {
|
||||||
|
uvMap = {Vec4(0.0f, 1.0F, 1.0F, 0.0f), Vec4(0.0f + 1, 1.0F, 1.0F, 0.0f),
|
||||||
|
Vec4(0.0f, 0.0f, 1.0F, 0.0f),
|
||||||
|
|
||||||
|
Vec4(0.0f + 1, 1.0F, 1.0F, 0.0f), Vec4(0.0f, 0.0f, 1.0F, 0.0f),
|
||||||
|
Vec4(0.0f + 1.0F, 0.0f, 1.0F, 0.0f)};
|
||||||
|
|
||||||
|
TYRA_LOG("Reseting texture wrap settings");
|
||||||
|
UVCheckerTex->setDefaultWrapSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial11::setTextureRegionRepeat() {
|
||||||
|
const float _scale = 1.0f / (float)MAX_TILES;
|
||||||
|
const Vec4 scale =
|
||||||
|
Vec4(MAX_TILES > 0 ? _scale * MAX_TILES : _scale,
|
||||||
|
MAX_TILES > 0 ? _scale * MAX_TILES : _scale, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
uvMap = {
|
||||||
|
Vec4(TILE_COL, TILE_ROW + 1.0F, 1.0F, 0.0f) * scale,
|
||||||
|
Vec4(TILE_COL + 1, TILE_ROW + 1.0F, 1.0F, 0.0f) * scale,
|
||||||
|
Vec4(TILE_COL, TILE_ROW, 1.0F, 0.0f) * scale,
|
||||||
|
|
||||||
|
Vec4(TILE_COL + 1, TILE_ROW + 1.0F, 1.0F, 0.0f) * scale,
|
||||||
|
Vec4(TILE_COL, TILE_ROW, 1.0F, 0.0f) * scale,
|
||||||
|
Vec4(TILE_COL + 1.0F, TILE_ROW, 1.0F, 0.0f) * scale,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto tileW = (UVCheckerTex->getWidth() * _scale) - 1;
|
||||||
|
const auto tileH = (UVCheckerTex->getHeight() * _scale) - 1;
|
||||||
|
const auto tileU = TILE_COL * tileW + TILE_COL;
|
||||||
|
const auto tileV = TILE_ROW * tileH + TILE_ROW;
|
||||||
|
|
||||||
|
int minu = tileW;
|
||||||
|
int minv = tileH;
|
||||||
|
int maxu = tileU;
|
||||||
|
int maxv = tileV;
|
||||||
|
|
||||||
|
TYRA_LOG("Changing the texture wraping...");
|
||||||
|
UVCheckerTex->setWrapSettings(TextureWrap::RegionRepeat,
|
||||||
|
TextureWrap::RegionRepeat, minu, minv, maxu,
|
||||||
|
maxv);
|
||||||
|
|
||||||
|
TILE_COL++;
|
||||||
|
if (TILE_COL >= MAX_TILES) {
|
||||||
|
TILE_COL %= MAX_TILES;
|
||||||
|
TILE_ROW = (TILE_ROW + 1) % MAX_TILES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial11::loadBags() {
|
||||||
|
/**
|
||||||
|
* Create info bag and fill it with model matrix and shading type.
|
||||||
|
* Keep rest of the options as default.
|
||||||
|
*/
|
||||||
|
infoBag = std::make_unique<StaPipInfoBag>();
|
||||||
|
infoBag->model = &model;
|
||||||
|
infoBag->shadingType = TyraShadingGouraud;
|
||||||
|
infoBag->textureMappingType = TyraNearest;
|
||||||
|
|
||||||
|
/** Create colors bag and set data pointer */
|
||||||
|
colorBag = std::make_unique<StaPipColorBag>();
|
||||||
|
colorBag->many = colors.begin();
|
||||||
|
|
||||||
|
texBag = std::make_unique<StaPipTextureBag>();
|
||||||
|
texBag.get()->texture = UVCheckerTex;
|
||||||
|
texBag.get()->coordinates = uvMap.data();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create main bag and set:
|
||||||
|
* - vertices data
|
||||||
|
* - vertices count
|
||||||
|
* - pointers to other bags
|
||||||
|
*
|
||||||
|
* You can add here lighting and texture bag as well.
|
||||||
|
* If you want to have deeper look of this feature, please
|
||||||
|
* read static_pipeline.cpp code file.
|
||||||
|
*/
|
||||||
|
bag = std::make_unique<StaPipBag>();
|
||||||
|
bag->color = colorBag.get();
|
||||||
|
bag->texture = texBag.get();
|
||||||
|
bag->info = infoBag.get();
|
||||||
|
bag->vertices = vertices.begin();
|
||||||
|
bag->count = vertices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
+70
-6
@@ -1,12 +1,76 @@
|
|||||||
$PCSX2_PATH = "${Env:ProgramFiles(x86)}/PCSX2"
|
# =======================
|
||||||
$PCSX2_EXE = 'pcsx2.exe'
|
$CUSTOM_PCSX2_PATH = "" # "D:/My/Path/To/PCSX2"
|
||||||
|
# =======================
|
||||||
|
|
||||||
function GetTargetELFName {
|
function GetTargetELFName {
|
||||||
return (Select-String -Path './Makefile' -Pattern "[^ ]*.elf").Matches.Value
|
return (Select-String -Path './Makefile' -Pattern "[^ ]*.elf").Matches.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function FindPCSX2Directory {
|
||||||
|
if (-not [string]::IsNullOrEmpty($CUSTOM_PCSX2_PATH)) {
|
||||||
|
return $CUSTOM_PCSX2_PATH
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Try to find in program files
|
||||||
|
$pcsx2Path = "${Env:ProgramFiles}/PCSX2"
|
||||||
|
$pcsx2Pathx86 = "${Env:ProgramFiles(x86)}/PCSX2"
|
||||||
|
|
||||||
|
if (Test-Path -Path $pcsx2Path) {
|
||||||
|
return $pcsx2Path
|
||||||
|
}
|
||||||
|
elseif (Test-Path -Path $pcsx2Pathx86) {
|
||||||
|
return $pcsx2Pathx86
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "PCSX2 directory not found!"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function IsNewQtVersionOfPCSX2 {
|
||||||
|
param (
|
||||||
|
[string]$path
|
||||||
|
)
|
||||||
|
|
||||||
|
return Test-Path -Path "$path/qt.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
function FindPCSX2Executable {
|
||||||
|
param (
|
||||||
|
[string]$directory
|
||||||
|
)
|
||||||
|
|
||||||
|
$pcsx2ExePath = Join-Path -Path $directory -ChildPath 'pcsx2.exe'
|
||||||
|
$pcsx2QtExePath = Join-Path -Path $directory -ChildPath 'pcsx2-qt.exe'
|
||||||
|
|
||||||
|
if (Test-Path -Path $pcsx2ExePath) {
|
||||||
|
return 'pcsx2.exe'
|
||||||
|
}
|
||||||
|
elseif (Test-Path -Path $pcsx2QtExePath) {
|
||||||
|
return 'pcsx2-qt.exe'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "PCSX2 executable not found in: $directory!"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function RunPCSX2 {
|
function RunPCSX2 {
|
||||||
$PCSX2_EXE_WITHOUT_EXT = (Split-Path $PCSX2_EXE -Leaf).Split('.')[0]
|
$dirPath = FindPCSX2Directory
|
||||||
Stop-Process -Name $PCSX2_EXE_WITHOUT_EXT -ErrorAction 'SilentlyContinue'
|
$isNewVersion = IsNewQtVersionOfPCSX2 -path $dirPath
|
||||||
Start-Process -FilePath "$PCSX2_PATH/$PCSX2_EXE" -ArgumentList "--elf=$PWD/bin/$(GetTargetELFName)"
|
$executableName = FindPCSX2Executable -directory $dirPath
|
||||||
}
|
$executableNameWithoutExt = (Split-Path $executableName -Leaf).Split('.')[0]
|
||||||
|
$targetFileName = "$PWD/bin/$(GetTargetELFName)"
|
||||||
|
|
||||||
|
Stop-Process -Name $executableNameWithoutExt -ErrorAction 'SilentlyContinue'
|
||||||
|
|
||||||
|
if ($isNewVersion) {
|
||||||
|
Start-Process -FilePath "$dirPath/$executableName" -ArgumentList "-elf", $targetFileName
|
||||||
|
}
|
||||||
|
else { # Old version of PCSX2
|
||||||
|
Start-Process -FilePath "$dirPath/$executableName" -ArgumentList "--elf=$targetFileName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RunPCSX2
|
||||||
Reference in New Issue
Block a user