initial prototype

This commit is contained in:
Haze Weathers 2024-12-26 03:34:11 -05:00
commit 6c298e1b0d
9 changed files with 2371 additions and 0 deletions

15
.gitignore vendored Normal file
View file

@ -0,0 +1,15 @@
# Python cache files
__pycache__/
# Setuptools
build/
dist/
*.egg-info/
# Virtual environments
env/
# ninja
build.ninja
.ninja_deps
.ninja_log

10
architectds/__init__.py Normal file
View 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

2117
architectds/architectds.py Normal file

File diff suppressed because it is too large Load diff

18
architectds/license.txt Normal file
View file

@ -0,0 +1,18 @@
Copyright (c) 2024 Antonio Niño Díaz <antonio_nd@outlook.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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 OR
COPYRIGHT HOLDERS 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.

25
build.py Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env python3
from architectds import *
nitrofs = NitroFS()
nitrofs.add_nflib_sprite_3d(['res/sprite'], 'sprite')
nitrofs.generate_image()
arm9 = Arm9Binary(
sourcedirs=['src'],
libs=['nds9', 'nflib'],
libdirs=['${BLOCKSDS}/libs/libnds', '${BLOCKSDSEXT}/nflib']
)
arm9.generate_elf()
nds = NdsRom(
binaries=[arm9, nitrofs],
nitrofsdirs=['res/data'],
game_title='Uncanny Cat Golf',
game_subtitle='Cat Golf On The Go',
game_author='SH2K + Fogwaves',
)
nds.generate_nds()
nds.run_command_line_arguments()

BIN
res/sprite/canny_cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
res/sprite/line.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
res/sprite/target.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

186
src/main.c Normal file
View file

@ -0,0 +1,186 @@
#include <stdio.h>
#include <nds.h>
#include <nds/arm9/console.h>
#include <filesystem.h>
#include <nds/arm9/input.h>
#include <nds/touch.h>
#include <nds/arm9/videoGL.h>
#include <nds/arm9/video.h>
#include <gl2d.h>
#include <nds/arm9/math.h>
#include <nf_lib.h>
const u32 SPR_CANNY = 2;
const u32 SPR_TARGET = 0;
const u32 SPR_LINE = 1;
const int32_t POWER_PER_PX = floattof32(0.1);
const int32_t SPEED_DECAY = floattof32(0.98);
typedef struct vec2 {
int32_t x;
int32_t y;
} vec2;
static inline int32_t v2Len(vec2 const *v) {
return sqrtf32(mulf32(v->x, v->x) + mulf32(v->y, v->y));
}
static inline void v2Norm(vec2 *v) {
int32_t magnitude = v2Len(v);
v->x = divf32(v->x, magnitude);
v->y = divf32(v->y, magnitude);
}
static inline void v2Scale(vec2 *v, int32_t s) {
v->x = mulf32(v->x, s);
v->y = mulf32(v->y, s);
}
static inline void v2Add(vec2 *v1, vec2 const *v2) {
v1->x += v2->x;
v1->y += v2->y;
}
static inline vec2 v2To(vec2 const *v1, vec2 const *v2) {
vec2 res = {v2->x - v1->x, v2->y - v1->y};
return res;
}
void loadSprite(const char *file, u32 id, u32 width, u32 height) {
NF_LoadSpriteGfx(file, id, width, height);
NF_LoadSpritePal(file, id);
NF_Vram3dSpriteGfx(id, id, true);
NF_Vram3dSpritePal(id, id);
}
int main(int argc, char **argv) {
NF_Set2D(0, 0);
NF_Set2D(1, 0);
// NitroFS init screen.
consoleDemoInit();
printf("\n NitroFS init. Please wait.\n\n");
swiWaitForVBlank();
// Init NitroFS and set as root of filesystem
if (!nitroFSInit(NULL)) {
return 0;
}
NF_SetRootFolder("NITROFS");
// init 3D engine on top screen
NF_Set3D(1, 0);
// init 2D engine on bottom screen
// NF_Set2D(1, 0);
// init 3D sprite system
NF_InitSpriteBuffers();
NF_Init3dSpriteSys();
// load the canny cat
loadSprite("sprite/canny_cat", SPR_CANNY, 32, 32);
// load target
loadSprite("sprite/target", SPR_TARGET, 8, 8);
struct movingSprite {
vec2 pos;
vec2 vel;
} canny = {
.pos = {floattof32(128), floattof32(96)},
.vel = {floattof32(0.0), floattof32(0.0)},
};
NF_Create3dSprite(SPR_CANNY, SPR_CANNY, SPR_CANNY, canny.pos.x, canny.pos.y);
NF_Create3dSprite(SPR_TARGET, SPR_TARGET, SPR_TARGET, 0, 0);
NF_Show3dSprite(SPR_TARGET, false);
NF_Sort3dSprites();
bool moving = false;
bool pulling = false;
vec2 target_pos;
vec2 pulled_pos;
while (true) {
// get state of keys
scanKeys();
u16 keys = keysDown();
touchPosition touch;
touchRead(&touch);
// pulling
if (!pulling && (touch.px > 0 || touch.py > 0)) {
pulling = true;
target_pos.x = inttof32(touch.px);
target_pos.y = inttof32(touch.py);
NF_Show3dSprite(SPR_TARGET, true);
NF_Move3dSprite(SPR_TARGET, touch.px - 4, touch.py - 4);
}
// printf("target_pos: %d, %d\n", f32toint(target_pos.x), f32toint(target_pos.y));
if (pulling) {
if (touch.px <= 0 && touch.py <= 0) {
NF_Show3dSprite(SPR_TARGET, false);
vec2 dir = v2To(&pulled_pos, &target_pos);
pulling = false;
int32_t power = v2Len(&dir);
v2Norm(&dir);
v2Scale(&dir, mulf32(power, POWER_PER_PX));
printf("new_vel: %f, %f\n", f32tofloat(dir.x), f32tofloat(dir.y));
canny.vel = dir;
} else {
pulled_pos.x = inttof32(touch.px);
pulled_pos.y = inttof32(touch.py);
glBegin2D();
glLine(f32toint(target_pos.x), f32toint(target_pos.y), touch.px, touch.py, RGB15(31, 0, 0));
glEnd2D();
}
}
// printf("direction: %f, %f\n", f32tofloat(canny.vel.x), f32tofloat(canny.vel.y));
v2Add(&canny.pos, &canny.vel);
v2Scale(&canny.vel, SPEED_DECAY);
if (canny.pos.x <= inttof32(0)) {
canny.pos.x = inttof32(0);
canny.vel.x = mulf32(canny.vel.x, floattof32(-1.0));
}
if (canny.pos.x >= inttof32(255 -32)) {
canny.pos.x = inttof32(255 - 32);
canny.vel.x = mulf32(canny.vel.x, floattof32(-1.0));
}
if (canny.pos.y <= inttof32(0)) {
canny.pos.y = inttof32(0);
canny.vel.y = mulf32(canny.vel.y, floattof32(-1.0));
}
if (canny.pos.y >= inttof32(191 - 32)) {
canny.pos.y = inttof32(191 - 32);
canny.vel.y = mulf32(canny.vel.y, floattof32(-1.0));
}
NF_Move3dSprite(SPR_CANNY, f32toint(canny.pos.x), f32toint(canny.pos.y));
// draw sprites and make GPU draw scene
NF_Draw3dSprites();
glFlush(0);
swiWaitForVBlank();
}
}
void load3dSprite(const char *file, u32 id, u32 width, u32 height) {
NF_LoadSpriteGfx(file, id, width, height);
NF_LoadSpritePal(file, id);
NF_Vram3dSpriteGfx(id, id, true);
NF_Vram3dSpritePal(id, id);
}