all: Import initial version and examples
13
.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# Python cache files
|
||||
__pycache__/
|
||||
|
||||
# Setuptools
|
||||
build/
|
||||
dist/
|
||||
*.egg-info/
|
||||
|
||||
# Vim
|
||||
.*swp
|
||||
|
||||
# Virtual environments
|
||||
env/
|
10
architectds/__init__.py
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2024 Antonio Niño Díaz <antonio_nd@outlook.com>
|
||||
|
||||
from .architectds import (Arm9Binary, Arm7Binary, TeakBinary, NitroFS, FatFS,
|
||||
NdsRom, AUTHOR_STRING, VERSION_STRING)
|
||||
|
||||
__all__ = ['Arm9Binary', 'Arm7Binary', 'TeakBinary', 'NitroFS', 'FatFS', 'NdsRom']
|
||||
__author__ = AUTHOR_STRING
|
||||
__version__ = VERSION_STRING
|
1908
architectds/architectds.py
Normal file
8
examples/libnds/all/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libnds/all/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
1
examples/libnds/all/arm7/data/data_string.bin
Normal file
@ -0,0 +1 @@
|
||||
Hello from a bin file!
|
79
examples/libnds/all/arm7/source/main.c
Normal file
@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
//
|
||||
// Copyright (C) 2005 Michael Noland (joat)
|
||||
// Copyright (C) 2005 Jason Rogers (Dovoto)
|
||||
// Copyright (C) 2005-2015 Dave Murphy (WinterMute)
|
||||
// Copyright (C) 2023 Antonio Niño Díaz
|
||||
|
||||
// Default ARM7 core
|
||||
|
||||
#include <dswifi7.h>
|
||||
#include <nds.h>
|
||||
#include <maxmod7.h>
|
||||
|
||||
volatile bool exit_loop = false;
|
||||
|
||||
void power_button_callback(void)
|
||||
{
|
||||
exit_loop = true;
|
||||
}
|
||||
|
||||
void vblank_handler(void)
|
||||
{
|
||||
inputGetAndSend();
|
||||
Wifi_Update();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Initialize sound hardware
|
||||
enableSound();
|
||||
|
||||
// Read user information from the firmware (name, birthday, etc)
|
||||
readUserSettings();
|
||||
|
||||
// Stop LED blinking
|
||||
ledBlink(0);
|
||||
|
||||
// Using the calibration values read from the firmware with
|
||||
// readUserSettings(), calculate some internal values to convert raw
|
||||
// coordinates into screen coordinates.
|
||||
touchInit();
|
||||
|
||||
irqInit();
|
||||
irqSet(IRQ_VBLANK, vblank_handler);
|
||||
|
||||
fifoInit();
|
||||
|
||||
installWifiFIFO();
|
||||
installSoundFIFO();
|
||||
installSystemFIFO(); // Sleep mode, storage, firmware...
|
||||
|
||||
// Initialize Maxmod. It uses timer 0 internally.
|
||||
mmInstall(FIFO_MAXMOD);
|
||||
|
||||
// This sets a callback that is called when the power button in a DSi
|
||||
// console is pressed. It has no effect in a DS.
|
||||
setPowerButtonCB(power_button_callback);
|
||||
|
||||
// Read current date from the RTC and setup an interrupt to update the time
|
||||
// regularly. The interrupt simply adds one second every time, it doesn't
|
||||
// read the date. Reading the RTC is very slow, so it's a bad idea to do it
|
||||
// frequently.
|
||||
initClockIRQTimer(3);
|
||||
|
||||
irqEnable(IRQ_VBLANK);
|
||||
|
||||
while (!exit_loop)
|
||||
{
|
||||
const uint16_t key_mask = KEY_SELECT | KEY_START | KEY_L | KEY_R;
|
||||
uint16_t keys_pressed = ~REG_KEYINPUT;
|
||||
|
||||
if ((keys_pressed & key_mask) == key_mask)
|
||||
exit_loop = true;
|
||||
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
BIN
examples/libnds/all/arm9/audio/music/joint_people.mod
Normal file
BIN
examples/libnds/all/arm9/audio/sfx/fire_explosion.wav
Normal file
1
examples/libnds/all/arm9/data/data_string.bin
Normal file
@ -0,0 +1 @@
|
||||
Hello from a bin file!
|
2
examples/libnds/all/arm9/graphics/neon.grit
Normal file
@ -0,0 +1,2 @@
|
||||
# bitmap, 16 bit
|
||||
-gb -gB16
|
BIN
examples/libnds/all/arm9/graphics/neon.png
Normal file
After Width: | Height: | Size: 55 KiB |
245
examples/libnds/all/arm9/source/main.c
Normal file
@ -0,0 +1,245 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nds.h>
|
||||
#include <maxmod9.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// Headers autogenerated when files are find inside AUDIODIRS in the Makefile
|
||||
#include "maxmod/soundbank_info.h"
|
||||
#include "maxmod/soundbank_bin.h"
|
||||
|
||||
// Header autogenerated for each PNG file inside GFXDIRS in the Makefile
|
||||
#include "grit/neon_png.h"
|
||||
|
||||
// Header autogenerated for each BIN file inside BINDIRS in the Makefile
|
||||
#include "data/data_string_bin.h"
|
||||
|
||||
#include "teak/teak1_tlf.h"
|
||||
|
||||
// Callback called whenver the keyboard is pressed so that a character is
|
||||
// printed on the screen.
|
||||
void on_key_pressed(int key)
|
||||
{
|
||||
if (key > 0)
|
||||
printf("%c", key);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int textureID;
|
||||
|
||||
videoSetMode(MODE_0_3D);
|
||||
|
||||
glInit();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_ANTIALIAS);
|
||||
|
||||
// The background must be fully opaque and have a unique polygon ID
|
||||
// (different from the polygons that are going to be drawn) so that
|
||||
// antialias works.
|
||||
glClearColor(0, 0, 0, 31);
|
||||
glClearPolyID(63);
|
||||
|
||||
glClearDepth(0x7FFF);
|
||||
|
||||
glViewport(0, 0, 255, 191);
|
||||
|
||||
// Setup some VRAM as memory for textures
|
||||
vramSetBankA(VRAM_A_TEXTURE);
|
||||
|
||||
// Load texture
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(0, textureID);
|
||||
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0,
|
||||
TEXGEN_TEXCOORD, (u8*)neon_pngBitmap);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
|
||||
|
||||
gluLookAt(0.0, 0.0, 2.0, // Position
|
||||
0.0, 0.0, 0.0, // Look at
|
||||
0.0, 1.0, 0.0); // Up
|
||||
|
||||
// Setup sub screen for the text console
|
||||
consoleDemoInit();
|
||||
|
||||
if (isDSiMode())
|
||||
{
|
||||
if (dspExecuteDefaultTLF(teak1_tlf) != DSP_EXEC_OK)
|
||||
{
|
||||
printf("Failed to execute TLF");
|
||||
while (1)
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
}
|
||||
|
||||
// Load demo keyboard
|
||||
Keyboard *kbd = keyboardDemoInit();
|
||||
kbd->OnKeyPressed = on_key_pressed;
|
||||
|
||||
// Setup sound bank
|
||||
mmInitDefaultMem((mm_addr)soundbank_bin);
|
||||
|
||||
// load the module
|
||||
mmLoad(MOD_JOINT_PEOPLE);
|
||||
|
||||
// load sound effects
|
||||
mmLoadEffect(SFX_FIRE_EXPLOSION);
|
||||
|
||||
// Start playing module
|
||||
mmStart(MOD_JOINT_PEOPLE, MM_PLAY_LOOP);
|
||||
|
||||
int angle_x = 0;
|
||||
int angle_z = 0;
|
||||
char name[256] = { 0 };
|
||||
|
||||
uint16_t cmd0 = 0;
|
||||
int16_t cmd1 = 0;
|
||||
int16_t cmd2 = 0;
|
||||
|
||||
uint16_t rep0 = 0;
|
||||
int16_t rep1 = 0;
|
||||
int16_t rep2 = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Synchronize game loop to the screen refresh
|
||||
swiWaitForVBlank();
|
||||
|
||||
// Print some text in the demo console
|
||||
// -----------------------------------
|
||||
|
||||
// Clear console
|
||||
printf("\x1b[2J");
|
||||
|
||||
// Print current time
|
||||
char str[100];
|
||||
time_t t = time(NULL);
|
||||
struct tm *tmp = localtime(&t);
|
||||
if (strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S%z", tmp) == 0)
|
||||
snprintf(str, sizeof(str), "Failed to get time");
|
||||
printf("%s\n\n", str);
|
||||
|
||||
// Print contents of the BIN file
|
||||
for (int i = 0; i < data_string_bin_size; i++)
|
||||
printf("%c", data_string_bin[i]);
|
||||
printf("\n");
|
||||
|
||||
// Print some controls
|
||||
printf("PAD: Rotate triangle\n");
|
||||
printf("SELECT: Keyboard input test\n");
|
||||
printf("START: Exit to loader\n");
|
||||
printf("A: Play SFX\n");
|
||||
printf("\n");
|
||||
|
||||
// Test code from a different folder
|
||||
printf("Name: [%s]\n", name);
|
||||
printf("Name length: %d\n", my_strlen(name));
|
||||
|
||||
// Handle user input
|
||||
// -----------------
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint16_t keys = keysHeld();
|
||||
uint16_t keys_down = keysDown();
|
||||
|
||||
if (keys & KEY_LEFT)
|
||||
angle_z += 3;
|
||||
if (keys & KEY_RIGHT)
|
||||
angle_z -= 3;
|
||||
|
||||
if (keys & KEY_UP)
|
||||
angle_x += 3;
|
||||
if (keys & KEY_DOWN)
|
||||
angle_x -= 3;
|
||||
|
||||
if (keys_down & KEY_A)
|
||||
mmEffect(SFX_FIRE_EXPLOSION);
|
||||
|
||||
if (keys & KEY_SELECT)
|
||||
{
|
||||
printf("\x1b[12;1HType your name: ");
|
||||
scanf("%255s", name);
|
||||
}
|
||||
|
||||
if (keys & KEY_START)
|
||||
break;
|
||||
|
||||
// DSP communications
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (isDSiMode())
|
||||
{
|
||||
printf("CMD: %u %d %d\n", cmd0, cmd1, cmd2);
|
||||
|
||||
cmd0++; // Heartbeat
|
||||
cmd1 = angle_x;
|
||||
cmd2 = angle_z;
|
||||
|
||||
if (dspSendDataReady(0))
|
||||
dspSendData(0, cmd0);
|
||||
if (dspSendDataReady(1))
|
||||
dspSendData(1, cmd1);
|
||||
if (dspSendDataReady(2))
|
||||
dspSendData(2, cmd2);
|
||||
|
||||
if (dspReceiveDataReady(0))
|
||||
rep0 = dspReceiveData(0);
|
||||
if (dspReceiveDataReady(1))
|
||||
rep1 = dspReceiveData(1);
|
||||
if (dspReceiveDataReady(2))
|
||||
rep2 = dspReceiveData(2);
|
||||
|
||||
printf("REP: %u %d %d\n", rep0, rep1, rep2);
|
||||
}
|
||||
|
||||
// Render 3D scene
|
||||
// ---------------
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glRotateZ(angle_z);
|
||||
glRotateX(angle_x);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
|
||||
|
||||
glBindTexture(0, textureID);
|
||||
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(0, inttot16(128)));
|
||||
glVertex3v16(floattov16(-1), floattov16(-1), 0);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(inttot16(128),inttot16(128)));
|
||||
glVertex3v16(floattov16(1), floattov16(-1), 0);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(inttot16(128), 0));
|
||||
glVertex3v16(floattov16(1), floattov16(1), 0);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(0,0));
|
||||
glVertex3v16(floattov16(-1), floattov16(1), 0);
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
glPopMatrix(1);
|
||||
|
||||
glFlush(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
65
examples/libnds/all/build.py
Normal file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
teak1 = TeakBinary(
|
||||
name='teak1',
|
||||
sourcedirs=['teak/source1'],
|
||||
)
|
||||
teak1.generate_tlf()
|
||||
|
||||
teak2 = TeakBinary(
|
||||
name='teak2',
|
||||
sourcedirs=['teak/source2'],
|
||||
)
|
||||
teak2.generate_tlf()
|
||||
|
||||
nitrofs = NitroFS()
|
||||
nitrofs.add_tlf(teak2)
|
||||
nitrofs.add_grit(['nitrofs/graphics'])
|
||||
# The header of the soundbank in NitroFS must be added as a dependency of the ARM9
|
||||
nitrofs_soundbank_header = nitrofs.add_mmutil(['nitrofs/audio'])
|
||||
nitrofs.generate_image()
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['arm9/source', 'common/source'],
|
||||
defines=[],
|
||||
includedirs=['common/include'],
|
||||
libs=['nds9', 'mm9'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/maxmod']
|
||||
)
|
||||
arm9.add_header_dependencies([nitrofs_soundbank_header])
|
||||
arm9.add_data(['arm9/data'])
|
||||
arm9.add_grit(['arm9/graphics'])
|
||||
arm9.add_mmutil(['arm9/audio'])
|
||||
arm9.add_tlf(teak1)
|
||||
arm9.generate_elf()
|
||||
|
||||
arm7 = Arm7Binary(
|
||||
sourcedirs=['arm7/source', 'common/source'],
|
||||
defines=[],
|
||||
includedirs=['common/include'],
|
||||
libs=['nds7', 'mm7', 'dswifi7'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/maxmod',
|
||||
'${BLOCKSDS}/libs/dswifi']
|
||||
)
|
||||
arm7.add_data(['arm7/data'])
|
||||
arm7.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
nitrofsdirs=['nitrofs/root'],
|
||||
# Note: If no ARM7 is specified, it uses the default one
|
||||
binaries=[teak1, teak2, arm9, arm7, nitrofs],
|
||||
nds_path='rom.nds',
|
||||
game_title='Python build system',
|
||||
game_subtitle='Built with BlocksDS',
|
||||
game_author='github.com/blocksds/sdk',
|
||||
game_icon='icon.bmp'
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
10
examples/libnds/all/common/include/common.h
Normal file
@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
|
||||
#ifndef COMMON_H__
|
||||
#define COMMON_H__
|
||||
|
||||
int my_strlen(const char *s);
|
||||
|
||||
#endif // COMMON_H__
|
10
examples/libnds/all/common/source/common.c
Normal file
@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int my_strlen(const char *s)
|
||||
{
|
||||
return strlen(s);
|
||||
}
|
BIN
examples/libnds/all/icon.bmp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/libnds/all/nitrofs/audio/music/joint_people.mod
Normal file
5
examples/libnds/all/nitrofs/audio/music/joint_people.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Name: jointpeople
|
||||
Author: Anadune & Floppy
|
||||
License: Mod Archive Distribution license
|
||||
|
||||
https://modarchive.org/index.php?request=view_by_moduleid&query=115447
|
52
examples/libnds/all/nitrofs/audio/music/mod-archive-faq.txt
Normal file
@ -0,0 +1,52 @@
|
||||
Original site: https://modarchive.org/index.php?faq-licensing
|
||||
|
||||
===============================================================================
|
||||
|
||||
Licensing Modules and Copyright
|
||||
|
||||
- Who owns the copyrights to the modules?
|
||||
|
||||
The composers do - unless the Public Domain license attribution has been
|
||||
specifically attributed in which case you are free to do with the module
|
||||
whatever you like.
|
||||
|
||||
- Can I use a module of modarchive.org in my game/application/etc...?
|
||||
|
||||
If the module in question has license deeds attributed to it, please refer to
|
||||
those.
|
||||
|
||||
Otherwise, the only way to be genuinely fair to the artist who's music you want
|
||||
to use is to contact them and get their permission. We can't grant permissions
|
||||
on their behalf. Period.
|
||||
|
||||
- Can I redistribute the module in its original unmodified form?
|
||||
|
||||
Yes. All uploads to the site are governed by an upload agreement of which one of
|
||||
the terms is the right to redistribute the original unmodified module file. This
|
||||
does not cover inclusion in a packed/bundled application or game. See previous
|
||||
item.
|
||||
|
||||
- The contact information isn't in the module, what can I do to contact the
|
||||
artist?
|
||||
|
||||
You can try using the modarchive.org forums, specifically the Wanted: forum.
|
||||
Search the Internet, do some homework. If you fail to find the necessary
|
||||
information then you are pretty much out of luck.
|
||||
|
||||
- I can't get in contact with an artist who's music I want to use, what now?
|
||||
|
||||
It's up to you how you proceed. We will not condone illegal use of someone's
|
||||
works, but if you still wish to continue to use that particular piece of music
|
||||
in your project, then you take on those risks yourself.
|
||||
|
||||
If your project is small and free (non commercial) then it's wise to give clear
|
||||
and concise due credit to the artist in your production. If your production is
|
||||
for commercial purposes then you are technically left with no other choice than
|
||||
to find a different module where the artist has attributed a compatible license,
|
||||
or is contactable - or go out on a limb and ask to have someone compose a custom
|
||||
module for your project.
|
||||
|
||||
- Where can I find the license attribution information on a module?
|
||||
|
||||
Look on a module's information page, there is a section dedicated to the License
|
||||
Attribution information.
|
287
examples/libnds/all/nitrofs/audio/music/mod-archive-terms.txt
Normal file
@ -0,0 +1,287 @@
|
||||
Original site: https://modarchive.org/index.php?terms
|
||||
|
||||
===============================================================================
|
||||
|
||||
Terms & Disclaimer
|
||||
|
||||
Revised 2014-04-30
|
||||
|
||||
Cookies
|
||||
|
||||
By using our website, you agree to the use of cookies and other technologies as
|
||||
set out in this policy. If you do not agree to such use, please refrain from
|
||||
using the website. We use cookies to manage your experience on the site, without
|
||||
these you may suffer from lack of functionality, these are not used to track
|
||||
you.
|
||||
|
||||
Legalese.
|
||||
|
||||
1.1 LEGAL LIABILITY. By providing a song/file to our server you acknowledge that
|
||||
you may be held liable if the uploaded material is in any way illegal. You agree
|
||||
that you will notify The Mod Archive with no unnecessary delays should it at a
|
||||
later point be revealed that a song/file previously uploaded was illegally
|
||||
distributed, has illegal contents or is in some other way illegal to distribute.
|
||||
|
||||
1.3 AGREEMENT TERM AND TERMINATION. This Agreement is non-terminable and may not
|
||||
be cancelled by any party. Modified versions of this document may follow, but
|
||||
this Agreement shall remain in effect for any songs/files uploaded under this
|
||||
Agreement.
|
||||
|
||||
1.4 AGREEMENT SCOPE. This Agreement sets forth the entire understanding and
|
||||
agreement of the parties as to this Agreement's subject matter and supersedes
|
||||
all prior proposals, discussions or agreements with respect to such subject
|
||||
matter. All headings in the Agreement are for convenience only and shall have no
|
||||
legal or contractual effect. Should we choose not to exercise or enforce any
|
||||
right or provision of this Agreement, this shall not constitute a waiver of such
|
||||
right or provisions. You agree that you and we are independent contractors under
|
||||
this Agreement, and nothing in this Agreement shall be used to create a
|
||||
partnership, or joint venture.
|
||||
|
||||
1.5 LINK TO THIRD PARTIES: The Website may contain links to websites operated by
|
||||
third parties ("Third Party Websites"). The Mod Archive does not have any
|
||||
influence or control over any such Third Party Websites and, unless otherwise
|
||||
stated, is not responsible for and does not endorse any Third Party Websites or
|
||||
their availability or contents.
|
||||
|
||||
1.6 CONTENT: The Mod Archive does not in any way guarantee the accuracy of the
|
||||
information contained on the website nor does it guarantee that such information
|
||||
will be free of objectionable content or free of content which is unsuitable for
|
||||
minors.
|
||||
|
||||
2.1 We reserve the right to change these Terms of Service without notice. You
|
||||
are responsible for regularly reviewing these Terms of Service. Continued use of
|
||||
The Mod Archive after any such changes shall constitute your consent to such
|
||||
changes. The Mod Archive does not and will not assume any obligation to notify
|
||||
you of any changes to the Terms of Service.
|
||||
|
||||
3. GENERAL RULES RELATING TO CONDUCT: The Website Service is made available for
|
||||
your own, personal use. The Website Service must not be used for any commercial
|
||||
purpose whatsoever or for any illegal or unauthorised purpose. When you use the
|
||||
Website Service you must comply with all applicable Dutch laws relating to
|
||||
online conduct (including, without limitation, content which can be posted
|
||||
online) and with any applicable international laws, including the local laws in
|
||||
your country of residence (together referred to as "Applicable Laws").
|
||||
|
||||
4. CONTENT SUBMITTED TO THE WEBSITE: You are responsible for any information,
|
||||
data, text, music, software, sound, photographs, graphics, video, messages or
|
||||
other content ("Content") which you post or upload and/or display (in public or
|
||||
privately) to the Website. The Mod Archive may (but shall not be obliged to)
|
||||
delete, edit, lock, move or remove any Content without notice and for any reason
|
||||
and/or to record the IP address from which any Content is posted, uploaded
|
||||
and/or displayed without notice and for any reason, including, without
|
||||
limitation, Content which, in our sole discretion, violates these Terms or is or
|
||||
may be irrelevant, out of date, inappropriate or objectionable in any way
|
||||
whatsoever, or in respect of which The Mod Archive receives any complaint
|
||||
(whether justified or not). By posting, uploading and/or displaying any Content
|
||||
to the Website you warrant that: (a) you own all intellectual property and
|
||||
proprietary rights in such Content or that you have a licence from the owner of
|
||||
such rights to post, upload and/or display such Content on the Website; and (b)
|
||||
the posting, uploading and/or displaying of such Content on the Website and the
|
||||
grant of the licence to The Mod Archive (on the terms set out below) will not
|
||||
infringe the intellectual property or proprietary rights of any third party.
|
||||
|
||||
If you upload, post or otherwise transmit any Content to the Website, you
|
||||
automatically: (a) grant other users of the Website and the Website Service the
|
||||
right to access the same and use it in accordance with these Terms, and (b)
|
||||
grant The Mod Archive a non-exclusive, royalty free, sub-licensable, perpetual,
|
||||
world-wide licence to use, modify, publish, publicly perform, publicly display
|
||||
and distribute such Content on and through the Website and the Website Service
|
||||
and in any other form or medium. You continue to own the Content after it is
|
||||
posted to the Website.
|
||||
|
||||
You acknowledge that The Mod Archive will not screen or otherwise check any
|
||||
Content (with the exception of module uploads) which is submitted by you or any
|
||||
other user of the Website Service before it is posted, not monitor yours or any
|
||||
person’s use of the Website Service. As such, you as the user of the Website
|
||||
Service are responsible for any Content you submit to the Website and the manner
|
||||
in which the Website Service is used under your username. If you become aware of
|
||||
any misuse of the Website Service by any person including (without limitation)
|
||||
any posting of Content which violates these Terms, please contact us by
|
||||
following the instructions set out in paragraph 11 of these Terms.
|
||||
|
||||
5. SPECIFIC RULES RELATING TO CONDUCT: You agree that when using the Website
|
||||
Service you will comply with all Applicable Laws (as defined in paragraph 3),
|
||||
these Terms and you acknowledge that you are responsible for all acts and
|
||||
omissions which occur under your user-name. In particular, but without
|
||||
limitation, you agree not to:
|
||||
|
||||
a. Upload, post or otherwise display Content which is or promotes behaviour
|
||||
which violates the rights (including, without limitation, the intellectual
|
||||
property rights) of a third party or which is unlawful, harmful,
|
||||
threatening, abusive, flaming, hateful, offensive (whether in relation to
|
||||
sex, race, religion or otherwise) harassing, hateful, defamatory, vulgar,
|
||||
obscene, invasive of another's privacy, solicits personal information from
|
||||
anyone under the age of 18 years, or contains any illegal content; or
|
||||
|
||||
b. Upload, post or otherwise display any Content which contains software
|
||||
viruses or any other files or programs that may interrupt, destroy or limit
|
||||
the functionality of the Website or the Website Service or any server or
|
||||
networks connected to the Website or another's computer, or that contains
|
||||
any chain letters, pyramid-selling schemes, bulk mail, junk mail or similar;
|
||||
or
|
||||
|
||||
c. Upload, post or otherwise display any Content containing a photograph of
|
||||
another person unless you have obtained that person’s consent;
|
||||
|
||||
d. Harvest or collect any IP addresses or email addresses or other contact
|
||||
information of any members of the Website, by electronic means or otherwise;
|
||||
or
|
||||
|
||||
e. Upload, post or otherwise display any Content for any commercial or
|
||||
business purpose including (without limitation) any Content which contains
|
||||
any advertising or promotional materials; or
|
||||
|
||||
f. Restrict or in any way inhibit any other person’s use of the Website or
|
||||
the Website Service; or
|
||||
|
||||
g. Upload, post or otherwise display any Content which is false, misleading,
|
||||
un-necessary and/or repetitive including any Content which is inaccurate,
|
||||
out of date or repeats that previously uploaded, posted or displayed by you
|
||||
or another visitor, unless absolutely necessary; or
|
||||
|
||||
h. Upload, post or otherwise transmit any Content to a part of the Website
|
||||
which is irrelevant to the subject matter of the Content; or
|
||||
|
||||
i. Register an account with us under more than one user name and/or user
|
||||
account number; or
|
||||
|
||||
j. Use the Website or the Website Service in a manner that is inconsistent
|
||||
with these Terms and/or any Applicable Laws in force from time to time or in
|
||||
a manner which promotes or encourages illegal activity; or
|
||||
|
||||
k. Breach the terms of any suspension or ban or seek alternative access; or
|
||||
|
||||
l. In the interests of free speech, bring any action for defamation against
|
||||
The Mod Archive, or any of the companies in the same group; or
|
||||
|
||||
m. Use or solicit any other account holder’s personal data for any purpose
|
||||
other than establishing non-commercial, lawful contact that such account
|
||||
holder would reasonably expect to welcome; or
|
||||
|
||||
n. Submit Content owned by a third party without consent from that third
|
||||
party or submit Content in a manner which expressly or impliedly infers that
|
||||
such Content is sponsored or endorsed by the Website; or
|
||||
|
||||
o. Use the Website in any unlawful manner or in a manner which promotes or
|
||||
encourages illegal activity or in a manner which could damage, disable,
|
||||
overburden or impair the Website or the Website Service; or
|
||||
|
||||
p. Attempt to gain unauthorised access to the Website or any networks,
|
||||
servers or computer systems connected to the Website; or
|
||||
|
||||
q. Modify, adapt, translate or reverse engineer any part of the Website or
|
||||
use any robot, spider, site search/retrieval application or other device to
|
||||
retrieve or index any part of the Website or re-format or frame any portion
|
||||
of the web pages comprising the Website, unless permitted by law; or
|
||||
|
||||
r. Remove or obstruct from view any advertisements and/or any copyright,
|
||||
trademark or other proprietary notices contained on or in the Website; or
|
||||
|
||||
s. Contact any other user of the Website if they have expressly asked you
|
||||
not to; or
|
||||
|
||||
t. Attempt to impersonate any other user or account holder of the Website or
|
||||
the Website Service; or
|
||||
|
||||
u. Use the username and/or password of any other account holder of the
|
||||
Website or disclose your password to any other person; or
|
||||
|
||||
v. Upload, post or otherwise display any Content comprising an advertisement
|
||||
or accept payment or anything of value from any person in exchange for you
|
||||
uploading, posting or displaying any Content or otherwise performing any
|
||||
commercial activity on or through the Website or the Website Service on
|
||||
behalf of such person (including, without limitation, posting
|
||||
blogs/comments/profiles or bulletins for a commercial purpose and/or sending
|
||||
messages to other users of the Website with a commercial purpose).
|
||||
|
||||
|
||||
You agree to indemnify The Mod Archive in full and on demand from and against
|
||||
any loss, damage, costs or expenses which they suffer or incur directly or
|
||||
indirectly as a result of your use of the Website and/or the Website Service,
|
||||
and any use of the same under your username other than in accordance with these
|
||||
Terms or Applicable Law.
|
||||
|
||||
6. DISCLAIMER / LIABILITY: USE OF THE WEBSITE AND/OR THE WEBSITE SERVICE IS AT
|
||||
YOUR OWN RISK. THE WEBSITE AND THE WEBSITE SERVICE IS PROVIDED ON AN “AS IS”
|
||||
BASIS. TO THE MAXIMUM EXTENT PERMITTED BY LAW: (A) THE MOD ARCHIVE DISCLAIMS ALL
|
||||
LIABILITY WHATSOEVER, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE)
|
||||
OR OTHERWISE IN RELATION TO THE WEBSITE AND/OR THE WEBSITE SERVICE; AND (B) ALL
|
||||
IMPLIED WARRANTIES, TERMS AND CONDITIONS RELATING TO THE WEBSITE AND/OR THE
|
||||
WEBSITE SERVICE (WHETHER IMPLIED BY STATUE, COMMON LAW OR OTHERWISE), INCLUDING
|
||||
(WITHOUT LIMITATION) ANY WARRANTY, TERM OR CONDITION AS TO ACCURACY,
|
||||
COMPLETENESS, SATISFACTORY QUALITY, PERFORMANCE, FITNESS FOR PURPOSE OR ANY
|
||||
SPECIAL PURPOSE, AVAILABILITY, NON INFRINGEMENT, INFORMATION ACCURACY,
|
||||
INTEROPERABILITY, QUIET ENJOYMENT AND TITLE ARE, AS BETWEEN THE MOD ARCHIVE AND
|
||||
YOU, HEREBY EXCLUDED. IN PARTICULAR, BUT WITHOUT PREJUDICE TO THE FOREGOING, WE
|
||||
ACCEPT NO RESPONSIBILITY FOR THE CONDUCT OF ANY USER AND/OR ACCOUNT HOLDER OF
|
||||
THE WEBSITE AND/OR WEBSITE SERVICE; ANY ERROR, DELAY OR FAILURE IN THE
|
||||
TRANSMISSION OF ANY COMMUNICATION BETWEEN USERS AND/OR ACCOUNT HOLDERS; ANY
|
||||
TECHNICAL FAILURE OF THE INTERNET, THE WEBSITE AND/OR THE WEBSITE SERVICE; OR
|
||||
ANY DAMAGE OR INJURY TO USERS OR THEIR EQUIPMENT AS A RESULT OF OR RELATING TO
|
||||
THEIR USE OF THE WEBSITE OR THE WEBSITE SERVICE. YOUR STATUTORY RIGHTS ARE NOT
|
||||
AFFECTED.
|
||||
|
||||
The Mod Archive will not be liable, in contract, tort (including, without
|
||||
limitation, negligence), under statute or otherwise, as a result of or in
|
||||
connection with the Website and/or the Website Service, for any: (i) economic
|
||||
loss (including, without limitation, loss of revenues, profits, contracts,
|
||||
business or anticipated savings); or (ii) loss of goodwill or reputation; or
|
||||
(iii) special or indirect or consequential loss.
|
||||
|
||||
Nothing in these Terms shall be construed as excluding or limiting the liability
|
||||
of The Mod Archive for death or personal injury caused by its negligence or for
|
||||
any other liability which cannot be excluded by Dutch law.
|
||||
|
||||
7. ACCESS RESTRICTION AND SERVICE SUSPENSION OR TERMINATION: The Mod Archive
|
||||
reserves the right in its sole discretion to deny you access to the Website
|
||||
and/or the Website Service, or any part thereof, with or without notice and for
|
||||
any reason including, without limitation, if you fail to comply with any clause
|
||||
5 (Member Conduct) or any other provision of these Terms. In particular, The Mod
|
||||
Archive may deny you access to the Website and/or the Website Services if The
|
||||
Mod Archive exercises its right to delete, edit, lock or remove any Content
|
||||
posted, uploaded or displayed by you. The Mod Archive reserves the right to
|
||||
suspend or cease providing all or any of the Website Service, without notice,
|
||||
and shall have no liability or responsibility to you in any manner whatsoever if
|
||||
it chooses to do so.
|
||||
|
||||
8. ADVERTISERS ON THE WEBSITE: We accept no responsibility for adverts posted on
|
||||
the Website. If you agree to purchase goods and/or services from any third party
|
||||
who advertises on the Website, you do so at your own risk. The advertiser, not
|
||||
The Mod Archive, is responsible for such goods and/or services and if you have
|
||||
any queries or complaints in relation to them, your only recourse is against the
|
||||
advertiser.
|
||||
|
||||
9. ACCOUNT HOLDER INTERACTION You are responsible for how you interact with
|
||||
other account holders and users of the Website and the Website Service. We
|
||||
reserve the right, but have no obligation, to monitor how you interact with
|
||||
those persons.
|
||||
|
||||
10 GENERAL: These Terms (as amended from time to time) constitute the entire
|
||||
agreement between you and The Mod Archive concerning your use of the Website and
|
||||
the Website Service and supersede any previous arrangement, agreement,
|
||||
undertaking or proposal, written or oral between you and The Mod Archive in
|
||||
relation to such matters. The Mod Archive reserves the right to update these
|
||||
Terms from time to time. If it does so, the updated version will be effective as
|
||||
soon as it is uploaded on to this the Website and your continued use of the
|
||||
Website Service following any changes constitutes your acceptance of the new
|
||||
Terms. You are responsible for regularly reviewing these Terms so that you are
|
||||
aware of any changes to them. No other variation to these Terms shall be
|
||||
effective unless in writing and signed by an authorised representative on behalf
|
||||
of The Mod Archive. These Terms shall be governed by and construed in
|
||||
accordance with Dutch law and you agree to submit to the exclusive jurisdiction
|
||||
of the Dutch Courts in relation to any dispute arising out of or relating to
|
||||
these Terms and/or your use of the Website and/or the Website Service. If any
|
||||
provision(s) of these Terms is held by a court of competent jurisdiction to be
|
||||
invalid or unenforceable, then such provision(s) shall be construed, as nearly
|
||||
as possible, to reflect the intentions of the parties (as reflected in the
|
||||
provision(s)) and all other provisions shall remain in full force and effect.
|
||||
The Mod Archive's failure to exercise or enforce any right or provision of these
|
||||
Terms shall not constitute a waiver of such right or provision unless
|
||||
acknowledged and agreed to by The Mod Archive in writing. Unless otherwise
|
||||
expressly stated, nothing in the Terms shall create any rights or any other
|
||||
benefits whether pursuant to the Contracts (Rights of Third Parties) Act 1999 or
|
||||
otherwise in favour of any person other than you and The Mod Archive.
|
||||
|
||||
11. CONTACT: For support and help, use the appropriate forum within the site
|
||||
forums.
|
||||
|
79
examples/libnds/all/nitrofs/audio/music/mod-archive.txt
Normal file
@ -0,0 +1,79 @@
|
||||
Original site: https://modarchive.org/index.php?terms-upload
|
||||
|
||||
===============================================================================
|
||||
|
||||
Mod Archive Upload Terms, Conditions and License Agreement
|
||||
|
||||
Version 2.2 as of April 29th, 2009
|
||||
|
||||
This Agreement describes the legal relationship between you (an individual
|
||||
providing material by uploading songs or other files to the modarchive.org/com
|
||||
server) and the modarchive.org/com server operators ("us", "we" in the following
|
||||
text). Please read this document carefully. As this document is modified, the
|
||||
new version will apply to any files uploaded later than that date, but will not
|
||||
be applicable to previously uploaded files (see section 3.3).
|
||||
|
||||
Section 1: Copyright holders
|
||||
|
||||
1.1, General license. By providing a song/file to us, if you are the
|
||||
copyright holder of the song/file in question, you agree to grant us a
|
||||
non-exclusive, royalty-free, non-retractable non-terminable, worldwide
|
||||
license to: a) Distribute your song/file on the modarchive.org/com web site
|
||||
or in any other form of distribution that we deem appropriate. b) Publicly
|
||||
display, publicly perform, broadcast, encode, transmit, reproduce,
|
||||
manufacture and distribute your song/file in whole or in part, alone or in
|
||||
compilation with content provided by third parties, through any medium now
|
||||
known or hereafter devised. c) Apply non-destructive and non-changing
|
||||
compression systems to decrease the file sizes of the files uploaded to us.
|
||||
|
||||
1.2, License to redistribute. By providing a song/file to modarchive.org/com
|
||||
you furthermore agree to give anyone who wishes to redistribute your
|
||||
song/file a license to download the song/file from modarchive.org/com and do
|
||||
so, provided it has stayed in its original, unmodified, unbundled form.
|
||||
|
||||
Note: If you are visitor looking for information about using modules in your
|
||||
productions i.e games/applications, please see the Licensing FAQ in file
|
||||
mod-archive-faq.txt.
|
||||
|
||||
1.3, Ownership of Copyrights. You retain ownership of the copyrights and all
|
||||
other rights in the song/file provided to us, subject only to the
|
||||
non-exclusive rights granted to us under this Agreement. You are free to
|
||||
grant similar rights to others.
|
||||
|
||||
|
||||
Section 2: Non-copyright holders
|
||||
|
||||
2.1 License. By providing a song/file to us if you are not the copyright
|
||||
holder of said song/file, you agree that you have previously secured a
|
||||
license to redistribute the song, according to the terms of Section 1.
|
||||
|
||||
2.2 Copyright infringement. Furthermore you agree that you are fully
|
||||
responsible for your action of providing the song to modarchive.org/com, and
|
||||
that modarchive.org/com may hold you liable for any copyright infringement
|
||||
caused by your uploading of the song/file to the modarchive.org/com server,
|
||||
and thus that modarchive.org/com should not be held liable for any
|
||||
consequences of your actions.
|
||||
|
||||
|
||||
Section 3: General terms and conditions
|
||||
|
||||
See file mod-archive-terms.txt.
|
||||
|
||||
Section 4: Footnotes
|
||||
|
||||
4.1 Works in the public domain. Materials that have previously been
|
||||
distributed under public domain license (for example, PD Disk Distributors)
|
||||
are quite legal to upload to our servers as long as the material has not
|
||||
been modified from its original state since release. Any works submitted to
|
||||
The Mod Archive that are not uploaded by their creators or copyright holders
|
||||
are assumed to be released into the public domain prior to upload and
|
||||
therefore legally licensed for redistribution as Public Domain material by
|
||||
The Mod Archive. Materials that have been uploaded but have been modified
|
||||
since origin are submitted entirely at the uploaders own risk, where all
|
||||
liabilities remain with the uploader concerning any legal implications that
|
||||
arise from subsequent litigation should there be any incident where a party
|
||||
has cause to complain.
|
||||
|
||||
4.2 Footnote disclaimer. Should any section of the footnoted contradict the
|
||||
previous paragraphs in sections 1-3 inclusive, the paragraphs in sections
|
||||
1-3 inclusive take precedence.
|
@ -0,0 +1 @@
|
||||
{"_version":1,"_name":"fire_explosion","_locked":[],"sampleRate":44100,"attack":0,"sustain":0.027705693940245357,"sustainPunch":0,"decay":0.13257979056125957,"tremoloDepth":0,"tremoloFrequency":2.2776006915244977,"frequency":2095.7030570339975,"frequencySweep":-541.3667290180666,"frequencyDeltaSweep":-2800,"repeatFrequency":0,"frequencyJump1Onset":33,"frequencyJump1Amount":0,"frequencyJump2Onset":66,"frequencyJump2Amount":0,"harmonics":0,"harmonicsFalloff":0.5,"waveform":"whitenoise","interpolateNoise":false,"vibratoDepth":0,"vibratoFrequency":10,"squareDuty":50,"squareDutySweep":0,"flangerOffset":0,"flangerOffsetSweep":0,"bitCrush":16,"bitCrushSweep":0,"lowPassCutoff":22050,"lowPassCutoffSweep":0,"highPassCutoff":0,"highPassCutoffSweep":0,"compression":0.9,"normalization":true,"amplification":50}
|
BIN
examples/libnds/all/nitrofs/audio/sfx/fire_explosion.wav
Normal file
2
examples/libnds/all/nitrofs/graphics/neon.grit
Normal file
@ -0,0 +1,2 @@
|
||||
# bitmap, 16 bit
|
||||
-gb -gB16
|
BIN
examples/libnds/all/nitrofs/graphics/neon.png
Normal file
After Width: | Height: | Size: 55 KiB |
2
examples/libnds/all/nitrofs/graphics/neon.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Author: Antonio Niño Díaz, 2023
|
||||
License: CC0-1.0
|
1
examples/libnds/all/nitrofs/root/data_string.bin
Normal file
@ -0,0 +1 @@
|
||||
Hello from a bin file!
|
23
examples/libnds/all/teak/source1/main.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <teak/teak.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
teakInit();
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint16_t data0 = apbpReceiveData(0);
|
||||
uint16_t data1 = apbpReceiveData(1);
|
||||
uint16_t data2 = apbpReceiveData(2);
|
||||
|
||||
apbpSendData(0, data0);
|
||||
apbpSendData(1, data1 + data2);
|
||||
apbpSendData(2, data1 - data2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
23
examples/libnds/all/teak/source2/main.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <teak/teak.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
teakInit();
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint16_t data0 = apbpReceiveData(0);
|
||||
uint16_t data1 = apbpReceiveData(1);
|
||||
uint16_t data2 = apbpReceiveData(2);
|
||||
|
||||
apbpSendData(0, data0);
|
||||
apbpSendData(1, data1 + data2);
|
||||
apbpSendData(2, data1 - data2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
examples/libnds/arm9/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libnds/arm9/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
18
examples/libnds/arm9/build.py
Normal file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
arm9 = Arm9Binary(sourcedirs=['source'])
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9],
|
||||
game_title='ARM9 only',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
63
examples/libnds/arm9/source/main.c
Normal file
@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
|
||||
// Information about ANSI escape codes:
|
||||
//
|
||||
// https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences
|
||||
// Check the source code of the console in libnds to check which codes are
|
||||
// supported and which ones are not: source/arm9/console.c
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDemoInit();
|
||||
|
||||
// Clear console: [2J
|
||||
printf("\x1b[2J");
|
||||
|
||||
// Set cursor coordinates: [y;xH
|
||||
printf("\x1b[8;10HHello World!");
|
||||
|
||||
// Move cursor up: [deltayA
|
||||
printf("\x1b[8ALine 0");
|
||||
|
||||
// Move cursor left: [deltaxD
|
||||
printf("\x1b[28DColumn 0");
|
||||
|
||||
// Move cursor down: [deltayB
|
||||
printf("\x1b[19BLine 19");
|
||||
|
||||
// Move cursor right: [deltaxC
|
||||
printf("\x1b[5CColumn 20");
|
||||
|
||||
// Print colored text
|
||||
printf("\x1b[14;4H");
|
||||
|
||||
// Colors (30 to 37): Black, Red, Green, Yellow, BLue, Magenta, Cyan, White
|
||||
// Setting intensity to 1 will make them brighter.
|
||||
char c = 'A';
|
||||
for (int intensity = 0; intensity < 2; intensity++)
|
||||
for (int color = 30; color < 38; color++)
|
||||
printf("\x1b[%d;%dm%c", color, intensity, c++);
|
||||
|
||||
// Reset color to white
|
||||
printf("\x1b[39;0m");
|
||||
|
||||
printf("\x1b[23;0HPress START to exit to loader");
|
||||
|
||||
while (1)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & KEY_START)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
examples/libnds/arm9_arm7/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libnds/arm9_arm7/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
79
examples/libnds/arm9_arm7/arm7/source/main.c
Normal file
@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
//
|
||||
// Copyright (C) 2005 Michael Noland (joat)
|
||||
// Copyright (C) 2005 Jason Rogers (Dovoto)
|
||||
// Copyright (C) 2005-2015 Dave Murphy (WinterMute)
|
||||
// Copyright (C) 2023 Antonio Niño Díaz
|
||||
|
||||
// Default ARM7 core
|
||||
|
||||
#include <dswifi7.h>
|
||||
#include <nds.h>
|
||||
#include <maxmod7.h>
|
||||
|
||||
volatile bool exit_loop = false;
|
||||
|
||||
void power_button_callback(void)
|
||||
{
|
||||
exit_loop = true;
|
||||
}
|
||||
|
||||
void vblank_handler(void)
|
||||
{
|
||||
inputGetAndSend();
|
||||
Wifi_Update();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Initialize sound hardware
|
||||
enableSound();
|
||||
|
||||
// Read user information from the firmware (name, birthday, etc)
|
||||
readUserSettings();
|
||||
|
||||
// Stop LED blinking
|
||||
ledBlink(0);
|
||||
|
||||
// Using the calibration values read from the firmware with
|
||||
// readUserSettings(), calculate some internal values to convert raw
|
||||
// coordinates into screen coordinates.
|
||||
touchInit();
|
||||
|
||||
irqInit();
|
||||
irqSet(IRQ_VBLANK, vblank_handler);
|
||||
|
||||
fifoInit();
|
||||
|
||||
installWifiFIFO();
|
||||
installSoundFIFO();
|
||||
installSystemFIFO(); // Sleep mode, storage, firmware...
|
||||
|
||||
// Initialize Maxmod. It uses timer 0 internally.
|
||||
mmInstall(FIFO_MAXMOD);
|
||||
|
||||
// This sets a callback that is called when the power button in a DSi
|
||||
// console is pressed. It has no effect in a DS.
|
||||
setPowerButtonCB(power_button_callback);
|
||||
|
||||
// Read current date from the RTC and setup an interrupt to update the time
|
||||
// regularly. The interrupt simply adds one second every time, it doesn't
|
||||
// read the date. Reading the RTC is very slow, so it's a bad idea to do it
|
||||
// frequently.
|
||||
initClockIRQTimer(3);
|
||||
|
||||
irqEnable(IRQ_VBLANK);
|
||||
|
||||
while (!exit_loop)
|
||||
{
|
||||
const uint16_t key_mask = KEY_SELECT | KEY_START | KEY_L | KEY_R;
|
||||
uint16_t keys_pressed = ~REG_KEYINPUT;
|
||||
|
||||
if ((keys_pressed & key_mask) == key_mask)
|
||||
exit_loop = true;
|
||||
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
46
examples/libnds/arm9_arm7/arm9/source/main.c
Normal file
@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nds.h>
|
||||
#include <maxmod9.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Setup sub screen for the text console
|
||||
consoleDemoInit();
|
||||
|
||||
while (1)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint16_t keys = keysHeld();
|
||||
|
||||
if (keys & KEY_START)
|
||||
break;
|
||||
|
||||
// Clear console
|
||||
printf("\x1b[2J");
|
||||
|
||||
// Print current time
|
||||
char str[100];
|
||||
time_t t = time(NULL);
|
||||
struct tm *tmp = localtime(&t);
|
||||
if (strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S%z", tmp) == 0)
|
||||
snprintf(str, sizeof(str), "Failed to get time");
|
||||
printf("%s\n\n", str);
|
||||
|
||||
// Print some controls
|
||||
printf("START: Exit to loader\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
32
examples/libnds/arm9_arm7/build.py
Normal file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['arm9/source', 'common/source'],
|
||||
includedirs=['common/include'],
|
||||
libs=['nds9', 'mm9'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/maxmod']
|
||||
)
|
||||
arm9.generate_elf()
|
||||
|
||||
arm7 = Arm7Binary(
|
||||
sourcedirs=['arm7/source', 'common/source'],
|
||||
includedirs=['common/include'],
|
||||
libs=['nds7', 'mm7', 'dswifi7'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/maxmod',
|
||||
'${BLOCKSDS}/libs/dswifi']
|
||||
)
|
||||
arm7.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9, arm7],
|
||||
game_title='ARM9 + ARM7',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
10
examples/libnds/arm9_arm7/common/include/common.h
Normal file
@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
|
||||
#ifndef COMMON_H__
|
||||
#define COMMON_H__
|
||||
|
||||
int my_strlen(const char *s);
|
||||
|
||||
#endif // COMMON_H__
|
10
examples/libnds/arm9_arm7/common/source/common.c
Normal file
@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int my_strlen(const char *s)
|
||||
{
|
||||
return strlen(s);
|
||||
}
|
8
examples/libnds/arm9_nitrofs/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libnds/arm9_nitrofs/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
19
examples/libnds/arm9_nitrofs/build.py
Normal file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
arm9 = Arm9Binary(sourcedirs=['source'])
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
nitrofsdirs=['nitrofs'],
|
||||
binaries=[arm9],
|
||||
game_title='ARM9 and NitroFS',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
BIN
examples/libnds/arm9_nitrofs/nitrofs/random.bin
Normal file
177
examples/libnds/arm9_nitrofs/source/main.c
Normal file
@ -0,0 +1,177 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
|
||||
// Random file generated with:
|
||||
//
|
||||
// dd bs=1024 count=2048 < /dev/urandom > random.bin
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fatfs.h>
|
||||
#include <nds.h>
|
||||
#include <nds/cothread.h>
|
||||
#include <nds/arm9/dldi.h>
|
||||
|
||||
#include "md5/md5.h"
|
||||
|
||||
static char input_buffer[1024];
|
||||
|
||||
PrintConsole topScreen;
|
||||
PrintConsole bottomScreen;
|
||||
|
||||
int calculate_file_md5(void *arg)
|
||||
{
|
||||
const char *path = arg;
|
||||
|
||||
FILE *f = fopen(path, "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
consoleSelect(&topScreen);
|
||||
perror("fopen(random.bin)");
|
||||
fflush(stdout);
|
||||
return -1;
|
||||
}
|
||||
|
||||
consoleSelect(&topScreen);
|
||||
printf("Calculating MD5 in a thread\n");
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
size_t input_size = 0;
|
||||
|
||||
MD5Context ctx;
|
||||
md5Init(&ctx);
|
||||
|
||||
uint32_t size = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
input_size = fread(input_buffer, 1, 1024, f);
|
||||
if (input_size <= 0)
|
||||
break;
|
||||
|
||||
md5Update(&ctx, (uint8_t *)input_buffer, input_size);
|
||||
|
||||
size += input_size;
|
||||
if ((size % (1024 * 64)) == 0)
|
||||
{
|
||||
consoleSelect(&topScreen);
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
consoleSelect(&topScreen);
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
md5Finalize(&ctx);
|
||||
|
||||
uint8_t digest[16];
|
||||
memcpy(digest, ctx.digest, 16);
|
||||
|
||||
consoleSelect(&topScreen);
|
||||
for (int i = 0; i < 16; i++)
|
||||
printf("%02X", digest[i]);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
videoSetMode(MODE_0_2D);
|
||||
videoSetModeSub(MODE_0_2D);
|
||||
|
||||
vramSetBankA(VRAM_A_MAIN_BG);
|
||||
vramSetBankC(VRAM_C_SUB_BG);
|
||||
|
||||
consoleInit(&topScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true);
|
||||
consoleInit(&bottomScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
|
||||
|
||||
consoleSelect(&bottomScreen);
|
||||
|
||||
printf("\x1b[2J"); // Clear console
|
||||
|
||||
printf("DLDI name:\n");
|
||||
printf("%s\n", io_dldi_data->friendlyName);
|
||||
printf("\n");
|
||||
printf("DSi mode: %d\n", isDSiMode());
|
||||
|
||||
if (isDSiMode() == 0)
|
||||
{
|
||||
// In DS mode, access to the SD card is done with DLDI. When running on
|
||||
// emulators DLDI is not be needed, but cartridge reads happen in the
|
||||
// ARM7 at the moment. DLDI usually runs in the ARM9.
|
||||
//
|
||||
// If DLDI runs on the ARM9, it isn't possible to do multithreading
|
||||
// while accessing the filesystem. That can only work if the ARM7 loads
|
||||
// data while the ARM9 waits for it and switches to other threads in the
|
||||
// meantime.
|
||||
printf("Forcing DLDI in ARM7...\n");
|
||||
dldiSetMode(DLDI_MODE_ARM7);
|
||||
}
|
||||
|
||||
bool init_ok = nitroFSInit(NULL);
|
||||
if (!init_ok)
|
||||
{
|
||||
perror("nitroFSInit()");
|
||||
goto wait_loop;
|
||||
}
|
||||
|
||||
chdir("nitro:/");
|
||||
char *cwd = getcwd(NULL, 0);
|
||||
printf("Current dir: %s\n\n", cwd);
|
||||
free(cwd);
|
||||
|
||||
printf("\x1b[10;0;HMain thread: ");
|
||||
fflush(stdout);
|
||||
|
||||
// This thread needs enough stack to do filesystem access. By default it
|
||||
// isn't enough for it and it will make the ROM crash because of a stack
|
||||
// overflow.
|
||||
cothread_t load_thread = cothread_create(calculate_file_md5,
|
||||
(void *)"random.bin", 4 * 1024, 0);
|
||||
|
||||
int count = 0;
|
||||
while (1)
|
||||
{
|
||||
cothread_yield_irq(IRQ_VBLANK);
|
||||
|
||||
consoleSelect(&bottomScreen);
|
||||
printf("\x1b[10;14;H%5d", count);
|
||||
fflush(stdout);
|
||||
|
||||
count++;
|
||||
|
||||
if (cothread_has_joined(load_thread))
|
||||
{
|
||||
cothread_delete(load_thread);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wait_loop:
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
printf("Press START to exit to loader\n");
|
||||
|
||||
while (1)
|
||||
{
|
||||
cothread_yield_irq(IRQ_VBLANK);
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint32_t keys_down = keysDown();
|
||||
if (keys_down & KEY_START)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
291
examples/libnds/arm9_nitrofs/source/md5/README.md
Normal file
@ -0,0 +1,291 @@
|
||||
# MD5
|
||||
|
||||
Takes an input string or file and outputs its MD5 hash.
|
||||
|
||||
This repo is gaining a little more traffic than I expected, so I'll put this here as a little disclaimer. I wrote this code as a side project in college in an attempt to better understand the algorithm. I consider this repository to be a reference implementation with a good step by step walkthrough of the algorithm, not necessarily code to be built upon. I did verify the correctness of the output by comparing to other existing standalone programs. However, I did not research edge cases, set up automated testing, or attempt to run the program on any machine other than the laptop I had at the time, so here's the warning:
|
||||
|
||||
This code may be generally correct, but you should consider it untested to be on the safe side. There may be edge cases, vulnerabilities, or optimizations I did not consider when I wrote this. I can only confirm that this code probably worked correctly on a single computer in 2017.
|
||||
|
||||
Knowing that, do feel free to use this code in any way you wish, no credit needed. And if you find a problem, raise an issue.
|
||||
|
||||
### Implementing into Code
|
||||
|
||||
If you want to include the md5 algorithm in your own code, you'll only need `md5.c` and `md5.h`.
|
||||
|
||||
```c
|
||||
#include "md5.h"
|
||||
|
||||
...
|
||||
|
||||
void foo(){
|
||||
uint8_t result[16];
|
||||
md5String("Hello, World!", result); // *result = 65a8e27d8879283831b664bd8b7f0ad4
|
||||
|
||||
FILE bar = fopen("bar.txt", "r");
|
||||
md5File(bar, result); // Reads a file from a file pointer
|
||||
md5File(stdin, result); // Can easily read from stdin
|
||||
|
||||
// Manual use
|
||||
..
|
||||
MD5Context ctx;
|
||||
md5Init(&ctx);
|
||||
|
||||
...
|
||||
md5Update(&ctx, input1, input1_size);
|
||||
...
|
||||
md5Update(&ctx, input2, input2_size);
|
||||
...
|
||||
md5Update(&ctx, input3, input3_size);
|
||||
...
|
||||
|
||||
md5Finalize(&ctx);
|
||||
|
||||
ctx.digest; // Result of hashing (as uint8_t* with 16 bytes)
|
||||
}
|
||||
```
|
||||
|
||||
### Command Line
|
||||
|
||||
You can directly use the binary built with this Makefile to process text or files in the command line.
|
||||
|
||||
Any arguments will be interpreted as strings. Each argument will be interpreted as a separate string to hash, and will be given its own output (in the order of input).
|
||||
|
||||
```shell
|
||||
$ make
|
||||
|
||||
$ ./md5 "Hello, World!"
|
||||
65a8e27d8879283831b664bd8b7f0ad4
|
||||
|
||||
$ ./md5 "Multiple" Strings
|
||||
a0bf169f2539e893e00d7b1296bc4d8e
|
||||
89be9433646f5939040a78971a5d103a
|
||||
|
||||
$ ./md5 ""
|
||||
d41d8cd98f00b204e9800998ecf8427e
|
||||
|
||||
$ ./md5 "Can use \" escapes"
|
||||
7bf94222f6dbcd25d6fa21d5985f5634
|
||||
```
|
||||
If no arguments are given, input is taken from standard input.
|
||||
```shell
|
||||
$ make
|
||||
|
||||
$ echo -n "Hello, World!" | ./md5
|
||||
65a8e27d8879283831b664bd8b7f0ad4
|
||||
|
||||
$ echo "Hello, World!" | ./md5
|
||||
bea8252ff4e80f41719ea13cdf007273
|
||||
|
||||
$ echo "File Input" > testFile | ./md5
|
||||
d41d8cd98f00b204e9800998ecf8427e
|
||||
|
||||
$ cat testFile | ./md5
|
||||
7dacda86e382b27c25a92f8f2f6a5cd8
|
||||
|
||||
```
|
||||
As seen above, it is important to note that many programs will output a newline character after their output. This newline *will* affect the output of the MD5 algorithm. `echo` has the `-n` flag that prevents the output of said character.
|
||||
|
||||
If entering input by hand, end collection of data by entering an EOF character (`Ctrl+D` in some cases).
|
||||
|
||||
# The Algorithm
|
||||
|
||||
While researching this algorithm, the only relatively complete description I found came from RSA Data Security itself in [this memo][1]. And while the description is adequate, any confusion is very difficult to clear up, especially given the nature of the algorithm's output. So here I will try to describe the algorithm used in these implementations with examples.
|
||||
|
||||
The algorithm considers all words to be little-endian. I will also specify where this may be confusing.
|
||||
|
||||
The algorithm takes in an input of arbitrary length in bits. This can be a string, a file, a number, a struct, etc... It also doesn't need to be byte-aligned, though it almost always is. We'll call this input the message. The output is the digest.
|
||||
|
||||
#### Step 1: Padding
|
||||
|
||||
The provided message is padded by appending bits to the end until its length is congruent to `448 mod 512` bits. In other words, the message is padded so that its length is 64 bits less than the next multiple of 512. If the original message's length already meets this requirement before padding, it is still padded with 512 bits.
|
||||
|
||||
The padding is simply a single "1" bit at the end of the message followed by enough "0" bits to satisfy the length condition above.
|
||||
|
||||
##### Example
|
||||
|
||||
Let's pass the string "Hello, world!" to the algorithm. Those characters converted to hexadecimal numbers look like this:
|
||||
```
|
||||
48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21
|
||||
```
|
||||
(Note: Strings are often null-terminated. This null character is not taken into account, as you will see.)
|
||||
|
||||
Now we have to pad our message bits:
|
||||
```
|
||||
0x 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 80 00 00
|
||||
0x 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x 00 00 00 00 00 00 00 00
|
||||
```
|
||||
Note the `0x80` right after the end of our message. We're writing a stream of bits, not bytes. Setting the bit after our message to "1" and the next 7 bits to "0" means writing the byte `1000 0000` or `0x80`.
|
||||
|
||||
#### Step 2: Appending the Length
|
||||
|
||||
Next, the length of the message modulus 2^64 is appended in little endian to the message to round out the total length to a multiple of 512. This length is the number of *bits* in the original message, modulus 2^64. It's common to split this number into two 32-bit words, so keep careful track of which bytes are put where; the highest order byte should be the last byte in the message. This will round out the length of the whole message to a multiple of 512.
|
||||
|
||||
##### Example 1
|
||||
|
||||
The length of our message is 104 bits. The 64-bit representation of the number 104 in hexadecimal is `0x00000000 00000068`. So we'll append that number to the end.
|
||||
|
||||
```
|
||||
0x 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 80 00 00
|
||||
0x 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x 00 00 00 00 00 00 00 00 68 00 00 00 00 00 00 00
|
||||
```
|
||||
|
||||
(We're writing in little-endian, so the lowest order byte is written first.)
|
||||
|
||||
If you're holding the length in two separate 32-bit words, make sure to append the lower order bytes first.
|
||||
|
||||
##### Example 2
|
||||
|
||||
Because our "Hello, world!" example is so small and doesn't give a length with more than two digits, let's say we have a different, bigger message of `0x12345678 90ABCDEF` bits and this chunk we're looking at is just the tail end that we have to pad out. The appended length would look like this:
|
||||
|
||||
```
|
||||
0x 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 80 00 00
|
||||
0x 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
0x 00 00 00 00 00 00 00 00 EF CD AB 90 78 56 34 12
|
||||
```
|
||||
|
||||
#### Step 3: Initializing the Buffer
|
||||
|
||||
The variables that will eventually hold our digest must be initialized to the following:
|
||||
|
||||
```
|
||||
A = 0x01234567
|
||||
B = 0x89abcdef
|
||||
C = 0xfedcba98
|
||||
D = 0x76543210
|
||||
```
|
||||
|
||||
#### Step 4: Processing
|
||||
|
||||
There are four functions defined in the RSA memo that are used to collapse three 32-bit words into one 32-bit word:
|
||||
|
||||
```
|
||||
F(X, Y, Z) = (X & Y) | (~X & Z)
|
||||
G(X, Y, Z) = (X & Z) | (Y & ~Z)
|
||||
H(X, Y, Z) = X ^ Y ^ Z
|
||||
I(X, Y, Z) = Y ^ (X | ~Z)
|
||||
```
|
||||
|
||||
These are bitwise operations.
|
||||
|
||||
We also have to do a left rotate on the bits in a word. That is, shift the bits left, and move overflow to the right. Like spinning a bottle and seeing the label loop around. The function is defined as follows:
|
||||
|
||||
```
|
||||
rotate_left(x, n) = (x << n) | (x >> (32 - n))
|
||||
```
|
||||
|
||||
The constants in K and S can be found at the bottom of this section.
|
||||
|
||||
The message is split into blocks of 512 bits. Each block is split into 16 32-bit words. For each block, do the following:
|
||||
|
||||
```c
|
||||
AA = A;
|
||||
BB = B;
|
||||
CC = C;
|
||||
DD = D;
|
||||
|
||||
for(i in 0 to 63){
|
||||
if(0 <= i <= 15){
|
||||
E = F(BB, CC, DD);
|
||||
j = i;
|
||||
}
|
||||
else if(16 <= i <= 31){
|
||||
E = G(BB, CC, DD);
|
||||
j = ((i * 5) + 1) % 16;
|
||||
}
|
||||
else if(32 <= i <= 47){
|
||||
E = H(BB, CC, DD);
|
||||
j = ((i * 3) + 5) % 16;
|
||||
}
|
||||
else{
|
||||
E = I(BB, CC, DD);
|
||||
j = (i * 7) % 16;
|
||||
}
|
||||
|
||||
temp = DD;
|
||||
DD = CC;
|
||||
CC = BB;
|
||||
BB = BB + rotate_left(AA + E + K[i] + input[j], S[i]);
|
||||
AA = temp;
|
||||
}
|
||||
|
||||
A += AA;
|
||||
B += BB;
|
||||
C += CC;
|
||||
D += DD;
|
||||
```
|
||||
|
||||
The RSA memo explicitly lists each step instead of using control structures. The result is the same.
|
||||
|
||||
An example for this step is not particularly useful, as the data produced by the loop is not very meaningful for observation.
|
||||
|
||||
#### Step 5: Output
|
||||
|
||||
The digest is a 128-bit number written in little endian, and is contained in A, B, C, and D after the algorithm is finished. Just arrange the bytes so that the lowest-order byte of the digest is the lowest-order byte of A, and the highest-order byte of the digest is the highest-order byte of D.
|
||||
|
||||
##### Example
|
||||
|
||||
Here is the output of a few strings to check against:
|
||||
|
||||
"Hello, world!"
|
||||
|
||||
```
|
||||
6cd3556deb0da54bca060b4c39479839
|
||||
```
|
||||
|
||||
"" (empty string)
|
||||
|
||||
```
|
||||
d41d8cd98f00b204e9800998ecf8427e
|
||||
```
|
||||
|
||||
"The quick brown fox jumps over the lazy dog."
|
||||
|
||||
```
|
||||
e4d909c290d0fb1ca068ffaddf22cbd0
|
||||
```
|
||||
|
||||
#### Constants and Functions
|
||||
|
||||
```c
|
||||
A = 0x01234567
|
||||
B = 0x89abcdef
|
||||
C = 0xfedcba98
|
||||
D = 0x76543210
|
||||
|
||||
K[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}
|
||||
|
||||
S[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}
|
||||
|
||||
|
||||
F(X, Y, Z) = (X & Y) | (~X & Z)
|
||||
G(X, Y, Z) = (X & Z) | (Y & ~Z)
|
||||
H(X, Y, Z) = X ^ Y ^ Z
|
||||
I(X, Y, Z) = Y ^ (X | ~Z)
|
||||
|
||||
rotate_left(x, n) = (x << n) | (x >> (32 - n))
|
||||
```
|
||||
|
||||
[1]: https://tools.ietf.org/html/rfc1321
|
22
examples/libnds/arm9_nitrofs/source/md5/UNLICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
223
examples/libnds/arm9_nitrofs/source/md5/md5.c
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
|
||||
* and modified slightly to be functionally identical but condensed into control structures.
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
* Constants defined by the MD5 algorithm
|
||||
*/
|
||||
#define A 0x67452301
|
||||
#define B 0xefcdab89
|
||||
#define C 0x98badcfe
|
||||
#define D 0x10325476
|
||||
|
||||
static uint32_t S[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||
|
||||
static uint32_t K[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
||||
|
||||
/*
|
||||
* Padding used to make the size (in bits) of the input congruent to 448 mod 512
|
||||
*/
|
||||
static uint8_t PADDING[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/*
|
||||
* Bit-manipulation functions defined by the MD5 algorithm
|
||||
*/
|
||||
#define F(X, Y, Z) ((X & Y) | (~X & Z))
|
||||
#define G(X, Y, Z) ((X & Z) | (Y & ~Z))
|
||||
#define H(X, Y, Z) (X ^ Y ^ Z)
|
||||
#define I(X, Y, Z) (Y ^ (X | ~Z))
|
||||
|
||||
/*
|
||||
* Rotates a 32-bit word left by n bits
|
||||
*/
|
||||
uint32_t rotateLeft(uint32_t x, uint32_t n){
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize a context
|
||||
*/
|
||||
void md5Init(MD5Context *ctx){
|
||||
ctx->size = (uint64_t)0;
|
||||
|
||||
ctx->buffer[0] = (uint32_t)A;
|
||||
ctx->buffer[1] = (uint32_t)B;
|
||||
ctx->buffer[2] = (uint32_t)C;
|
||||
ctx->buffer[3] = (uint32_t)D;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add some amount of input to the context
|
||||
*
|
||||
* If the input fills out a block of 512 bits, apply the algorithm (md5Step)
|
||||
* and save the result in the buffer. Also updates the overall size.
|
||||
*/
|
||||
void md5Update(MD5Context *ctx, uint8_t *input_buffer, size_t input_len){
|
||||
uint32_t input[16];
|
||||
unsigned int offset = ctx->size % 64;
|
||||
ctx->size += (uint64_t)input_len;
|
||||
|
||||
// Copy each byte in input_buffer into the next space in our context input
|
||||
for(unsigned int i = 0; i < input_len; ++i){
|
||||
ctx->input[offset++] = (uint8_t)*(input_buffer + i);
|
||||
|
||||
// If we've filled our context input, copy it into our local array input
|
||||
// then reset the offset to 0 and fill in a new buffer.
|
||||
// Every time we fill out a chunk, we run it through the algorithm
|
||||
// to enable some back and forth between cpu and i/o
|
||||
if(offset % 64 == 0){
|
||||
for(unsigned int j = 0; j < 16; ++j){
|
||||
// Convert to little-endian
|
||||
// The local variable `input` our 512-bit chunk separated into 32-bit words
|
||||
// we can use in calculations
|
||||
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
|
||||
(uint32_t)(ctx->input[(j * 4)]);
|
||||
}
|
||||
md5Step(ctx->buffer, input);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad the current input to get to 448 bytes, append the size in bits to the very end,
|
||||
* and save the result of the final iteration into digest.
|
||||
*/
|
||||
void md5Finalize(MD5Context *ctx){
|
||||
uint32_t input[16];
|
||||
unsigned int offset = ctx->size % 64;
|
||||
unsigned int padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset;
|
||||
|
||||
// Fill in the padding and undo the changes to size that resulted from the update
|
||||
md5Update(ctx, PADDING, padding_length);
|
||||
ctx->size -= (uint64_t)padding_length;
|
||||
|
||||
// Do a final update (internal to this function)
|
||||
// Last two 32-bit words are the two halves of the size (converted from bytes to bits)
|
||||
for(unsigned int j = 0; j < 14; ++j){
|
||||
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
|
||||
(uint32_t)(ctx->input[(j * 4)]);
|
||||
}
|
||||
input[14] = (uint32_t)(ctx->size * 8);
|
||||
input[15] = (uint32_t)((ctx->size * 8) >> 32);
|
||||
|
||||
md5Step(ctx->buffer, input);
|
||||
|
||||
// Move the result into digest (convert from little-endian)
|
||||
for(unsigned int i = 0; i < 4; ++i){
|
||||
ctx->digest[(i * 4) + 0] = (uint8_t)((ctx->buffer[i] & 0x000000FF));
|
||||
ctx->digest[(i * 4) + 1] = (uint8_t)((ctx->buffer[i] & 0x0000FF00) >> 8);
|
||||
ctx->digest[(i * 4) + 2] = (uint8_t)((ctx->buffer[i] & 0x00FF0000) >> 16);
|
||||
ctx->digest[(i * 4) + 3] = (uint8_t)((ctx->buffer[i] & 0xFF000000) >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Step on 512 bits of input with the main MD5 algorithm.
|
||||
*/
|
||||
void md5Step(uint32_t *buffer, uint32_t *input){
|
||||
uint32_t AA = buffer[0];
|
||||
uint32_t BB = buffer[1];
|
||||
uint32_t CC = buffer[2];
|
||||
uint32_t DD = buffer[3];
|
||||
|
||||
uint32_t E;
|
||||
|
||||
unsigned int j;
|
||||
|
||||
for(unsigned int i = 0; i < 64; ++i){
|
||||
switch(i / 16){
|
||||
case 0:
|
||||
E = F(BB, CC, DD);
|
||||
j = i;
|
||||
break;
|
||||
case 1:
|
||||
E = G(BB, CC, DD);
|
||||
j = ((i * 5) + 1) % 16;
|
||||
break;
|
||||
case 2:
|
||||
E = H(BB, CC, DD);
|
||||
j = ((i * 3) + 5) % 16;
|
||||
break;
|
||||
default:
|
||||
E = I(BB, CC, DD);
|
||||
j = (i * 7) % 16;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t temp = DD;
|
||||
DD = CC;
|
||||
CC = BB;
|
||||
BB = BB + rotateLeft(AA + E + K[i] + input[j], S[i]);
|
||||
AA = temp;
|
||||
}
|
||||
|
||||
buffer[0] += AA;
|
||||
buffer[1] += BB;
|
||||
buffer[2] += CC;
|
||||
buffer[3] += DD;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions that run the algorithm on the provided input and put the digest into result.
|
||||
* result should be able to store 16 bytes.
|
||||
*/
|
||||
void md5String(char *input, uint8_t *result){
|
||||
MD5Context ctx;
|
||||
md5Init(&ctx);
|
||||
md5Update(&ctx, (uint8_t *)input, strlen(input));
|
||||
md5Finalize(&ctx);
|
||||
|
||||
memcpy(result, ctx.digest, 16);
|
||||
}
|
||||
|
||||
void md5File(FILE *file, uint8_t *result){
|
||||
char *input_buffer = malloc(1024);
|
||||
size_t input_size = 0;
|
||||
|
||||
MD5Context ctx;
|
||||
md5Init(&ctx);
|
||||
|
||||
while((input_size = fread(input_buffer, 1, 1024, file)) > 0){
|
||||
md5Update(&ctx, (uint8_t *)input_buffer, input_size);
|
||||
}
|
||||
|
||||
md5Finalize(&ctx);
|
||||
|
||||
free(input_buffer);
|
||||
|
||||
memcpy(result, ctx.digest, 16);
|
||||
}
|
24
examples/libnds/arm9_nitrofs/source/md5/md5.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct{
|
||||
uint64_t size; // Size of input in bytes
|
||||
uint32_t buffer[4]; // Current accumulation of hash
|
||||
uint8_t input[64]; // Input to be used in the next step
|
||||
uint8_t digest[16]; // Result of algorithm
|
||||
}MD5Context;
|
||||
|
||||
void md5Init(MD5Context *ctx);
|
||||
void md5Update(MD5Context *ctx, uint8_t *input, size_t input_len);
|
||||
void md5Finalize(MD5Context *ctx);
|
||||
void md5Step(uint32_t *buffer, uint32_t *input);
|
||||
|
||||
void md5String(char *input, uint8_t *result);
|
||||
void md5File(FILE *file, uint8_t *result);
|
||||
|
||||
#endif
|
1
examples/libnds/arm9_nitrofs/source/md5/url.txt
Normal file
@ -0,0 +1 @@
|
||||
https://github.com/Zunawe/md5-c/tree/f3529b666b7ae8b80b0a9fa88ac2a91b389909c7
|
8
examples/libnds/debug_build/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libnds/debug_build/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
34
examples/libnds/debug_build/build.py
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
import sys
|
||||
|
||||
argv = sys.argv
|
||||
|
||||
if '--debug' in argv:
|
||||
argv.remove('--debug') # Don't pass this to the build system
|
||||
defines_ = []
|
||||
libs_ = ['nds9d']
|
||||
else:
|
||||
defines_ = ['NDEBUG']
|
||||
libs_ = ['nds9']
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['source'],
|
||||
defines=defines_,
|
||||
libs=libs_,
|
||||
)
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9],
|
||||
game_title='Debug and release builds',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments(args=argv)
|
18
examples/libnds/debug_build/readme.rst
Normal file
@ -0,0 +1,18 @@
|
||||
Instructions
|
||||
============
|
||||
|
||||
When switching between debug and release builds, the build system will detect
|
||||
that the libraries and defines have changed and rebuild everything that has been
|
||||
affected.
|
||||
|
||||
Build release ROM:
|
||||
|
||||
.. code:: python
|
||||
|
||||
python3 build.py
|
||||
|
||||
Build debug ROM:
|
||||
|
||||
.. code:: python
|
||||
|
||||
python3 build.py --debug
|
38
examples/libnds/debug_build/source/main.c
Normal file
@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDemoInit();
|
||||
|
||||
printf("sassert() test\n\n");
|
||||
|
||||
// The values passed to this function are out of range, and they should
|
||||
// cause an assertion to fail.
|
||||
|
||||
glFogColor(54, 30, 12, 70);
|
||||
|
||||
// In a debug build this point will never be reached.
|
||||
|
||||
printf("This is a release build.\n");
|
||||
printf("No sassert() will be checked\n\n");
|
||||
|
||||
printf("Press START to exit to loader");
|
||||
|
||||
while (1)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
|
||||
scanKeys();
|
||||
|
||||
if (keysDown() & KEY_START)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
examples/libnds/dsp/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libnds/dsp/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
177
examples/libnds/dsp/arm9/source/main.c
Normal file
@ -0,0 +1,177 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <filesystem.h>
|
||||
#include <nds.h>
|
||||
|
||||
#include "teak/teak1_tlf.h"
|
||||
|
||||
__attribute__((noreturn)) void WaitLoop(void)
|
||||
{
|
||||
printf("Press START to exit");
|
||||
while (1)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
if (keysHeld() & KEY_START)
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void *load_file(const char *path)
|
||||
{
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
|
||||
if (fseek(file, 0, SEEK_END) != 0)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
void *buffer = malloc(size);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(buffer, 1, size, file) != size)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void load_tlf(const void *ptr)
|
||||
{
|
||||
if (dspExecuteDefaultTLF(ptr) != DSP_EXEC_OK)
|
||||
{
|
||||
printf("Failed to execute TLF");
|
||||
WaitLoop();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Setup sub screen for the text console
|
||||
consoleDemoInit();
|
||||
|
||||
if (!isDSiMode())
|
||||
{
|
||||
printf("This demo must run on a DSi");
|
||||
WaitLoop();
|
||||
}
|
||||
|
||||
if (!nitroFSInit(NULL))
|
||||
{
|
||||
printf("nitroFSInit failed.\n");
|
||||
WaitLoop();
|
||||
}
|
||||
|
||||
void *tlf_from_nitrofs = load_file("teak/teak2.tlf");
|
||||
if (tlf_from_nitrofs == NULL)
|
||||
{
|
||||
printf("Failed to load TLF file from NitroFS");
|
||||
WaitLoop();
|
||||
}
|
||||
|
||||
uint16_t cmd0 = 0;
|
||||
int16_t cmd1 = 15;
|
||||
int16_t cmd2 = 5;
|
||||
|
||||
uint16_t rep0 = 0;
|
||||
int16_t rep1 = 0;
|
||||
int16_t rep2 = 0;
|
||||
|
||||
// Load the binary from ARM9 data initially
|
||||
load_tlf(teak1_tlf);
|
||||
char *tlf_name = "teak1";
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Synchronize game loop to the screen refresh
|
||||
swiWaitForVBlank();
|
||||
|
||||
// Clear console
|
||||
printf("\x1b[2J");
|
||||
|
||||
// Print some controls
|
||||
printf("Current TLF: %s\n", tlf_name);
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
printf("L: Load TLF1\n");
|
||||
printf("R: Load TLF2\n");
|
||||
printf("PAD: Change values\n");
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
printf("START: Exit to loader\n");
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
// Handle user input
|
||||
// -----------------
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint16_t keys = keysHeld();
|
||||
uint16_t keys_down = keysDown();
|
||||
|
||||
if (keys & KEY_LEFT)
|
||||
cmd1++;
|
||||
if (keys & KEY_RIGHT)
|
||||
cmd1--;
|
||||
|
||||
if (keys & KEY_UP)
|
||||
cmd2++;
|
||||
if (keys & KEY_DOWN)
|
||||
cmd2--;
|
||||
|
||||
if (keys_down & KEY_L)
|
||||
{
|
||||
// Load the binary from ARM9 data initially
|
||||
load_tlf(teak1_tlf);
|
||||
tlf_name = "teak1";
|
||||
}
|
||||
if (keys_down & KEY_R)
|
||||
{
|
||||
// Load the binary from NitroFS
|
||||
load_tlf(tlf_from_nitrofs);
|
||||
tlf_name = "teak2";
|
||||
}
|
||||
|
||||
if (keys & KEY_START)
|
||||
break;
|
||||
|
||||
// DSP communications
|
||||
|
||||
printf("CMD: %u %d %d\n", cmd0, cmd1, cmd2);
|
||||
|
||||
cmd0++; // Heartbeat
|
||||
|
||||
if (dspSendDataReady(0))
|
||||
dspSendData(0, cmd0);
|
||||
if (dspSendDataReady(1))
|
||||
dspSendData(1, cmd1);
|
||||
if (dspSendDataReady(2))
|
||||
dspSendData(2, cmd2);
|
||||
|
||||
if (dspReceiveDataReady(0))
|
||||
rep0 = dspReceiveData(0);
|
||||
if (dspReceiveDataReady(1))
|
||||
rep1 = dspReceiveData(1);
|
||||
if (dspReceiveDataReady(2))
|
||||
rep2 = dspReceiveData(2);
|
||||
|
||||
printf("REP: %u %d %d\n", rep0, rep1, rep2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
37
examples/libnds/dsp/build.py
Normal file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
teak1 = TeakBinary(
|
||||
name='teak1',
|
||||
sourcedirs=['teak/source1'],
|
||||
)
|
||||
teak1.generate_tlf()
|
||||
|
||||
teak2 = TeakBinary(
|
||||
name='teak2',
|
||||
sourcedirs=['teak/source2'],
|
||||
)
|
||||
teak2.generate_tlf()
|
||||
|
||||
nitrofs = NitroFS()
|
||||
nitrofs.add_tlf(teak2)
|
||||
nitrofs.generate_image()
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['arm9/source'],
|
||||
)
|
||||
arm9.add_tlf(teak1)
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[teak1, teak2, arm9, nitrofs],
|
||||
game_title='Multiple DSP binaries',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
23
examples/libnds/dsp/teak/source1/main.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <teak/teak.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
teakInit();
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint16_t data0 = apbpReceiveData(0);
|
||||
uint16_t data1 = apbpReceiveData(1);
|
||||
uint16_t data2 = apbpReceiveData(2);
|
||||
|
||||
apbpSendData(0, data0);
|
||||
apbpSendData(1, data1 + data2);
|
||||
apbpSendData(2, data1 - data2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
23
examples/libnds/dsp/teak/source2/main.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <teak/teak.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
teakInit();
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint16_t data0 = apbpReceiveData(0);
|
||||
uint16_t data1 = apbpReceiveData(1);
|
||||
uint16_t data2 = apbpReceiveData(2);
|
||||
|
||||
apbpSendData(0, data0);
|
||||
apbpSendData(1, -data1);
|
||||
apbpSendData(2, -data2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
examples/libnds/opengl/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libnds/opengl/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
21
examples/libnds/opengl/build.py
Normal file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['source'],
|
||||
)
|
||||
arm9.add_grit(['graphics'])
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9],
|
||||
game_title='OpenGL example',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
2
examples/libnds/opengl/graphics/neon.grit
Normal file
@ -0,0 +1,2 @@
|
||||
# bitmap, 16 bit
|
||||
-gb -gB16
|
BIN
examples/libnds/opengl/graphics/neon.png
Normal file
After Width: | Height: | Size: 55 KiB |
130
examples/libnds/opengl/source/main.c
Normal file
@ -0,0 +1,130 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
#include "grit/neon_png.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int textureID;
|
||||
|
||||
videoSetMode(MODE_0_3D);
|
||||
|
||||
glInit();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_ANTIALIAS);
|
||||
|
||||
// The background must be fully opaque and have a unique polygon ID
|
||||
// (different from the polygons that are going to be drawn) so that
|
||||
// antialias works.
|
||||
glClearColor(0, 0, 0, 31);
|
||||
glClearPolyID(63);
|
||||
|
||||
glClearDepth(0x7FFF);
|
||||
|
||||
glViewport(0, 0, 255, 191);
|
||||
|
||||
// Setup some VRAM as memory for textures
|
||||
vramSetBankA(VRAM_A_TEXTURE);
|
||||
|
||||
// Load texture
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(0, textureID);
|
||||
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0,
|
||||
TEXGEN_TEXCOORD, (u8*)neon_pngBitmap);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
|
||||
|
||||
gluLookAt(0.0, 0.0, 2.0, // Position
|
||||
0.0, 0.0, 0.0, // Look at
|
||||
0.0, 1.0, 0.0); // Up
|
||||
|
||||
// Setup sub screen for the text console
|
||||
consoleDemoInit();
|
||||
|
||||
int angle_x = 0;
|
||||
int angle_z = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Synchronize game loop to the screen refresh
|
||||
swiWaitForVBlank();
|
||||
|
||||
// Print some text in the demo console
|
||||
// -----------------------------------
|
||||
|
||||
// Clear console
|
||||
printf("\x1b[2J");
|
||||
|
||||
// Print some controls
|
||||
printf("PAD: Rotate triangle\n");
|
||||
printf("START: Exit to loader\n");
|
||||
printf("\n");
|
||||
|
||||
// Handle user input
|
||||
// -----------------
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint16_t keys = keysHeld();
|
||||
|
||||
if (keys & KEY_LEFT)
|
||||
angle_z += 3;
|
||||
if (keys & KEY_RIGHT)
|
||||
angle_z -= 3;
|
||||
|
||||
if (keys & KEY_UP)
|
||||
angle_x += 3;
|
||||
if (keys & KEY_DOWN)
|
||||
angle_x -= 3;
|
||||
|
||||
if (keys & KEY_START)
|
||||
break;
|
||||
|
||||
// Render 3D scene
|
||||
// ---------------
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glRotateZ(angle_z);
|
||||
glRotateX(angle_x);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
|
||||
|
||||
glBindTexture(0, textureID);
|
||||
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(0, inttot16(128)));
|
||||
glVertex3v16(floattov16(-1), floattov16(-1), 0);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(inttot16(128),inttot16(128)));
|
||||
glVertex3v16(floattov16(1), floattov16(-1), 0);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(inttot16(128), 0));
|
||||
glVertex3v16(floattov16(1), floattov16(1), 0);
|
||||
|
||||
GFX_TEX_COORD = (TEXTURE_PACK(0,0));
|
||||
glVertex3v16(floattov16(-1), floattov16(1), 0);
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
glPopMatrix(1);
|
||||
|
||||
glFlush(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
examples/libxm7/play_songs/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/libxm7/play_songs/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
92
examples/libxm7/play_songs/arm7/source/main.c
Normal file
@ -0,0 +1,92 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
//
|
||||
// Copyright (C) 2005 Michael Noland (joat)
|
||||
// Copyright (C) 2005 Jason Rogers (Dovoto)
|
||||
// Copyright (C) 2005-2015 Dave Murphy (WinterMute)
|
||||
// Copyright (C) 2023 Antonio Niño Díaz
|
||||
|
||||
#include <dswifi7.h>
|
||||
#include <libxm7.h>
|
||||
#include <nds.h>
|
||||
|
||||
// Assign FIFO_USER_07 channel to libxm7
|
||||
#define FIFO_XM7 (FIFO_USER_07)
|
||||
|
||||
volatile bool exit_loop = false;
|
||||
|
||||
void power_button_callback(void)
|
||||
{
|
||||
exit_loop = true;
|
||||
}
|
||||
|
||||
void vblank_handler(void)
|
||||
{
|
||||
inputGetAndSend();
|
||||
Wifi_Update();
|
||||
}
|
||||
|
||||
void XM7_Value32Handler(u32 command, void *userdata)
|
||||
{
|
||||
XM7_ModuleManager_Type *module = (XM7_ModuleManager_Type *)command;
|
||||
|
||||
if (module == NULL)
|
||||
XM7_StopModule();
|
||||
else
|
||||
XM7_PlayModule(module);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Initialize sound hardware
|
||||
enableSound();
|
||||
|
||||
// Read user information from the firmware (name, birthday, etc)
|
||||
readUserSettings();
|
||||
|
||||
// Stop LED blinking
|
||||
ledBlink(0);
|
||||
|
||||
// Using the calibration values read from the firmware with
|
||||
// readUserSettings(), calculate some internal values to convert raw
|
||||
// coordinates into screen coordinates.
|
||||
touchInit();
|
||||
|
||||
irqInit();
|
||||
irqSet(IRQ_VBLANK, vblank_handler);
|
||||
|
||||
fifoInit();
|
||||
|
||||
installWifiFIFO();
|
||||
installSoundFIFO();
|
||||
installSystemFIFO(); // Sleep mode, storage, firmware...
|
||||
|
||||
// This sets a callback that is called when the power button in a DSi
|
||||
// console is pressed. It has no effect in a DS.
|
||||
setPowerButtonCB(power_button_callback);
|
||||
|
||||
// Read current date from the RTC and setup an interrupt to update the time
|
||||
// regularly. The interrupt simply adds one second every time, it doesn't
|
||||
// read the date. Reading the RTC is very slow, so it's a bad idea to do it
|
||||
// frequently.
|
||||
initClockIRQTimer(3);
|
||||
|
||||
irqEnable(IRQ_VBLANK);
|
||||
|
||||
// Initialize libxm7. It uses timer 1 internally.
|
||||
XM7_Initialize();
|
||||
// Setup the FIFO handler for libXM7
|
||||
fifoSetValue32Handler(FIFO_XM7, XM7_Value32Handler, 0);
|
||||
|
||||
while (!exit_loop)
|
||||
{
|
||||
const uint16_t key_mask = KEY_SELECT | KEY_START | KEY_L | KEY_R;
|
||||
uint16_t keys_pressed = ~REG_KEYINPUT;
|
||||
|
||||
if ((keys_pressed & key_mask) == key_mask)
|
||||
exit_loop = true;
|
||||
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
120
examples/libxm7/play_songs/arm9/source/main.c
Normal file
@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
|
||||
#include <nds.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libxm7.h>
|
||||
|
||||
// XM module by Lasse. Obtained from the original libxm7 example by sverx
|
||||
#include <data/lasse_haen_pyykit_xm.h>
|
||||
|
||||
// Parallax Glacier by Raina:
|
||||
// http://modarchive.org/index.php?request=view_by_moduleid&query=163194
|
||||
#include <data/parallax_80599_xm.h>
|
||||
|
||||
// Assign FIFO_USER_07 channel to libxm7
|
||||
#define FIFO_XM7 (FIFO_USER_07)
|
||||
|
||||
void song_start(XM7_ModuleManager_Type *module)
|
||||
{
|
||||
fifoSendValue32(FIFO_XM7, (u32)module);
|
||||
}
|
||||
|
||||
void song_stop(void)
|
||||
{
|
||||
fifoSendValue32(FIFO_XM7, 0);
|
||||
}
|
||||
|
||||
// You can also allocate this with malloc()
|
||||
static XM7_ModuleManager_Type module[2];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDemoInit();
|
||||
|
||||
printf("libXM7 example\n");
|
||||
printf("==============\n");
|
||||
printf("\n");
|
||||
printf("X: haen pyykit by Lasse\n");
|
||||
printf("Y: Parallax Glacier by Raina\n");
|
||||
printf("\n");
|
||||
printf("B: Stop song\n");
|
||||
printf("\n");
|
||||
printf("START: Return to loader\n");
|
||||
|
||||
bool songs_loaded = true;
|
||||
|
||||
u16 res;
|
||||
|
||||
res = XM7_LoadXM(&module[0], lasse_haen_pyykit_xm);
|
||||
if (res != 0)
|
||||
{
|
||||
printf("libxm7 error (module 0): 0x%04x\n", res);
|
||||
songs_loaded = false;
|
||||
}
|
||||
|
||||
res = XM7_LoadXM(&module[1], parallax_80599_xm);
|
||||
if (res != 0)
|
||||
{
|
||||
printf("libxm7 error (module 1): 0x%04x\n", res);
|
||||
songs_loaded = false;
|
||||
}
|
||||
|
||||
// Ensure that the ARM7 can see the libxm7 initialized data
|
||||
DC_FlushAll();
|
||||
|
||||
soundEnable();
|
||||
|
||||
bool playing = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint16_t keys_down = keysDown();
|
||||
|
||||
if (songs_loaded)
|
||||
{
|
||||
if (keys_down & KEY_B)
|
||||
{
|
||||
if (playing)
|
||||
{
|
||||
song_stop();
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keys_down & KEY_X)
|
||||
{
|
||||
if (playing)
|
||||
song_stop();
|
||||
|
||||
song_start(&module[0]);
|
||||
playing = true;
|
||||
}
|
||||
if (keys_down & KEY_Y)
|
||||
{
|
||||
if (playing)
|
||||
song_stop();
|
||||
|
||||
song_start(&module[1]);
|
||||
playing = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (keys_down & KEY_START)
|
||||
break;
|
||||
}
|
||||
|
||||
XM7_UnloadXM(&module[0]);
|
||||
XM7_UnloadXM(&module[1]);
|
||||
|
||||
soundDisable();
|
||||
|
||||
return 0;
|
||||
}
|
34
examples/libxm7/play_songs/build.py
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['arm9/source'],
|
||||
libs=['nds9', 'xm79'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/libxm7']
|
||||
)
|
||||
arm9.add_data(['music'])
|
||||
arm9.generate_elf()
|
||||
|
||||
arm7 = Arm7Binary(
|
||||
sourcedirs=['arm7/source'],
|
||||
libs=['nds7', 'xm77', 'dswifi7'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/libxm7',
|
||||
'${BLOCKSDS}/libs/dswifi']
|
||||
)
|
||||
arm7.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9, arm7],
|
||||
game_title='LIBXM7 example',
|
||||
game_subtitle='how to use LIBXM7',
|
||||
game_author='(sverx, 2009-01-07)'
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
||||
|
BIN
examples/libxm7/play_songs/music/lasse_haen_pyykit.xm
Normal file
BIN
examples/libxm7/play_songs/music/parallax_80599.xm
Normal file
8
examples/maxmod/audio_as_data/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/maxmod/audio_as_data/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
BIN
examples/maxmod/audio_as_data/audio/music/joint_people.mod
Normal file
BIN
examples/maxmod/audio_as_data/audio/sfx/fire_explosion.wav
Normal file
24
examples/maxmod/audio_as_data/build.py
Normal file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['source'],
|
||||
libs=['nds9', 'mm9'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/maxmod']
|
||||
)
|
||||
arm9.add_mmutil(['audio'])
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9],
|
||||
game_title='maxmod example',
|
||||
game_subtitle='Audio as data',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
65
examples/maxmod/audio_as_data/source/main.c
Normal file
@ -0,0 +1,65 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nds.h>
|
||||
#include <maxmod9.h>
|
||||
|
||||
// Headers autogenerated when files are find inside AUDIODIRS in the Makefile
|
||||
#include "maxmod/soundbank_info.h"
|
||||
#include "maxmod/soundbank_bin.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Setup sub screen for the text console
|
||||
consoleDemoInit();
|
||||
|
||||
// Setup sound bank
|
||||
mmInitDefaultMem((mm_addr)soundbank_bin);
|
||||
|
||||
// load the module
|
||||
mmLoad(MOD_JOINT_PEOPLE);
|
||||
|
||||
// load sound effects
|
||||
mmLoadEffect(SFX_FIRE_EXPLOSION);
|
||||
|
||||
// Start playing module
|
||||
mmStart(MOD_JOINT_PEOPLE, MM_PLAY_LOOP);
|
||||
|
||||
// Clear console
|
||||
printf("\x1b[2J");
|
||||
|
||||
printf("Maxmod demo\n");
|
||||
printf("===========\n");
|
||||
printf("\n");
|
||||
printf("A: Play SFX\n");
|
||||
printf("START: Exit to loader\n");
|
||||
printf("\n");
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Synchronize game loop to the screen refresh
|
||||
swiWaitForVBlank();
|
||||
|
||||
// Print some text in the demo console
|
||||
// -----------------------------------
|
||||
|
||||
// Handle user input
|
||||
// -----------------
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint16_t keys = keysHeld();
|
||||
uint16_t keys_down = keysDown();
|
||||
|
||||
if (keys_down & KEY_A)
|
||||
mmEffect(SFX_FIRE_EXPLOSION);
|
||||
|
||||
if (keys & KEY_START)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
examples/maxmod/audio_in_nitrofs/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/maxmod/audio_in_nitrofs/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
BIN
examples/maxmod/audio_in_nitrofs/audio/music/joint_people.mod
Normal file
@ -0,0 +1,5 @@
|
||||
Name: jointpeople
|
||||
Author: Anadune & Floppy
|
||||
License: Mod Archive Distribution license
|
||||
|
||||
https://modarchive.org/index.php?request=view_by_moduleid&query=115447
|
@ -0,0 +1,52 @@
|
||||
Original site: https://modarchive.org/index.php?faq-licensing
|
||||
|
||||
===============================================================================
|
||||
|
||||
Licensing Modules and Copyright
|
||||
|
||||
- Who owns the copyrights to the modules?
|
||||
|
||||
The composers do - unless the Public Domain license attribution has been
|
||||
specifically attributed in which case you are free to do with the module
|
||||
whatever you like.
|
||||
|
||||
- Can I use a module of modarchive.org in my game/application/etc...?
|
||||
|
||||
If the module in question has license deeds attributed to it, please refer to
|
||||
those.
|
||||
|
||||
Otherwise, the only way to be genuinely fair to the artist who's music you want
|
||||
to use is to contact them and get their permission. We can't grant permissions
|
||||
on their behalf. Period.
|
||||
|
||||
- Can I redistribute the module in its original unmodified form?
|
||||
|
||||
Yes. All uploads to the site are governed by an upload agreement of which one of
|
||||
the terms is the right to redistribute the original unmodified module file. This
|
||||
does not cover inclusion in a packed/bundled application or game. See previous
|
||||
item.
|
||||
|
||||
- The contact information isn't in the module, what can I do to contact the
|
||||
artist?
|
||||
|
||||
You can try using the modarchive.org forums, specifically the Wanted: forum.
|
||||
Search the Internet, do some homework. If you fail to find the necessary
|
||||
information then you are pretty much out of luck.
|
||||
|
||||
- I can't get in contact with an artist who's music I want to use, what now?
|
||||
|
||||
It's up to you how you proceed. We will not condone illegal use of someone's
|
||||
works, but if you still wish to continue to use that particular piece of music
|
||||
in your project, then you take on those risks yourself.
|
||||
|
||||
If your project is small and free (non commercial) then it's wise to give clear
|
||||
and concise due credit to the artist in your production. If your production is
|
||||
for commercial purposes then you are technically left with no other choice than
|
||||
to find a different module where the artist has attributed a compatible license,
|
||||
or is contactable - or go out on a limb and ask to have someone compose a custom
|
||||
module for your project.
|
||||
|
||||
- Where can I find the license attribution information on a module?
|
||||
|
||||
Look on a module's information page, there is a section dedicated to the License
|
||||
Attribution information.
|
@ -0,0 +1,287 @@
|
||||
Original site: https://modarchive.org/index.php?terms
|
||||
|
||||
===============================================================================
|
||||
|
||||
Terms & Disclaimer
|
||||
|
||||
Revised 2014-04-30
|
||||
|
||||
Cookies
|
||||
|
||||
By using our website, you agree to the use of cookies and other technologies as
|
||||
set out in this policy. If you do not agree to such use, please refrain from
|
||||
using the website. We use cookies to manage your experience on the site, without
|
||||
these you may suffer from lack of functionality, these are not used to track
|
||||
you.
|
||||
|
||||
Legalese.
|
||||
|
||||
1.1 LEGAL LIABILITY. By providing a song/file to our server you acknowledge that
|
||||
you may be held liable if the uploaded material is in any way illegal. You agree
|
||||
that you will notify The Mod Archive with no unnecessary delays should it at a
|
||||
later point be revealed that a song/file previously uploaded was illegally
|
||||
distributed, has illegal contents or is in some other way illegal to distribute.
|
||||
|
||||
1.3 AGREEMENT TERM AND TERMINATION. This Agreement is non-terminable and may not
|
||||
be cancelled by any party. Modified versions of this document may follow, but
|
||||
this Agreement shall remain in effect for any songs/files uploaded under this
|
||||
Agreement.
|
||||
|
||||
1.4 AGREEMENT SCOPE. This Agreement sets forth the entire understanding and
|
||||
agreement of the parties as to this Agreement's subject matter and supersedes
|
||||
all prior proposals, discussions or agreements with respect to such subject
|
||||
matter. All headings in the Agreement are for convenience only and shall have no
|
||||
legal or contractual effect. Should we choose not to exercise or enforce any
|
||||
right or provision of this Agreement, this shall not constitute a waiver of such
|
||||
right or provisions. You agree that you and we are independent contractors under
|
||||
this Agreement, and nothing in this Agreement shall be used to create a
|
||||
partnership, or joint venture.
|
||||
|
||||
1.5 LINK TO THIRD PARTIES: The Website may contain links to websites operated by
|
||||
third parties ("Third Party Websites"). The Mod Archive does not have any
|
||||
influence or control over any such Third Party Websites and, unless otherwise
|
||||
stated, is not responsible for and does not endorse any Third Party Websites or
|
||||
their availability or contents.
|
||||
|
||||
1.6 CONTENT: The Mod Archive does not in any way guarantee the accuracy of the
|
||||
information contained on the website nor does it guarantee that such information
|
||||
will be free of objectionable content or free of content which is unsuitable for
|
||||
minors.
|
||||
|
||||
2.1 We reserve the right to change these Terms of Service without notice. You
|
||||
are responsible for regularly reviewing these Terms of Service. Continued use of
|
||||
The Mod Archive after any such changes shall constitute your consent to such
|
||||
changes. The Mod Archive does not and will not assume any obligation to notify
|
||||
you of any changes to the Terms of Service.
|
||||
|
||||
3. GENERAL RULES RELATING TO CONDUCT: The Website Service is made available for
|
||||
your own, personal use. The Website Service must not be used for any commercial
|
||||
purpose whatsoever or for any illegal or unauthorised purpose. When you use the
|
||||
Website Service you must comply with all applicable Dutch laws relating to
|
||||
online conduct (including, without limitation, content which can be posted
|
||||
online) and with any applicable international laws, including the local laws in
|
||||
your country of residence (together referred to as "Applicable Laws").
|
||||
|
||||
4. CONTENT SUBMITTED TO THE WEBSITE: You are responsible for any information,
|
||||
data, text, music, software, sound, photographs, graphics, video, messages or
|
||||
other content ("Content") which you post or upload and/or display (in public or
|
||||
privately) to the Website. The Mod Archive may (but shall not be obliged to)
|
||||
delete, edit, lock, move or remove any Content without notice and for any reason
|
||||
and/or to record the IP address from which any Content is posted, uploaded
|
||||
and/or displayed without notice and for any reason, including, without
|
||||
limitation, Content which, in our sole discretion, violates these Terms or is or
|
||||
may be irrelevant, out of date, inappropriate or objectionable in any way
|
||||
whatsoever, or in respect of which The Mod Archive receives any complaint
|
||||
(whether justified or not). By posting, uploading and/or displaying any Content
|
||||
to the Website you warrant that: (a) you own all intellectual property and
|
||||
proprietary rights in such Content or that you have a licence from the owner of
|
||||
such rights to post, upload and/or display such Content on the Website; and (b)
|
||||
the posting, uploading and/or displaying of such Content on the Website and the
|
||||
grant of the licence to The Mod Archive (on the terms set out below) will not
|
||||
infringe the intellectual property or proprietary rights of any third party.
|
||||
|
||||
If you upload, post or otherwise transmit any Content to the Website, you
|
||||
automatically: (a) grant other users of the Website and the Website Service the
|
||||
right to access the same and use it in accordance with these Terms, and (b)
|
||||
grant The Mod Archive a non-exclusive, royalty free, sub-licensable, perpetual,
|
||||
world-wide licence to use, modify, publish, publicly perform, publicly display
|
||||
and distribute such Content on and through the Website and the Website Service
|
||||
and in any other form or medium. You continue to own the Content after it is
|
||||
posted to the Website.
|
||||
|
||||
You acknowledge that The Mod Archive will not screen or otherwise check any
|
||||
Content (with the exception of module uploads) which is submitted by you or any
|
||||
other user of the Website Service before it is posted, not monitor yours or any
|
||||
person’s use of the Website Service. As such, you as the user of the Website
|
||||
Service are responsible for any Content you submit to the Website and the manner
|
||||
in which the Website Service is used under your username. If you become aware of
|
||||
any misuse of the Website Service by any person including (without limitation)
|
||||
any posting of Content which violates these Terms, please contact us by
|
||||
following the instructions set out in paragraph 11 of these Terms.
|
||||
|
||||
5. SPECIFIC RULES RELATING TO CONDUCT: You agree that when using the Website
|
||||
Service you will comply with all Applicable Laws (as defined in paragraph 3),
|
||||
these Terms and you acknowledge that you are responsible for all acts and
|
||||
omissions which occur under your user-name. In particular, but without
|
||||
limitation, you agree not to:
|
||||
|
||||
a. Upload, post or otherwise display Content which is or promotes behaviour
|
||||
which violates the rights (including, without limitation, the intellectual
|
||||
property rights) of a third party or which is unlawful, harmful,
|
||||
threatening, abusive, flaming, hateful, offensive (whether in relation to
|
||||
sex, race, religion or otherwise) harassing, hateful, defamatory, vulgar,
|
||||
obscene, invasive of another's privacy, solicits personal information from
|
||||
anyone under the age of 18 years, or contains any illegal content; or
|
||||
|
||||
b. Upload, post or otherwise display any Content which contains software
|
||||
viruses or any other files or programs that may interrupt, destroy or limit
|
||||
the functionality of the Website or the Website Service or any server or
|
||||
networks connected to the Website or another's computer, or that contains
|
||||
any chain letters, pyramid-selling schemes, bulk mail, junk mail or similar;
|
||||
or
|
||||
|
||||
c. Upload, post or otherwise display any Content containing a photograph of
|
||||
another person unless you have obtained that person’s consent;
|
||||
|
||||
d. Harvest or collect any IP addresses or email addresses or other contact
|
||||
information of any members of the Website, by electronic means or otherwise;
|
||||
or
|
||||
|
||||
e. Upload, post or otherwise display any Content for any commercial or
|
||||
business purpose including (without limitation) any Content which contains
|
||||
any advertising or promotional materials; or
|
||||
|
||||
f. Restrict or in any way inhibit any other person’s use of the Website or
|
||||
the Website Service; or
|
||||
|
||||
g. Upload, post or otherwise display any Content which is false, misleading,
|
||||
un-necessary and/or repetitive including any Content which is inaccurate,
|
||||
out of date or repeats that previously uploaded, posted or displayed by you
|
||||
or another visitor, unless absolutely necessary; or
|
||||
|
||||
h. Upload, post or otherwise transmit any Content to a part of the Website
|
||||
which is irrelevant to the subject matter of the Content; or
|
||||
|
||||
i. Register an account with us under more than one user name and/or user
|
||||
account number; or
|
||||
|
||||
j. Use the Website or the Website Service in a manner that is inconsistent
|
||||
with these Terms and/or any Applicable Laws in force from time to time or in
|
||||
a manner which promotes or encourages illegal activity; or
|
||||
|
||||
k. Breach the terms of any suspension or ban or seek alternative access; or
|
||||
|
||||
l. In the interests of free speech, bring any action for defamation against
|
||||
The Mod Archive, or any of the companies in the same group; or
|
||||
|
||||
m. Use or solicit any other account holder’s personal data for any purpose
|
||||
other than establishing non-commercial, lawful contact that such account
|
||||
holder would reasonably expect to welcome; or
|
||||
|
||||
n. Submit Content owned by a third party without consent from that third
|
||||
party or submit Content in a manner which expressly or impliedly infers that
|
||||
such Content is sponsored or endorsed by the Website; or
|
||||
|
||||
o. Use the Website in any unlawful manner or in a manner which promotes or
|
||||
encourages illegal activity or in a manner which could damage, disable,
|
||||
overburden or impair the Website or the Website Service; or
|
||||
|
||||
p. Attempt to gain unauthorised access to the Website or any networks,
|
||||
servers or computer systems connected to the Website; or
|
||||
|
||||
q. Modify, adapt, translate or reverse engineer any part of the Website or
|
||||
use any robot, spider, site search/retrieval application or other device to
|
||||
retrieve or index any part of the Website or re-format or frame any portion
|
||||
of the web pages comprising the Website, unless permitted by law; or
|
||||
|
||||
r. Remove or obstruct from view any advertisements and/or any copyright,
|
||||
trademark or other proprietary notices contained on or in the Website; or
|
||||
|
||||
s. Contact any other user of the Website if they have expressly asked you
|
||||
not to; or
|
||||
|
||||
t. Attempt to impersonate any other user or account holder of the Website or
|
||||
the Website Service; or
|
||||
|
||||
u. Use the username and/or password of any other account holder of the
|
||||
Website or disclose your password to any other person; or
|
||||
|
||||
v. Upload, post or otherwise display any Content comprising an advertisement
|
||||
or accept payment or anything of value from any person in exchange for you
|
||||
uploading, posting or displaying any Content or otherwise performing any
|
||||
commercial activity on or through the Website or the Website Service on
|
||||
behalf of such person (including, without limitation, posting
|
||||
blogs/comments/profiles or bulletins for a commercial purpose and/or sending
|
||||
messages to other users of the Website with a commercial purpose).
|
||||
|
||||
|
||||
You agree to indemnify The Mod Archive in full and on demand from and against
|
||||
any loss, damage, costs or expenses which they suffer or incur directly or
|
||||
indirectly as a result of your use of the Website and/or the Website Service,
|
||||
and any use of the same under your username other than in accordance with these
|
||||
Terms or Applicable Law.
|
||||
|
||||
6. DISCLAIMER / LIABILITY: USE OF THE WEBSITE AND/OR THE WEBSITE SERVICE IS AT
|
||||
YOUR OWN RISK. THE WEBSITE AND THE WEBSITE SERVICE IS PROVIDED ON AN “AS IS”
|
||||
BASIS. TO THE MAXIMUM EXTENT PERMITTED BY LAW: (A) THE MOD ARCHIVE DISCLAIMS ALL
|
||||
LIABILITY WHATSOEVER, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE)
|
||||
OR OTHERWISE IN RELATION TO THE WEBSITE AND/OR THE WEBSITE SERVICE; AND (B) ALL
|
||||
IMPLIED WARRANTIES, TERMS AND CONDITIONS RELATING TO THE WEBSITE AND/OR THE
|
||||
WEBSITE SERVICE (WHETHER IMPLIED BY STATUE, COMMON LAW OR OTHERWISE), INCLUDING
|
||||
(WITHOUT LIMITATION) ANY WARRANTY, TERM OR CONDITION AS TO ACCURACY,
|
||||
COMPLETENESS, SATISFACTORY QUALITY, PERFORMANCE, FITNESS FOR PURPOSE OR ANY
|
||||
SPECIAL PURPOSE, AVAILABILITY, NON INFRINGEMENT, INFORMATION ACCURACY,
|
||||
INTEROPERABILITY, QUIET ENJOYMENT AND TITLE ARE, AS BETWEEN THE MOD ARCHIVE AND
|
||||
YOU, HEREBY EXCLUDED. IN PARTICULAR, BUT WITHOUT PREJUDICE TO THE FOREGOING, WE
|
||||
ACCEPT NO RESPONSIBILITY FOR THE CONDUCT OF ANY USER AND/OR ACCOUNT HOLDER OF
|
||||
THE WEBSITE AND/OR WEBSITE SERVICE; ANY ERROR, DELAY OR FAILURE IN THE
|
||||
TRANSMISSION OF ANY COMMUNICATION BETWEEN USERS AND/OR ACCOUNT HOLDERS; ANY
|
||||
TECHNICAL FAILURE OF THE INTERNET, THE WEBSITE AND/OR THE WEBSITE SERVICE; OR
|
||||
ANY DAMAGE OR INJURY TO USERS OR THEIR EQUIPMENT AS A RESULT OF OR RELATING TO
|
||||
THEIR USE OF THE WEBSITE OR THE WEBSITE SERVICE. YOUR STATUTORY RIGHTS ARE NOT
|
||||
AFFECTED.
|
||||
|
||||
The Mod Archive will not be liable, in contract, tort (including, without
|
||||
limitation, negligence), under statute or otherwise, as a result of or in
|
||||
connection with the Website and/or the Website Service, for any: (i) economic
|
||||
loss (including, without limitation, loss of revenues, profits, contracts,
|
||||
business or anticipated savings); or (ii) loss of goodwill or reputation; or
|
||||
(iii) special or indirect or consequential loss.
|
||||
|
||||
Nothing in these Terms shall be construed as excluding or limiting the liability
|
||||
of The Mod Archive for death or personal injury caused by its negligence or for
|
||||
any other liability which cannot be excluded by Dutch law.
|
||||
|
||||
7. ACCESS RESTRICTION AND SERVICE SUSPENSION OR TERMINATION: The Mod Archive
|
||||
reserves the right in its sole discretion to deny you access to the Website
|
||||
and/or the Website Service, or any part thereof, with or without notice and for
|
||||
any reason including, without limitation, if you fail to comply with any clause
|
||||
5 (Member Conduct) or any other provision of these Terms. In particular, The Mod
|
||||
Archive may deny you access to the Website and/or the Website Services if The
|
||||
Mod Archive exercises its right to delete, edit, lock or remove any Content
|
||||
posted, uploaded or displayed by you. The Mod Archive reserves the right to
|
||||
suspend or cease providing all or any of the Website Service, without notice,
|
||||
and shall have no liability or responsibility to you in any manner whatsoever if
|
||||
it chooses to do so.
|
||||
|
||||
8. ADVERTISERS ON THE WEBSITE: We accept no responsibility for adverts posted on
|
||||
the Website. If you agree to purchase goods and/or services from any third party
|
||||
who advertises on the Website, you do so at your own risk. The advertiser, not
|
||||
The Mod Archive, is responsible for such goods and/or services and if you have
|
||||
any queries or complaints in relation to them, your only recourse is against the
|
||||
advertiser.
|
||||
|
||||
9. ACCOUNT HOLDER INTERACTION You are responsible for how you interact with
|
||||
other account holders and users of the Website and the Website Service. We
|
||||
reserve the right, but have no obligation, to monitor how you interact with
|
||||
those persons.
|
||||
|
||||
10 GENERAL: These Terms (as amended from time to time) constitute the entire
|
||||
agreement between you and The Mod Archive concerning your use of the Website and
|
||||
the Website Service and supersede any previous arrangement, agreement,
|
||||
undertaking or proposal, written or oral between you and The Mod Archive in
|
||||
relation to such matters. The Mod Archive reserves the right to update these
|
||||
Terms from time to time. If it does so, the updated version will be effective as
|
||||
soon as it is uploaded on to this the Website and your continued use of the
|
||||
Website Service following any changes constitutes your acceptance of the new
|
||||
Terms. You are responsible for regularly reviewing these Terms so that you are
|
||||
aware of any changes to them. No other variation to these Terms shall be
|
||||
effective unless in writing and signed by an authorised representative on behalf
|
||||
of The Mod Archive. These Terms shall be governed by and construed in
|
||||
accordance with Dutch law and you agree to submit to the exclusive jurisdiction
|
||||
of the Dutch Courts in relation to any dispute arising out of or relating to
|
||||
these Terms and/or your use of the Website and/or the Website Service. If any
|
||||
provision(s) of these Terms is held by a court of competent jurisdiction to be
|
||||
invalid or unenforceable, then such provision(s) shall be construed, as nearly
|
||||
as possible, to reflect the intentions of the parties (as reflected in the
|
||||
provision(s)) and all other provisions shall remain in full force and effect.
|
||||
The Mod Archive's failure to exercise or enforce any right or provision of these
|
||||
Terms shall not constitute a waiver of such right or provision unless
|
||||
acknowledged and agreed to by The Mod Archive in writing. Unless otherwise
|
||||
expressly stated, nothing in the Terms shall create any rights or any other
|
||||
benefits whether pursuant to the Contracts (Rights of Third Parties) Act 1999 or
|
||||
otherwise in favour of any person other than you and The Mod Archive.
|
||||
|
||||
11. CONTACT: For support and help, use the appropriate forum within the site
|
||||
forums.
|
||||
|
79
examples/maxmod/audio_in_nitrofs/audio/music/mod-archive.txt
Normal file
@ -0,0 +1,79 @@
|
||||
Original site: https://modarchive.org/index.php?terms-upload
|
||||
|
||||
===============================================================================
|
||||
|
||||
Mod Archive Upload Terms, Conditions and License Agreement
|
||||
|
||||
Version 2.2 as of April 29th, 2009
|
||||
|
||||
This Agreement describes the legal relationship between you (an individual
|
||||
providing material by uploading songs or other files to the modarchive.org/com
|
||||
server) and the modarchive.org/com server operators ("us", "we" in the following
|
||||
text). Please read this document carefully. As this document is modified, the
|
||||
new version will apply to any files uploaded later than that date, but will not
|
||||
be applicable to previously uploaded files (see section 3.3).
|
||||
|
||||
Section 1: Copyright holders
|
||||
|
||||
1.1, General license. By providing a song/file to us, if you are the
|
||||
copyright holder of the song/file in question, you agree to grant us a
|
||||
non-exclusive, royalty-free, non-retractable non-terminable, worldwide
|
||||
license to: a) Distribute your song/file on the modarchive.org/com web site
|
||||
or in any other form of distribution that we deem appropriate. b) Publicly
|
||||
display, publicly perform, broadcast, encode, transmit, reproduce,
|
||||
manufacture and distribute your song/file in whole or in part, alone or in
|
||||
compilation with content provided by third parties, through any medium now
|
||||
known or hereafter devised. c) Apply non-destructive and non-changing
|
||||
compression systems to decrease the file sizes of the files uploaded to us.
|
||||
|
||||
1.2, License to redistribute. By providing a song/file to modarchive.org/com
|
||||
you furthermore agree to give anyone who wishes to redistribute your
|
||||
song/file a license to download the song/file from modarchive.org/com and do
|
||||
so, provided it has stayed in its original, unmodified, unbundled form.
|
||||
|
||||
Note: If you are visitor looking for information about using modules in your
|
||||
productions i.e games/applications, please see the Licensing FAQ in file
|
||||
mod-archive-faq.txt.
|
||||
|
||||
1.3, Ownership of Copyrights. You retain ownership of the copyrights and all
|
||||
other rights in the song/file provided to us, subject only to the
|
||||
non-exclusive rights granted to us under this Agreement. You are free to
|
||||
grant similar rights to others.
|
||||
|
||||
|
||||
Section 2: Non-copyright holders
|
||||
|
||||
2.1 License. By providing a song/file to us if you are not the copyright
|
||||
holder of said song/file, you agree that you have previously secured a
|
||||
license to redistribute the song, according to the terms of Section 1.
|
||||
|
||||
2.2 Copyright infringement. Furthermore you agree that you are fully
|
||||
responsible for your action of providing the song to modarchive.org/com, and
|
||||
that modarchive.org/com may hold you liable for any copyright infringement
|
||||
caused by your uploading of the song/file to the modarchive.org/com server,
|
||||
and thus that modarchive.org/com should not be held liable for any
|
||||
consequences of your actions.
|
||||
|
||||
|
||||
Section 3: General terms and conditions
|
||||
|
||||
See file mod-archive-terms.txt.
|
||||
|
||||
Section 4: Footnotes
|
||||
|
||||
4.1 Works in the public domain. Materials that have previously been
|
||||
distributed under public domain license (for example, PD Disk Distributors)
|
||||
are quite legal to upload to our servers as long as the material has not
|
||||
been modified from its original state since release. Any works submitted to
|
||||
The Mod Archive that are not uploaded by their creators or copyright holders
|
||||
are assumed to be released into the public domain prior to upload and
|
||||
therefore legally licensed for redistribution as Public Domain material by
|
||||
The Mod Archive. Materials that have been uploaded but have been modified
|
||||
since origin are submitted entirely at the uploaders own risk, where all
|
||||
liabilities remain with the uploader concerning any legal implications that
|
||||
arise from subsequent litigation should there be any incident where a party
|
||||
has cause to complain.
|
||||
|
||||
4.2 Footnote disclaimer. Should any section of the footnoted contradict the
|
||||
previous paragraphs in sections 1-3 inclusive, the paragraphs in sections
|
||||
1-3 inclusive take precedence.
|
@ -0,0 +1 @@
|
||||
{"_version":1,"_name":"fire_explosion","_locked":[],"sampleRate":44100,"attack":0,"sustain":0.027705693940245357,"sustainPunch":0,"decay":0.13257979056125957,"tremoloDepth":0,"tremoloFrequency":2.2776006915244977,"frequency":2095.7030570339975,"frequencySweep":-541.3667290180666,"frequencyDeltaSweep":-2800,"repeatFrequency":0,"frequencyJump1Onset":33,"frequencyJump1Amount":0,"frequencyJump2Onset":66,"frequencyJump2Amount":0,"harmonics":0,"harmonicsFalloff":0.5,"waveform":"whitenoise","interpolateNoise":false,"vibratoDepth":0,"vibratoFrequency":10,"squareDuty":50,"squareDutySweep":0,"flangerOffset":0,"flangerOffsetSweep":0,"bitCrush":16,"bitCrushSweep":0,"lowPassCutoff":22050,"lowPassCutoffSweep":0,"highPassCutoff":0,"highPassCutoffSweep":0,"compression":0.9,"normalization":true,"amplification":50}
|
BIN
examples/maxmod/audio_in_nitrofs/audio/sfx/fire_explosion.wav
Normal file
30
examples/maxmod/audio_in_nitrofs/build.py
Normal file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
nitrofs = NitroFS()
|
||||
# The header of the soundbank in NitroFS must be added as a dependency of the ARM9
|
||||
nitrofs_soundbank_header = nitrofs.add_mmutil(['audio'])
|
||||
nitrofs.generate_image()
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['source'],
|
||||
libs=['nds9', 'mm9'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDS}/libs/maxmod']
|
||||
)
|
||||
arm9.add_header_dependencies([nitrofs_soundbank_header])
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9, nitrofs],
|
||||
game_title='maxmod example',
|
||||
game_subtitle='Audio in NitroFS',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
||||
|
82
examples/maxmod/audio_in_nitrofs/source/main.c
Normal file
@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <filesystem.h>
|
||||
#include <nds.h>
|
||||
#include <maxmod9.h>
|
||||
|
||||
#include "nitrofs/soundbank_info.h"
|
||||
|
||||
__attribute__((noreturn)) void WaitLoop(void)
|
||||
{
|
||||
printf("Press START to exit");
|
||||
while (1)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
if (keysHeld() & KEY_START)
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Setup sub screen for the text console
|
||||
consoleDemoInit();
|
||||
|
||||
if (!nitroFSInit(NULL))
|
||||
{
|
||||
printf("nitroFSInit failed.\n");
|
||||
WaitLoop();
|
||||
}
|
||||
|
||||
// Setup sound bank
|
||||
mmInitDefault("maxmod/soundbank.bin");
|
||||
|
||||
// load the module
|
||||
mmLoad(MOD_JOINT_PEOPLE);
|
||||
|
||||
// load sound effects
|
||||
mmLoadEffect(SFX_FIRE_EXPLOSION);
|
||||
|
||||
// Start playing module
|
||||
mmStart(MOD_JOINT_PEOPLE, MM_PLAY_LOOP);
|
||||
|
||||
// Clear console
|
||||
printf("\x1b[2J");
|
||||
|
||||
printf("Maxmod demo\n");
|
||||
printf("===========\n");
|
||||
printf("\n");
|
||||
printf("A: Play SFX\n");
|
||||
printf("START: Exit to loader\n");
|
||||
printf("\n");
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Synchronize game loop to the screen refresh
|
||||
swiWaitForVBlank();
|
||||
|
||||
// Print some text in the demo console
|
||||
// -----------------------------------
|
||||
|
||||
// Handle user input
|
||||
// -----------------
|
||||
|
||||
scanKeys();
|
||||
|
||||
uint16_t keys = keysHeld();
|
||||
uint16_t keys_down = keysDown();
|
||||
|
||||
if (keys_down & KEY_A)
|
||||
mmEffect(SFX_FIRE_EXPLOSION);
|
||||
|
||||
if (keys & KEY_START)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
examples/nflib/3dsprites/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
graph.png
|
||||
*.nds
|
||||
*.sav
|
||||
build
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
*.ninja
|
1
examples/nflib/3dsprites/architectds
Symbolic link
@ -0,0 +1 @@
|
||||
../../../architectds
|
BIN
examples/nflib/3dsprites/assets/bgtiled/bg3.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
examples/nflib/3dsprites/assets/bgtiled/nfl.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
examples/nflib/3dsprites/assets/spr3d/blueball.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
examples/nflib/3dsprites/assets/spr3d/redcar.png
Normal file
After Width: | Height: | Size: 19 KiB |
27
examples/nflib/3dsprites/build.py
Normal file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2024
|
||||
|
||||
from architectds import *
|
||||
|
||||
nitrofs = NitroFS()
|
||||
nitrofs.add_nflib_bg_tiled(['assets/bgtiled'], 'bg')
|
||||
nitrofs.add_nflib_sprite_3d(['assets/spr3d'], 'sprite')
|
||||
nitrofs.generate_image()
|
||||
|
||||
arm9 = Arm9Binary(
|
||||
sourcedirs=['source'],
|
||||
libs=['nds9', 'nflib'],
|
||||
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDSEXT}/nflib']
|
||||
)
|
||||
arm9.generate_elf()
|
||||
|
||||
nds = NdsRom(
|
||||
binaries=[arm9, nitrofs],
|
||||
game_title='NFlib: 3D sprites',
|
||||
)
|
||||
nds.generate_nds()
|
||||
|
||||
nds.run_command_line_arguments()
|
143
examples/nflib/3dsprites/source/main.c
Normal file
@ -0,0 +1,143 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
//
|
||||
// SPDX-FileContributor: NightFox & Co., 2009-2011
|
||||
//
|
||||
// Basic 3D sprite example.
|
||||
// http://www.nightfoxandco.com
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nds.h>
|
||||
#include <filesystem.h>
|
||||
|
||||
#include <nf_lib.h>
|
||||
|
||||
#define MAXSPRITES 32
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Set random seed based on the current time
|
||||
srand(time(NULL));
|
||||
|
||||
// Prepare a NitroFS initialization screen
|
||||
NF_Set2D(0, 0);
|
||||
NF_Set2D(1, 0);
|
||||
consoleDemoInit();
|
||||
printf("\n NitroFS init. Please wait.\n\n");
|
||||
printf(" Iniciando NitroFS,\n por favor, espere.\n\n");
|
||||
swiWaitForVBlank();
|
||||
|
||||
// Initialize NitroFS and set it as the root folder of the filesystem
|
||||
nitroFSInit(NULL);
|
||||
NF_SetRootFolder("NITROFS");
|
||||
|
||||
// Initialize 3D engine in the top screen in mode 0
|
||||
NF_Set3D(0, 0);
|
||||
|
||||
// Initialize 2D engine in the bottom screen in mode 0
|
||||
NF_Set2D(1, 0);
|
||||
|
||||
// Initialize tiled backgrounds system
|
||||
NF_InitTiledBgBuffers(); // Initialize storage buffers
|
||||
NF_InitTiledBgSys(0); // Top screen
|
||||
NF_InitTiledBgSys(1); // Bottom screen
|
||||
|
||||
// Initialize 3D sprite system
|
||||
NF_InitSpriteBuffers(); // Initialize storage buffers
|
||||
NF_Init3dSpriteSys();
|
||||
|
||||
// Load background files from NitroFS
|
||||
NF_LoadTiledBg("bg/nfl", "nfl", 256, 256);
|
||||
NF_LoadTiledBg("bg/bg3", "bg3", 256, 256);
|
||||
|
||||
// Load sprite files from NitroFS
|
||||
NF_LoadSpriteGfx("sprite/blueball", 0, 64, 64);
|
||||
NF_LoadSpritePal("sprite/blueball", 0);
|
||||
NF_LoadSpriteGfx("sprite/redcar", 1, 128, 64);
|
||||
NF_LoadSpritePal("sprite/redcar", 1);
|
||||
|
||||
// Transfer the required sprites to VRAM
|
||||
NF_Vram3dSpriteGfx(0, 0, true);
|
||||
NF_Vram3dSpritePal(0, 0);
|
||||
NF_Vram3dSpriteGfx(1, 1, true);
|
||||
NF_Vram3dSpritePal(1, 1);
|
||||
|
||||
// Create backgrounds in both screens
|
||||
NF_CreateTiledBg(0, 3, "bg3");
|
||||
NF_CreateTiledBg(1, 3, "nfl");
|
||||
|
||||
// Variables
|
||||
s16 x[MAXSPRITES];
|
||||
s16 y[MAXSPRITES];
|
||||
s16 ix[MAXSPRITES];
|
||||
s16 iy[MAXSPRITES];
|
||||
|
||||
// Initialize sprite variables and create the sprites
|
||||
for (int n = 0; n < MAXSPRITES; n++)
|
||||
{
|
||||
int r = n % 2;
|
||||
|
||||
x[n] = rand() % 128;
|
||||
y[n] = rand() % 112;
|
||||
if ((rand() % 100) > 50)
|
||||
ix[n] = 1;
|
||||
else
|
||||
ix[n] = -1;
|
||||
|
||||
if ((rand() % 100) > 50)
|
||||
iy[n] = 1;
|
||||
else
|
||||
iy[n] = -1;
|
||||
|
||||
NF_Create3dSprite(n, r, r, x[n], y[n]);
|
||||
}
|
||||
|
||||
// Sort their priorites based on their IDs (lower IDs have higher priority)
|
||||
NF_Sort3dSprites();
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Read keys
|
||||
scanKeys();
|
||||
u16 keys = keysDown();
|
||||
|
||||
// Move sprites
|
||||
for (int n = 0; n < MAXSPRITES; n++)
|
||||
{
|
||||
x[n] += ix[n];
|
||||
if ((x[n] < 0) || (x[n] > (255 - NF_3DSPRITE[n].width)))
|
||||
ix[n] = -ix[n];
|
||||
|
||||
y[n] += iy[n];
|
||||
if ((y[n] < 0) || (y[n] > (191 - NF_3DSPRITE[n].height)))
|
||||
iy[n] = -iy[n];
|
||||
|
||||
NF_Move3dSprite(n, x[n], y[n]);
|
||||
}
|
||||
|
||||
// Show or hide all sprites with even ID
|
||||
if (keys & KEY_A)
|
||||
{
|
||||
for (int n = 0; n < MAXSPRITES; n += 2)
|
||||
NF_Show3dSprite(n, true);
|
||||
}
|
||||
|
||||
if (keys & KEY_B)
|
||||
{
|
||||
for (int n = 0; n < MAXSPRITES; n += 2)
|
||||
NF_Show3dSprite(n, false);
|
||||
}
|
||||
|
||||
// Draw all 3D sprites
|
||||
NF_Draw3dSprites();
|
||||
|
||||
// Tell the GPU to draw the scene and wait until it's done
|
||||
glFlush(0);
|
||||
|
||||
// Wait for the screen refresh
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|