Initial commit
This commit is contained in:
commit
9a75f89146
10 changed files with 376 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
build/
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "libraries/lvgl"]
|
||||||
|
path = libraries/lvgl
|
||||||
|
url = https://github.com/lvgl/lvgl.git
|
||||||
80
CMakeLists.txt
Normal file
80
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Project
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
project(Lomo C CXX ASM)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# devkitPro / libctru setup
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
if(NOT DEFINED ENV{DEVKITPRO})
|
||||||
|
message(FATAL_ERROR "Please set DEVKITPRO in your environment.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{DEVKITARM})
|
||||||
|
message(FATAL_ERROR "Please set DEVKITARM in your environment.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(DEVKITPRO $ENV{DEVKITPRO})
|
||||||
|
set(DEVKITARM $ENV{DEVKITARM})
|
||||||
|
|
||||||
|
# Load devkitPro CMake support
|
||||||
|
include("${DEVKITPRO}/cmake/3DS.cmake")
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# LVGL
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set(LV_CONF_INCLUDE_SIMPLE ON)
|
||||||
|
set(LV_BUILD_CONF_DIR include)
|
||||||
|
|
||||||
|
add_subdirectory(libraries/lvgl)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Target
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
add_executable(${PROJECT_NAME}
|
||||||
|
source/main.c
|
||||||
|
source/lv_ctr_disp.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||||
|
include
|
||||||
|
)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Libraries
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
lvgl
|
||||||
|
ctru
|
||||||
|
citro2d
|
||||||
|
citro3d
|
||||||
|
m
|
||||||
|
)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 3DS metadata
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
OUTPUT_NAME "lomo"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Generates:
|
||||||
|
# .3dsx
|
||||||
|
# .smdh
|
||||||
|
# .elf
|
||||||
|
ctr_generate_smdh(
|
||||||
|
OUTPUT "${PROJECT_NAME}.smdh"
|
||||||
|
NAME "Lomo"
|
||||||
|
DESCRIPTION "Camera app for the rest of us"
|
||||||
|
AUTHOR "BluRaf"
|
||||||
|
)
|
||||||
|
|
||||||
|
ctr_create_3dsx(${PROJECT_NAME}
|
||||||
|
SMDH "${PROJECT_NAME}.smdh"
|
||||||
|
)
|
||||||
13
CMakePresets.json
Normal file
13
CMakePresets.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "3ds",
|
||||||
|
"generator": "Unix Makefiles",
|
||||||
|
"binaryDir": "build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_TOOLCHAIN_FILE": "$env{DEVKITPRO}/cmake/3DS.cmake"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
build.sh
Executable file
3
build.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
cmake --preset 3ds
|
||||||
|
cmake --build build --parallel $(nproc)
|
||||||
16
include/lv_conf.h
Normal file
16
include/lv_conf.h
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef LV_CONF_H
|
||||||
|
#define LV_CONF_H
|
||||||
|
|
||||||
|
#define LV_COLOR_DEPTH 16
|
||||||
|
|
||||||
|
#define LV_MEM_SIZE (256U * 1024U)
|
||||||
|
|
||||||
|
#define LV_USE_LOG 0
|
||||||
|
|
||||||
|
#define LV_USE_ASSERT_NULL 1
|
||||||
|
|
||||||
|
#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN
|
||||||
|
#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN
|
||||||
|
#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN
|
||||||
|
|
||||||
|
#endif
|
||||||
56
include/lv_ctr_disp.h
Normal file
56
include/lv_ctr_disp.h
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* @file lv_ctr_disp.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
#ifndef LV_CTR_DISP_H
|
||||||
|
#define LV_CTR_DISP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
/* Initialize low level display driver */
|
||||||
|
void lv_ctr_disp_init(void);
|
||||||
|
|
||||||
|
/* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
||||||
|
*/
|
||||||
|
void disp_enable_update(void);
|
||||||
|
|
||||||
|
/* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
||||||
|
*/
|
||||||
|
void disp_disable_update(void);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /*extern "C"*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*LV_CTR_DISP_H*/
|
||||||
|
|
||||||
|
#endif /*Disable/Enable content*/
|
||||||
1
libraries/lvgl
Submodule
1
libraries/lvgl
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit fe121205addd990871d350f252c7d40dab9789da
|
||||||
163
source/lv_ctr_disp.c
Normal file
163
source/lv_ctr_disp.c
Normal file
|
|
@ -0,0 +1,163 @@
|
||||||
|
/**
|
||||||
|
* @file lv_ctr_disp.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "lv_ctr_disp.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <3ds.h>
|
||||||
|
#include <citro3d.h>
|
||||||
|
#include <citro2d.h>
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
#define BOTTOM_DISP_HOR_RES 320
|
||||||
|
#define BOTTOM_DISP_VER_RES 240
|
||||||
|
#define BOTTOM_TEX_HOR_RES 512
|
||||||
|
#define BOTTOM_TEX_VER_RES 256
|
||||||
|
|
||||||
|
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_ARGB8888))
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
static void disp_init(void);
|
||||||
|
|
||||||
|
static void disp_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||||
|
|
||||||
|
/* Calculate nearest power of 2 for a given size */
|
||||||
|
__attribute__ ((const)) static inline u32 tex_pot(u32 x) {
|
||||||
|
if (x < 32) return 32;
|
||||||
|
return 1 << (32 - __builtin_clz(x - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
C3D_RenderTarget *bottom_screen;
|
||||||
|
C3D_Tex tex;
|
||||||
|
Tex3DS_SubTexture subt3x;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
void lv_ctr_disp_init(void)
|
||||||
|
{
|
||||||
|
/*-------------------------
|
||||||
|
* Initialize your display
|
||||||
|
* -----------------------*/
|
||||||
|
disp_init();
|
||||||
|
|
||||||
|
/*------------------------------------
|
||||||
|
* Create a display and set a flush_cb
|
||||||
|
* -----------------------------------*/
|
||||||
|
lv_display_t * bottom_disp = lv_display_create(BOTTOM_DISP_HOR_RES, BOTTOM_DISP_VER_RES);
|
||||||
|
lv_display_set_flush_cb(bottom_disp, disp_flush);
|
||||||
|
|
||||||
|
/* Two buffers for double buffering. */
|
||||||
|
#define BOTTOM_TEX_STRIDE (BOTTOM_TEX_HOR_RES * BYTE_PER_PIXEL)
|
||||||
|
LV_ATTRIBUTE_MEM_ALIGN static uint8_t buf_1[BOTTOM_TEX_STRIDE * BOTTOM_DISP_VER_RES];
|
||||||
|
LV_ATTRIBUTE_MEM_ALIGN static uint8_t buf_2[BOTTOM_TEX_STRIDE * BOTTOM_DISP_VER_RES];
|
||||||
|
lv_display_set_buffers_with_stride(bottom_disp, buf_1, buf_2, sizeof(buf_1), BOTTOM_TEX_STRIDE, LV_DISPLAY_RENDER_MODE_FULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/*Initialize your display and the required peripherals.*/
|
||||||
|
static void disp_init(void)
|
||||||
|
{
|
||||||
|
gfxInitDefault();
|
||||||
|
|
||||||
|
ptmuInit();
|
||||||
|
|
||||||
|
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||||
|
C2D_Init(C2D_DEFAULT_MAX_OBJECTS);
|
||||||
|
C2D_Prepare();
|
||||||
|
bottom_screen = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT);
|
||||||
|
|
||||||
|
if(0 == C3D_TexInit(&tex, BOTTOM_TEX_HOR_RES, BOTTOM_TEX_VER_RES, GPU_RGB8)) puts("Could not create main texture.");
|
||||||
|
memset(tex.data, 0, tex.size);
|
||||||
|
tex.border = 0xFFFFFFFF;
|
||||||
|
C3D_TexSetWrap(&tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
|
||||||
|
|
||||||
|
subt3x.width = BOTTOM_DISP_HOR_RES;
|
||||||
|
subt3x.height = BOTTOM_DISP_VER_RES;
|
||||||
|
subt3x.left = 0.0f;
|
||||||
|
subt3x.top = 1.0f;
|
||||||
|
subt3x.right = (BOTTOM_DISP_HOR_RES/(float)tex.width);
|
||||||
|
subt3x.bottom = (1.0f - BOTTOM_DISP_VER_RES/(float)tex.height);
|
||||||
|
|
||||||
|
C3D_TexSetFilter(&tex, GPU_NEAREST, GPU_NEAREST);
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile bool disp_flush_enabled = true;
|
||||||
|
|
||||||
|
/* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
||||||
|
*/
|
||||||
|
void disp_enable_update(void)
|
||||||
|
{
|
||||||
|
disp_flush_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
|
||||||
|
*/
|
||||||
|
void disp_disable_update(void)
|
||||||
|
{
|
||||||
|
disp_flush_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Flush the content of the internal buffer the specific area on the display.
|
||||||
|
*`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display.
|
||||||
|
*You can use DMA or any hardware acceleration to do this operation in the background but
|
||||||
|
*'lv_display_flush_ready()' has to be called when it's finished.*/
|
||||||
|
static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)
|
||||||
|
{
|
||||||
|
if (lv_display_flush_is_last(disp_drv)) {
|
||||||
|
GSPGPU_FlushDataCache(px_map, tex.width * tex.height * 4);
|
||||||
|
|
||||||
|
u32 dim = GX_BUFFER_DIM(tex.width, tex.height);
|
||||||
|
C3D_SyncDisplayTransfer((u32 *)px_map, dim, (u32*)tex.data, dim,
|
||||||
|
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) |
|
||||||
|
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) |
|
||||||
|
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
|
||||||
|
);
|
||||||
|
|
||||||
|
// start frame, clear targets
|
||||||
|
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||||
|
C2D_TargetClear(bottom_screen, C2D_Color32f(0, 0, 0, 1));
|
||||||
|
|
||||||
|
C2D_SceneBegin(bottom_screen);
|
||||||
|
|
||||||
|
C2D_Image img = { &tex, &subt3x };
|
||||||
|
C2D_DrawImageAt(img, 0, 0, 0.6f, NULL, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
C3D_FrameEnd(0);
|
||||||
|
}
|
||||||
|
lv_display_flush_ready(disp_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /*Enable this file at the top*/
|
||||||
|
|
||||||
|
/*This dummy typedef exists purely to silence -Wpedantic.*/
|
||||||
|
typedef int keep_pedantic_happy;
|
||||||
|
#endif
|
||||||
|
|
||||||
40
source/main.c
Normal file
40
source/main.c
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <3ds.h>
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include "lv_ctr_disp.h"
|
||||||
|
|
||||||
|
// ote: expected 'lv_tick_get_cb_t' {aka 'long unsigned int (*)(void)'} but argument is of type 'u64 (*)(void)' {aka 'long long unsigned int (*)(void)'}
|
||||||
|
long unsigned int sys_tick(void)
|
||||||
|
{
|
||||||
|
return (long unsigned int)svcGetSystemTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
lv_ctr_disp_init();
|
||||||
|
lv_init();
|
||||||
|
lv_tick_set_cb(sys_tick);
|
||||||
|
|
||||||
|
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||||
|
lv_label_set_text(label, "Hello world");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
while (aptMainLoop())
|
||||||
|
{
|
||||||
|
lv_timer_handler();
|
||||||
|
gspWaitForVBlank();
|
||||||
|
gfxSwapBuffers();
|
||||||
|
hidScanInput();
|
||||||
|
|
||||||
|
// Your code goes here
|
||||||
|
u32 kDown = hidKeysDown();
|
||||||
|
if (kDown & KEY_START)
|
||||||
|
break; // break in order to return to hbmenu
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxExit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue