Showing preview only (451K chars total). Download the full file or copy to clipboard to get everything.
Repository: ABelliqueux/nolibgs_hello_worlds
Branch: main
Commit: 48790325a9e3
Files: 186
Total size: 40.3 MB
Directory structure:
gitextract_v4hb7egi/
├── .github/
│ └── workflows/
│ ├── Linux-build-archive.yml
│ ├── linux-build.yml
│ ├── macos-build.yml
│ └── windows-build.yml
├── .gitmodules
├── LICENSE
├── Makefile
├── README.md
├── TIM/
│ ├── README.md
│ ├── TIM16.tim
│ ├── TIM4.tim
│ ├── TIM8.tim
│ ├── bousai.tim
│ └── cubetex.tim
├── VAG/
│ ├── 0_come.vag
│ ├── 1_cuek.vag
│ ├── 2_erro.vag
│ ├── 3_hehe.vag
│ ├── 4_m4a1.vag
│ ├── 5_punc.vag
│ ├── 7_wron.vag
│ ├── 8_yooo.vag
│ ├── README.md
│ ├── hello.vag
│ ├── hello_poly.vag
│ └── poly.vag
├── common.mk
├── hello_2pads/
│ ├── Makefile
│ └── hello_2pads.c
├── hello_bs/
│ ├── Makefile
│ ├── README.md
│ ├── bs/
│ │ ├── bace.bs
│ │ ├── bace.rgb
│ │ ├── bace.tim
│ │ └── bace.yuv
│ ├── hello_bs.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_cd/
│ ├── Makefile
│ ├── README.md
│ ├── hello_cd.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_cdda/
│ ├── Makefile
│ ├── README.md
│ ├── hello_cdda.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_cube/
│ ├── Makefile
│ ├── cube.c
│ └── hello_cube.c
├── hello_cubetex/
│ ├── Makefile
│ ├── cubetex.c
│ └── hello_cubetex.c
├── hello_cubetex_stp/
│ ├── Makefile
│ ├── README.md
│ ├── TIM/
│ │ ├── stpOn8bpp.tim
│ │ ├── stpOnBlack.tim
│ │ └── stpOnNonBlack.tim
│ ├── cubetex.c
│ └── hello_cubetex_stp.c
├── hello_font/
│ ├── Makefile
│ ├── README.md
│ ├── fnt.tim
│ └── hello_font.c
├── hello_fx/
│ ├── Makefile
│ ├── TIM/
│ │ ├── bg.tim
│ │ ├── cube.tim
│ │ └── sky.tim
│ ├── cubetex.c
│ └── hello_fx.c
├── hello_gte_opti/
│ ├── Makefile
│ └── hello_gte_opti.c
├── hello_light/
│ ├── Makefile
│ ├── cube.c
│ └── hello_light.c
├── hello_mod/
│ ├── HIT/
│ │ ├── STAR.HIT
│ │ └── STAR.mod
│ ├── Makefile
│ ├── README.md
│ ├── hello_mod.c
│ └── src/
│ ├── mod.c
│ └── mod.h
├── hello_multi_vag/
│ ├── Makefile
│ ├── README.md
│ └── hello_multi_vag.c
├── hello_multi_xa/
│ ├── Makefile
│ ├── README.md
│ ├── hello_multi_xa.c
│ ├── isoconfig.xml
│ ├── system.cnf
│ └── xa/
│ ├── 5_come.xa
│ ├── 5_erro.xa
│ ├── 5_sile_h.xa
│ ├── 6_cuek.xa
│ ├── 6_hehe.xa
│ ├── 6_sile_h.xa
│ ├── 6_wron.xa
│ ├── 7_m4a1.xa
│ ├── 7_punch.xa
│ ├── 7_sile_h.xa
│ ├── 8_yooo.xa
│ ├── channel5.xa
│ ├── channel6.xa
│ ├── channel7.xa
│ ├── channel8.xa
│ ├── interleave8.txt
│ └── vert8.xa
├── hello_ovl_exec/
│ ├── Makefile
│ ├── README.md
│ ├── common.h
│ ├── hello_ovl_exec.c
│ ├── hello_ovl_world/
│ │ ├── Makefile
│ │ ├── hello_ovl_world.c
│ │ └── hello_world.c
│ ├── hello_poly/
│ │ ├── Makefile
│ │ ├── hello_ovl_poly.c
│ │ └── hello_poly.c
│ ├── hello_tile/
│ │ ├── Makefile
│ │ ├── hello_ovl_tile.c
│ │ └── hello_tile.c
│ ├── isoconfig.xml
│ ├── overlay.ld
│ └── system.cnf
├── hello_pad/
│ ├── Makefile
│ └── hello_pad.c
├── hello_poly/
│ ├── Makefile
│ └── hello_poly.c
├── hello_poly_ft/
│ ├── Makefile
│ └── hello_poly_ft.c
├── hello_poly_fun/
│ ├── Makefile
│ └── hello_poly_fun.c
├── hello_poly_gt/
│ ├── Makefile
│ └── hello_poly_gt.c
├── hello_poly_gt_tw/
│ ├── Makefile
│ └── hello_poly_gt_tw.c
├── hello_poly_inline/
│ ├── Makefile
│ └── hello_poly_inline.c
├── hello_poly_stp/
│ ├── Makefile
│ ├── README.md
│ ├── TIM/
│ │ ├── stpOnAlpha.tim
│ │ ├── stpOnAlphaI.tim
│ │ ├── stpOnBlack.tim
│ │ ├── stpOnCol.tim
│ │ ├── stpOnColIndex.tim
│ │ └── stpOnNonBlack.tim
│ └── hello_poly_stp.c
├── hello_sio/
│ ├── Makefile
│ └── hello_sio.c
├── hello_sprt/
│ ├── Makefile
│ └── hello_sprt.c
├── hello_spu_readback/
│ ├── Makefile
│ ├── README.md
│ ├── hello_spu_readback.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_str/
│ ├── Makefile
│ ├── README.md
│ ├── hello_str.c
│ ├── isoconfig.xml
│ ├── str/
│ │ └── copyings.str
│ └── system.cnf
├── hello_strplay/
│ ├── Makefile
│ ├── README.md
│ ├── hello_strplay.c
│ ├── isoconfig.xml
│ ├── str/
│ │ └── copyings.str
│ ├── strplay.c
│ └── system.cnf
├── hello_tile/
│ ├── Makefile
│ └── hello_tile.c
├── hello_vag/
│ ├── Makefile
│ ├── README.md
│ └── hello_vag.c
├── hello_world/
│ ├── Makefile
│ └── hello_world.c
├── hello_xa/
│ ├── Makefile
│ ├── README.md
│ ├── hello_xa.c
│ ├── isoconfig.xml
│ ├── system.cnf
│ └── xa/
│ ├── inter4.xa
│ ├── inter8.xa
│ ├── interleave4.txt
│ └── interleave8.txt
└── includes/
└── CPUMAC.H
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/Linux-build-archive.yml
================================================
name: Linux archive build
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get repo archive
run: |
wget https://github.com/ABelliqueux/nolibgs_hello_worlds/releases/download/v0.11/nolibgs_hello_worlds.zip
7z x nolibgs_hello_worlds.zip -o${{github.workspace}}
- name: Install mipsel toolchain
run: |
sudo apt-get update
sudo apt-get install gcc-mipsel-linux-gnu g++-mipsel-linux-gnu binutils-mipsel-linux-gnu p7zip cmake build-essential libtinyxml2-10 libtinyxml2-dev
- name: Clone mkpsxiso
uses: GuillaumeFalourd/clone-github-repo-action@v1
with:
owner: 'Lameguy64'
repository: 'mkpsxiso'
- name: Build mkpsxiso
run: |
sudo chown -R runner:docker ${{github.workspace}}/mkpsxiso/
mkdir ${{github.workspace}}/mkpsxiso/build
cmake -DCMAKE_BUILD_TYPE=Release -S ${{github.workspace}}/mkpsxiso/ -B ${{github.workspace}}/mkpsxiso/build
cmake --build ${{github.workspace}}/mkpsxiso/build
echo "${{github.workspace}}/mkpsxiso/build" >> $GITHUB_PATH
- name: Get converted libs
run: |
wget http://psx.arthus.net/sdk/Psy-Q/psyq-4.7-converted-full.7z
7z x psyq-4.7-converted-full.7z -o${{github.workspace}}/nolibgs_hello_worlds/psyq
- name: Make all
run: |
cd ${{github.workspace}}/nolibgs_hello_worlds
make all
================================================
FILE: .github/workflows/linux-build.yml
================================================
name: Linux build
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install mipsel toolchain
run: |
sudo apt-get update
sudo apt-get install gcc-mipsel-linux-gnu g++-mipsel-linux-gnu binutils-mipsel-linux-gnu p7zip cmake build-essential libtinyxml2-10 libtinyxml2-dev
- name: Fetch submodules
run: git submodule update --init --recursive
- name: Clone mkpsxiso
uses: GuillaumeFalourd/clone-github-repo-action@v1
with:
owner: 'Lameguy64'
repository: 'mkpsxiso'
- name: Build mkpsxiso
run: |
sudo chown -R runner:docker ${{github.workspace}}/mkpsxiso/
git -C ${{github.workspace}}/mkpsxiso/ submodule update --init --recursive
mkdir ${{github.workspace}}/mkpsxiso/build
cmake -DCMAKE_BUILD_TYPE=Release -S ${{github.workspace}}/mkpsxiso/ -B ${{github.workspace}}/mkpsxiso/build
cmake --build ${{github.workspace}}/mkpsxiso/build
echo "${{github.workspace}}/mkpsxiso/build" >> $GITHUB_PATH
- name: Get converted libs
run: |
wget http://psx.arthus.net/sdk/Psy-Q/psyq-4.7-converted-full.7z
7z x psyq-4.7-converted-full.7z -o./psyq
- name: Make all
run: make all
================================================
FILE: .github/workflows/macos-build.yml
================================================
name: macOS build
on:
push:
branches: [ main ]
jobs:
build:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- name: Fetch submodules
run: git submodule update --init --recursive
- name: Install tinyxml2
run : |
brew update --verbose
brew install tinyxml2
- name: Install mipsel binutils
run: |
wget https://raw.githubusercontent.com/grumpycoders/pcsx-redux/a899d09d81cf602ef48e51cda09a6c62638fa5c5/tools/macos-mips/mipsel-none-elf-binutils.rb -O ${{github.workspace}}/mipsel-none-elf-binutils.rb
brew install ${{github.workspace}}/mipsel-none-elf-binutils.rb --debug
- name: Upload mipsel-binutils
uses: actions/upload-artifact@v2
with:
name: mipsel-none-elf-binutils-macos
path: /usr/local/Cellar/mipsel-none-elf-binutils/
- name: Install mipsel gcc
run: |
wget https://raw.githubusercontent.com/grumpycoders/pcsx-redux/a899d09d81cf602ef48e51cda09a6c62638fa5c5/tools/macos-mips/mipsel-none-elf-gcc.rb -O ${{github.workspace}}/mipsel-none-elf-gcc.rb
brew install ${{github.workspace}}/mipsel-none-elf-gcc.rb --debug
- name: Upload mipsel-gcc
uses: actions/upload-artifact@v2
with:
name: mipsel-none-elf-gcc-macos
path: /usr/local/Cellar/mipsel-none-elf-gcc/
- name: Build mkpsxiso
run: |
wget https://github.com/Lameguy64/mkpsxiso/archive/refs/heads/master.zip -O ${{github.workspace}}/master.zip
7z x ${{github.workspace}}/master.zip -o${{github.workspace}}
awk 'n>=4 { print a[n%7] } { a[n%7]=$0; n=n+1 }' ${{github.workspace}}/mkpsxiso-master/CMakeLists.txt >> ${{github.workspace}}/mkpsxiso-master/CMakeLists.txt.tmp
mv -f ${{github.workspace}}/mkpsxiso-master/CMakeLists.txt.tmp ${{github.workspace}}/mkpsxiso-master/CMakeLists.txt
mkdir ${{github.workspace}}/mkpsxiso-master/build
cmake -DCMAKE_BUILD_TYPE=Release -S ${{github.workspace}}/mkpsxiso-master -B ${{github.workspace}}/mkpsxiso-master/build
cmake --build ${{github.workspace}}/mkpsxiso-master/build
echo "${{github.workspace}}/mkpsxiso-master/build" >> $GITHUB_PATH
- name: Upload mkpsxiso-macos
uses: actions/upload-artifact@v2
with:
name: mkpsxiso-macos
path: ${{github.workspace}}/mkpsxiso-master/build
- name: Get converted libs
run: |
wget http://psx.arthus.net/sdk/Psy-Q/psyq-4.7-converted-full.7z
7z x psyq-4.7-converted-full.7z -o./psyq
- name: Make all
run: make all
================================================
FILE: .github/workflows/windows-build.yml
================================================
name: Windows build
on:
push:
branches: [ main ]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Fetch submodules
run: git submodule update --init --recursive
- name: Get prebuilt stuff
run: |
C:\msys64\usr\bin\wget.exe http://static.grumpycoder.net/pixel/mips/g++-mipsel-none-elf-11.2.0.zip
C:\msys64\usr\bin\wget.exe http://lameguy64.github.io/mkpsxiso/mkpsxiso-1.20.zip
C:\msys64\usr\bin\wget.exe http://psx.arthus.net/sdk/Psy-Q/psyq-4.7-converted-full.7z
7z.exe x g++-mipsel-none-elf-11.2.0.zip -o"$GITHUB_WORKSPACE\mipsel"
7z.exe x mkpsxiso-1.20.zip -o"$GITHUB_WORKSPACE\mkpsxiso"
7z.exe x psyq-4.7-converted-full.7z -o"D:\a\nolibgs_hello_worlds\nolibgs_hello_worlds\psyq"
echo "$GITHUB_WORKSPACE/mipsel/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "$GITHUB_WORKSPACE/mkpsxiso" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo $GITHUB_PATH
- name: Make all
run: make all
================================================
FILE: .gitmodules
================================================
[submodule "thirdparty/nugget"]
path = thirdparty/nugget
url = https://github.com/pcsx-redux/nugget.git
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: Makefile
================================================
hello_2pads:
$(MAKE) -C hello_2pads
hello_bs:
$(MAKE) -C hello_bs
hello_cd:
$(MAKE) -C hello_cd
hello_cdda:
$(MAKE) -C hello_cdda
hello_cd_exec:
$(MAKE) -C hello_cd_exec
hello_cube:
$(MAKE) -C hello_cube
hello_cubetex:
$(MAKE) -C hello_cubetex
hello_cubetex_stp:
$(MAKE) -C hello_cubetex_stp
hello_font:
$(MAKE) -C hello_font
hello_fx:
$(MAKE) -C hello_fx
hello_gte_opti:
$(MAKE) -C hello_gte_opti
hello_light:
$(MAKE) -C hello_light
hello_mod:
$(MAKE) -C hello_mod
hello_multi_vag:
$(MAKE) -C hello_multi_vag
hello_multi_xa:
$(MAKE) -C hello_multi_xa
hello_ovl_exec:
$(MAKE) -C hello_ovl_exec
hello_pad:
$(MAKE) -C hello_pad
hello_poly:
$(MAKE) -C hello_poly
hello_poly_ft:
$(MAKE) -C hello_poly_ft
hello_poly_fun:
$(MAKE) -C hello_poly_fun
hello_poly_gt:
$(MAKE) -C hello_poly_gt
hello_poly_gt_tw:
$(MAKE) -C hello_poly_gt_tw
hello_poly_inline:
$(MAKE) -C hello_poly_inline
hello_poly_stp:
$(MAKE) -C hello_poly_stp
hello_sio:
$(MAKE) -C hello_sio
hello_sprt:
$(MAKE) -C hello_sprt
hello_spu_readback:
$(MAKE) -C hello_spu_readback
hello_str:
$(MAKE) -C hello_str
hello_strplay:
$(MAKE) -C hello_strplay
hello_tile:
$(MAKE) -C hello_tile
hello_vag:
$(MAKE) -C hello_vag
hello_world:
$(MAKE) -C hello_world
hello_xa:
$(MAKE) -C hello_xa
hello_xa_streaming:
$(MAKE) -C hello_xa_streaming
clean:
$(MAKE) -C hello_2pads clean
$(MAKE) -C hello_cube clean
$(MAKE) -C hello_cubetex clean
$(MAKE) -C hello_cubetex_stp clean
$(MAKE) -C hello_poly_fun clean
$(MAKE) -C hello_gte_opti clean
$(MAKE) -C hello_light clean
$(MAKE) -C hello_mod clean
$(MAKE) -C hello_multi_vag clean
$(MAKE) -C hello_multi_xa clean
$(MAKE) -C hello_ovl_exec cleansub
$(MAKE) -C hello_pad clean
$(MAKE) -C hello_poly clean
$(MAKE) -C hello_poly_ft clean
$(MAKE) -C hello_poly_stp clean
$(MAKE) -C hello_poly_gt clean
$(MAKE) -C hello_poly_gt_tw clean
$(MAKE) -C hello_poly_inline clean
$(MAKE) -C hello_sio clean
$(MAKE) -C hello_sprt clean
$(MAKE) -C hello_spu_readback cleansub
$(MAKE) -C hello_tile clean
$(MAKE) -C hello_vag clean
$(MAKE) -C hello_world clean
$(MAKE) -C hello_cdda cleansub
$(MAKE) -C hello_cd cleansub
$(MAKE) -C hello_xa cleansub
$(MAKE) -C hello_bs cleansub
$(MAKE) -C hello_str cleansub
$(MAKE) -C hello_strplay cleansub
all:
$(MAKE) -C hello_2pads
$(MAKE) -C hello_cube
$(MAKE) -C hello_cubetex
$(MAKE) -C hello_cubetex_stp
$(MAKE) -C hello_poly_fun
$(MAKE) -C hello_gte_opti
$(MAKE) -C hello_light
$(MAKE) -C hello_mod
$(MAKE) -C hello_multi_vag
$(MAKE) -C hello_multi_xa
$(MAKE) -C hello_ovl_exec
$(MAKE) -C hello_pad
$(MAKE) -C hello_poly
$(MAKE) -C hello_poly_ft
$(MAKE) -C hello_poly_gt
$(MAKE) -C hello_poly_gt_tw
$(MAKE) -C hello_poly_inline
$(MAKE) -C hello_sio
$(MAKE) -C hello_sprt
$(MAKE) -C hello_spu_readback
$(MAKE) -C hello_tile
$(MAKE) -C hello_vag
$(MAKE) -C hello_world
$(MAKE) -C hello_cd all
$(MAKE) -C hello_cdda all
$(MAKE) -C hello_xa all
$(MAKE) -C hello_bs all
$(MAKE) -C hello_str all
$(MAKE) -C hello_strplay all
# declare phony rules
.PHONY: hello_2pads hello_bs hello_cd hello_cdda hello_cd_exec hello_cube hello_cubetex hello_cubetex_stp hello_font hello_fx hello_gte_opti hello_light hello_mod hello_multi_vag hello_multi_xa hello_ovl_exec hello_pad hello_poly hello_poly_ft hello_poly_fun hello_poly_gt hello_poly_gt_tw hello_poly_inline hello_poly_stp hello_sio hello_sprt hello_spu_readback hello_str hello_strplay hello_tile hello_vag hello_world hello_xa hello_xa_streaming \
clean all
================================================
FILE: README.md
================================================
# Nolibgs Hello Worlds !
<p align="center">
<img height="240px" src="http://wiki.arthus.net/assets/cube.gif" alt="3D power !">
<img height="240px" src="http://wiki.arthus.net/assets/polyfun.jpg" alt="3D power !">
<img height="240px" src="http://wiki.arthus.net/assets/hello_gt.jpg" alt="3D power !">
</p>
So you want to begin developping on the original PSX but don't know where to start ?
This repo is destined to host a bunch of simple examples, each describing how to do one thing.
The code here will be using **Nugget + PsyQ**, the "Official" Sony SDK but with a modern MIPS toolchain.
We will not be using libGS, the Extended Graphics Library for the graphic stuff...
Instead we'll try to devise methods to reproduce libgs functions. This will not necessarly be more efficient, but we'll learn
a lot more stuff !
## Installation
We'll keep things simple for now. If you want to read about more methods to get things up and running, see the wiki's [Installation methods](https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/Installation-methods) section.
### Windows
#### MIPS toolchain setup
You can setup a pre-built MIPS toolchain by copy-pasting the following into a command prompt:
```
powershell -c "& { iwr https://raw.githubusercontent.com/grumpycoders/pcsx-redux/main/mips.ps1 | iex }"
```
Then, open a new command prompt, and type the following:
```
mips install 11.2.0
```
#### Nugget + PsyQ setup
1. Download the PsyQ converted libraries here : [http://psx.arthus.net/sdk/Psy-Q/psyq-4.7-converted-full.7z](http://psx.arthus.net/sdk/Psy-Q/psyq-4.7-converted-full.7z)
2. Clone the 'nolibgs_hello_worlds' repo with
`git clone https://github.com/ABelliqueux/nolibgs_hello_worlds.git --recursive`
or download this [repository's release](https://github.com/ABelliqueux/nolibgs_hello_worlds/releases/download/v0.11/nolibgs_hello_worlds.zip) and extract **`nolibgs_hello_worlds.zip`**'s content to `C:\no_libgs_hello_worlds\` .
3. Extract the content of `psyq-4.7-converted-full.7z` in `C:\no_libgs_hello_worlds\psyq`. You should now have `C:\no_libgs_hello_worlds\psyq\include` and `C:\no_libgs_hello_worlds\psyq\lib` ;
```
no_libgs_hello_worlds
├── common.mk
├── hello_world
| ├── hello_world.c
| ├── Makefile
├── hello_...
└── psyq
├── lib
| └── *.a
└── include
└── *.h
```
4. Test everything is working by [launching a command prompt](https://www.lifewire.com/how-to-open-command-prompt-2618089), change to the `C:\no_libgs_hello_worlds\` directory with the following command: `cd C:\no_libgs_hello_worlds\`, then type `make` and hit enter.
By default, this should build the `hello_world` example, and you should now have a `hello_world.ps-exe` file in `C:\no_libgs_hello_worlds\hello_world`. This a PSX executable that can be run in an emulator like [pcsx-redux](https://github.com/grumpycoders/pcsx-redux/).
### Linux
#### Install your distribution's MIPS toolchain
In a terminal :
On Debian derivatives (Ubuntu, Mint...) :
```bash
sudo apt-get install make gcc-mipsel-linux-gnu g++-mipsel-linux-gnu binutils-mipsel-linux-gnu
```
On Arch derivatives (Manjaro), the mipsel environment can be installed from [AUR](https://wiki.archlinux.org/index.php/Aur) : [mipsel-linux-gnu-binutils](https://aur.archlinux.org/packages/mipsel-linux-gnu-binutils/) and [mipsel-linux-gnu-gcc](https://aur.archlinux.org/packages/mipsel-linux-gnu-gcc/) using your [AURhelper](https://wiki.archlinux.org/index.php/AUR_helpers) of choice:
```bash
yay -S make mipsel-linux-gnu-binutils mipsel-linux-gnu-gcc
```
#### Nugget + PsyQ setup
Let's do it all on the [CLI](https://en.wikipedia.org/wiki/Command-line_interface) !
1. Install the git client :
```bash
sudo apt-get install git
```
2. Clone this repository :
```bash
git clone https://github.com/ABelliqueux/nolibgs_hello_worlds.git --recursive
```
3. Change to the repo's directory and get the PsyQ converted libraries:
```bash
cd nolibgs_hello_worlds
wget http://psx.schnappy.xyz/sdk/Psy-Q/psyq-4.7-converted-full.7z
7z x psyq-4.7-converted-full.7z -o./psyq
```
4. Try your setup :
```bash
make
```
By default, this should build the `hello_world` example, and you should now have a `hello_world.ps-exe` file in `./hello_world/`. This a PSX executable that can be run in an emulator like [pcsx-redux](https://github.com/grumpycoders/pcsx-redux/).
### MacOS
A [brew](https://brew.sh/) installation script can be found [here.](https://github.com/grumpycoders/pcsx-redux#macos).
## Compilation
In a terminal, `cd` to your psxdev setup directory and type `make all` to build all examples in their respective directories.
Alternatively, you can use `make example_name` to only build that example, i.e : `make hello_poly`.
If you want to remove all the files generated by the compilation process, type `make clean`.
## Upcoming examples
* hello_poly_subdiv (polygon subdivision)
* hello_rsd (rsd format)
# Links and Doc
* [Getting started with PSX dev](https://psx.arthus.net/starting.html)
* [Ps1 dev ressource center](https://ps1.consoledev.net/)
* [PsyQ docs](https://psx.arthus.net/sdk/Psy-Q/DOCS/)
* [psxdev.net](http://psxdev.net/)
* [psxdev Discord](https://discord.com/invite/N2mmwp)
# Credits, thanks, hugs
Everything here was learnt from some more talented persons, mainly but not excluding others that hang around on the [psxdev discord](https://discord.com/channels/642647820683444236/642848627823345684)
Nicolas Noble, Lameguy64, NDR008, Jaby smoll seamonstah, danhans42, rama, sickle, paul, squaresoft74, and lot mores !
================================================
FILE: TIM/README.md
================================================
See here for more informations about the TIM fileformat and tools :
https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/TIM
================================================
FILE: VAG/README.md
================================================
See here for more informations about the VAG fileformat and tools :
https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/VAG
================================================
FILE: common.mk
================================================
# If you change this to exe, you'll have to rename the file ./thirdparty/nugget/ps-exe.ld too.
TYPE = ps-exe
THISDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
SRCS += $(THISDIR)thirdparty/nugget/common/crt0/crt0.s
SRCS += $(THISDIR)thirdparty/nugget/common/syscalls/printf.s
CPPFLAGS += -I$(THISDIR)thirdparty/nugget/psyq/include -I$(THISDIR)psyq-4_7-converted/include -I$(THISDIR)psyq-4.7-converted-full/include -I$(THISDIR)psyq/include
LDFLAGS += -L$(THISDIR)thirdparty/nugget/psyq/lib -L$(THISDIR)psyq-4_7-converted/lib -L$(THISDIR)psyq-4.7-converted-full/lib -L$(THISDIR)psyq/lib
# add support for NDR008's VScode setup
CPPFLAGS += -I$(THISDIR)../third_party/psyq/include
LDFLAGS += -L$(THISDIR)../third_party/psyq/lib
LDFLAGS += -Wl,--start-group
LDFLAGS += -lapi
LDFLAGS += -lc
LDFLAGS += -lc2
LDFLAGS += -lcard
LDFLAGS += -lcomb
LDFLAGS += -lds
LDFLAGS += -letc
LDFLAGS += -lgpu
LDFLAGS += -lgs
LDFLAGS += -lgte
LDFLAGS += -lgun
LDFLAGS += -lhmd
LDFLAGS += -lmath
LDFLAGS += -lmcrd
LDFLAGS += -lmcx
LDFLAGS += -lpad
LDFLAGS += -lpress
LDFLAGS += -lsio
LDFLAGS += -lsnd
LDFLAGS += -lspu
LDFLAGS += -ltap
LDFLAGS += -lcd
LDFLAGS += -Wl,--end-group
include $(THISDIR)thirdparty/nugget/common.mk
define OBJCOPYME
$(PREFIX)-objcopy -I binary --set-section-alignment .data=4 --rename-section .data=.rodata,alloc,load,readonly,data,contents -O $(FORMAT) -B mips $< $@
endef
# convert TIM file to bin
%.o: %.tim
$(call OBJCOPYME)
# convert VAG files to bin
%.o: %.vag
$(call OBJCOPYME)
# convert HIT to bin
%.o: %.HIT
$(call OBJCOPYME)
================================================
FILE: hello_2pads/Makefile
================================================
TARGET = hello_2pads
SRCS = hello_2pads.c \
include ../common.mk
================================================
FILE: hello_2pads/hello_2pads.c
================================================
// hello_libpad example
//
// We're using libpad this time.
// You can use the classic controller, analog, wheel, gun buttons or mouse
//
// Schnappy - 12/2020
//
// Based on : ../psyq/addons/scea/CNTRL/PAD.C
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include <libapi.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define MARGINX 32 // margins for text display
#define MARGINY 32
#define FONTSIZE 8 * 7 // Text Field Height
#define OTLEN 8 // Ordering Table Length
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
u_long ot[2][OTLEN]; // double ordering table of length 8 * 32 = 256 bits / 32 bytes
char primbuff[2][32768]; // double primitive buffer of length 32768 * 8 = 262.144 bits / 32,768 Kbytes
char *nextpri = primbuff[0]; // pointer to the next primitive in primbuff. Initially, points to the first bit of primbuff[0]
short db = 0; // index of which buffer is used, values 0, 1
// Pad stuff
// Structure for RAW hardware-based light gun position values
typedef struct
{
unsigned short v_count; // Y-axis (vertical scan counter)
unsigned short h_count; // H-axis (horizontal pixel clock value)
} Gun_Position;
// Structure for storing processed controller data
typedef struct
{
int xpos, ypos; // Stored position for sprite(s)
int xpos2, ypos2; // controlled by this controller.
unsigned char status; // These 8 values are obtained
unsigned char type; // directly from the controller
unsigned char button1; // buffer we installed with InitPAD.
unsigned char button2;
unsigned char analog0;
unsigned char analog1;
unsigned char analog2;
unsigned char analog3;
} Controller_Data;
// All-purpose controller data buffer
typedef struct
{
unsigned char pad[34]; // 8-bytes w/o Multi-Tap, 34-bytes w/Multi-Tap
} Controller_Buffer;
Controller_Buffer controllers[2]; // Buffers for reading controllers
Controller_Data theControllers[8]; // Processed controller data
void init(void)
{
ResetGraph(0);
SetDefDispEnv(&disp[0], 0, 0, SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 50, 50, 50);
setRGB0(&draw[1], 50, 50, 50);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
FntLoad(960, 0);
FntOpen(MARGINX, SCREENYRES - MARGINY - FONTSIZE, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 );
}
void display(void)
{
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
void get_digital_direction( Controller_Data *c, int buttondata ) // get analog stick values
{
int i;
i = ~(buttondata);
if( i & 0x80 )
c->xpos -= 1;
if( i & 0x20 )
c->xpos += 1;
if( i & 0x40 )
c->ypos += 1;
if( i & 0x10 )
c->ypos -= 1;
}
void read_controller( Controller_Data *c, unsigned char *buf, int port ) // get the raw values from controller
{
register int mouse_x, mouse_y, x;
register Gun_Position *g;
c->status = buf[0]; // Copy over raw controller data
c->type = buf[1];
c->button1 = buf[2];
c->button2 = buf[3];
c->analog0 = buf[4];
c->analog1 = buf[5];
c->analog2 = buf[6];
c->analog3 = buf[7];
if( buf[0] == 0xff ) // If controller returns BAD status then bail on it.
{
c->type = 0;
return;
}
// Look at the controller type code & process controller data as indicated
switch( c->type )
{
case 0x12: // Sony Mouse
mouse_x = buf[4];
mouse_y = buf[5];
if( mouse_x & 0x80 )
mouse_x |= 0xffffff80;
if( mouse_y & 0x80 )
mouse_y |= 0xffffff80;
c->xpos += mouse_x;
c->ypos += mouse_y;
break;
case 0x23: // Namco negCon
// Steering wheel
// Sankyo Pachinko controler
get_digital_direction( c, buf[2] );
break;
case 0x53: // Analog 2-stick
get_digital_direction( c, buf[2] );
break;
case 0x41: // Standard Sony PAD controller
get_digital_direction( c, buf[2] );
break;
default: // If don't know what it is, treat it like standard controller
get_digital_direction( c, buf[2] );
break;
}
}
int main(void)
{
TILE * PADL; // Tile primitives
TILE * TRIGGERL;
TILE * PADR;
TILE * TRIGGERR;
TILE * START, * SELECT;
init();
InitPAD(controllers[0].pad, 34, controllers[1].pad, 34);
StartPAD();
while (1)
{
read_controller( &theControllers[0], &controllers[0].pad[0], 0 ); // Read controllers
read_controller( &theControllers[1], &controllers[1].pad[0], 1 );
ClearOTagR(ot[db], OTLEN);
// D-cross
PADL = (TILE *)nextpri;
setTile(PADL);
setRGB0(PADL, 80, 180, 255);
setXY0(PADL, CENTERX - 80, CENTERY);
setWH(PADL, 24, 24);
addPrim(ot[db], PADL);
nextpri += sizeof(TILE);
// L1+L2
TRIGGERL = (TILE *)nextpri;
setTile(TRIGGERL);
setRGB0(TRIGGERL, 255, 0, 0);
setXY0(TRIGGERL, CENTERX - 80, CENTERY - 80);
setWH(TRIGGERL, 24, 24);
addPrim(ot[db], TRIGGERL);
nextpri += sizeof(TILE);
// /\, X, O, []
PADR = (TILE *)nextpri;
setTile(PADR);
setRGB0(PADR, 0, 255, 0);
setXY0(PADR, CENTERX + 50, CENTERY);
setWH(PADR, 24, 24);
addPrim(ot[db], PADR);
nextpri += sizeof(TILE);
// R1+R2
TRIGGERR = (TILE *)nextpri;
setTile(TRIGGERR);
setRGB0(TRIGGERR, 255, 0, 255);
setXY0(TRIGGERR, CENTERX + 50, CENTERY -80);
setWH(TRIGGERR, 24, 24);
addPrim(ot[db], TRIGGERR);
nextpri += sizeof(TILE);
// START + SELECT
START = (TILE *)nextpri;
setTile(START);
setRGB0(START, 240, 240, 240);
setXY0(START, CENTERX - 16, CENTERY - 36);
setWH(START, 24, 24);
addPrim(ot[db], START);
nextpri += sizeof(TILE);
// D-pad
switch(theControllers[0].button1){
case 0xDF: // Right
PADL->x0 = CENTERX - 64;
break;
case 0x7F: // Left
PADL->x0 = CENTERX - 96;
break;
case 0xEF: // Up
PADL->y0 = CENTERY - 16;
break;
case 0xBF: // Down
PADL->y0 = CENTERY + 16;
break;
// Start & Select
case 0xF7:
START->w = 32; START->h = 32;START->x0 -= 4;START->y0 -= 4; // START
break;
case 0xFE: // SELECT
START->r0 = 0;
break;
// Dualshock L3 + R3
case 0xFD: // L3
TRIGGERL->w += 10;
TRIGGERL->h += 10;
break;
case 0xFB: //R3
TRIGGERR->w += 10;
TRIGGERR->h += 10;
break;
}
// Buttons
switch(theControllers[0].button2){
case 0xDF: // ⭘
PADR->x0 = CENTERX + 66;
break;
case 0x7F: // ⬜
PADR->x0 = CENTERX + 34;
break;
case 0xEF: // △
PADR->y0 = CENTERY - 16;
break;
case 0xBF: // ╳
PADR->y0 = CENTERY + 16;
break;
// Shoulder buttons
case 0xFB: // L1
TRIGGERL->y0 = CENTERY - 64;
break;
case 0xFE: // L2
TRIGGERL->y0 = CENTERY - 96;
break;
case 0xF7: // R1
TRIGGERR->y0 = CENTERY - 96;
break;
case 0xFD: // R2
TRIGGERR->y0 = CENTERY - 64;
break;
// Mouse buttons
case 0xF4: // Mouse Left click
PADL->w += 10;
PADL->h += 10;
break;
case 0xF8: // Mouse Right click
PADL->w -= 10;
PADL->h -= 10;
break;
}
FntPrint("Hello 2 pads!\n\n");
FntPrint( "Pad 1 : %02x\nButtons:%02x %02x, Stick:%02x %02x %02x %02x\n",
theControllers[0].type, // Controller type : 00 == none, 41 == standard, 73 == analog/dualshock, 12 == mouse, 23 == steering wheel, 63 == gun, 53 == analog joystick
theControllers[0].button1, //
theControllers[0].button2,
theControllers[0].analog0,
theControllers[0].analog1,
theControllers[0].analog2,
theControllers[0].analog3 );
FntPrint( "Pad 2 : %02x\nButtons:%02x %02x, Stick:%02x %02x %02x %02x\n",
theControllers[1].type, // Controller type : 00 == none, 41 == standard, 73 == analog/dualshock, 12 == mouse, 23 == steering wheel, 63 == gun, 53 == analog joystick
theControllers[1].button1, //
theControllers[1].button2,
theControllers[1].analog0, // R3 horizontal
theControllers[1].analog1, // R3 vertical
theControllers[1].analog2, // L3 horizontal
theControllers[1].analog3 ); // L3 vertical
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_bs/Makefile
================================================
.PHONY: all cleansub
all:
mkpsxiso -y ./isoconfig.xml
cleansub:
$(MAKE) clean
rm -f hello_bs.cue hello_bs.bin
TARGET = hello_bs
SRCS = hello_bs.c \
include ../common.mk
================================================
FILE: hello_bs/README.md
================================================
# Loading a BS still image
You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image.
## Compile
```bash
make all
```
## Clean directory
```bash
make cleansub
```
## Converting a still image to BS
`MC32` can convert these formats to BS : TIM, RGB, YUV.
### Image > TIM with img2tim
Convert your image to a 24bpp TIM with [`img2tim`](https://github.com/Lameguy64/img2tim):
```bash
img2tim -bpp 24 -o output.tim input.png
```
Then use `MC32` as instructed below.
Result :
```bash
identify bace.tim
bace.tim TIM 320x240 320x240+0+0 8-bit sRGB 230420B 0.000u 0:00.000
```
### Image > RGB with imagemagick
You can convert your image to RGB with:
```bash
convert input.png RGB:output.rgb
```
Result :
```bash
identify -size 320x240 -depth 8 RGB:bace.rgb
RGB:bace.rgb=>bace.rgb RGB 320x240 320x240+0+0 8-bit sRGB 230400B 0.000u 0:00.003
```
### Image > YUV422 UYVY with imagemagick
You can convert your image to YUV with:
```bash
convert input.png UYVY:output.yuv
```
Result :
```bash
dentify -size 320x240 UYVY:bace.yuv
UYVY:bace.yuv=>bace.yuv UYVY 320x240 320x240+0+0 8-bit YCbCr 153600B 0.000u 0:00.005
```
### TIM/RGB/UYVY > BS conversion
Use the [`MC32` tool](http://psx.arthus.net/tools/pimp-psx.zip) conversion tool to import the image, specifying the right dimensions, and convert to `bs` with those settings :
**Note that a BS image must have a width and height that is a multiple of 16**
```
Input: RGB, Output: bs
MDEC version : 2
Custom: Size in sectors or (2048 * sector number) bytes, Variable frame size
```

## Sources & Refs
img2tim : https://github.com/Lameguy64/img2tim
MC32 : http://psx.arthus.net/tools/pimp-psx.zip
mdecnote : http://psx.arthus.net/sdk/Psy-Q/DOCS/TECHNOTE/mdecnote.pdf
PSX RGB and YUV format : http://psx.arthus.net/sdk/Psy-Q/DOCS/Devrefs/Dataconv.pdf , p.68
YUV pixel format : https://www.fourcc.org/pixel-format/yuv-uyvy/
RGB pixelformat : https://www.fourcc.org/pixel-format/rgb-bi_rgb/
RGB<>YUV conversion formulas : https://www.fourcc.org/fccyvrgb.php
================================================
FILE: hello_bs/hello_bs.c
================================================
// Load a BS file from CD, decompress and display it.
// Schnappy 07-2021
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
// CD library
#include <libcd.h>
// CODEC library
#include <libpress.h>
#include <malloc.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320 // Screen width
#define SCREENYRES 240 + (VMODE << 4) // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256
#define CENTERX SCREENXRES/2 // Center of screen on x
#define CENTERY SCREENYRES/2 // Center of screen on y
#define MARGINX 8 // margins for text display
#define MARGINY 16
#define FONTSIZE 8 * 7 // Text Field Height
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
short db = 0; // index of which buffer is used, values 0, 1
// CD specifics
#define CD_SECTOR_SIZE 2048
// Converting bytes to sectors SECTOR_SIZE is defined in words, aka int
#define BtoS(len) ( ( len + CD_SECTOR_SIZE - 1 ) / CD_SECTOR_SIZE )
// Name of file to load
static char * loadFile;
// libcd's CD file structure contains size, location and filename
CdlFILE filePos = {0};
//~ struct EXEC * exeStruct;
// Define start address of allocated memory
// Let's use an array so we don't have to worry about using a memory segment that's already in use.
static unsigned char ramAddr[0x40000]; // https://discord.com/channels/642647820683444236/663664210525290507/864936962199781387
// We could also set a memory address manually, but we have to make sure this won't get in the way of other routines.
// void * ramAddr = (void *)0x80030D40;
// Load data to this buffer
u_long * dataBuffer;
// Those are not strictly needed, but we'll use them to see the commands results.
// They could be replaced by a 0 in the various functions they're used with.
u_char CtrlResult[8];
// Value returned by CDread() - 1 is good, 0 is bad
int CDreadOK = 0;
// Value returned by CDsync() - Returns remaining sectors to load. 0 is good.
int CDreadResult = 0;
// BS decompression
// Store size of uncompressed data
long bsBufferSize;
// Allocated memory address
void * bsWorkBuffer;
// Define image draw area
RECT bsDrawArea = { 0, 0, 16, SCREENYRES};
// Used to store a 16x240 image strip
u_long bsStrip[16*240];
void init(void)
{
ResetGraph(0); // Initialize drawing engine with a complete reset (0)
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); // Set display area for both &disp[0] and &disp[1]
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES); // &disp[0] is on top of &disp[1]
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES); // Set draw for both &draw[0] and &draw[1]
SetDefDrawEnv(&draw[1], 0, 0 , SCREENXRES, SCREENYRES); // &draw[0] is below &draw[1]
// Set video mode
if (VMODE){ SetVideoMode(MODE_PAL);}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 155, 0, 150); // set color for first draw area
setRGB0(&draw[1], 155, 0, 150); // set color for second draw area
draw[0].isbg = 0; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 0;
PutDispEnv(&disp[db]); // set the disp and draw environnments
PutDrawEnv(&draw[db]);
FntLoad(960, 0); // Load font to vram at 960,0(+128)
FntOpen(MARGINX, MARGINY, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 ); // FntOpen(x, y, width, height, black_bg, max. nbr. chars
}
void display(void)
{
DrawSync(0); // Wait for all drawing to terminate
VSync(0); // Wait for the next vertical blank
PutDispEnv(&disp[db]); // set alternate disp and draw environnments
PutDrawEnv(&draw[db]);
db = !db; // flip db value (0 or 1)
}
int main(void)
{
// Init display
init();
// Init CD system
CdInit();
// Init heap
InitHeap((u_long *)ramAddr, sizeof(ramAddr));
// If the other method was chosen at l.39
// InitHeap((void *)0x80030D40, 0x40000);
// Set name of file to load
loadFile = "\\BACE.BS;1";
// Get file position from filename
CdSearchFile( &filePos, loadFile);
// Allocate memory
dataBuffer = malloc( BtoS(filePos.size) * CD_SECTOR_SIZE );
// Issue CdlSetloc CDROM command : Set the seek target position
// Beware of a misnomed 'sector' member in the CdlLOC struct that should really be named 'frame'.
// https://discord.com/channels/642647820683444236/663664210525290507/864912470996942910
CdControl(CdlSetloc, (u_char *)&filePos.pos, CtrlResult);
// Read data and load it to dataBuffer
CDreadOK = CdRead( (int)BtoS(filePos.size), (u_long *)dataBuffer, CdlModeSpeed );
// Wait for operation to complete
CDreadResult = CdReadSync(0, 0);
// Image Decompression
// Initialize image processing subsystem
DecDCTReset(0);
// Find the needed buffer size
bsBufferSize = DecDCTBufSize(dataBuffer);
// Allocate buffer size at &bsWorkBuffer
bsWorkBuffer = malloc( bsBufferSize );
// Decode Huffman (also called VLC: variable length coding ) compressed image
DecDCTvlc( dataBuffer, (u_long *) bsWorkBuffer );
// Send decoded data to MDEC for RLE decoding.
DecDCTin( (u_long*) bsWorkBuffer, 0);
// Fetch decoded image in 16x240 strips
for( bsDrawArea.x = 0; bsDrawArea.x < SCREENXRES; bsDrawArea.x += 16 ){
// Request decoded data from MDEC
// Request 16 * 240 pixel high lines.
// But size is in long words (4B), so divide by 2 to get words (2B) ?
DecDCTout( bsStrip, (16*SCREENYRES)/2);
// Wait for transfer to complete
DecDCToutSync(0);
// Load image data to fb
LoadImage( &bsDrawArea, bsStrip );
}
free( bsWorkBuffer );
while (1) // infinite loop
{
// Copy BS image to the other buffer
MoveImage2(&disp[db].disp, 0, disp[!db].disp.y );
DrawSync(0);
FntPrint("Hello BS! \n");
// Print filesize in bytes/sectors
FntPrint("Bs Size: %dB sectors: %d\n", filePos.size, BtoS(filePos.size));
// Print heap and buffer addresses
FntPrint("Heap: %x - Buf: %x\n", ramAddr, dataBuffer);
FntPrint("bsWork: %x\nbsBufSize: %dB\n", bsWorkBuffer, bsBufferSize);
FntFlush(-1); // Draw print stream
display(); // Execute display()
}
return 0;
}
================================================
FILE: hello_bs/isoconfig.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- MKPSXISO example XML script -->
<!-- <iso_project>
Starts an ISO image project to build. Multiple <iso_project> elements may be
specified within the same xml script which useful for multi-disc projects.
<iso_project> elements must contain at least one <track> element.
Attributes:
image_name - File name of the ISO image file to generate.
cue_sheet - Optional, file name of the cue sheet for the image file
(required if more than one track is specified).
-->
<iso_project image_name="hello_bs.bin" cue_sheet="hello_bs.cue">
<!-- <track>
Specifies a track to the ISO project. This example element creates a data
track for storing data files and CD-XA/STR streams.
Only one data track is allowed and data tracks must only be specified as the
first track in the ISO image and cannot be specified after an audio track.
Attributes:
type - Track type (either data or audio).
source - For audio tracks only, specifies the file name of a wav audio
file to use for the audio track.
-->
<track type="data">
<!-- <identifiers>
Optional, Specifies the identifier strings to use for the data track.
Attributes:
system - Optional, specifies the system identifier (PLAYSTATION if unspecified).
application - Optional, specifies the application identifier (PLAYSTATION if unspecified).
volume - Optional, specifies the volume identifier.
volume_set - Optional, specifies the volume set identifier.
publisher - Optional, specifies the publisher identifier.
data_preparer - Optional, specifies the data preparer identifier. If unspecified, MKPSXISO
will fill it with lengthy text telling that the image file was generated
using MKPSXISO.
-->
<identifiers
system ="PLAYSTATION"
application ="PLAYSTATION"
volume ="HELOCD"
volume_set ="HELOCD"
publisher ="SCHNAPPY"
data_preparer ="MKPSXISO"
/>
<!-- <license>
Optional, specifies the license file to use, the format of the license file must be in
raw 2336 byte sector format, like the ones included with the PsyQ SDK in psyq\cdgen\LCNSFILE.
License data is not included within the MKPSXISO program to avoid possible legal problems
in the open source environment... Better be safe than sorry.
Attributes:
file - Specifies the license file to inject into the ISO image.
-->
<!--
<license file="LICENSEA.DAT"/>
-->
<!-- <directory_tree>
Specifies and contains the directory structure for the data track.
Attributes:
None.
-->
<directory_tree>
<!-- <file>
Specifies a file in the directory tree.
Attributes:
name - File name to use in the directory tree (can be used for renaming).
type - Optional, type of file (data for regular files and is the default, xa for
XA audio and str for MDEC video).
source - File name of the source file.
-->
<!-- Stores system.txt as system.cnf -->
<file name="system.cnf" type="data" source="system.cnf"/>
<file name="SCES_313.37" type="data" source="hello_bs.ps-exe"/>
<file name="BACE.BS" type="data" source="bs/bace.bs"/>
<dummy sectors="1024"/>
<!-- <dir>
Specifies a directory in the directory tree. <file> and <dir> elements inside the element
will be inside the specified directory.
-->
</directory_tree>
</track>
</iso_project>
================================================
FILE: hello_bs/system.cnf
================================================
BOOT=cdrom:\SCES_313.37;1
TCB=4
EVENT=10
STACK=801FFFF0
================================================
FILE: hello_cd/Makefile
================================================
.PHONY: all cleansub
all:
mkpsxiso -y ./isoconfig.xml
cleansub:
$(MAKE) clean
rm -f hello_cd.cue hello_cd.bin
TARGET = hello_cd
SRCS = hello_cd.c \
include ../common.mk
================================================
FILE: hello_cd/README.md
================================================
## Loading a file from CD
You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image.
### Compile
```bash
make all
```
### Clean directory
```bash
make cleansub
```
### Adding data to the CD
In `isoconfig.xml`, in the data track's `directory_tree` section, use this syntax :
```xml
<file name="HELO.DAT" type="data" source="theFile.dat"/>
```
See https://github.com/Lameguy64/mkpsxiso/blob/master/examples/example.xml for more details.
================================================
FILE: hello_cd/hello_cd.c
================================================
// Load files from CD and execute them
// Schnappy 07-2021
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include <libapi.h>
// CD library
#include <libcd.h>
#include <malloc.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320 // Screen width
#define SCREENYRES 240 + (VMODE << 4) // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256
#define CENTERX SCREENXRES/2 // Center of screen on x
#define CENTERY SCREENYRES/2 // Center of screen on y
#define MARGINX 0 // margins for text display
#define MARGINY 32
#define FONTSIZE 8 * 7 // Text Field Height
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
short db = 0; // index of which buffer is used, values 0, 1
// CD specifics
#define CD_SECTOR_SIZE 2048
// Converting bytes to sectors SECTOR_SIZE is defined in words, aka int
#define BtoS(len) ( ( len + CD_SECTOR_SIZE - 1 ) / CD_SECTOR_SIZE )
// Name of file to load
static char * loadFile;
// libcd's CD file structure contains size, location and filename
CdlFILE filePos = {0};
//~ struct EXEC * exeStruct;
// Define start address of allocated memory
// Let's use an array so we don't have to worry about using a memory segment that's already in use.
static unsigned char ramAddr[0x40000]; // https://discord.com/channels/642647820683444236/663664210525290507/864936962199781387
// We could also set a memory address manually, but we have to make sure this won't get in the way of other routines.
// void * ramAddr = (void *)0x80030D40;
// Load data to this buffer
u_long * dataBuffer;
// Those are not strictly needed, but we'll use them to see the commands results.
// They could be replaced by a 0 in the various functions they're used with.
u_char CtrlResult[8];
// Value returned by CDread() - 1 is good, 0 is bad
int CDreadOK = 0;
// Value returned by CDsync() - Returns remaining sectors to load. 0 is good.
int CDreadResult = 0;
void init(void)
{
ResetGraph(0); // Initialize drawing engine with a complete reset (0)
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); // Set display area for both &disp[0] and &disp[1]
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES); // &disp[0] is on top of &disp[1]
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES); // Set draw for both &draw[0] and &draw[1]
SetDefDrawEnv(&draw[1], 0, 0 , SCREENXRES, SCREENYRES); // &draw[0] is below &draw[1]
// Set video mode
if (VMODE){ SetVideoMode(MODE_PAL);}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 255, 50, 50); // set color for first draw area
setRGB0(&draw[1], 255, 50, 50); // set color for second draw area
draw[0].isbg = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 1;
PutDispEnv(&disp[db]); // set the disp and draw environnments
PutDrawEnv(&draw[db]);
FntLoad(960, 0); // Load font to vram at 960,0(+128)
FntOpen(MARGINX, SCREENYRES - MARGINY - FONTSIZE, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 ); // FntOpen(x, y, width, height, black_bg, max. nbr. chars
}
void display(void)
{
DrawSync(0); // Wait for all drawing to terminate
VSync(0); // Wait for the next vertical blank
PutDispEnv(&disp[db]); // set alternate disp and draw environnments
PutDrawEnv(&draw[db]);
db = !db; // flip db value (0 or 1)
}
int main(void)
{
// Init display
init();
// Init CD system
CdInit();
// Init heap
InitHeap((u_long *)ramAddr, sizeof(ramAddr));
// If the other method was chosen at l.39
// InitHeap((void *)0x80030D40, 0x40000);
// Set name of file to load
loadFile = "\\HELO.DAT;1";
// Get file position from filename
CdSearchFile( &filePos, loadFile);
// Allocate memory
dataBuffer = malloc( BtoS(filePos.size) * CD_SECTOR_SIZE );
// Issue CdlSetloc CDROM command : Set the seek target position
// Beware of a misnomed 'sector' member in the CdlLOC struct that should really be named 'frame'.
// https://discord.com/channels/642647820683444236/663664210525290507/864912470996942910
CdControl(CdlSetloc, (u_char *)&filePos.pos, CtrlResult);
// Read data and load it to dataBuffer
CDreadOK = CdRead( (int)BtoS(filePos.size), (u_long *)dataBuffer, CdlModeSpeed );
// Wait for operation to complete
CDreadResult = CdReadSync(0, 0);
while (1) // infinite loop
{
// Print the content of the loaded file - See HELO.DAT
FntPrint("%s%d\n", (char *)dataBuffer, VSync(-1));
// Print heap and buffer addresses
FntPrint("Heap: %x - Buf: %x\n", ramAddr, dataBuffer);
// Print returned values
FntPrint("CdCtrl: %d\nRead : %d %d\n", CtrlResult[0], CDreadOK, CDreadResult);
// Print filesize in bytes/sectors
FntPrint("Size: %dB sectors: %d", filePos.size, BtoS(filePos.size));
FntFlush(-1); // Draw print stream
display(); // Execute display()
}
return 0;
}
================================================
FILE: hello_cd/isoconfig.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- MKPSXISO example XML script -->
<!-- <iso_project>
Starts an ISO image project to build. Multiple <iso_project> elements may be
specified within the same xml script which useful for multi-disc projects.
<iso_project> elements must contain at least one <track> element.
Attributes:
image_name - File name of the ISO image file to generate.
cue_sheet - Optional, file name of the cue sheet for the image file
(required if more than one track is specified).
-->
<iso_project image_name="hello_cd.bin" cue_sheet="hello_cd.cue">
<!-- <track>
Specifies a track to the ISO project. This example element creates a data
track for storing data files and CD-XA/STR streams.
Only one data track is allowed and data tracks must only be specified as the
first track in the ISO image and cannot be specified after an audio track.
Attributes:
type - Track type (either data or audio).
source - For audio tracks only, specifies the file name of a wav audio
file to use for the audio track.
-->
<track type="data">
<!-- <identifiers>
Optional, Specifies the identifier strings to use for the data track.
Attributes:
system - Optional, specifies the system identifier (PLAYSTATION if unspecified).
application - Optional, specifies the application identifier (PLAYSTATION if unspecified).
volume - Optional, specifies the volume identifier.
volume_set - Optional, specifies the volume set identifier.
publisher - Optional, specifies the publisher identifier.
data_preparer - Optional, specifies the data preparer identifier. If unspecified, MKPSXISO
will fill it with lengthy text telling that the image file was generated
using MKPSXISO.
-->
<identifiers
system ="PLAYSTATION"
application ="PLAYSTATION"
volume ="HELOCD"
volume_set ="HELOCD"
publisher ="SCHNAPPY"
data_preparer ="MKPSXISO"
/>
<!-- <license>
Optional, specifies the license file to use, the format of the license file must be in
raw 2336 byte sector format, like the ones included with the PsyQ SDK in psyq\cdgen\LCNSFILE.
License data is not included within the MKPSXISO program to avoid possible legal problems
in the open source environment... Better be safe than sorry.
Attributes:
file - Specifies the license file to inject into the ISO image.
-->
<!--
<license file="LICENSEA.DAT"/>
-->
<!-- <directory_tree>
Specifies and contains the directory structure for the data track.
Attributes:
None.
-->
<directory_tree>
<!-- <file>
Specifies a file in the directory tree.
Attributes:
name - File name to use in the directory tree (can be used for renaming).
type - Optional, type of file (data for regular files and is the default, xa for
XA audio and str for MDEC video).
source - File name of the source file.
-->
<!-- Stores system.txt as system.cnf -->
<file name="system.cnf" type="data" source="system.cnf"/>
<file name="SCES_313.37" type="data" source="hello_cd.ps-exe"/>
<file name="HELO.DAT" type="data" source="HELO.DAT"/>
<dummy sectors="1024"/>
<!-- <dir>
Specifies a directory in the directory tree. <file> and <dir> elements inside the element
will be inside the specified directory.
-->
</directory_tree>
</track>
</iso_project>
================================================
FILE: hello_cd/system.cnf
================================================
BOOT=cdrom:\SCES_313.37;1
TCB=4
EVENT=10
STACK=801FFFF0
================================================
FILE: hello_cdda/Makefile
================================================
.PHONY: all cleansub
all:
mkpsxiso -y ./isoconfig.xml
cleansub:
$(MAKE) clean
rm -f hello_cdda.cue hello_cdda.bin
TARGET = hello_cdda
SRCS = hello_cdda.c \
include ../common.mk
================================================
FILE: hello_cdda/README.md
================================================
## Compiling
You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image.
Typing
```bash
make
```
in a terminal will compile and generate the bin/cue files.
Typing
```bash
make cleansub
```
will clean the current directory
## Creating the disk image
```bash
mkpsxiso -y isoconfig.xml
```
## Using ffmpeg to generate a CDDA compliant Wav file
Needed Specification : `RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz`
### Conversion
```bash
ffmpeg -i input.mp3 -acodec pcm_s16le -ac 2 -ar 44100 output.wav
```
### Merging two mono audio channels into one stereo channel
```bash
ffmpeg -i herb.wav.new -filter_complex "[0:a][0:a]amerge=inputs=2[a]" -map "[a]" herbi.wav
```
### Adding the audio track to the CD
Add a track section **after** your data track in `isoconfig.xml` :
```xml
<track type="audio" source="file.wav"/>
```
## Music credits
Track 1 :
Beach Party by Kevin MacLeod
Link: https://incompetech.filmmusic.io/song/3429-beach-party
License: https://filmmusic.io/standard-license
Track 2:
Funk Game Loop by Kevin MacLeod
Link: https://incompetech.filmmusic.io/song/3787-funk-game-loop
License: https://filmmusic.io/standard-license
================================================
FILE: hello_cdda/hello_cdda.c
================================================
// CDDA track playback example
// Schnappy 07-2021
#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
// CD library
#include <libcd.h>
// SPU library
#include <libspu.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320 // Screen width
#define SCREENYRES 240 + (VMODE << 4) // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256
#define CENTERX SCREENXRES/2 // Center of screen on x
#define CENTERY SCREENYRES/2 // Center of screen on y
#define MARGINX 0 // margins for text display
#define MARGINY 32
#define FONTSIZE 8 * 7 // Text Field Height
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
short db = 0; // index of which buffer is used, values 0, 1
// SPU attributes
SpuCommonAttr spuSettings;
// CD tracks
int playing = -1;
int tracks[] = {2, 0}; // Track to play , 1 is data, 2 is beach.wav, 3 is funk.wav. See isoconfig.xml
void init(void)
{
ResetGraph(0); // Initialize drawing engine with a complete reset (0)
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); // Set display area for both &disp[0] and &disp[1]
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES); // &disp[0] is on top of &disp[1]
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES); // Set draw for both &draw[0] and &draw[1]
SetDefDrawEnv(&draw[1], 0, 0 , SCREENXRES, SCREENYRES); // &draw[0] is below &draw[1]
// Set video mode
if (VMODE){ SetVideoMode(MODE_PAL);}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 50, 50, 50); // set color for first draw area
setRGB0(&draw[1], 50, 50, 50); // set color for second draw area
draw[0].isbg = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 1;
PutDispEnv(&disp[db]); // set the disp and draw environnments
PutDrawEnv(&draw[db]);
FntLoad(960, 0); // Load font to vram at 960,0(+128)
FntOpen(MARGINX, SCREENYRES - MARGINY - FONTSIZE, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 ); // FntOpen(x, y, width, height, black_bg, max. nbr. chars
}
void display(void)
{
DrawSync(0); // Wait for all drawing to terminate
VSync(0); // Wait for the next vertical blank
PutDispEnv(&disp[db]); // set alternate disp and draw environnments
PutDrawEnv(&draw[db]);
db = !db; // flip db value (0 or 1)
}
int main(void)
{
int count = 0;
int flip = 1;
CdlLOC loc[100];
int ntoc;
// Init display
init();
// Init extended CD system
CdInit();
// Init Spu
SpuInit();
// Set master & CD volume to max
spuSettings.mask = (SPU_COMMON_MVOLL | SPU_COMMON_MVOLR | SPU_COMMON_CDVOLL | SPU_COMMON_CDVOLR | SPU_COMMON_CDMIX);
// Master volume should be in range 0x0000 - 0x3fff
spuSettings.mvol.left = 0x3fff;
spuSettings.mvol.right = 0x3fff;
// Cd volume should be in range 0x0000 - 0x7fff
spuSettings.cd.volume.left = 0x7fff;
spuSettings.cd.volume.right = 0x7fff;
// Enable CD input ON
spuSettings.cd.mix = SPU_ON;
// Apply settings
SpuSetCommonAttr(&spuSettings);
// Set transfer mode
SpuSetTransferMode(SPU_TRANSFER_BY_DMA);
// CD Playback setup
// Play second audio track
// Get CD TOC
while ((ntoc = CdGetToc(loc)) == 0) { /* Read TOC */
FntPrint("No TOC found: please use CD-DA disc...\n");
}
// Prevent out of bound pos
for (int i = 1; i < ntoc; i++) {
CdIntToPos(CdPosToInt(&loc[i]) - 74, &loc[i]);
}
// Those array will hold the return values of the CD commands
u_char param[4], result[8];
// Set CD parameters ; Report Mode ON, CD-DA ON. See LibeOver47.pdf, p.188
param[0] = CdlModeRept|CdlModeDA;
CdControlB (CdlSetmode, param, 0); /* set mode */
VSync (3); /* wait three vsync times */
// Play second track in toc array
CdControlB (CdlPlay, (u_char *)&loc[3], 0); /* play */
while (1) // infinite loop
{
count ++;
// Get current track number ~ every second
// See LibeOver47.pdf, p.188
if (count%50 == 0){
CdReady(1, &result[0]);
// current track number can also be obtained with
// CdControlB (CdlGetlocP, 0, &result[0]);
}
// Switch track after ~ 20 seconds
if (count%(50*20) == 0){
// Flip can have a value of 1 or -1
flip *= -1;
uint8_t nextTrackIndex = result[1] + flip;
// Send CD command to switch track
CdControlB (CdlPlay, (u_char *)&loc[ nextTrackIndex ], 0);
}
FntPrint("Hello CDDA !\n"); // Send string to print stream
FntPrint("Playback status: %d", result[1]); // Send string to print stream
FntFlush(-1); // Draw printe stream
display(); // Execute display()
}
return 0;
}
================================================
FILE: hello_cdda/isoconfig.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- MKPSXISO example XML script -->
<!-- <iso_project>
Starts an ISO image project to build. Multiple <iso_project> elements may be
specified within the same xml script which useful for multi-disc projects.
<iso_project> elements must contain at least one <track> element.
Attributes:
image_name - File name of the ISO image file to generate.
cue_sheet - Optional, file name of the cue sheet for the image file
(required if more than one track is specified).
-->
<iso_project image_name="hello_cdda.bin" cue_sheet="hello_cdda.cue">
<!-- <track>
Specifies a track to the ISO project. This example element creates a data
track for storing data files and CD-XA/STR streams.
Only one data track is allowed and data tracks must only be specified as the
first track in the ISO image and cannot be specified after an audio track.
Attributes:
type - Track type (either data or audio).
source - For audio tracks only, specifies the file name of a wav audio
file to use for the audio track.
-->
<track type="data">
<!-- <identifiers>
Optional, Specifies the identifier strings to use for the data track.
Attributes:
system - Optional, specifies the system identifier (PLAYSTATION if unspecified).
application - Optional, specifies the application identifier (PLAYSTATION if unspecified).
volume - Optional, specifies the volume identifier.
volume_set - Optional, specifies the volume set identifier.
publisher - Optional, specifies the publisher identifier.
data_preparer - Optional, specifies the data preparer identifier. If unspecified, MKPSXISO
will fill it with lengthy text telling that the image file was generated
using MKPSXISO.
-->
<identifiers
system ="PLAYSTATION"
application ="PLAYSTATION"
volume ="HELOCD"
volume_set ="HELOCD"
publisher ="SCHNAPPY"
data_preparer ="MKPSXISO"
/>
<!-- <license>
Optional, specifies the license file to use, the format of the license file must be in
raw 2336 byte sector format, like the ones included with the PsyQ SDK in psyq\cdgen\LCNSFILE.
License data is not included within the MKPSXISO program to avoid possible legal problems
in the open source environment... Better be safe than sorry.
Attributes:
file - Specifies the license file to inject into the ISO image.
-->
<!--
<license file="LICENSEA.DAT"/>
-->
<!-- <directory_tree>
Specifies and contains the directory structure for the data track.
Attributes:
None.
-->
<directory_tree>
<!-- <file>
Specifies a file in the directory tree.
Attributes:
name - File name to use in the directory tree (can be used for renaming).
type - Optional, type of file (data for regular files and is the default, xa for
XA audio and str for MDEC video).
source - File name of the source file.
-->
<!-- Stores system.txt as system.cnf -->
<file name="system.cnf" type="data" source="system.cnf"/>
<file name="SCES_313.37" type="data" source="hello_cdda.ps-exe"/>
<dummy sectors="1024"/>
<!-- <dir>
Specifies a directory in the directory tree. <file> and <dir> elements inside the element
will be inside the specified directory.
-->
</directory_tree>
</track>
<!--
Track 1 :
Beach Party by Kevin MacLeod
Link: https://incompetech.filmmusic.io/song/3429-beach-party
License: https://filmmusic.io/standard-license
Track 2:
Funk Game Loop by Kevin MacLeod
Link: https://incompetech.filmmusic.io/song/3787-funk-game-loop
License: https://filmmusic.io/standard-license
-->
<track type="audio" source="audio/beach.wav"/>
<track type="audio" source="audio/funk.wav"/>
</iso_project>
================================================
FILE: hello_cdda/system.cnf
================================================
BOOT=cdrom:\SCES_313.37;1
TCB=4
EVENT=10
STACK=801FFFF0
================================================
FILE: hello_cube/Makefile
================================================
TARGET = hello_cube
SRCS = hello_cube.c \
include ../common.mk
================================================
FILE: hello_cube/cube.c
================================================
SVECTOR modelCube_mesh[] = {
{ -128,128,128 },
{ 128,128,128 },
{ 128,128,-128 },
{ -128,128,-128 },
{ -128,-128,128 },
{ 128,-128,128 },
{ 128,-128,-128 },
{ -128,-128,-128 }
};
SVECTOR modelCube_normal[] = {
2365,-2365,-2365, 0,
-2365,-2365,-2365, 0,
-2365,-2365,2365, 0,
2365,-2365,2365, 0,
2365,2365,-2365, 0,
-2365,2365,-2365, 0,
-2365,2365,2365, 0,
2365,2365,2365, 0
};
CVECTOR modelCube_color[] = {
255,237,0, 0,
255,235,0, 0,
255,236,0, 0,
255,2,0, 0,
254,3,0, 0,
255,8,0, 0,
229,0,255, 0,
229,0,255, 0,
229,0,255, 0,
5,16,250, 0,
0,12,255, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0,
255,237,0, 0,
255,237,0, 0,
255,235,0, 0,
255,2,0, 0,
255,6,2, 0,
254,3,0, 0,
229,0,255, 0,
232,21,232, 0,
229,0,255, 0,
5,16,250, 0,
2,13,253, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0
};
int modelCube_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube = {
modelCube_mesh,
modelCube_normal,
0,
modelCube_color,
12
};
SVECTOR modelCube1_mesh[] = {
{ -128,128,128 },
{ 128,128,128 },
{ 128,128,-128 },
{ -128,128,-128 },
{ -128,-128,128 },
{ 128,-128,128 },
{ 128,-128,-128 },
{ -128,-128,-128 }
};
SVECTOR modelCube1_normal[] = {
2365,-2365,-2365, 0,
-2365,-2365,-2365, 0,
-2365,-2365,2365, 0,
2365,-2365,2365, 0,
2365,2365,-2365, 0,
-2365,2365,-2365, 0,
-2365,2365,2365, 0,
2365,2365,2365, 0
};
CVECTOR modelCube1_color[] = {
255,237,0, 0,
255,235,0, 0,
255,236,0, 0,
255,2,0, 0,
254,3,0, 0,
255,8,0, 0,
229,0,255, 0,
229,0,255, 0,
229,0,255, 0,
5,16,250, 0,
0,12,255, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0,
255,237,0, 0,
255,237,0, 0,
255,235,0, 0,
255,2,0, 0,
255,6,2, 0,
254,3,0, 0,
229,0,255, 0,
232,21,232, 0,
229,0,255, 0,
5,16,250, 0,
2,13,253, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0
};
int modelCube1_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube1 = {
modelCube1_mesh,
modelCube1_normal,
0,
modelCube1_color,
12
};
================================================
FILE: hello_cube/hello_cube.c
================================================
/* primdrawG.c, by Schnappy, 12-2020
- Draw a gouraud shaded mesh exported as a TMESH by the blender <= 2.79b plugin io_export_psx_tmesh.py
based on primdraw.c by Lameguy64 (http://www.psxdev.net/forum/viewtopic.php?f=64&t=537)
2014 Meido-Tek Productions.
Controls:
Start - Toggle interactive/non-interactive mode.
Select - Reset object's position and angles.
L1/L2 - Move object closer/farther.
L2/R2 - Rotate object (XY).
Up/Down/Left/Right - Rotate object (XZ/YZ).
Triangle/Cross/Square/Circle - Move object up/down/left/right.
*/
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <stdio.h>
// Sample vector model
#include "cube.c"
#define VMODE 0
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define OTLEN 2048 // Maximum number of OT entries
#define PRIMBUFFLEN 32768 // Maximum number of POLY_GT3 primitives
// Display and draw environments, double buffered
DISPENV disp[2];
DRAWENV draw[2];
u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives)
char primbuff[2][PRIMBUFFLEN]; // Primitive list // That's our prim buffer
char * nextpri = primbuff[0]; // Primitive counter
short db = 0; // Current buffer counter
// Prototypes
void init(void);
void display(void);
//~ void LoadTexture(u_long * tim, TIM_IMAGE * tparam);
void init(){
// Reset the GPU before doing anything and the controller
PadInit(0);
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY); // x, y offset
SetGeomScreen(CENTERX); // Distance between eye and screen
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 0, 128, 255);
setRGB0(&draw[1], 0, 128, 255);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Init font system
FntLoad(960, 0);
FntOpen(16, 16, 196, 64, 0, 256);
}
void display(void){
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
int main() {
int i;
int PadStatus;
int TPressed=0;
int AutoRotate=1;
long t, p, OTz, Flag; // t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143
POLY_G3 *poly = {0}; // pointer to a POLY_G4
SVECTOR Rotate={ 232, 232, 0, 0 }; // Rotation coordinates
VECTOR Trans={ 0, 0, CENTERX * 3, 0 }; // Translation coordinates
// Scaling coordinates
VECTOR Scale={ ONE/2, ONE/2, ONE/2, 0 }; // ONE == 4096
MATRIX Matrix={0}; // Matrix data for the GTE
init();
// Main loop
while (1) {
// Read pad status
PadStatus = PadRead(0);
if (AutoRotate == 0) {
if (PadStatus & PADL1) Trans.vz -= 4;
if (PadStatus & PADR1) Trans.vz += 4;
if (PadStatus & PADL2) Rotate.vz -= 8;
if (PadStatus & PADR2) Rotate.vz += 8;
if (PadStatus & PADLup) Rotate.vx -= 8;
if (PadStatus & PADLdown) Rotate.vx += 8;
if (PadStatus & PADLleft) Rotate.vy -= 8;
if (PadStatus & PADLright) Rotate.vy += 8;
if (PadStatus & PADRup) Trans.vy -= 2;
if (PadStatus & PADRdown) Trans.vy += 2;
if (PadStatus & PADRleft) Trans.vx -= 2;
if (PadStatus & PADRright) Trans.vx += 2;
if (PadStatus & PADselect) {
Rotate.vx = Rotate.vy = Rotate.vz = 0;
Scale.vx = Scale.vy = Scale.vz = ONE/2;
Trans.vx = Trans.vy = 0;
Trans.vz = CENTERX * 3;
}
}
if (PadStatus & PADstart) {
if (TPressed == 0) {
AutoRotate = (AutoRotate + 1) & 1;
Rotate.vx = Rotate.vy = Rotate.vz = 0;
Scale.vx = Scale.vy = Scale.vz = ONE/2;
Trans.vx = Trans.vy = 0;
Trans.vz = CENTERX * 3;
}
TPressed = 1;
} else {
TPressed = 0;
}
if (AutoRotate) {
Rotate.vy += 28; // Pan
Rotate.vx += 28; // Tilt
//~ Rotate.vz += 8; // Roll
}
// Clear the current OT
ClearOTagR(ot[db], OTLEN);
// Convert and set the matrixes
RotMatrix(&Rotate, &Matrix);
TransMatrix(&Matrix, &Trans);
ScaleMatrix(&Matrix, &Scale);
SetRotMatrix(&Matrix);
SetTransMatrix(&Matrix);
// Render the sample vector model
t=0;
// modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
for (i = 0; i < (modelCube.len*3); i += 3) {
poly = (POLY_G3 *)nextpri;
// Initialize the primitive and set its color values
SetPolyG3(poly);
setRGB0(poly, modelCube.c[i].r , modelCube.c[i].g , modelCube.c[i].b);
setRGB1(poly, modelCube.c[i+2].r, modelCube.c[i+2].g, modelCube.c[i+2].b);
setRGB2(poly, modelCube.c[i+1].r, modelCube.c[i+1].g, modelCube.c[i+1].b);
// Rotate, translate, and project the vectors and output the results into a primitive
OTz = RotTransPers(&modelCube_mesh[modelCube_index[t]] , (long*)&poly->x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+2]], (long*)&poly->x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+1]], (long*)&poly->x2, &p, &Flag);
// Sort the primitive into the OT
OTz /= 3;
if ((OTz > 0) && (OTz < OTLEN))
AddPrim(&ot[db][OTz-2], poly);
nextpri += sizeof(POLY_G3);
t+=3;
}
FntPrint("Hello gouraud shaded cube!\n");
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_cubetex/Makefile
================================================
TARGET = hello_cubetex
SRCS = hello_cubetex.c \
../TIM/cubetex.tim \
include ../common.mk
================================================
FILE: hello_cubetex/cubetex.c
================================================
SVECTOR modelCube_mesh[] = {
{32,32,-32.0},
{32,-32,-32},
{-32,-32,-32},
{-32,32,-32},
{32,32,32},
{32,-32,32},
{-32,-32,32},
{-32,32,32}
};
SVECTOR modelCube_normal[] = {
0,-0,-1,0,
0,0,1,0,
1,0,-2,0,
-9,-1,-3,0,
-1,2,-1,0,
3,1,2,0,
0,0,-1,0,
0,-0,1,0,
1,-6,3,0,
-5,-1,9,0,
-1,2,-1,0,
2,1,2,0
};
SVECTOR modelCube_uv[] = {
84,84, 0, 0,
125,42, 0, 0,
84,42, 0, 0,
125,84, 0, 0,
84,125, 0, 0,
125,125, 0, 0,
1,84, 0, 0,
42,125, 0, 0,
42,84, 0, 0,
42,125, 0, 0,
84,84, 0, 0,
42,84, 0, 0,
42,1, 0, 0,
1,42, 0, 0,
42,42, 0, 0,
42,84, 0, 0,
1,42, 0, 0,
1,84, 0, 0,
84,84, 0, 0,
125,84, 0, 0,
125,42, 0, 0,
125,84, 0, 0,
84,84, 0, 0,
84,125, 0, 0,
1,84, 0, 0,
1,125, 0, 0,
42,125, 0, 0,
42,125, 0, 0,
84,125, 0, 0,
84,84, 0, 0,
42,1, 0, 0,
1,1, 0, 0,
1,42, 0, 0,
42,84, 0, 0,
42,42, 0, 0,
1,42, 0, 0
};
CVECTOR modelCube_color[] = {
255,255,255, 0,
255,255,255, 0,
255,0,251, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
4,18,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
254,255,23, 0,
122,255,107, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
254,255,94, 0,
255,255,255, 0,
35,255,11, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
254,255,23, 0,
255,255,255, 0,
122,255,107, 0,
255,255,255, 0,
54,65,255, 0,
255,255,255, 0
};
int modelCube_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube = {
modelCube_mesh,
modelCube_normal,
modelCube_uv,
modelCube_color,
12
};
extern unsigned long _binary____TIM_cubetex_tim_start[];
extern unsigned long _binary____TIM_cubetex_tim_end[];
extern unsigned long _binary____TIM_cubetex_tim_length;
TIM_IMAGE tim_cube;
================================================
FILE: hello_cubetex/hello_cubetex.c
================================================
/* primdrawG.c, by Schnappy, 12-2020
- Draw a gouraud shaded textured mesh exported as a TMESH by the blender <= 2.79b plugin io_export_psx_tmesh.py
based on primdraw.c by Lameguy64 (http://www.psxdev.net/forum/viewtopic.php?f=64&t=537)
2014 Meido-Tek Productions.
Demonstrates:
- Using a primitive OT to draw triangles without libgs.
- Using the GTE to rotate, translate, and project 3D primitives.
Controls:
Start - Toggle interactive/non-interactive mode.
Select - Reset object's position and angles.
L1/L2 - Move object closer/farther.
L2/R2 - Rotate object (XY).
Up/Down/Left/Right - Rotate object (XZ/YZ).
Triangle/Cross/Square/Circle - Move object up/down/left/right.
*/
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <stdio.h>
// Sample vector model
#include "cubetex.c"
#define VMODE 0
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define OTLEN 2048 // Maximum number of OT entries
#define PRIMBUFFLEN 32768 // Maximum number of POLY_GT3 primitives
// Display and draw environments, double buffered
DISPENV disp[2];
DRAWENV draw[2];
u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives)
char primbuff[2][PRIMBUFFLEN] = {0}; // Primitive list // That's our prim buffer
//~ int primcnt=0; // Primitive counter
char * nextpri = primbuff[0]; // Primitive counter
short db = 0; // Current buffer counter
// Prototypes
void init(void);
void display(void);
void LoadTexture(u_long * tim, TIM_IMAGE * tparam);
void init(){
// Reset the GPU before doing anything and the controller
PadInit(0);
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY); // x, y offset
SetGeomScreen(CENTERX); // Distance between eye and screen
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1);
setRGB0(&draw[0], 0, 0, 255);
setRGB0(&draw[1], 0, 0, 255);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Init font system
FntLoad(960, 0);
FntOpen(16, 16, 196, 64, 0, 256);
}
void display(void){
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous
OpenTIM(tim); // Open the tim binary data, feed it the address of the data in memory
ReadTIM(tparam); // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure
LoadImage(tparam->prect, tparam->paddr); // Transfer the data from memory to VRAM at position prect.x, prect.y
DrawSync(0); // Wait for the drawing to end
if (tparam->mode & 0x8){ // check 4th bit // If 4th bit == 1, TIM has a CLUT
LoadImage(tparam->crect, tparam->caddr); // Load it to VRAM at position crect.x, crect.y
DrawSync(0); // Wait for drawing to end
}
}
int main() {
int i;
int PadStatus;
int TPressed=0;
int AutoRotate=1;
long t, p, OTz, Flag; // t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143
POLY_GT3 *poly = {0}; // pointer to a POLY_G4
SVECTOR Rotate={ 0 }; // Rotation coordinates
VECTOR Trans={ 0, 0, CENTERX, 0 }; // Translation coordinates
// Scaling coordinates
VECTOR Scale={ ONE, ONE, ONE, 0 }; // ONE == 4096
MATRIX Matrix={0}; // Matrix data for the GTE
// Texture window
DR_MODE * dr_mode; // Pointer to dr_mode prim
RECT tws = {0, 0, 32, 32}; // Texture window coordinates : x, y, w, h
init();
LoadTexture(_binary____TIM_cubetex_tim_start, &tim_cube);
// Main loop
while (1) {
// Read pad status
PadStatus = PadRead(0);
if (AutoRotate == 0) {
if (PadStatus & PADL1) Trans.vz -= 4;
if (PadStatus & PADR1) Trans.vz += 4;
if (PadStatus & PADL2) Rotate.vz -= 8;
if (PadStatus & PADR2) Rotate.vz += 8;
if (PadStatus & PADLup) Rotate.vx -= 8;
if (PadStatus & PADLdown) Rotate.vx += 8;
if (PadStatus & PADLleft) Rotate.vy -= 8;
if (PadStatus & PADLright) Rotate.vy += 8;
if (PadStatus & PADRup) Trans.vy -= 2;
if (PadStatus & PADRdown) Trans.vy += 2;
if (PadStatus & PADRleft) Trans.vx -= 2;
if (PadStatus & PADRright) Trans.vx += 2;
if (PadStatus & PADselect) {
Rotate.vx = Rotate.vy = Rotate.vz = 0;
Scale.vx = Scale.vy = Scale.vz = ONE;
Trans.vx = Trans.vy = 0;
Trans.vz = CENTERX;
}
}
if (PadStatus & PADstart) {
if (TPressed == 0) {
AutoRotate = (AutoRotate + 1) & 1;
Rotate.vx = Rotate.vy = Rotate.vz = 0;
Scale.vx = Scale.vy = Scale.vz = ONE;
Trans.vx = Trans.vy = 0;
Trans.vz = CENTERX;
}
TPressed = 1;
} else {
TPressed = 0;
}
if (AutoRotate) {
Rotate.vy += 8; // Pan
Rotate.vx += 8; // Tilt
//~ Rotate.vz += 8; // Roll
}
// Clear the current OT
ClearOTagR(ot[db], OTLEN);
// Convert and set the matrixes
RotMatrix(&Rotate, &Matrix);
TransMatrix(&Matrix, &Trans);
ScaleMatrix(&Matrix, &Scale);
SetRotMatrix(&Matrix);
SetTransMatrix(&Matrix);
// Render the sample vector model
t=0;
// modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
for (i = 0; i < (modelCube.len*3); i += 3) {
poly = (POLY_GT3 *)nextpri;
// Initialize the primitive and set its color values
SetPolyGT3(poly);
((POLY_GT3 *)poly)->tpage = getTPage(tim_cube.mode&0x3, 0,
tim_cube.prect->x,
tim_cube.prect->y
);
setRGB0(poly, modelCube.c[i].r , modelCube.c[i].g , modelCube.c[i].b);
setRGB1(poly, modelCube.c[i+2].r, modelCube.c[i+2].g, modelCube.c[i+2].b);
setRGB2(poly, modelCube.c[i+1].r, modelCube.c[i+1].g, modelCube.c[i+1].b);
setUV3(poly, modelCube.u[i].vx, modelCube.u[i].vy,
modelCube.u[i+2].vx, modelCube.u[i+2].vy,
modelCube.u[i+1].vx, modelCube.u[i+1].vy);
// Rotate, translate, and project the vectors and output the results into a primitive
OTz = RotTransPers(&modelCube_mesh[modelCube_index[t]] , (long*)&poly->x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+2]], (long*)&poly->x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+1]], (long*)&poly->x2, &p, &Flag);
// Sort the primitive into the OT
OTz /= 3;
if ((OTz > 0) && (OTz < OTLEN))
AddPrim(&ot[db][OTz-2], poly);
nextpri += sizeof(POLY_GT3);
t+=3;
}
dr_mode = (DR_MODE *)nextpri;
setDrawMode(dr_mode,1,0, getTPage(tim_cube.mode&0x3, 0,
tim_cube.prect->x,
tim_cube.prect->y), &tws); //set texture window
AddPrim(&ot[db], dr_mode);
nextpri += sizeof(DR_MODE);
FntPrint("Hello textured cube!\n");
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_cubetex_stp/Makefile
================================================
TARGET = hello_cubetex_stp
SRCS = hello_cubetex_stp.c \
TIM/stpOnBlack.tim \
TIM/stpOnNonBlack.tim \
TIM/stpOn8bpp.tim \
include ../common.mk
================================================
FILE: hello_cubetex_stp/README.md
================================================

# STP : Semi-Transparency usage
This example shows the effect of activating Semi-Transparency on a textured primitive.
Use the `SELECT` button to switch primitive semi-transparency on and off.
Use the `START` button to cycle throught the 4 transparency rates.
It also features a few C struct to facilitate access to the TIM file / pixel data.
See [https://github.com/ABelliqueux/nolibgs_hello_worlds/tree/main/hello_poly_stp](https://github.com/ABelliqueux/nolibgs_hello_worlds/tree/main/hello_poly_stp) for more information on how to convert your images to TIM while preserving transparency.
See [https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/TIM#transparency](https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/TIM#transparency) for mor details on transparency.
## Documentation
http://psx.arthus.net/sdk/Psy-Q/DOCS/LibOver47.pdf, p.107
http://psx.arthus.net/sdk/Psy-Q/DOCS/FileFormat47.pdf, p.181
http://psx.arthus.net/sdk/Psy-Q/DOCS/LibRef47.pdf, p.306, 345, 365
================================================
FILE: hello_cubetex_stp/cubetex.c
================================================
SVECTOR modelCube_mesh[] = {
{48,48,-48.0},
{48,-48,-48},
{-48,-48,-48},
{-48,48,-48},
{48,48,48},
{48,-48,48},
{-48,-48,48},
{-48,48,48}
};
SVECTOR modelCube_normal[] = {
0,-0,-1,0,
0,0,1,0,
1,0,-2,0,
-9,-1,-3,0,
-1,2,-1,0,
3,1,2,0,
0,0,-1,0,
0,-0,1,0,
1,-6,3,0,
-5,-1,9,0,
-1,2,-1,0,
2,1,2,0
};
SVECTOR modelCube_uv[] = {
84,84, 0, 0,
125,42, 0, 0,
84,42, 0, 0,
125,84, 0, 0,
84,125, 0, 0,
125,125, 0, 0,
1,84, 0, 0,
42,125, 0, 0,
42,84, 0, 0,
42,125, 0, 0,
84,84, 0, 0,
42,84, 0, 0,
42,1, 0, 0,
1,42, 0, 0,
42,42, 0, 0,
42,84, 0, 0,
1,42, 0, 0,
1,84, 0, 0,
84,84, 0, 0,
125,84, 0, 0,
125,42, 0, 0,
125,84, 0, 0,
84,84, 0, 0,
84,125, 0, 0,
1,84, 0, 0,
1,125, 0, 0,
42,125, 0, 0,
42,125, 0, 0,
84,125, 0, 0,
84,84, 0, 0,
42,1, 0, 0,
1,1, 0, 0,
1,42, 0, 0,
42,84, 0, 0,
42,42, 0, 0,
1,42, 0, 0
};
CVECTOR modelCube_color[] = {
255,255,255, 0,
255,255,255, 0,
255,0,251, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
4,18,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
254,255,23, 0,
122,255,107, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
254,255,94, 0,
255,255,255, 0,
35,255,11, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
254,255,23, 0,
255,255,255, 0,
122,255,107, 0,
255,255,255, 0,
54,65,255, 0,
255,255,255, 0
};
int modelCube_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube = {
modelCube_mesh,
modelCube_normal,
modelCube_uv,
modelCube_color,
12
};
typedef struct RGB_PIX {
u_int R:5, G:5, B:5, STP:1;
} RGB_PIX;
// Some structures to handle TIM files
typedef struct PIXEL {
u_long bnum;
u_short DX, DY;
u_short W, H;
RGB_PIX data[];
} PIXEL;
typedef struct CLUT {
u_long bnum;
u_short DX, DY;
u_short W, H;
u_short clut[];
} CLUT;
typedef struct TIM_FILE_CLUT{
u_long ID;
u_long flag;
u_long clut;
PIXEL pixel[];
} TIM_FILE_CLUT;
typedef struct TIM_FILE{
u_long ID;
u_long flag;
PIXEL pixel[];
} TIM_FILE;
extern TIM_FILE _binary_TIM_stpOnBlack_tim_start;
extern TIM_FILE _binary_TIM_stpOnNonBlack_tim_start;
extern TIM_FILE _binary_TIM_stpOn8bpp_tim_start;
================================================
FILE: hello_cubetex_stp/hello_cubetex_stp.c
================================================
// Demo the different settings and rates for pixel and primitive semi-transparency on a cube
// Controls :
// SELECT : Switch semi-transparency on/off on primitives
// START : Cycle semi-transparency rates on/off on primitives
// Schnappy 07-2021
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <libapi.h>
//~ #include <stdio.h>
// Sample vector model
#include "cubetex.c"
#define VMODE 0
// Number of primitives to draw
#define NUM_PRIM 3
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define MARGINX 16 // margins for text display
#define MARGINY 16
#define OTLEN 2048 // Maximum number of OT entries
#define PRIMBUFFLEN 32768 // Maximum number of POLY_GT3 primitives
// Display and draw environments, double buffered
DISPENV disp[2];
DRAWENV draw[2];
u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives)
char primbuff[2][PRIMBUFFLEN]; // Primitive list // That's our prim buffer
char * nextpri = primbuff[0]; // Primitive counter
short db = 0; // Current buffer counter
// Store TIM files in an array so we can iterate over them - see 'cubetex.c' for TIM_FILE struct and declaration
TIM_FILE * timFiles[3];
TIM_IMAGE timImages[3];
// Prototypes
void init(void);
void display(void);
void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam);
void init(){
// Reset the GPU before doing anything and the controller
PadInit(0);
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY); // x, y offset
SetGeomScreen(CENTERX); // Distance between eye and screen
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1);
setRGB0(&draw[0], 0, 0, 255);
setRGB0(&draw[1], 0, 0, 255);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Init font system
FntLoad(960, 0);
FntOpen(MARGINX, MARGINY, SCREENXRES - MARGINX * 2, SCREENXRES - MARGINY * 2, 0, 512 );
}
void display(void){
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam){ // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous
OpenTIM((u_long*)tim); // Open the tim binary data, feed it the address of the data in memory
ReadTIM(tparam); // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure
LoadImage(tparam->prect, tparam->paddr); // Transfer the data from memory to VRAM at position prect.x, prect.y
DrawSync(0); // Wait for the drawing to end
if (tparam->mode & 0x8){ // check 4th bit // If 4th bit == 1, TIM has a CLUT
LoadImage(tparam->crect, tparam->caddr); // Load it to VRAM at position crect.x, crect.y
DrawSync(0); // Wait for drawing to end
}
}
int main() {
// Populate array with pointers to TIM data
timFiles[0] = &_binary_TIM_stpOnBlack_tim_start;
timFiles[1] = &_binary_TIM_stpOnNonBlack_tim_start;
timFiles[2] = &_binary_TIM_stpOn8bpp_tim_start;
// Pad values
int pad, oldPad;
// Set semi-transparency on (1) and off (0)
int stpFlag = 0;
// Set primitive semi-transparency rate - See LibOver47.pdf, p.107
int stpRate = 0;
// If set, rotate cube
int rotateCube = 1;
// Array of pointers to a POLY_G4 we iterate over
POLY_GT3 * poly[NUM_PRIM];
// Rotation vector
SVECTOR rotVector={ 496, 0, 0, 0 };
// Translation vector
VECTOR transVector= { -SCREENXRES/NUM_PRIM, -SCREENYRES/NUM_PRIM, SCREENXRES, 0};
// Init Disp/Drawenv, Font, etc.
init();
// Load textures to VRAM
for (char tim = 0; tim < NUM_PRIM; tim++){
LoadTexture(timFiles[tim], &timImages[tim]);
}
// Main loop
while (1) {
// Work matrix
MATRIX Work= {0} ;
// Triangle counters array - one for each cube
long curTriangle[3] = {0,0,0};
// Clear the current OT
ClearOTagR(ot[db], OTLEN);
// Rotate cube
if(rotateCube) rotVector.vy += 10;
// Apply Transl, Rot, then matrix
RotMatrix(&rotVector, &Work);
TransMatrix(&Work, &transVector);
SetRotMatrix(&Work);
SetTransMatrix(&Work);
// Draw NUM_PRIM primitives
for (int prim = 0; prim < NUM_PRIM; prim++){
// Draw prims with an offset based on iteration number
// A bit messy but the cubes are drawn where we want them :)
transVector.vx = ( SCREENXRES/NUM_PRIM + ( prim * (SCREENXRES/NUM_PRIM + 48) )) - SCREENXRES + 56 ;
transVector.vy = SCREENYRES/NUM_PRIM - SCREENYRES + 86;
// Add vertical offset to second cube
if ( prim == 1) {
transVector.vy = SCREENYRES/NUM_PRIM + 48;
}
// Apply transl matrix
TransMatrix(&Work, &transVector);
SetTransMatrix(&Work);
// modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
for (int i = 0; i < (modelCube.len * 3); i += 3) {
// t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143
long p, OTz, Flag;
// cast nextpri as POLY_GT3
poly[prim] = (POLY_GT3 *)nextpri;
// Initialize the primitive and set its color values
SetPolyGT3(poly[prim]);
// Get TPAGE
poly[prim]->tpage = getTPage( timImages[prim].mode&0x3, stpRate,
timImages[prim].prect->x,
timImages[prim].prect->y
);
// Set RGB colors for each vertex
setRGB0(poly[prim] , modelCube.c[i].r , modelCube.c[i].g , modelCube.c[i].b);
setRGB1(poly[prim], modelCube.c[i+2].r, modelCube.c[i+2].g, modelCube.c[i+2].b);
setRGB2(poly[prim], modelCube.c[i+1].r, modelCube.c[i+1].g, modelCube.c[i+1].b);
// If 8/4bpp, load CLUT to vram
if ( (timImages[prim].mode & 0x3) < 2 ) {
setClut( poly[prim],
timImages[prim].crect->x,
timImages[prim].crect->y
);
}
// Set stpFlag
SetSemiTrans(poly[prim], stpFlag);
// Set UV coordinates
setUV3(poly[prim], modelCube.u[i].vx, modelCube.u[i].vy,
modelCube.u[i+2].vx, modelCube.u[i+2].vy,
modelCube.u[i+1].vx, modelCube.u[i+1].vy);
// Rotate, translate, and project the vectors and output the results into a primitive
// curTriangle, +1, +2 point to the vertices index of the triangle we're drawing.
OTz = RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[prim] ] ] , ( long * ) &poly[prim]->x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[prim] + 2] ], ( long*) &poly[prim]->x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[prim] + 1] ], ( long * ) &poly[prim]->x2, &p, &Flag);
// Average OTz value for 3 vertices
// OTz is 1/4 of screen to vertex length
OTz /= 3;
// If OTz is in range (not to close)
if ((OTz > 0) && (OTz < OTLEN))
// Add to ordering table, at index OTz-2
AddPrim(&ot[ db ][ OTz-2 ], poly[prim]);
// Increment next primitive address
nextpri += sizeof(POLY_GT3);
// Increment to next triangle
curTriangle[prim] += 3;
}
}
// Get pad input
pad = PadRead(0);
// If select button is used
if ( pad & PADselect && !(oldPad & PADselect) ){
// Flip STP flag
stpFlag = !stpFlag;
// Set flag to avoir misfire
oldPad = pad;
}
// Reset flag when button released
if ( !(pad & PADselect) && oldPad & PADselect) {
oldPad = pad;
}
// If start button is used
if ( pad & PADstart && !( oldPad & PADstart ) ){
// Switch STP rates
stpRate > 2 ? stpRate = 0 : stpRate++;
// Set flag to avoir misfire
oldPad = pad;
}
// Reset flag when button released
if (!(pad & PADstart) && oldPad & PADstart) {
oldPad = pad;
}
FntPrint("Hello semi-transparency !\nPrim STP (push Select) : %d\nSTP rate (push start): %d\n\n\n\n\n\n\n\n\n\n\n\n", stpFlag, stpRate);
FntPrint(" stp on black stp on col index\n\n\n\n\n\n\n\n\n\n\n\n");
FntPrint(" stp on non-black");
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_font/Makefile
================================================
TARGET = hello_font
SRCS = hello_font.c \
fnt.tim \
include ../common.mk
================================================
FILE: hello_font/README.md
================================================
See the **wiki** for more details : [https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/FONT](https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/FONT)
================================================
FILE: hello_font/hello_font.c
================================================
// Change the debug font face and colors !
// Schnappy 2020
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320 // Screen width
#define SCREENYRES 240 // Screen height
#define CENTERX SCREENXRES/2 // Center of screen on x
#define CENTERY SCREENYRES/2 // Center of screen on y
#define MARGINX 96 // margins for text display
#define MARGINY 64
#define FONTSIZE 8 * 7 // Text Field Height
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
short db = 0; // index of which buffer is used, values 0, 1
#define FONTX 960
#define FONTY 0
// Two color vectors R,G,B
CVECTOR fntColor = { 255, 0, 0 };
CVECTOR fntColorBG = { 0, 0, 0 };
extern unsigned long _binary_fnt_tim_start[];
extern unsigned long _binary_fnt_tim_end[];
extern unsigned long _binary_fnt_tim_length;
// Loading an image to vram. See https://github.com/ABelliqueux/nolibgs_hello_worlds/blob/main/hello_sprt/hello_sprt.c#L42
TIM_IMAGE fontface;
void LoadTexture(u_long * tim, TIM_IMAGE * tparam){
OpenTIM(tim);
ReadTIM(tparam);
LoadImage(tparam->prect, tparam->paddr);
DrawSync(0);
if (tparam->mode & 0x8){ // check 4th bit
LoadImage(tparam->crect, tparam->caddr);
DrawSync(0);
}
}
void FntColor(CVECTOR fgcol, CVECTOR bgcol )
{
// The debug font clut is at tx, ty + 128
// tx = bg color
// tx + 1 = fg color
// We can override the color by drawing a rect at these coordinates
//
// Define 1 pixel at 960,128 (background color) and 1 pixel at 961, 128 (foreground color)
RECT fg = { FONTX+1, FONTY + 128, 1, 1 };
RECT bg = { FONTX, FONTY + 128, 1, 1 };
// Set colors
ClearImage(&fg, fgcol.r, fgcol.g, fgcol.b);
ClearImage(&bg, bgcol.r, bgcol.g, bgcol.b);
}
void init(void)
{
ResetGraph(0); // Initialize drawing engine with a complete reset (0)
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); // Set display area for both &disp[0] and &disp[1]
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES); // &disp[0] is on top of &disp[1]
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES); // Set draw for both &draw[0] and &draw[1]
SetDefDrawEnv(&draw[1], 0, 0 , SCREENXRES, SCREENYRES); // &draw[0] is below &draw[1]
if (VMODE) // PAL
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8; // add offset : 240 + 8 + 8 = 256
disp[1].screen.y += 8;
}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 50, 50, 50); // set color for first draw area
setRGB0(&draw[1], 50, 50, 50); // set color for second draw area
draw[0].isbg = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 1;
PutDispEnv(&disp[db]); // set the disp and draw environnments
PutDrawEnv(&draw[db]);
FntLoad(960, 0); // Load font to vram at 960,0(+128)
FntOpen(MARGINX, MARGINY, SCREENXRES, SCREENXRES, 0, 280 ); // FntOpen(x, y, width, height, black_bg, max. nbr. chars
}
void display(void)
{
DrawSync(0); // Wait for all drawing to terminate
VSync(0); // Wait for the next vertical blank
PutDispEnv(&disp[db]); // set alternate disp and draw environnments
PutDrawEnv(&draw[db]);
db = !db; // flip db value (0 or 1)
}
int main(void)
{
u_int t = 0;
u_short step = 10;
u_char * channel, * prevChannel;
channel = &fntColor.r;
prevChannel = &fntColor.b;
init(); // execute init()
LoadTexture(_binary_fnt_tim_start, &fontface);
FntColor(fntColor, fntColorBG);
while (1) // infinite loop
{
t++;
if (fntColor.r >= 254 - step ){channel = &fntColor.g; prevChannel = &fntColor.r;}
if (fntColor.g >= 254 - step ){channel = &fntColor.b; prevChannel = &fntColor.g;}
if (fntColor.b >= 254 - step ){channel = &fntColor.r; prevChannel = &fntColor.b;}
*channel += step;
if (*prevChannel){
*prevChannel -= step;
}
//~ fntColorBG.g = 255 - color ;
FntColor(fntColor, fntColorBG);
// 4lines, 16 glyphs on each line
// Glyphs are 5x7 pixels wide in 16bpp,
FntPrint("!\"#$%%&'()*+,-./\n");
FntPrint("0123456789:;<=^?\n");
FntPrint("@ABCDEFGHIJKLMNO\n");
FntPrint("PQRSTUVWXYZ[\\]>");
FntPrint("\n\nHELLO DEBUG FONT! %d", t);
FntFlush(-1); // Draw print stream
display(); // Execute display()
}
return 0;
}
================================================
FILE: hello_fx/Makefile
================================================
TARGET = hello_fx
SRCS = hello_fx.c \
TIM/cube.tim \
TIM/sky.tim \
TIM/bg.tim \
include ../common.mk
================================================
FILE: hello_fx/cubetex.c
================================================
SVECTOR modelCube_mesh[] = {
{48,48,-48.0},
{48,-48,-48},
{-48,-48,-48},
{-48,48,-48},
{48,48,48},
{48,-48,48},
{-48,-48,48},
{-48,48,48}
};
SVECTOR modelCube_normal[] = {
0,-0,-1,0,
0,0,1,0,
1,0,-2,0,
-9,-1,-3,0,
-1,2,-1,0,
3,1,2,0,
0,0,-1,0,
0,-0,1,0,
1,-6,3,0,
-5,-1,9,0,
-1,2,-1,0,
2,1,2,0
};
SVECTOR modelCube_uv[] = {
84,84, 0, 0,
125,42, 0, 0,
84,42, 0, 0,
125,84, 0, 0,
84,125, 0, 0,
125,125, 0, 0,
1,84, 0, 0,
42,125, 0, 0,
42,84, 0, 0,
42,125, 0, 0,
84,84, 0, 0,
42,84, 0, 0,
42,1, 0, 0,
1,42, 0, 0,
42,42, 0, 0,
42,84, 0, 0,
1,42, 0, 0,
1,84, 0, 0,
84,84, 0, 0,
125,84, 0, 0,
125,42, 0, 0,
125,84, 0, 0,
84,84, 0, 0,
84,125, 0, 0,
1,84, 0, 0,
1,125, 0, 0,
42,125, 0, 0,
42,125, 0, 0,
84,125, 0, 0,
84,84, 0, 0,
42,1, 0, 0,
1,1, 0, 0,
1,42, 0, 0,
42,84, 0, 0,
42,42, 0, 0,
1,42, 0, 0
};
CVECTOR modelCube_color[] = {
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0,
128,128,128, 0
};
int modelCube_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube = {
modelCube_mesh,
modelCube_normal,
modelCube_uv,
modelCube_color,
12
};
typedef struct RGB_PIX {
u_int R:5, G:5, B:5, STP:1;
} RGB_PIX;
// Some structures to handle TIM files
typedef struct PIXEL {
u_long bnum;
u_short DX, DY;
u_short W, H;
RGB_PIX data[];
} PIXEL;
typedef struct CLUT {
u_long bnum;
u_short DX, DY;
u_short W, H;
u_short clut[];
} CLUT;
typedef struct TIM_FILE_CLUT{
u_long ID;
u_long flag;
u_long clut;
PIXEL pixel[];
} TIM_FILE_CLUT;
typedef struct TIM_FILE{
u_long ID;
u_long flag;
PIXEL pixel[];
} TIM_FILE;
================================================
FILE: hello_fx/hello_fx.c
================================================
// Controls :
// SELECT : Switch semi-transparency on/off on primitives
// START : Cycle semi-transparency rates on/off on primitives
// LEFT/RIGHT: Move forward cube
// X : Reset Cube position
// Schnappy 11-2021
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <libapi.h>
#include <inline_n.h>
#include <gtemac.h>
// Sample vector model
#include "cubetex.c"
#define VMODE 0
// Number of primitives to draw
#define NUM_PRIM 2
// Number of textures to load
#define NUM_TEX 3
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define MARGINX 16 // margins for text display
#define MARGINY 16
#define OTLEN 2048 // Maximum number of OT entries
#define PRIMBUFFLEN 32768 // Maximum number of POLY_GT3 primitives
// Display and draw environments, double buffered
DISPENV disp[2];
DRAWENV draw[2];
u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives)
char primbuff[2][PRIMBUFFLEN]; // Primitive list // That's our prim buffer
char * nextpri = primbuff[0]; // Primitive counter
short db = 0; // Current buffer counter
// Store TIM files in an array so we can iterate over them - see 'cubetex.c' for TIM_FILE struct and declaration
TIM_FILE * timFiles[3];
TIM_IMAGE timImages[3];
// Get included tim files address
extern TIM_FILE _binary_TIM_cube_tim_start;
extern TIM_FILE _binary_TIM_sky_tim_start;
extern TIM_FILE _binary_TIM_bg_tim_start;
// Light
CVECTOR BGc = {130, 200, 255, 0};
// Back color
VECTOR BKc = {128, 128, 128, 0};
// Light rotation angle
SVECTOR lgtang = {0, 0, 0};
// These will be used to store the light rotation matrix, cube rotation matrix, and composite light matrix.
MATRIX rotlgt, rotcube, light;
// Local Light Matrix : Direction and reach of each light source.
MATRIX lgtmat = {
// X Y Z
0, -ONE, 0, // Lightsource 1 : here, the light source is at the Bottom-Left of the screen, and points into the screen.
0, 0, 0, // Lightsource 2
0, 0, 0, // Lightsource 3
};
// Local Color Matrix
MATRIX cmat = {
// L1 L2 L3
4096, 0, 0, // R
4096, 0, 0, // G
4096, 0, 0 // B
};
// Prototypes
void init(void);
void display(void);
void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam);
void init(){
// Reset the GPU before doing anything and the controller
PadInit(0);
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY); // x, y offset
SetGeomScreen(CENTERX); // Distance between eye and screen
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1);
// Set far color
SetFarColor( BGc.r, BGc.g, BGc.b );
// Set Ambient color
SetBackColor( BKc.vx, BKc.vy, BKc.vz );
// Set Color matrix
SetColorMatrix(&cmat);
// Set Fog settings
SetFogNearFar( 128, 1024, CENTERX );
setRGB0(&draw[0], 0, 0, 0);
setRGB0(&draw[1], 0, 0, 0);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Init font system
FntLoad(960, 0);
FntOpen(MARGINX, MARGINY, SCREENXRES - MARGINX * 2, SCREENXRES - MARGINY * 2, 0, 512 );
}
void display(void){
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam){ // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous
OpenTIM((u_long*)tim); // Open the tim binary data, feed it the address of the data in memory
ReadTIM(tparam); // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure
LoadImage(tparam->prect, tparam->paddr); // Transfer the data from memory to VRAM at position prect.x, prect.y
DrawSync(0); // Wait for the drawing to end
if (tparam->mode & 0x8){ // check 4th bit // If 4th bit == 1, TIM has a CLUT
LoadImage(tparam->crect, tparam->caddr); // Load it to VRAM at position crect.x, crect.y
DrawSync(0); // Wait for drawing to end
}
}
int main() {
// Populate array with pointers to TIM data
timFiles[0] = &_binary_TIM_cube_tim_start;
timFiles[1] = &_binary_TIM_sky_tim_start;
timFiles[2] = &_binary_TIM_bg_tim_start;
// Pad values
int pad, oldPad;
// Set semi-transparency on (1) and off (0)
int stpFlag = 1;
// Set primitive semi-transparency rate - See LibOver47.pdf, p.107
int stpRate = 0;
// If set, rotate cube
int rotateCube = 1;
int offsetCube = 0;
// Array of pointers to a POLY_G4 we iterate over
POLY_GT3 * poly[NUM_PRIM];
// Rotation vector
SVECTOR rotVector={ 384, 0, 128, 0 };
// Translation vector
VECTOR transVector= { 0, 0, 256, 0};
// BG sprt
POLY_FT4 * bg;
// Normalized UV coordinates for the X axis
long normH = ((255 << 12) / SCREENXRES);
// Init Disp/Drawenv, Font, etc.
init();
// Load textures to VRAM
for (char tex = 0; tex < NUM_TEX; tex++){
LoadTexture(timFiles[tex], &timImages[tex]);
}
// Main loop
while (1) {
// Work matrix
MATRIX Work= {0} ;
// Triangle counters array - one for each cube
long curTriangle[3] = {0,0,0};
// Clear the current OT
ClearOTagR(ot[db], OTLEN);
// Draw BG
bg = (POLY_FT4 * )nextpri;
SetPolyFT4(bg);
bg->tpage = getTPage( timImages[2].mode&0x3, 0,
timImages[2].prect->x,
timImages[2].prect->y
);
if ( (timImages[2].mode & 0x3) < 2 ) {
setClut( bg,
timImages[2].crect->x,
timImages[2].crect->y
);
}
setRGB0(bg, 127,127,127);
setUV4(bg, 0, 0,
SCREENYRES, 0,
0, SCREENYRES,
SCREENYRES, SCREENYRES
);
setXY4(bg, 0 , 0,
SCREENXRES, 0,
0 , SCREENYRES,
SCREENXRES, SCREENYRES);
addPrim(ot[db][OTLEN-1], bg);
nextpri += sizeof(POLY_FT4);
// Rotate cube
if(rotateCube) rotVector.vy += 10;
// Find and apply light rotation matrix
// Find rotmat from light angles
RotMatrix_gte(&lgtang, &rotlgt);
// Find rotmat from cube angles
RotMatrix_gte(&rotVector, &rotcube);
// RotMatrix cube * RotMatrix light
MulMatrix0(&rotcube, &rotlgt, &rotlgt);
// Light Matrix * RotMatrix light
MulMatrix0(&lgtmat, &rotlgt, &light);
// Set new light matrix
SetLightMatrix(&light);
// Apply Transl, Rot, then matrix
RotMatrix(&rotVector, &Work);
TransMatrix(&Work, &transVector);
SetRotMatrix(&Work);
SetTransMatrix(&Work);
long p, OTz, Flag;
// Draw NUM_PRIM primitives
for (int i = 0; i < (modelCube.len * 3); i += 3) {
// Set projection matrices
transVector.vx = 0;
TransMatrix(&Work, &transVector);
SetRotMatrix(&Work);
SetTransMatrix(&Work);
// Cast nextpri as POLY_GT3
poly[0] = (POLY_GT3 *)nextpri;
poly[1] = (POLY_GT3 *)nextpri+sizeof(POLY_GT3);
// Initialize the primitives
SetPolyGT3(poly[0]);
SetPolyGT3(poly[1]);
// Reflection Cube
// This cube has its UVs mapped directly to VRAM coordinates
// We're using the framebuffers as a texture (0,0 and 0,256)
// Get 256x256 texture page that's at x0, y0
poly[1]->tpage = getTPage( 2, stpRate,
0,
!(db) << 8 // Here, we're using db's value that can be either 0 or 1 to determine the texture page Y coordinate.
);
// Set STP
SetSemiTrans(poly[1], stpFlag);
// Map coordinates from drawarea (320x240) to texture size (128x128) in fixed point math
// x = x * (256 / 320) => ( x * ( 128 * 4096 ) / 320 ) / 4096
// y = y * (240 / 240) => ( y * ( 240 * 4096 ) / 240 ) / 4096 => y * 2184 >> 12 -> y
setUV3( poly[1],
(poly[1]->x0 * normH) >> 12,
poly[1]->y0 - (!(db) << 4) , // We're using db's value again to add a 16 pixels offset to the Y's coordinates of the UVs
(poly[1]->x1 * normH) >> 12,
poly[1]->y1 - (!(db) << 4), // We have to do that because the buffer is 240 high, whereas our texture page is 256, hence 256 - 240 == 16
(poly[1]->x2 * normH) >> 12,
poly[1]->y2 - (!(db) << 4)
);
// Draw "container" cube
// This cube has a texture with transparent areas.
// STP bit is set on PNG's alpha channel : img2tim -usealpha -org 320 0 -o cube.tim cube.png
poly[0]->tpage = getTPage( timImages[0].mode&0x3, stpRate,
timImages[0].prect->x,
timImages[0].prect->y
);
// If 8/4bpp, load CLUT to vram
if ( (timImages[0].mode & 0x3) < 2 ) {
setClut( poly[0],
timImages[0].crect->x,
timImages[0].crect->y
);
}
// Set UV coordinates
setUV3(poly[0], modelCube.u[i].vx, modelCube.u[i].vy,
modelCube.u[i+2].vx, modelCube.u[i+2].vy,
modelCube.u[i+1].vx, modelCube.u[i+1].vy
);
// Rotate, translate, and project the vectors and output the results into a primitive
// curTriangle, +1, +2 point to the vertices index of the triangle we're drawing.
OTz = RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] ] ] , ( long * ) &poly[1]->x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 2] ], ( long*) &poly[1]->x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 1] ], ( long * ) &poly[1]->x2, &p, &Flag);
// Here we're only messing with the matrices so that the foreground cube can be moved independantly from the backgound one.
// In real code, you don't want to do the same calculation twice !
transVector.vx = offsetCube;
TransMatrix(&Work, &transVector);
SetRotMatrix(&Work);
SetTransMatrix(&Work);
OTz = RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] ] ] , ( long * ) &poly[0]->x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 2] ], ( long*) &poly[0]->x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 1] ], ( long * ) &poly[0]->x2, &p, &Flag);
// The right way to do it is re-using the results from the first RotTransPer() batch
// i.e commenting lines 273 to 280 and uncommenting lines 284 to 289
//~ poly[0]->x0 = poly[1]->x0;
//~ poly[0]->y0 = poly[1]->y0;
//~ poly[0]->x1 = poly[1]->x1;
//~ poly[0]->y1 = poly[1]->y1;
//~ poly[0]->x2 = poly[1]->x2;
//~ poly[0]->y2 = poly[1]->y2;
// Average OTz value for 3 vertices
// OTz is 1/4 of screen to vertex length
OTz /= 3;
// Work color vectors
// This is the hue of the transparent cube
CVECTOR prismCol = {0xff,0xff,0x0,0x0};
// This will store the result of the depth cueing.
CVECTOR outCol, outCol1, outCol2 = { 0,0,0,0 };
// Find local color from three normal vectors and perform depth cueing.
gte_NormalColorDpq3( &modelCube.n[i+0],
&modelCube.n[i+2],
&modelCube.n[i+3],
&prismCol, p, &outCol, &outCol1, &outCol2);
// Set vertex colors on transparent/background cube
setRGB0(poly[1], outCol.r, outCol.g , outCol.b);
setRGB1(poly[1], outCol1.r, outCol1.g, outCol1.b);
setRGB2(poly[1], outCol2.r, outCol2.g, outCol2.b);
// Non-transparent/foreground cube color
// Find local color from three normal vectors and perform depth cueing.
gte_NormalColorDpq( &modelCube.n[i+0], &modelCube.c[i+0], p, &outCol);
gte_NormalColorDpq( &modelCube.n[i+2], &modelCube.c[i+2], p, &outCol2);
gte_NormalColorDpq( &modelCube.n[i+1], &modelCube.c[i+1], p, &outCol1);
// Set vertex colors
setRGB0(poly[0], outCol.r, outCol.g , outCol.b);
setRGB1(poly[0], outCol1.r, outCol1.g, outCol1.b);
setRGB2(poly[0], outCol2.r, outCol2.g, outCol2.b);
// If OTz is in range (not too close)
if ((OTz > 0) && (OTz < OTLEN))
// Add to ordering table, at index OTz-2
AddPrim(&ot[ db ][ OTz-2 ], poly[0]);
AddPrim(&ot[ db ][ OTz-2 ], poly[1]);
// Increment next primitive address
nextpri += sizeof(POLY_GT3)*2;
// Increment to next triangle
curTriangle[0] += 3;
curTriangle[1] += 3;
}
// Get pad input
pad = PadRead(0);
// If select button is used
if ( pad & PADselect && !(oldPad & PADselect) ){
// Flip STP flag
stpFlag = !stpFlag;
// Set flag to avoir misfire
oldPad = pad;
}
// Reset flag when button released
if ( !(pad & PADselect) && oldPad & PADselect) {
oldPad = pad;
}
// If start button is used
if ( pad & PADstart && !( oldPad & PADstart ) ){
// Switch STP rates
stpRate > 2 ? stpRate = 0 : stpRate++;
// Set flag to avoir misfire
oldPad = pad;
}
// Reset flag when button released
if (!(pad & PADstart) && oldPad & PADstart) {
oldPad = pad;
}
if ( pad & PADRdown && !( oldPad & PADRdown ) ){
// Switch STP rates
offsetCube = 0;
// Set flag to avoir misfire
oldPad = pad;
}
// Reset flag when button released
if (!(pad & PADRdown) && oldPad & PADRdown) {
oldPad = pad;
}
if ( pad & PADLright && !( oldPad & PADLright ) ){
offsetCube += 6;
}
if ( pad & PADLleft && !( oldPad & PADLleft ) ){
offsetCube -= 6;
}
FntPrint("Hello fx !\n");
FntPrint("Select: STP on/off\nStart: Cycle STP rates\nLeft/Right: Move FG cube.\nX: Reset cube pos\n");
FntPrint("STP : %d\n", stpFlag);
FntPrint("STP rate : %d\n", stpRate);
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_gte_opti/Makefile
================================================
TARGET = hello_gte_opti
SRCS = hello_gte_opti.c \
include ../common.mk
================================================
FILE: hello_gte_opti/hello_gte_opti.c
================================================
// Hello free cycles !
//
// Ref : /psyq/DOCS/Devrefs/Inlinref.pdf, p.18
// /psyq/psx/sample/scea/GTE
// https://psx-spx.consoledev.net/geometrytransformationenginegte/
// PSX / Z+
// screen /
//coordinate +-----X+
//system / |
// eye | Y+
//
// Credits, thanks : Nicolas Noble, Sickle, Lameguy64 @ psxdev discord : https://discord.com/invite/N2mmwp
// https://discord.com/channels/642647820683444236/663664210525290507/834831466100949002
// Schnappy 2021
#include <sys/types.h>
#include <stdio.h>
#include <libetc.h>
#include <libgte.h>
#include <libgpu.h>
// OldWorld PsyQ has a inline_c.h file for inline GTE functions. We have to use the one at https://github.com/grumpycoders/pcsx-redux/blob/07f9b02d1dbb68f57a9f5b9773041813c55a4913/src/mips/psyq/include/inline_n.h
// because the real GTE commands are needed in nugget : https://psx-spx.consoledev.net/geometrytransformationenginegte/#gte-coordinate-calculation-commands
#include <inline_n.h>
// RAM -> CPU and CPU -> GTE macros :
#include "../includes/CPUMAC.H"
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320 // Screen width
#define SCREENYRES 240 + (VMODE << 4) // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256
#define CENTERX ( SCREENXRES >> 1 ) // Center of screen on x
#define CENTERY ( SCREENYRES >> 1 ) // Center of screen on y
#define MARGINX 0 // margins for text display
#define MARGINY 32
#define FONTSIZE 8 * 7 // Text Field Height
#define OTLEN 10 // Ordering Table Length
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
u_long ot[2][OTLEN]; // double ordering table of length 8 * 32 = 256 bits / 32 bytes
char primbuff[2][32768] = {1}; // double primitive buffer of length 32768 * 8 = 262.144 bits / 32,768 Kbytes
char *nextpri = primbuff[0]; // pointer to the next primitive in primbuff. Initially, points to the first bit of primbuff[0]
short db = 0; // index of which buffer is used, values 0, 1
// DCache setup
#define dc_camdirp ((sshort*) getScratchAddr(0))
#define dc_ip ((uchar*) getScratchAddr(1))
#define dc_opzp ((slong*) getScratchAddr(2))
#define dc_wmatp ((MATRIX*) getScratchAddr(3))
#define dc_cmatp ((MATRIX*) getScratchAddr(9))
#define dc_sxytbl ((DVECTOR*) getScratchAddr(15))
void init(void)
{
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
//~ SetGeomOffset(CENTERX,CENTERY);
gte_SetGeomOffset(CENTERX,CENTERY);
gte_SetGeomScreen(CENTERX);
// Set display environment
SetDefDispEnv(&disp[0], 0, 0, SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
// Set draw environment
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE){ SetVideoMode(MODE_PAL);}
SetDispMask(1);
// Set background color
setRGB0(&draw[0], 50, 50, 50);
setRGB0(&draw[1], 50, 50, 50);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
FntLoad(960, 0);
FntOpen(MARGINX, SCREENYRES - MARGINY - FONTSIZE, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 );
}
void display(void)
{
// Wait for drawing
DrawSync(0);
// Wait for vsync
VSync(1);
// Flip DISP and DRAW env
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
// Flip db index
db = !db;
// Get next primitive in buffer
nextpri = primbuff[db];
}
int main(void)
{
long p, flag, OTz;
SVECTOR rotVector = {0};
SVECTOR rotVector4 = {0}; // Initialize rotation vector {x, y, z} - ALWAYS !
VECTOR transVector = {0, 0, CENTERX, 0}; // Initialize translation vector {x, y, z}
SVECTOR vertPos[4] = {
{ 0, -32, 0, 0 }, // Vert 1
{ 32, 0, 0, 0 }, // Vert 2
{ -32, 0, 0, 0 },
{ 0, 32, 0, 0 }
}; // Vert 3
MATRIX workMatrix = {0};
POLY_F3 * poly = {0}; // pointer to a POLY_F4
POLY_F4 * poly4 = {0}; // pointer to a POLY_F4
init();
// Declare registers
register ulong ur0 asm("$16");
register ulong ur1 asm("$17");
register ulong ur2 asm("$18");
register ulong ur3 asm("$19");
register ulong ur4 asm("$20");
register ulong ur5 asm("$21");
while (1)
{
// Set Ordering table
ClearOTagR(ot[db], OTLEN);
// Cast next primitives in buffer as a POLY_F3 and a POLY_F4 (see display() )
poly = (POLY_F3 *)nextpri;
nextpri += sizeof(POLY_F3);
poly4 = (POLY_F4 *)nextpri;
// Set matrices - Move to left of screen
// Draw on the left part of the screen
transVector.vx = -CENTERX/2;
// Increment rotation angle on Y axis
rotVector.vy += 1;
// Find rotation matrix from vector, store in
RotMatrix_gte(&rotVector, &workMatrix);
// Ditto for translation
TransMatrix(&workMatrix, &transVector);
// Set the matrices we just found
gte_SetRotMatrix(&workMatrix);
gte_SetTransMatrix(&workMatrix);
// Draw a Tri and a Quad
// Copy Tri vertices from ram to cpu registers casting as ulong so that ur0 (len 32bits) contains vx and vy (2 * 8bits)
// Hence the use of vx, vz members
cpu_ldr(ur0,(ulong*)&vertPos[0].vx); // Put vx, vy value in ur0
cpu_ldr(ur1,(ulong*)&vertPos[0].vz); // Put vz, pad value in ur1
cpu_ldr(ur2,(ulong*)&vertPos[1].vx);
cpu_ldr(ur3,(ulong*)&vertPos[1].vz);
cpu_ldr(ur4,(ulong*)&vertPos[2].vx);
cpu_ldr(ur5,(ulong*)&vertPos[2].vz);
// Load the gte registers from the cpu registers (gte-cpu move 1 cycle) - mtc2 %0, $0;
cpu_gted0(ur0);
cpu_gted1(ur1);
cpu_gted2(ur2);
cpu_gted3(ur3);
cpu_gted4(ur4);
cpu_gted5(ur5);
// Tri RotTransPers3
// The two last cpu->gte copy will happen during the 2 nops in gte_rtpt()
gte_rtpt();
// Fill the cpu registers with the Quad vertices
cpu_ldr(ur0,(ulong*)&vertPos[0].vx);
cpu_ldr(ur1,(ulong*)&vertPos[0].vz);
cpu_ldr(ur2,(ulong*)&vertPos[1].vx);
cpu_ldr(ur3,(ulong*)&vertPos[1].vz);
cpu_ldr(ur4,(ulong*)&vertPos[2].vx);
cpu_ldr(ur5,(ulong*)&vertPos[2].vz);
// Get nclip value, and win two cycles
gte_nclip();
// Copy Tri 's screen coordinates from gte registers to d-cache.
gte_stsxy3c(&dc_sxytbl[0]);
// Set matrices - Move to right of screen
transVector.vx = CENTERX/2;
// Increment rot on X/Y axis
rotVector4.vy -= 1 ;
rotVector4.vx -= 1 ;
// Set matrices
RotMatrix_gte(&rotVector4, &workMatrix);
TransMatrix(&workMatrix, &transVector);
gte_SetRotMatrix(&workMatrix);
gte_SetTransMatrix(&workMatrix);
// Load the gte registers from the cpu registers (gte-cpu move 1 cycle) - mtc2 %0, $0;
cpu_gted0(ur0);
cpu_gted1(ur1);
cpu_gted2(ur2);
cpu_gted3(ur3);
cpu_gted4(ur4);
cpu_gted5(ur5);
// Quad RotTransPers3
// Getting 2 cycles back thanks to nops
gte_rtpt();
// gte_nclip() has 2 nops, lets use them to load the remaining vertex data from ram->cpu register
cpu_ldr(ur0,(ulong*)&vertPos[3].vx);
cpu_ldr(ur1,(ulong*)&vertPos[3].vz);
// Calculate nclip (outer product)
gte_nclip();
// Copy result to d-cache + 3
gte_stsxy3c(&dc_sxytbl[3]);
// Copy from cpu-gte
cpu_gted0(ur0);
cpu_gted1(ur1);
// Quad last vertex RotTransPers
// These two last cpu->gte load are free :p
gte_rtps();
gte_nclip();
// Copy last vertex value to d-cache
gte_stsxy(&dc_sxytbl[6]);
// Get p, flag, OTz
gte_stdp(&p);
gte_stflg(&flag);
gte_stszotz(&OTz);
// That's 10 cycles we won back ?
// Copy vertices data from d-cache to ram
// Tri
*(unsigned long long*)&poly->x0 = *(unsigned long long*)&dc_sxytbl[0];
*(ulong*)&poly->x2 = *(ulong*)&dc_sxytbl[2];
// Quad
*(unsigned long long*)&poly4->x0 = *(unsigned long long*)&dc_sxytbl[3];
*(unsigned long long*)&poly4->x2 = *(unsigned long long*)&dc_sxytbl[5];
// Initialize polygons
setPolyF3(poly);
setRGB0(poly, 255, 0, 255);
setPolyF4(poly4);
setRGB0(poly4, 0, 255, 255);
// Add to OT
addPrim(ot[db], poly);
addPrim(ot[db], poly4);
// Display text
FntPrint("Hello Free cycles !\n");
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_light/Makefile
================================================
TARGET = hello_light
SRCS = hello_light.c \
include ../common.mk
================================================
FILE: hello_light/cube.c
================================================
SVECTOR modelCube_mesh[] = {
{ -128,128,128 },
{ 128,128,128 },
{ 128,128,-128 },
{ -128,128,-128 },
{ -128,-128,128 },
{ 128,-128,128 },
{ 128,-128,-128 },
{ -128,-128,-128 }
};
SVECTOR modelCube_normal[] = {
2365,-2365,-2365, 0,
-2365,-2365,-2365, 0,
-2365,-2365,2365, 0,
2365,-2365,2365, 0,
2365,2365,-2365, 0,
-2365,2365,-2365, 0,
-2365,2365,2365, 0,
2365,2365,2365, 0
};
CVECTOR modelCube_color[] = {
255,237,0, 0,
255,235,0, 0,
255,236,0, 0,
255,2,0, 0,
254,3,0, 0,
255,8,0, 0,
229,0,255, 0,
229,0,255, 0,
229,0,255, 0,
5,16,250, 0,
0,12,255, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0,
255,237,0, 0,
255,237,0, 0,
255,235,0, 0,
255,2,0, 0,
255,6,2, 0,
254,3,0, 0,
229,0,255, 0,
232,21,232, 0,
229,0,255, 0,
5,16,250, 0,
2,13,253, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0
};
int modelCube_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube = {
modelCube_mesh,
modelCube_normal,
0,
modelCube_color,
12
};
SVECTOR modelCube1_mesh[] = {
{ -128,128,128 },
{ 128,128,128 },
{ 128,128,-128 },
{ -128,128,-128 },
{ -128,-128,128 },
{ 128,-128,128 },
{ 128,-128,-128 },
{ -128,-128,-128 }
};
SVECTOR modelCube1_normal[] = {
2365,-2365,-2365, 0,
-2365,-2365,-2365, 0,
-2365,-2365,2365, 0,
2365,-2365,2365, 0,
2365,2365,-2365, 0,
-2365,2365,-2365, 0,
-2365,2365,2365, 0,
2365,2365,2365, 0
};
CVECTOR modelCube1_color[] = {
255,237,0, 0,
255,235,0, 0,
255,236,0, 0,
255,2,0, 0,
254,3,0, 0,
255,8,0, 0,
229,0,255, 0,
229,0,255, 0,
229,0,255, 0,
5,16,250, 0,
0,12,255, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0,
255,237,0, 0,
255,237,0, 0,
255,235,0, 0,
255,2,0, 0,
255,6,2, 0,
254,3,0, 0,
229,0,255, 0,
232,21,232, 0,
229,0,255, 0,
5,16,250, 0,
2,13,253, 0,
0,12,255, 0,
4,251,25, 0,
0,255,26, 0,
0,255,26, 0,
0,248,255, 0,
0,248,255, 0,
0,248,255, 0
};
int modelCube1_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube1 = {
modelCube1_mesh,
modelCube1_normal,
0,
modelCube1_color,
12
};
================================================
FILE: hello_light/hello_light.c
================================================
/* hello_light.c, by Schnappy, 06-2021
- Demonstrates setting and using light sources in 3D without libgs.
Controls:
Start - Toggle interactive/non-interactive mode.
Select - Reset object's position and angles.
L1/L2 - Move object closer/farther.
L2/R2 - Rotate object (XY).
Up/Down/Left/Right - Rotate object (XZ/YZ).
Triangle/Cross/Square/Circle - Move object up/down/left/right.
based on primdraw.c by Lameguy64 (http://www.psxdev.net/forum/viewtopic.php?f=64&t=537)
2014 Meido-Tek Productions.
*/
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <stdio.h>
// Sample vector model
#include "cube.c"
#define VMODE 0
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define OTLEN 2048 // Maximum number of OT entries
#define PRIMBUFFLEN 32768 // Maximum number of POLY_GT3 primitives
// Display and draw environments, double buffered
DISPENV disp[2];
DRAWENV draw[2];
u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives)
char primbuff[2][PRIMBUFFLEN]; // Primitive list // That's our prim buffer
char * nextpri = primbuff[0]; // Primitive counter
short db = 0; // Current buffer counter
long t, p, OTz, Flag; // t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143
// Lighting
// See PsyQ's LibOver47.pdf, p.133 for more details on the purpose of each component and full calculations.
// Far color : This is the color used to fade to when the mesh is far from the cam (NearFog)
CVECTOR BGc = {150, 50, 75, 0};
// Back color
VECTOR BKc = {128, 128, 128, 0};
// Light rotation angle
SVECTOR lgtang = {0, 0, 0};
// These will be used to store the light rotation matrix, cube rotation matrix, and composite light matrix.
MATRIX rotlgt, rotcube, light;
// Local Light Matrix : Direction and reach of each light source.
// Each light points in the direction aligned with the axis, hence direction is in the same coordinate system as the PSX (see l.23-30 of this file)
// Negative/positive value denotes light direction on corresponding axis
// -4096 > Value < 4096 denotes reach/intensity of light source
MATRIX lgtmat = {
// X Y Z
-ONE, -ONE, ONE, // Lightsource 1 : here, the light source is at the Bottom-Left of the screen, and points into the screen.
0, 0, 0, // Lightsource 2
0, 0, 0, // Lightsource 3
};
// Local Color Matrix
// Set color of each light source (L)
// Value range : 0 > x < 4096
MATRIX cmat = {
// L1 L2 L3
4096, 0, 0, // R
4096, 0, 0, // G
4096, 0, 0 // B
};
// Prototypes
void init(void);
void display(void);
void init(){
// Reset the GPU before doing anything and the controller
PadInit(0);
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY); // x, y offset
SetGeomScreen(CENTERX); // Distance between eye and screen
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1);
// Set light env
// Set far color
SetFarColor( BGc.r, BGc.g, BGc.b );
// Set Ambient color
SetBackColor( BKc.vx, BKc.vy, BKc.vz );
// Set Color matrix
SetColorMatrix(&cmat);
// Set Fog settings
SetFogNearFar( 1200, 2200, SCREENXRES );
setRGB0(&draw[0], 0, 0, 255);
setRGB0(&draw[1], 0, 0, 255);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Init font system
FntLoad(960, 0);
FntOpen(16, 16, 196, 64, 0, 256);
}
void display(void){
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
int main() {
int i;
int PadStatus;
int TPressed=0;
int AutoRotate=1;
// Rotating cube
POLY_G3 * poly;
SVECTOR Rotate={ ONE/6,ONE/6,ONE/6 }; // Rotation coordinates
VECTOR Trans={ -SCREENXRES/2, 0, CENTERX * 3, 0 }; // Translation coordinates
VECTOR Scale={ ONE/2, ONE/2, ONE/2, 0 }; // Scaling coordinates : ONE == 4096
MATRIX Matrix={0}; // Matrix data for the GTE
// Static cube
POLY_G3 * poly1; // pointer to a POLY_G4
SVECTOR Rotate1={ ONE/6, ONE/6, ONE/6, 0 }; // Rotation coordinates
VECTOR Trans1={ SCREENXRES/2, 0, CENTERX * 3, 0 }; // Translation coordinates
VECTOR Scale1={ ONE/2, ONE/2, ONE/2, 0 }; // Scaling coordinates : ONE == 4096
MATRIX Matrix1={0}; // Matrix data for the GTE
init();
// Main loop
while (1) {
// Read pad status
PadStatus = PadRead(0);
if (AutoRotate == 0) {
if (PadStatus & PADL1) Trans.vz -= 4;
if (PadStatus & PADR1) Trans.vz += 4;
if (PadStatus & PADL2) Rotate.vz -= 8;
if (PadStatus & PADR2) Rotate.vz += 8;
if (PadStatus & PADLup) Rotate.vx -= 8;
if (PadStatus & PADLdown) Rotate.vx += 8;
if (PadStatus & PADLleft) Rotate.vy -= 8;
if (PadStatus & PADLright) Rotate.vy += 8;
if (PadStatus & PADRup) Trans.vy -= 2;
if (PadStatus & PADRdown) Trans.vy += 2;
if (PadStatus & PADRleft) Trans.vx -= 2;
if (PadStatus & PADRright) Trans.vx += 2;
}
if (PadStatus & PADstart) {
if (TPressed == 0) {
AutoRotate = (AutoRotate + 1) & 1;
Rotate.vy = Rotate.vx = Rotate.vz = ONE/6;
Scale.vx = Scale.vy = Scale.vz = ONE/2;
Trans.vx = -SCREENXRES/2;
Trans.vy = 0;
Trans.vz = CENTERX * 3;
}
TPressed = 1;
} else {
TPressed = 0;
}
if (AutoRotate) {
Rotate.vy += 8; // Pan
Rotate.vx += 8; // Tilt
//~ Rotate.vz += 8; // Roll
}
// Clear the current OT
ClearOTagR(ot[db], OTLEN);
// Render the sample vector model
t=0;
// modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
for (i = 0; i < (modelCube.len*3); i += 3) {
poly = (POLY_G3 *)nextpri;
// Initialize the primitive and set its color values
SetPolyG3(poly);
// Rotate, translate, and project the vectors and output the results into a primitive
// Could be replaced with one call with RotTransPers3()
OTz = RotTransPers(&modelCube_mesh[modelCube_index[t]] , (long*)&poly->x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+2]], (long*)&poly->x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+1]], (long*)&poly->x2, &p, &Flag);
// Find light color
// Work color vectors
CVECTOR outCol, outCol1, outCol2 = { 0,0,0,0 };
// Find local color from three normal vectors and perform depth cueing.
// Could be replaced with one call with NormalColorDpq3()
NormalColorDpq(&modelCube.n[ modelCube_index[t+0] ], &modelCube.c[i+0], p, &outCol);
NormalColorDpq(&modelCube.n[ modelCube_index[t+2] ], &modelCube.c[i+2], p, &outCol1);
NormalColorDpq(&modelCube.n[ modelCube_index[t+1] ], &modelCube.c[i+1], p, &outCol2);
// Set vertex colors
setRGB0(poly, outCol.r, outCol.g , outCol.b);
setRGB1(poly, outCol1.r, outCol1.g, outCol1.b);
setRGB2(poly, outCol2.r, outCol2.g, outCol2.b);
// Sort the primitive into the OT
OTz /= 3;
if ((OTz > 0) && (OTz < OTLEN))
AddPrim(&ot[db][OTz-2], poly);
nextpri += sizeof(POLY_G3);
t+=3;
}
// Find and apply light rotation matrix
// Find rotmat from light angles
RotMatrix_gte(&lgtang, &rotlgt);
// Find rotmat from cube angles
RotMatrix_gte(&Rotate, &rotcube);
// RotMatrix cube * RotMatrix light
MulMatrix0(&rotcube, &rotlgt, &rotlgt);
// Light Matrix * RotMatrix light
MulMatrix0(&lgtmat, &rotlgt, &light);
// Set new light matrix
SetLightMatrix(&light);
// Convert and set the matrices
// Find Rotation matrix from object's angles
RotMatrix(&Rotate, &Matrix);
// Find Scale matrix from object's angles
ScaleMatrix(&Matrix, &Scale);
// Find Translation matrix from object's angles
TransMatrix(&Matrix, &Trans);
// Set GTE's rotation matrix
SetRotMatrix(&Matrix);
// Set GTE's Translation matrix
SetTransMatrix(&Matrix);
// Draw static cube
t=0;
for (i = 0; i < (modelCube1.len*3); i += 3) {
poly1 = (POLY_G3 *)nextpri;
SetPolyG3(poly1);
OTz = RotTransPers(&modelCube1_mesh[modelCube1_index[t]] , (long*)&poly1->x0, &p, &Flag);
OTz += RotTransPers(&modelCube1_mesh[modelCube1_index[t+2]], (long*)&poly1->x1, &p, &Flag);
OTz += RotTransPers(&modelCube1_mesh[modelCube1_index[t+1]], (long*)&poly1->x2, &p, &Flag);
CVECTOR outCol = { 0,0,0,0 };
CVECTOR outCol1 = { 0,0,0,0 };
CVECTOR outCol2 = { 0,0,0,0 };
NormalColorDpq(&modelCube1.n[ modelCube1_index[t+0] ], &modelCube1.c[i+0], p, &outCol);
NormalColorDpq(&modelCube1.n[ modelCube1_index[t+2] ], &modelCube1.c[i+2], p, &outCol1);
NormalColorDpq(&modelCube1.n[ modelCube1_index[t+1] ], &modelCube1.c[i+1], p, &outCol2);
setRGB0(poly1, outCol.r, outCol.g , outCol.b);
setRGB1(poly1, outCol1.r, outCol1.g, outCol1.b);
setRGB2(poly1, outCol2.r, outCol2.g, outCol2.b);
OTz /= 3;
if ((OTz > 0) && (OTz < OTLEN))
AddPrim(&ot[db][OTz-2], poly1);
nextpri += sizeof(POLY_G3);
t+=3;
}
// See l.216
RotMatrix_gte(&lgtang, &rotlgt);
RotMatrix_gte(&Rotate1, &rotcube);
MulMatrix0(&rotcube, &rotlgt, &rotlgt);
MulMatrix0(&lgtmat, &rotlgt, &light);
SetLightMatrix(&light);
// See l.227
RotMatrix(&Rotate1, &Matrix1);
ScaleMatrix(&Matrix1, &Scale1);
TransMatrix(&Matrix1, &Trans1);
SetRotMatrix(&Matrix1);
SetTransMatrix(&Matrix1);
FntPrint("Hello lightsources !\n");
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_mod/Makefile
================================================
TARGET = hello_mod
SRCS = hello_mod.c \
src/mod.c \
../thirdparty/nugget/modplayer/modplayer.c \
HIT/STAR.HIT \
include ../common.mk
================================================
FILE: hello_mod/README.md
================================================
This is an example of how to use [@nicolasnoble](https://github.com/nicolasnoble/)'s [modplayer](https://github.com/grumpycoders/pcsx-redux/tree/main/src/mips/modplayer) port in conjunction with the psyq libs.
See the **wiki** for more details on MOD usage : [https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/MOD](https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/MOD).
## Credits & thanks
Many thanks to @nicolasnobe for his work and help on getting this example working.
MOD : stardust memories by Jester : https://modarchive.org/index.php?request=view_by_moduleid&query=59344
================================================
FILE: hello_mod/hello_mod.c
================================================
// Play a MOD file converted to HIT
// MOD Wiki page : https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/MOD
#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
// Mod playback
#include "src/mod.h"
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320 // Screen width
#define SCREENYRES 240 // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256
#define CENTERX SCREENXRES/2 // Center of screen on x
#define CENTERY SCREENYRES/2 // Center of screen on y
#define FONTX 960
#define FONTY 0
#define OTLEN 8
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
short db = 1; // index of which buffer is used, values 0, 1
// Font color
CVECTOR fntColor = { 128, 255, 0 };
CVECTOR fntColorBG = { 0, 0, 0 };
// MOD Playback
#define MAXVOLUME 65536
#define INCVOLUME 256
// State
enum PLAYBACK {
STOP = 0,
PLAY = 1,
PAUSE = 2,
};
// Music volume should range from 0 to 65536
u_int musicVolume = 2048;
enum PLAYBACK state = PLAY;
void init(void);
void FntColor(CVECTOR fgcol, CVECTOR bgcol );
void display(void);
void drawBG(void);
void checkPad(void);
void FntColor(CVECTOR fgcol, CVECTOR bgcol )
{
// The debug font clut is at tx, ty + 128
// tx = bg color
// tx + 1 = fg color
// We can override the color by drawing a rect at these coordinates
//
RECT fg = { FONTX+1, FONTY + 128, 1, 1 };
RECT bg = { FONTX, FONTY + 128, 1, 1 };
ClearImage(&fg, fgcol.r, fgcol.g, fgcol.b);
ClearImage(&bg, bgcol.r, bgcol.g, bgcol.b);
}
void init(void)
{
ResetCallback();
ResetGraph(0); // Initialize drawing engine with a complete reset (0)
InitGeom();
SetGeomOffset(CENTERX,CENTERY);
SetGeomScreen(CENTERX);
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); // Set display area for both &disp[0] and &disp[1]
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES); // &disp[0] is on top of &disp[1]
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES); // Set draw for both &draw[0] and &draw[1]
SetDefDrawEnv(&draw[1], 0, 0 , SCREENXRES, SCREENYRES); // &draw[0] is below &draw[1]
// Set video mode
#if VMODE
SetVideoMode(MODE_PAL);
disp[0].disp.y = 8;
disp[1].disp.y = 8;
#endif
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 40, 40, 40); // set color for first draw area
setRGB0(&draw[1], 40, 40, 40); // set color for second draw area
draw[0].isbg = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 1;
PutDispEnv(&disp[db]); // set the disp and draw environnments
PutDrawEnv(&draw[db]);
FntLoad(FONTX, FONTY); // Load font to vram at 960,0(+128)
FntOpen(16, 60, 288, 260, 0, 256 ); // FntOpen(x, y, width, height, black_bg, max. nbr. chars
FntColor(fntColor, fntColorBG);
}
void display(void)
{
DrawSync(0); // Wait for all drawing to terminate
VSync(0); // Wait for the next vertical blank
PutDispEnv(&disp[db]); // set alternate disp and draw environnments
PutDrawEnv(&draw[db]);
db = !db;
}
void checkPad(void)
{
u_short pad = 0;
static u_short oldPad;
pad = PadRead(0);
// Up
if ( pad & PADLup && !(oldPad & PADLup) )
{
MOD_PlaySoundEffect(11, 25, 15, 63);
oldPad = pad;
}
if ( !(pad & PADLup) && oldPad & PADLup )
{
oldPad = pad;
}
// Down
if ( pad & PADLdown && !(oldPad & PADLdown) )
{
MOD_PlaySoundEffect(12, 26, 15, 63);
oldPad = pad;
}
if ( !(pad & PADLdown) && oldPad & PADLdown )
{
oldPad = pad;
}
// Left
if ( pad & PADLleft && !(oldPad & PADLleft) )
{
MOD_PlaySoundEffect(13, 27, 15, 63);
oldPad = pad;
}
if ( !(pad & PADLleft) && oldPad & PADLleft )
{
oldPad = pad;
}
// Right
if ( pad & PADLright && !(oldPad & PADLright) )
{
// Channel 1 is transition anim, only take input when !transition
MOD_PlaySoundEffect(6, 21, 15, 63);
oldPad = pad;
}
if ( !(pad & PADLright) && oldPad & PADLright )
{
oldPad = pad;
}
// Cross button
if ( pad & PADRdown && !(oldPad & PADRdown) )
{
// Select sound
MOD_PlaySoundEffect(7, 22, 15, 63);
oldPad = pad;
}
if ( !(pad & PADRdown) && oldPad & PADRdown )
{
oldPad = pad;
}
// Square button
if ( pad & PADRleft && !(oldPad & PADRleft) )
{
// Select sound
MOD_PlaySoundEffect(8, 23, 15, 63);
oldPad = pad;
}
if ( !(pad & PADRleft) && oldPad & PADRleft )
{
oldPad = pad;
}
// Circle button
if ( pad & PADRright && !(oldPad & PADRright) )
{
// Select sound
MOD_PlaySoundEffect(9, 28, 15, 63);
oldPad = pad;
}
if ( !(pad & PADRright) && oldPad & PADRright )
{
oldPad = pad;
}
// Circle button
if ( pad & PADRup && !(oldPad & PADRup) )
{
// Select sound
MOD_PlaySoundEffect(9, 24, 15, 63);
oldPad = pad;
}
if ( !(pad & PADRup) && oldPad & PADRup )
{
oldPad = pad;
}
// Select button : Stop mod / Play back from the start
if ( pad & PADselect && !(oldPad & PADselect) )
{
if ( state == PLAY ) { stopMusic(); state = STOP; }
else if ( state == STOP ) { loadMod(); startMusic(); state = PLAY; }
oldPad = pad;
}
if ( !(pad & PADselect) && oldPad & PADselect )
{
oldPad = pad;
}
// Start button : Toggle playback pause
if ( pad & PADstart && !(oldPad & PADstart) )
{
if ( state == PLAY ) { pauseMusic(); state = PAUSE; }
else if ( state == PAUSE ) { resumeMusic(); state = PLAY; }
oldPad = pad;
}
if ( !(pad & PADstart) && oldPad & PADstart )
{
oldPad = pad;
}
// R1/R2 : change music volume
if ( pad & PADR1 && !(oldPad & PADR1) )
{
if(musicVolume < MAXVOLUME) {
musicVolume += INCVOLUME;
}
MOD_SetMusicVolume(musicVolume);
oldPad = pad;
}
if ( !(pad & PADR1) && oldPad & PADR1 )
{
oldPad = pad;
}
if ( pad & PADR2 && !(oldPad & PADR2) )
{
if(musicVolume > 0) {
musicVolume -= INCVOLUME;
}
MOD_SetMusicVolume(musicVolume);
oldPad = pad;
}
if ( !(pad & PADR2) && oldPad & PADR2 )
{
oldPad = pad;
}
}
int main() {
u_int t = 0;
init();
PadInit(0);
VSyncCallback(checkPad);
// Mod Playback
loadMod();
startMusic();
MOD_SetMusicVolume(musicVolume);
// Main loop
while (1)
{
// Timer
t++;
// Print stuff
FntPrint("Hello mod ! %d\nUse the pad's buttons to\nplay sound effects.\n", t);
FntPrint("State: %d, music volume : %d\n", state, musicVolume);
FntPrint("Start : play/pause music.\n");
FntPrint("select : stop/play music.\n");
FntPrint("R1/R2 : Change music volume.\n");
FntFlush(-1);
display();
}
return 0;
}
================================================
FILE: hello_mod/src/mod.c
================================================
#include "mod.h"
long musicEvent;
typedef struct SpuVoiceVolume {
short volL, volR;
} SpuVoiceVolume;
SpuVoiceVolume volumeState[24] = {0};
static void muteSPUvoices() {
for (unsigned i = 0; i < 24; i++) {
// Store current volume
SpuGetVoiceVolume(i, &(volumeState[i].volL), &(volumeState[i].volR) );
// Mute
SpuSetVoiceVolume(i, 0, 0);
}
}
static void restoreSPUvoices() {
for (unsigned i = 0; i < 24; i++) {
// Restore volume
SpuSetVoiceVolume(i, volumeState[i].volL, volumeState[i].volR );
}
}
// Playing a sound effect (aka mod note): https://discord.com/channels/642647820683444236/642848592754901033/898249196174458900
// Code by NicolasNoble : https://discord.com/channels/642647820683444236/663664210525290507/902624952715452436
void loadMod() {
printf("Loading MOD:\'%s\'\n", HITFILE);
MOD_Load((struct MODFileFormat*)HITFILE);
printf("%02d Channels, %02d Orders\n", MOD_Channels, MOD_SongLength);
}
static long processMusic() {
uint32_t old_hb
gitextract_v4hb7egi/
├── .github/
│ └── workflows/
│ ├── Linux-build-archive.yml
│ ├── linux-build.yml
│ ├── macos-build.yml
│ └── windows-build.yml
├── .gitmodules
├── LICENSE
├── Makefile
├── README.md
├── TIM/
│ ├── README.md
│ ├── TIM16.tim
│ ├── TIM4.tim
│ ├── TIM8.tim
│ ├── bousai.tim
│ └── cubetex.tim
├── VAG/
│ ├── 0_come.vag
│ ├── 1_cuek.vag
│ ├── 2_erro.vag
│ ├── 3_hehe.vag
│ ├── 4_m4a1.vag
│ ├── 5_punc.vag
│ ├── 7_wron.vag
│ ├── 8_yooo.vag
│ ├── README.md
│ ├── hello.vag
│ ├── hello_poly.vag
│ └── poly.vag
├── common.mk
├── hello_2pads/
│ ├── Makefile
│ └── hello_2pads.c
├── hello_bs/
│ ├── Makefile
│ ├── README.md
│ ├── bs/
│ │ ├── bace.bs
│ │ ├── bace.rgb
│ │ ├── bace.tim
│ │ └── bace.yuv
│ ├── hello_bs.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_cd/
│ ├── Makefile
│ ├── README.md
│ ├── hello_cd.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_cdda/
│ ├── Makefile
│ ├── README.md
│ ├── hello_cdda.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_cube/
│ ├── Makefile
│ ├── cube.c
│ └── hello_cube.c
├── hello_cubetex/
│ ├── Makefile
│ ├── cubetex.c
│ └── hello_cubetex.c
├── hello_cubetex_stp/
│ ├── Makefile
│ ├── README.md
│ ├── TIM/
│ │ ├── stpOn8bpp.tim
│ │ ├── stpOnBlack.tim
│ │ └── stpOnNonBlack.tim
│ ├── cubetex.c
│ └── hello_cubetex_stp.c
├── hello_font/
│ ├── Makefile
│ ├── README.md
│ ├── fnt.tim
│ └── hello_font.c
├── hello_fx/
│ ├── Makefile
│ ├── TIM/
│ │ ├── bg.tim
│ │ ├── cube.tim
│ │ └── sky.tim
│ ├── cubetex.c
│ └── hello_fx.c
├── hello_gte_opti/
│ ├── Makefile
│ └── hello_gte_opti.c
├── hello_light/
│ ├── Makefile
│ ├── cube.c
│ └── hello_light.c
├── hello_mod/
│ ├── HIT/
│ │ ├── STAR.HIT
│ │ └── STAR.mod
│ ├── Makefile
│ ├── README.md
│ ├── hello_mod.c
│ └── src/
│ ├── mod.c
│ └── mod.h
├── hello_multi_vag/
│ ├── Makefile
│ ├── README.md
│ └── hello_multi_vag.c
├── hello_multi_xa/
│ ├── Makefile
│ ├── README.md
│ ├── hello_multi_xa.c
│ ├── isoconfig.xml
│ ├── system.cnf
│ └── xa/
│ ├── 5_come.xa
│ ├── 5_erro.xa
│ ├── 5_sile_h.xa
│ ├── 6_cuek.xa
│ ├── 6_hehe.xa
│ ├── 6_sile_h.xa
│ ├── 6_wron.xa
│ ├── 7_m4a1.xa
│ ├── 7_punch.xa
│ ├── 7_sile_h.xa
│ ├── 8_yooo.xa
│ ├── channel5.xa
│ ├── channel6.xa
│ ├── channel7.xa
│ ├── channel8.xa
│ ├── interleave8.txt
│ └── vert8.xa
├── hello_ovl_exec/
│ ├── Makefile
│ ├── README.md
│ ├── common.h
│ ├── hello_ovl_exec.c
│ ├── hello_ovl_world/
│ │ ├── Makefile
│ │ ├── hello_ovl_world.c
│ │ └── hello_world.c
│ ├── hello_poly/
│ │ ├── Makefile
│ │ ├── hello_ovl_poly.c
│ │ └── hello_poly.c
│ ├── hello_tile/
│ │ ├── Makefile
│ │ ├── hello_ovl_tile.c
│ │ └── hello_tile.c
│ ├── isoconfig.xml
│ ├── overlay.ld
│ └── system.cnf
├── hello_pad/
│ ├── Makefile
│ └── hello_pad.c
├── hello_poly/
│ ├── Makefile
│ └── hello_poly.c
├── hello_poly_ft/
│ ├── Makefile
│ └── hello_poly_ft.c
├── hello_poly_fun/
│ ├── Makefile
│ └── hello_poly_fun.c
├── hello_poly_gt/
│ ├── Makefile
│ └── hello_poly_gt.c
├── hello_poly_gt_tw/
│ ├── Makefile
│ └── hello_poly_gt_tw.c
├── hello_poly_inline/
│ ├── Makefile
│ └── hello_poly_inline.c
├── hello_poly_stp/
│ ├── Makefile
│ ├── README.md
│ ├── TIM/
│ │ ├── stpOnAlpha.tim
│ │ ├── stpOnAlphaI.tim
│ │ ├── stpOnBlack.tim
│ │ ├── stpOnCol.tim
│ │ ├── stpOnColIndex.tim
│ │ └── stpOnNonBlack.tim
│ └── hello_poly_stp.c
├── hello_sio/
│ ├── Makefile
│ └── hello_sio.c
├── hello_sprt/
│ ├── Makefile
│ └── hello_sprt.c
├── hello_spu_readback/
│ ├── Makefile
│ ├── README.md
│ ├── hello_spu_readback.c
│ ├── isoconfig.xml
│ └── system.cnf
├── hello_str/
│ ├── Makefile
│ ├── README.md
│ ├── hello_str.c
│ ├── isoconfig.xml
│ ├── str/
│ │ └── copyings.str
│ └── system.cnf
├── hello_strplay/
│ ├── Makefile
│ ├── README.md
│ ├── hello_strplay.c
│ ├── isoconfig.xml
│ ├── str/
│ │ └── copyings.str
│ ├── strplay.c
│ └── system.cnf
├── hello_tile/
│ ├── Makefile
│ └── hello_tile.c
├── hello_vag/
│ ├── Makefile
│ ├── README.md
│ └── hello_vag.c
├── hello_world/
│ ├── Makefile
│ └── hello_world.c
├── hello_xa/
│ ├── Makefile
│ ├── README.md
│ ├── hello_xa.c
│ ├── isoconfig.xml
│ ├── system.cnf
│ └── xa/
│ ├── inter4.xa
│ ├── inter8.xa
│ ├── interleave4.txt
│ └── interleave8.txt
└── includes/
└── CPUMAC.H
SYMBOL INDEX (198 symbols across 43 files)
FILE: hello_2pads/hello_2pads.c
type Gun_Position (line 32) | typedef struct
type Controller_Data (line 38) | typedef struct
type Controller_Buffer (line 52) | typedef struct
function init (line 58) | void init(void)
function display (line 81) | void display(void)
function get_digital_direction (line 91) | void get_digital_direction( Controller_Data *c, int buttondata ) // get ...
function read_controller (line 104) | void read_controller( Controller_Data *c, unsigned char *buf, int port )...
function main (line 150) | int main(void)
FILE: hello_bs/hello_bs.c
function init (line 60) | void init(void)
function display (line 79) | void display(void)
function main (line 87) | int main(void)
FILE: hello_cd/hello_cd.c
function init (line 50) | void init(void)
function display (line 69) | void display(void)
function main (line 77) | int main(void)
FILE: hello_cdda/hello_cdda.c
function init (line 31) | void init(void)
function display (line 50) | void display(void)
function main (line 58) | int main(void)
FILE: hello_cube/hello_cube.c
function init (line 38) | void init(){
function display (line 68) | void display(void){
function main (line 77) | int main() {
FILE: hello_cubetex/hello_cubetex.c
function init (line 59) | void init(){
function display (line 100) | void display(void){
function LoadTexture (line 117) | void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is ...
function main (line 131) | int main() {
FILE: hello_cubetex_stp/cubetex.c
type RGB_PIX (line 128) | typedef struct RGB_PIX {
type PIXEL (line 133) | typedef struct PIXEL {
type CLUT (line 140) | typedef struct CLUT {
type TIM_FILE_CLUT (line 147) | typedef struct TIM_FILE_CLUT{
type TIM_FILE (line 154) | typedef struct TIM_FILE{
FILE: hello_cubetex_stp/hello_cubetex_stp.c
function init (line 39) | void init(){
function display (line 69) | void display(void){
function LoadTexture (line 78) | void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam){ // This part i...
function main (line 88) | int main() {
FILE: hello_font/hello_font.c
function LoadTexture (line 31) | void LoadTexture(u_long * tim, TIM_IMAGE * tparam){
function FntColor (line 42) | void FntColor(CVECTOR fgcol, CVECTOR bgcol )
function init (line 57) | void init(void)
function display (line 81) | void display(void)
function main (line 89) | int main(void)
FILE: hello_fx/cubetex.c
type RGB_PIX (line 128) | typedef struct RGB_PIX {
type PIXEL (line 133) | typedef struct PIXEL {
type CLUT (line 140) | typedef struct CLUT {
type TIM_FILE_CLUT (line 147) | typedef struct TIM_FILE_CLUT{
type TIM_FILE (line 154) | typedef struct TIM_FILE{
FILE: hello_fx/hello_fx.c
function init (line 70) | void init(){
function display (line 108) | void display(void){
function LoadTexture (line 117) | void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam){ // This part i...
function main (line 127) | int main() {
FILE: hello_gte_opti/hello_gte_opti.c
function init (line 51) | void init(void)
function display (line 78) | void display(void)
function main (line 94) | int main(void)
FILE: hello_light/hello_light.c
function init (line 68) | void init(){
function display (line 107) | void display(void){
function main (line 116) | int main() {
FILE: hello_mod/hello_mod.c
type PLAYBACK (line 32) | enum PLAYBACK {
type PLAYBACK (line 40) | enum PLAYBACK
function FntColor (line 48) | void FntColor(CVECTOR fgcol, CVECTOR bgcol )
function init (line 61) | void init(void)
function display (line 89) | void display(void)
function checkPad (line 98) | void checkPad(void)
function main (line 238) | int main() {
FILE: hello_mod/src/mod.c
type SpuVoiceVolume (line 4) | typedef struct SpuVoiceVolume {
function muteSPUvoices (line 10) | static void muteSPUvoices() {
function restoreSPUvoices (line 19) | static void restoreSPUvoices() {
function loadMod (line 27) | void loadMod() {
function processMusic (line 33) | static long processMusic() {
function startMusic (line 41) | void startMusic() {
function pauseMusic (line 50) | void pauseMusic() {
function resumeMusic (line 55) | void resumeMusic() {
function stopMusic (line 60) | void stopMusic() {
FILE: hello_multi_vag/hello_multi_vag.c
type VAGsound (line 40) | typedef struct VAGsound {
type VAGhdr (line 46) | typedef struct VAGhdr { // All the values in this header ...
function initGraph (line 96) | void initGraph(void)
function display (line 119) | void display(void)
function initSnd (line 128) | void initSnd(void){
function u_long (line 137) | u_long sendVAGtoSPU(unsigned int VAG_data_size, u_char *VAG_data){
function setVoiceAttr (line 144) | void setVoiceAttr(unsigned int pitch, long channel, unsigned long soundA...
function u_long (line 175) | u_long setSPUtransfer(VAGsound * sound){
function playSFX (line 192) | void playSFX(VAGsound * sound){
function main (line 203) | int main(void)
FILE: hello_multi_xa/hello_multi_xa.c
type XAsound (line 44) | typedef struct XAsound {
type XAbank (line 54) | typedef struct XAbank {
function init (line 88) | void init(void)
function display (line 107) | void display(void)
function spuSetup (line 116) | void spuSetup(SpuCommonAttr * spuSettings)
function XAsetup (line 134) | void XAsetup()
function main (line 147) | int main(void)
FILE: hello_ovl_exec/common.h
type OverlayNumber (line 38) | enum OverlayNumber {
type OverlayNumber (line 44) | enum OverlayNumber
FILE: hello_ovl_exec/hello_ovl_exec.c
type Overlay (line 17) | typedef struct Overlay {
type OverlayNumber (line 34) | enum OverlayNumber
type OverlayNumber (line 35) | enum OverlayNumber
function init (line 49) | void init(void)
function display (line 74) | void display(void)
function clearVRAM (line 87) | void clearVRAM(void)
function preInitOvl (line 92) | void preInitOvl(Overlay * overlay)
function postInitOvl (line 101) | void postInitOvl(Overlay * overlay)
function loadOverlayAndStart (line 113) | int loadOverlayAndStart(Overlay * overlay)
function EmptyPrimBuf (line 133) | void EmptyPrimBuf(char primbuff[2][32768], char ** nextpri)
function EmptyOTag (line 142) | void EmptyOTag(u_long ot[2][OTLEN])
function main (line 151) | int main(void)
FILE: hello_ovl_exec/hello_ovl_world/hello_ovl_world.c
function ovl_main_hello (line 3) | int ovl_main_hello(void)
FILE: hello_ovl_exec/hello_ovl_world/hello_world.c
function init (line 12) | void init(void)
function display (line 35) | void display(void)
function main (line 48) | int main(void)
FILE: hello_ovl_exec/hello_poly/hello_ovl_poly.c
function ovl_main_poly (line 4) | int ovl_main_poly(void)
FILE: hello_ovl_exec/hello_poly/hello_poly.c
function init (line 11) | void init(void)
function display (line 42) | void display(void)
function main (line 55) | int main(void)
FILE: hello_ovl_exec/hello_tile/hello_ovl_tile.c
function ovl_main_tile (line 3) | int ovl_main_tile(void)
FILE: hello_ovl_exec/hello_tile/hello_tile.c
function init (line 11) | void init(void)
function display (line 34) | void display(void)
function main (line 49) | int main(void)
FILE: hello_pad/hello_pad.c
function init (line 26) | void init(void)
function display (line 49) | void display(void)
function main (line 59) | int main(void)
FILE: hello_poly/hello_poly.c
function init (line 28) | void init(void)
function display (line 53) | void display(void)
function main (line 63) | int main(void)
FILE: hello_poly_ft/hello_poly_ft.c
function LoadTexture (line 46) | void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is ...
function init (line 59) | void init(void)
function display (line 97) | void display(void)
function main (line 113) | int main(void)
FILE: hello_poly_fun/hello_poly_fun.c
type polygon (line 28) | struct polygon
function init (line 45) | void init(void)
function display (line 73) | void display(void)
function pivotPoint (line 83) | void pivotPoint(SVECTOR VertPos[3],short width,short height, SVECTOR piv...
function main (line 98) | int main(void)
FILE: hello_poly_gt/hello_poly_gt.c
function LoadTexture (line 32) | void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is ...
function init (line 42) | void init(void)
function display (line 69) | void display(void)
function main (line 79) | int main(void)
FILE: hello_poly_gt_tw/hello_poly_gt_tw.c
function LoadTexture (line 32) | void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is ...
function init (line 42) | void init(void)
function display (line 69) | void display(void)
function main (line 79) | int main(void)
FILE: hello_poly_inline/hello_poly_inline.c
function init (line 41) | void init(void)
function display (line 69) | void display(void)
function main (line 85) | int main(void)
FILE: hello_poly_stp/hello_poly_stp.c
type RGB_PIX (line 29) | typedef struct RGB_PIX {
type PIXEL (line 35) | typedef struct PIXEL {
type CLUT (line 44) | typedef struct CLUT {
type TIM_FILE_CLUT (line 52) | typedef struct TIM_FILE_CLUT{
type TIM_FILE (line 61) | typedef struct TIM_FILE{
function LoadTexture (line 95) | void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam){ // This part i...
function init (line 105) | void init(void)
function display (line 132) | void display(void)
function main (line 142) | int main(void)
FILE: hello_sio/hello_sio.c
function init (line 42) | void init(){
function display (line 68) | void display(void){
function main (line 75) | int main() {
FILE: hello_sprt/hello_sprt.c
function LoadTexture (line 42) | void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is ...
function init (line 52) | void init(void)
function display (line 75) | void display(void)
function main (line 85) | int main(void)
FILE: hello_spu_readback/hello_spu_readback.c
function init (line 78) | void init(void)
function display (line 106) | void display(void)
function initPrimitives (line 117) | void initPrimitives(void)
function terminate (line 166) | void terminate(void)
function printDataInfo (line 199) | void printDataInfo(void)
function eachIRQ (line 209) | void eachIRQ (void)
function eachDMA (line 216) | void eachDMA (void)
function findSampleMaxVolume (line 228) | void findSampleMaxVolume(void)
function main (line 289) | int main(void)
FILE: hello_str/hello_str.c
function init (line 63) | void init(void)
function display (line 91) | void display(void)
function main (line 100) | int main() {
function strCheckRGB24 (line 235) | static void strCheckRGB24() {
FILE: hello_strplay/hello_strplay.c
function init (line 40) | void init(void)
function display (line 68) | void display(void)
function main (line 77) | void main() {
function strCheckRGB24 (line 93) | static void strCheckRGB24() {
FILE: hello_strplay/strplay.c
type STRFILE (line 65) | typedef struct {
type STRENV (line 73) | typedef struct {
function PlayStr (line 106) | int PlayStr(int xres, int yres, int xpos, int ypos, STRFILE *str) {
function strDoPlayback (line 132) | static void strDoPlayback(STRFILE *str) {
function strCallback (line 239) | static void strCallback() {
function strNextVlc (line 289) | static void strNextVlc(STRENV *strEnv) {
function u_long (line 317) | static u_long *strNext(STRENV *strEnv) {
function strSync (line 362) | static void strSync(STRENV *strEnv, int mode) {
function strKickCD (line 387) | static void strKickCD(CdlLOC *loc) {
FILE: hello_tile/hello_tile.c
function init (line 24) | void init(void)
function display (line 47) | void display(void)
function main (line 60) | int main(void)
FILE: hello_vag/hello_vag.c
type VAGhdr (line 46) | typedef struct VAGheader{ // All the values in this header must be...
function initGraph (line 76) | void initGraph(void)
function display (line 99) | void display(void)
function initSnd (line 108) | void initSnd(void){
function u_long (line 116) | u_long sendVAGtoRAM(unsigned int VAG_data_size, unsigned char *VAG_data){
function setVoiceAttr (line 123) | void setVoiceAttr(unsigned int pitch, long channel, unsigned long soundA...
function playSFX (line 154) | void playSFX(void){
function main (line 157) | int main(void)
FILE: hello_world/hello_world.c
function init (line 20) | void init(void)
function display (line 43) | void display(void)
function main (line 51) | int main(void)
FILE: hello_xa/hello_xa.c
type XA_TRACK (line 36) | typedef struct {
function init (line 54) | void init(void)
function display (line 73) | void display(void)
function main (line 82) | int main(void)
Condensed preview — 186 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (449K chars).
[
{
"path": ".github/workflows/Linux-build-archive.yml",
"chars": 1438,
"preview": "name: Linux archive build\n\non:\n push:\n branches: [ main ]\n\njobs:\n build:\n\n runs-on: ubuntu-latest\n\n steps:\n "
},
{
"path": ".github/workflows/linux-build.yml",
"chars": 1302,
"preview": "name: Linux build\n\non:\n push:\n branches: [ main ]\n\njobs:\n build:\n\n runs-on: ubuntu-latest\n\n steps:\n - uses"
},
{
"path": ".github/workflows/macos-build.yml",
"chars": 2665,
"preview": "name: macOS build\n\non:\n push:\n branches: [ main ]\n\njobs:\n build:\n runs-on: macOS-latest\n\n steps:\n - uses"
},
{
"path": ".github/workflows/windows-build.yml",
"chars": 1076,
"preview": "name: Windows build\non:\n push:\n branches: [ main ]\n\njobs:\n build:\n\n runs-on: windows-latest\n\n steps:\n - us"
},
{
"path": ".gitmodules",
"chars": 106,
"preview": "[submodule \"thirdparty/nugget\"]\n\tpath = thirdparty/nugget\n\turl = https://github.com/pcsx-redux/nugget.git\n"
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "Makefile",
"chars": 3537,
"preview": "hello_2pads:\n\t$(MAKE) -C hello_2pads\nhello_bs:\n\t$(MAKE) -C hello_bs\nhello_cd:\n\t$(MAKE) -C hello_cd\nhello_cdda:\n\t$(MAKE) "
},
{
"path": "README.md",
"chars": 5600,
"preview": "# Nolibgs Hello Worlds !\n\n<p align=\"center\">\n\n<img height=\"240px\" src=\"http://wiki.arthus.net/assets/cube.gif\" alt=\"3D p"
},
{
"path": "TIM/README.md",
"chars": 132,
"preview": "See here for more informations about the TIM fileformat and tools : \n\nhttps://github.com/ABelliqueux/nolibgs_hello_worl"
},
{
"path": "VAG/README.md",
"chars": 132,
"preview": "See here for more informations about the VAG fileformat and tools : \n\nhttps://github.com/ABelliqueux/nolibgs_hello_worl"
},
{
"path": "common.mk",
"chars": 1557,
"preview": "# If you change this to exe, you'll have to rename the file ./thirdparty/nugget/ps-exe.ld too.\nTYPE = ps-exe\n\nTHISDIR :="
},
{
"path": "hello_2pads/Makefile",
"chars": 68,
"preview": "TARGET = hello_2pads\n\nSRCS = hello_2pads.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_2pads/hello_2pads.c",
"chars": 10861,
"preview": "// hello_libpad example\n//\n// We're using libpad this time.\n// You can use the classic controller, analog, wheel, gun bu"
},
{
"path": "hello_bs/Makefile",
"chars": 177,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_bs.cue hello_bs.bin\n\t\nTARGE"
},
{
"path": "hello_bs/README.md",
"chars": 2147,
"preview": "# Loading a BS still image\n\nYou need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX d"
},
{
"path": "hello_bs/hello_bs.c",
"chars": 6648,
"preview": "// Load a BS file from CD, decompress and display it.\n// Schnappy 07-2021\n#include <sys/types.h>\n#include <stdio.h>\n#inc"
},
{
"path": "hello_bs/isoconfig.xml",
"chars": 4396,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_bs/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_cd/Makefile",
"chars": 177,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_cd.cue hello_cd.bin\n\t\nTARGE"
},
{
"path": "hello_cd/README.md",
"chars": 491,
"preview": "## Loading a file from CD\n\nYou need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX d"
},
{
"path": "hello_cd/hello_cd.c",
"chars": 5387,
"preview": "// Load files from CD and execute them\n// Schnappy 07-2021\n#include <sys/types.h>\n#include <stdio.h>\n#include <libgte.h>"
},
{
"path": "hello_cd/isoconfig.xml",
"chars": 4395,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_cd/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_cdda/Makefile",
"chars": 184,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_cdda.cue hello_cdda.bin\n\nTA"
},
{
"path": "hello_cdda/README.md",
"chars": 1239,
"preview": "## Compiling\n\nYou need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image.\nTyp"
},
{
"path": "hello_cdda/hello_cdda.c",
"chars": 5261,
"preview": "// CDDA track playback example\n// Schnappy 07-2021\n#include <sys/types.h>\n#include <stdio.h>\n#include <stdint.h>\n#includ"
},
{
"path": "hello_cdda/isoconfig.xml",
"chars": 4786,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_cdda/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_cube/Makefile",
"chars": 66,
"preview": "TARGET = hello_cube\n\nSRCS = hello_cube.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_cube/cube.c",
"chars": 2731,
"preview": "SVECTOR modelCube_mesh[] = {\n { -128,128,128 },\n { 128,128,128 },\n { 128,128,-128 },\n { -128,128,-128 },\n "
},
{
"path": "hello_cube/hello_cube.c",
"chars": 7028,
"preview": "/* primdrawG.c, by Schnappy, 12-2020\r\n - Draw a gouraud shaded mesh exported as a TMESH by the blender <= 2.79b plug"
},
{
"path": "hello_cubetex/Makefile",
"chars": 93,
"preview": "TARGET = hello_cubetex\n\nSRCS = hello_cubetex.c \\\n../TIM/cubetex.tim \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_cubetex/cubetex.c",
"chars": 2207,
"preview": "SVECTOR modelCube_mesh[] = {\n {32,32,-32.0},\n {32,-32,-32},\n {-32,-32,-32},\n {-32,32,-32},\n {32,32,32},\n "
},
{
"path": "hello_cubetex/hello_cubetex.c",
"chars": 9851,
"preview": "/* primdrawG.c, by Schnappy, 12-2020\r\n \r\n - Draw a gouraud shaded textured mesh exported as a TMESH by the blende"
},
{
"path": "hello_cubetex_stp/Makefile",
"chars": 145,
"preview": "TARGET = hello_cubetex_stp\n\nSRCS = hello_cubetex_stp.c \\\nTIM/stpOnBlack.tim \\\nTIM/stpOnNonBlack.tim \\\nTIM/stpOn8bpp.tim "
},
{
"path": "hello_cubetex_stp/README.md",
"chars": 1070,
"preview": "\n\n# STP : Semi-Transparency usage\n\nThis example shows "
},
{
"path": "hello_cubetex_stp/cubetex.c",
"chars": 2709,
"preview": "SVECTOR modelCube_mesh[] = {\n {48,48,-48.0},\n {48,-48,-48},\n {-48,-48,-48},\n {-48,48,-48},\n {48,48,48},\n "
},
{
"path": "hello_cubetex_stp/hello_cubetex_stp.c",
"chars": 10326,
"preview": "// Demo the different settings and rates for pixel and primitive semi-transparency on a cube\r\n// Controls :\r\n// "
},
{
"path": "hello_font/Makefile",
"chars": 76,
"preview": "TARGET = hello_font\n\nSRCS = hello_font.c \\\nfnt.tim \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_font/README.md",
"chars": 164,
"preview": "See the **wiki** for more details : [https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/FONT](https://github.com/A"
},
{
"path": "hello_font/hello_font.c",
"chars": 5215,
"preview": "// Change the debug font face and colors !\n// Schnappy 2020\n#include <sys/types.h>\n#include <stdio.h>\n#include <libgte.h"
},
{
"path": "hello_fx/Makefile",
"chars": 104,
"preview": "TARGET = hello_fx\n\nSRCS = hello_fx.c \\\nTIM/cube.tim \\\nTIM/sky.tim \\\nTIM/bg.tim \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_fx/cubetex.c",
"chars": 2588,
"preview": "SVECTOR modelCube_mesh[] = {\n {48,48,-48.0},\n {48,-48,-48},\n {-48,-48,-48},\n {-48,48,-48},\n {48,48,48},\n "
},
{
"path": "hello_fx/hello_fx.c",
"chars": 16642,
"preview": "// Controls :\r\n// SELECT : Switch semi-transparency on/off on primitives\r\n// START : Cycle semi-"
},
{
"path": "hello_gte_opti/Makefile",
"chars": 74,
"preview": "TARGET = hello_gte_opti\n\nSRCS = hello_gte_opti.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_gte_opti/hello_gte_opti.c",
"chars": 9308,
"preview": "// Hello free cycles !\n//\n// Ref : /psyq/DOCS/Devrefs/Inlinref.pdf, p.18\n// /psyq/psx/sample/scea/GTE\n// "
},
{
"path": "hello_light/Makefile",
"chars": 68,
"preview": "TARGET = hello_light\n\nSRCS = hello_light.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_light/cube.c",
"chars": 2731,
"preview": "SVECTOR modelCube_mesh[] = {\n { -128,128,128 },\n { 128,128,128 },\n { 128,128,-128 },\n { -128,128,-128 },\n "
},
{
"path": "hello_light/hello_light.c",
"chars": 11728,
"preview": "/* hello_light.c, by Schnappy, 06-2021\r\n - Demonstrates setting and using light sources in 3D without libgs.\r\n Co"
},
{
"path": "hello_mod/Makefile",
"chars": 136,
"preview": "TARGET = hello_mod\n\nSRCS = hello_mod.c \\\nsrc/mod.c \\\n../thirdparty/nugget/modplayer/modplayer.c \\\nHIT/STAR.HIT \\\n\ninclud"
},
{
"path": "hello_mod/README.md",
"chars": 604,
"preview": "This is an example of how to use [@nicolasnoble](https://github.com/nicolasnoble/)'s [modplayer](https://github.com/grum"
},
{
"path": "hello_mod/hello_mod.c",
"chars": 7463,
"preview": "// Play a MOD file converted to HIT \n// MOD Wiki page : https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/MOD\n#in"
},
{
"path": "hello_mod/src/mod.c",
"chars": 1685,
"preview": "#include \"mod.h\"\n\nlong musicEvent;\ntypedef struct SpuVoiceVolume {\n short volL, volR;\n} SpuVoiceVolume;\n\nSpuVoiceVolu"
},
{
"path": "hello_mod/src/mod.h",
"chars": 549,
"preview": "#pragma once\n#include <libapi.h>\n#include <libspu.h>\n#include \"../../thirdparty/nugget/common/hardware/hwregs.h\"\n#includ"
},
{
"path": "hello_multi_vag/Makefile",
"chars": 273,
"preview": "TARGET = hello_multi_vag\n\nSRCS = hello_multi_vag.c \\\n../VAG/hello.vag \\\n../VAG/poly.vag \\\n../VAG/0_come.vag \\\n../VAG/1_c"
},
{
"path": "hello_multi_vag/README.md",
"chars": 132,
"preview": "See here for more informations about the VAG fileformat and tools : \n\nhttps://github.com/ABelliqueux/nolibgs_hello_worl"
},
{
"path": "hello_multi_vag/hello_multi_vag.c",
"chars": 11053,
"preview": "// Hello multi vag by Schnappy\n// August 2021\n//\n//\n// Load VAG samples to the SPU sound buffer and play them back with "
},
{
"path": "hello_multi_xa/Makefile",
"chars": 201,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_multi_xa.cue hello_multi_xa"
},
{
"path": "hello_multi_xa/README.md",
"chars": 4925,
"preview": "## Multi XA samples playback\n\nUse an interleaved XA file to store multiple sound effects and use pre-calculated offset "
},
{
"path": "hello_multi_xa/hello_multi_xa.c",
"chars": 11650,
"preview": "// XA multi sample playback example\n//\n// Use an interleaved XA file to store multiple sound effects and use pre-calcula"
},
{
"path": "hello_multi_xa/isoconfig.xml",
"chars": 4414,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_multi_xa/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_multi_xa/xa/interleave8.txt",
"chars": 112,
"preview": "1 xa channel5.xa 0 5\n1 xa channel6.xa 0 6\n1 xa channel7.xa 0 7\n1 xa channel8.xa 0 8\n1 null\n1 null\n1 null\n1 null\n"
},
{
"path": "hello_ovl_exec/Makefile",
"chars": 562,
"preview": ".PHONY: all cleansub\nall:\n\t$(MAKE) -C hello_poly clean all\n\t$(MAKE) -C hello_ovl_world clean all\n\t$(MAKE) -C hello_tile "
},
{
"path": "hello_ovl_exec/README.md",
"chars": 351,
"preview": "This example shows how to load overlays from the CD and execute them.\n\nMany thanks to @nicolasnobe for his help on getti"
},
{
"path": "hello_ovl_exec/common.h",
"chars": 1329,
"preview": "#pragma once\n#include <sys/types.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <libgte.h>\n#include <libetc.h>\n#incl"
},
{
"path": "hello_ovl_exec/hello_ovl_exec.c",
"chars": 5701,
"preview": "// Load overlay files from CD and execute them\n// Schnappy 10-2021\n// With the help of Nicolas Noble and impiaa \n// http"
},
{
"path": "hello_ovl_exec/hello_ovl_world/Makefile",
"chars": 95,
"preview": "TARGET = hello_world\n\nSRCS = hello_world.c \\\n\nCPPFLAGS+=-DSTANDALONE\n\ninclude ../../common.mk \n"
},
{
"path": "hello_ovl_exec/hello_ovl_world/hello_ovl_world.c",
"chars": 435,
"preview": "#include \"../common.h\"\n\nint ovl_main_hello(void)\n{ \n init();\n int i = 0;\n while(1)\n {\n i++;\n "
},
{
"path": "hello_ovl_exec/hello_ovl_world/hello_world.c",
"chars": 1703,
"preview": "#include \"../common.h\"\n\nDISPENV disp[2]; // Double buffered DISPENV and DRAWENV\nDRAWENV draw[2];\nu_long ot[2"
},
{
"path": "hello_ovl_exec/hello_poly/Makefile",
"chars": 93,
"preview": "TARGET = hello_poly\n\nSRCS = hello_poly.c \\\n\nCPPFLAGS+=-DSTANDALONE\n\ninclude ../../common.mk \n"
},
{
"path": "hello_ovl_exec/hello_poly/hello_ovl_poly.c",
"chars": 2740,
"preview": "#include \"../common.h\"\n\n\nint ovl_main_poly(void)\n{ \n #ifndef STANDALONE\n useOT = 1;\n #endif\n init();\n "
},
{
"path": "hello_ovl_exec/hello_poly/hello_poly.c",
"chars": 1816,
"preview": "#include \"../common.h\"\n\nDISPENV disp[2]; // Double buffered DISPENV and DRAWENV\nDRAWENV draw[2];\nu_lon"
},
{
"path": "hello_ovl_exec/hello_tile/Makefile",
"chars": 93,
"preview": "TARGET = hello_tile\n\nSRCS = hello_tile.c \\\n\nCPPFLAGS+=-DSTANDALONE\n\ninclude ../../common.mk \n"
},
{
"path": "hello_ovl_exec/hello_tile/hello_ovl_tile.c",
"chars": 3029,
"preview": "#include \"../common.h\"\n\nint ovl_main_tile(void)\n{\n #ifndef STANDALONE\n useOT = 1;\n #endif\n uint16_t time"
},
{
"path": "hello_ovl_exec/hello_tile/hello_tile.c",
"chars": 1926,
"preview": "#include \"../common.h\"\n\nDISPENV disp[2]; // Double buffered DISPENV and DRAWENV\nDRAWENV draw[2];\nu_long ot[2"
},
{
"path": "hello_ovl_exec/isoconfig.xml",
"chars": 4565,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_ovl_exec/overlay.ld",
"chars": 1407,
"preview": "__heap_base = MAX(__ovly0_end, __ovly2_end);\n\nSECTIONS {\t\t\n\tOVERLAY __bss_end : NOCROSSREFS SUBALIGN(4)\n\t{\n\t\t.ovlyload\n "
},
{
"path": "hello_ovl_exec/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_pad/Makefile",
"chars": 64,
"preview": "TARGET = hello_pad\n\nSRCS = hello_pad.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_pad/hello_pad.c",
"chars": 5363,
"preview": "// hello_pad example\n//\n// We're using libetc PadInit() and PadRead() that only supports the 16 buttons pad\n// but doesn"
},
{
"path": "hello_poly/Makefile",
"chars": 66,
"preview": "TARGET = hello_poly\n\nSRCS = hello_poly.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_poly/hello_poly.c",
"chars": 5307,
"preview": "// Draw a colored poly primitive\n//\n// With help from Nicolas Noble, Jaby smoll Seamonstah, Lameguy64\n// \n// From ../psy"
},
{
"path": "hello_poly_ft/Makefile",
"chars": 92,
"preview": "TARGET = hello_poly_ft\n\nSRCS = hello_poly_ft.c \\\n../TIM/bousai.tim \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_poly_ft/hello_poly_ft.c",
"chars": 7342,
"preview": "// Draw a textured poly primitive\n//\n// With help from Nicolas Noble, Jaby smoll Seamonstah, Lameguy64\n// \n// From ../ps"
},
{
"path": "hello_poly_fun/Makefile",
"chars": 74,
"preview": "TARGET = hello_poly_fun\n\nSRCS = hello_poly_fun.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_poly_fun/hello_poly_fun.c",
"chars": 16123,
"preview": "// Having fun with polygons, matrices and vectors\n// Credits : Schnappy\n//With great help from Jaby smoll Seamonstah, Ni"
},
{
"path": "hello_poly_gt/Makefile",
"chars": 92,
"preview": "TARGET = hello_poly_gt\n\nSRCS = hello_poly_gt.c \\\n../TIM/bousai.tim \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_poly_gt/hello_poly_gt.c",
"chars": 6546,
"preview": "// Draw a textured poly primitive with gouraud shading\n//\n// With help from Nicolas Noble, Jaby smoll Seamonstah, Lamegu"
},
{
"path": "hello_poly_gt_tw/Makefile",
"chars": 98,
"preview": "TARGET = hello_poly_gt_tw\n\nSRCS = hello_poly_gt_tw.c \\\n../TIM/bousai.tim \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_poly_gt_tw/hello_poly_gt_tw.c",
"chars": 7321,
"preview": "// Draw a textured poly primitive with gouraud_shading, using a repeating texture pattern\n//\n// With help from Nicolas N"
},
{
"path": "hello_poly_inline/Makefile",
"chars": 80,
"preview": "TARGET = hello_poly_inline\n\nSRCS = hello_poly_inline.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_poly_inline/hello_poly_inline.c",
"chars": 8325,
"preview": "// Hello poly ! Inline / DMPSX version\n//\n// Ref : /psyq/DOCS/Devrefs/Inlinref.pdf, p.18\n// https://psx-sp"
},
{
"path": "hello_poly_stp/Makefile",
"chars": 186,
"preview": "TARGET = hello_poly_stp\n\nSRCS = hello_poly_stp.c \\\nTIM/stpOnAlpha.tim \\\nTIM/stpOnAlphaI.tim \\\nTIM/stpOnBlack.tim \\\nTIM/s"
},
{
"path": "hello_poly_stp/README.md",
"chars": 874,
"preview": "\n\n# STP : Semi-Transparency usage\n\nThis example shows the vari"
},
{
"path": "hello_poly_stp/hello_poly_stp.c",
"chars": 10177,
"preview": "// Demo the different settings for pixel and primitive semi-transparency\n//\n// Schnappy 07-2021\n#include <sys/types.h>\n#"
},
{
"path": "hello_sio/Makefile",
"chars": 64,
"preview": "TARGET = hello_sio\n\nSRCS = hello_sio.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_sio/hello_sio.c",
"chars": 3972,
"preview": "// hello_sio example\n// This example will display the RX data in a 64 char rolling buffer.\n// Use minicom or any other s"
},
{
"path": "hello_sprt/Makefile",
"chars": 121,
"preview": "TARGET = hello_sprt\n\nSRCS = hello_sprt.c \\\n../TIM/TIM16.tim \\\n../TIM/TIM8.tim \\\n../TIM/TIM4.tim \\\n\ninclude ../common.mk "
},
{
"path": "hello_sprt/hello_sprt.c",
"chars": 7989,
"preview": "// Draw a textured sprt primitive\n//\n// based on Lameguy64's tutorial : http://lameguy64.net/svn/pstutorials/chapter1/3-"
},
{
"path": "hello_spu_readback/Makefile",
"chars": 216,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_spu_readback.cue hello_spu_"
},
{
"path": "hello_spu_readback/README.md",
"chars": 2402,
"preview": "This example is adapted from PsyQ's sample : `psyq/psx/sample/sound/CDVOL, main.c,v 1.14 1997/05/02 13:05:21 by ayako`.\n"
},
{
"path": "hello_spu_readback/hello_spu_readback.c",
"chars": 14454,
"preview": "// SPU readback example\n// adapted from PsyQ's sample : psyq/psx/sample/sound/CDVOL, main.c,v 1.14 1997/05/02 13:05:21 b"
},
{
"path": "hello_spu_readback/isoconfig.xml",
"chars": 4838,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_spu_readback/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_str/Makefile",
"chars": 181,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_str.cue hello_str.bin\n\t\nTAR"
},
{
"path": "hello_str/README.md",
"chars": 3476,
"preview": "This example will play a fullscreen STR file and is as straightforward as possible. If you need more advanced control ot"
},
{
"path": "hello_str/hello_str.c",
"chars": 10358,
"preview": "// Stream a STR file from CD, decompress and play it.\n// Schnappy 07-2021\n// based on Lameguy64 strplay library : http:/"
},
{
"path": "hello_str/isoconfig.xml",
"chars": 4404,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_str/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_strplay/Makefile",
"chars": 197,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_strplay.cue hello_strplay.b"
},
{
"path": "hello_strplay/README.md",
"chars": 1434,
"preview": "This example show how to use Lameguy64's [STR playback library](https://github.com/ABelliqueux/nolibgs_hello_worlds/tre"
},
{
"path": "hello_strplay/hello_strplay.c",
"chars": 4399,
"preview": "// Using the strplay library.\n// Schnappy 07-2021\n// based on Lameguy64 strplay library : http://www.psxdev.net/forum/vi"
},
{
"path": "hello_strplay/isoconfig.xml",
"chars": 4416,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_strplay/strplay.c",
"chars": 10361,
"preview": "/*\r\n\t\r\n\tSimple STR Player Library by Lameguy64 \r\n\t(?) 2014 Meido-Tek Productions/Lame Studios\r\n\t\r\n\tOriginal PsyQ sample "
},
{
"path": "hello_strplay/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_tile/Makefile",
"chars": 66,
"preview": "TARGET = hello_tile\n\nSRCS = hello_tile.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_tile/hello_tile.c",
"chars": 5476,
"preview": "// Draw a tile primitive\n// Schnappy 2021\n// based on Lameguy64's tutorial : http://lameguy64.net/svn/pstutorials/chapte"
},
{
"path": "hello_vag/Makefile",
"chars": 87,
"preview": "TARGET = hello_vag\n\nSRCS = hello_vag.c \\\n../VAG/hello_poly.vag \n\ninclude ../common.mk \n"
},
{
"path": "hello_vag/README.md",
"chars": 132,
"preview": "See here for more informations about the VAG fileformat and tools : \n\nhttps://github.com/ABelliqueux/nolibgs_hello_worl"
},
{
"path": "hello_vag/hello_vag.c",
"chars": 9780,
"preview": "// VAGDEMO2020 by Schnappy\n// December 2020\n// Based on VAGDEMO_FIXED by Yagotzirck\n// Based on VAGDEMO by Shadow\n// bas"
},
{
"path": "hello_world/Makefile",
"chars": 68,
"preview": "TARGET = hello_world\n\nSRCS = hello_world.c \\\n\ninclude ../common.mk \n"
},
{
"path": "hello_world/hello_world.c",
"chars": 2954,
"preview": "// Demonstrate DISP/DRAW env, font setup, and display a text.\n// Schnappy 2020\n// Based on Lameguy64 tutorial : http://l"
},
{
"path": "hello_xa/Makefile",
"chars": 177,
"preview": ".PHONY: all cleansub\nall:\n\tmkpsxiso -y ./isoconfig.xml\ncleansub:\n\t$(MAKE) clean\n\trm -f hello_xa.cue hello_xa.bin\n\t\nTARGE"
},
{
"path": "hello_xa/README.md",
"chars": 130,
"preview": "See here for more informations about the XA fileformat and tools : \n\nhttps://github.com/ABelliqueux/nolibgs_hello_world"
},
{
"path": "hello_xa/hello_xa.c",
"chars": 6937,
"preview": "// XA track playback example\n// base on `psyq/addons/scee/CD/XAPLAYER`\n// Refs : http://psx.arthus.net/code/XA/XATUT.pdf"
},
{
"path": "hello_xa/isoconfig.xml",
"chars": 4466,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- MKPSXISO example XML script -->\n\n<!-- <iso_project>\n Starts an ISO i"
},
{
"path": "hello_xa/system.cnf",
"chars": 56,
"preview": "BOOT=cdrom:\\SCES_313.37;1\nTCB=4\nEVENT=10\nSTACK=801FFFF0\n"
},
{
"path": "hello_xa/xa/interleave4.txt",
"chars": 55,
"preview": "1 xa xa/funk.xa 1 0\n1 xa xa/beach.xa 1 1\n1 null\n1 null\n"
},
{
"path": "hello_xa/xa/interleave8.txt",
"chars": 83,
"preview": "1 xa xa/funk.xa 1 0\n1 xa xa/beach.xa 1 1\n1 null\n1 null\n1 null\n1 null\n1 null\n1 null\n"
},
{
"path": "includes/CPUMAC.H",
"chars": 1077,
"preview": "/*\r\n** cpumac.h\r\n mike acton\r\n*/\r\n\r\n// cpu_ldr(cpu register,data pointer)\r\n// copy 32bit data from dp to r\r\n#define cp"
}
]
// ... and 55 more files (download for full content)
About this extraction
This page contains the full source code of the ABelliqueux/nolibgs_hello_worlds GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 186 files (40.3 MB), approximately 125.4k tokens, and a symbol index with 198 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.