diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b5b706 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +.dir-locals.el \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6488e87 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.2) + +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(DEFINED ENV{VITASDK}) + set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file") + else() + message(FATAL_ERROR "Please define VITASDK to point to your SDK path!") + endif() +endif() + + +project(Apollon) +include("${VITASDK}/share/vita.cmake" REQUIRED) + +set(VITA_APP_NAME "Apollon") +set(VITA_TITLEID "HANE00001") +set(VITA_VERSION "01.00") + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wpedantic -std=gnu11") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +include_directories( + src + src/debugScreen + ) + +add_executable(${PROJECT_NAME} + src/main.c + src/debugScreen/debugScreen.c +) + +target_link_libraries(${PROJECT_NAME} + m + SceDisplay_stub + SceCtrl_stub + SceAudio_stub +) + +# RUNTIME_OUTPUT_DIRECTORY = ./build +vita_create_self(${PROJECT_NAME}.self ${PROJECT_NAME}) +vita_create_vpk(${PROJECT_NAME}.vpk ${VITA_TITLEID} ${PROJECT_NAME}.self + VERSION ${VITA_VERSION} + NAME ${VITA_APP_NAME} +) diff --git a/CMakeUserPresets.json b/CMakeUserPresets.json new file mode 100644 index 0000000..4934fb2 --- /dev/null +++ b/CMakeUserPresets.json @@ -0,0 +1,21 @@ +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20, + "patch": 0 + }, + "configurePresets": [ + { + "name": "hane", + "displayName": "Hane", + "description": "Hanecfg", + "generator": "Unix Makefiles", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + }, + "environment": { + } + } + ] +} diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..ff24cf8 --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash +if [ ! -d "build" ]; then + mkdir "build" +fi +cmake --preset=hane . && make -C build diff --git a/src/debugScreen/debugScreen.c b/src/debugScreen/debugScreen.c new file mode 100644 index 0000000..6d7f533 --- /dev/null +++ b/src/debugScreen/debugScreen.c @@ -0,0 +1,731 @@ +#ifndef DEBUG_SCREEN_C +#define DEBUG_SCREEN_C + +/* +* debugScreen.c of Vita SDK +* +* - psvDebugScreenInit() +* Initializes debug screen for output. +* +* - psvDebugScreenPuts() +* Similar to the C library function puts() writes a string to the debug +* screen up to but not including the NUL character. +* Supports the most important CSI sequences of ECMA-48 / ISO/IEC 6429:1992. +* Graphic Rendition Combination Mode (GRCM) supported is Cumulative. +* Modifications: +* - CSI SGR codes 30-37/38/39 & 40-47/48/49 set standard/fitting/default intensity, so instead of "\e[1;31m" use "\e31;1m" +* - ANSI color #8 is made darker (40<>80), so that "dark" white is still lighter than "bright" dark +* - support 16 save storages for CSI s and CSI u, e.g "\e[8s" and "\e[8u" +* [1] https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences +* [2] https://jonasjacek.github.io/colors/ +* [3] https://www.ecma-international.org/publications/standards/Ecma-048.htm +* [4] https://invisible-island.net/xterm/ctlseqs/ctlseqs.html +* [5] http://man7.org/linux/man-pages/man4/console_codes.4.html +* +* (CSI = "\e[") +* CSI [n] s = Save Cursor Position to slot #n (0-15). Default 0. +* CSI [n] u = Restore Cursor Position from slot #n (0-15). Default 0. +* CSI n A = Cursor Up times. +* CSI n B = Cursor Down times. +* CSI n C = Cursor Forward times. +* CSI n D = Cursor Back times. +* CSI n E = Cursor Next Line times and to Beginning of that Line. +* CSI n F = Cursor Previous Line times and to Beginning of that Line. +* CSI n G = Cursor to Column . The value is 1-based and defaults to 1 (first column) if omitted. +* CSI n ; m H = Cursor to Row and Column . The values are 1-based and default to 1 (top left corner) if omitted. +* CSI n ; m f = Cursor to Row and Column . The values are 1-based and default to 1 (top left corner) if omitted. +* CSI [n] J = Clears part of the screen. Cursor position does not change. +* 0 (default) from cursor to end of screen. +* 1 from cursor to beginning of the screen. +* 2 entire screen +* CSI [n] K = Clears part of the line. Cursor position does not change. +* 0 (default) from cursor to end of line. +* 1 from cursor to beginning of line. +* 2 clear entire line. +* CSI [n] m = Sets the appearance of the following characters. +* 0 Reset all (colors and inversion) (default) +* 1 Increased intensity ("bright" color) +* 2 Decreased intensity ("faint"/"dark" color) +* 7 Enable inversion +* 22 Standard intensity ("normal" color) +* 27 Disable inversion +* 30–37 Set ANSI foreground color with standard intensity +* 38 Set foreground color. Arguments are 5; or 2;;; +* 39 Default foreground color +* 40–47 Set standard ANSI background color with standard intensity +* 48 Set background color. Arguments are 5; or 2;;; +* 49 Default background color +* 90–97 Set ANSI foreground color with increased intensity +* 100–107 Set ANSI background color with increased intensity +* +* - psvDebugScreenPrintf() +* Similar to the C library function printf() formats a string and ouputs +* it via psvDebugScreenPuts() to the debug screen. +* +* - psvDebugScreenGetColorStateCopy(ColorState *copy) +* Get copy of current color state. +* +* - psvDebugScreenGetCoordsXY(int *x, int *y) +* Get copy of current pixel coordinates. +* Allows for multiple and custom position stores. +* Allows correct positioning when using different font sizes. +* +* - psvDebugScreenSetCoordsXY(int *x, int *y) +* Set pixel coordinates. +* Allows for multiple and custom position stores. +* Allows correct positioning when using different font sizes. +* +* - PsvDebugScreenFont *psvDebugScreenGetFont() +* Get current font. +* +* - PsvDebugScreenFont *psvDebugScreenSetFont(PsvDebugScreenFont *font) { +* Set font. Returns current font. +* +* - PsvDebugScreenFont *psvDebugScreenScaleFont2x(PsvDebugScreenFont *source_font) { +* Scales a font by 2 (e.g. 8x8 to 16x16) and returns new scaled font. +* +* Also see the following samples: +* - debugscreen +* - debug_print +* +*/ + +#include // for malloc(), free() +#include // for vsnprintf() +#include // for memset(), memcpy() +#include // for va_list, va_start(), va_end() +#include + +#include "debugScreen.h" + +#include "debugScreenFont.c" + +#define SCREEN_FB_WIDTH (960) // frame buffer aligned width for accessing vram +#define SCREEN_FB_SIZE (2 * 1024 * 1024) // Must be 256KB aligned +#ifndef SCREEN_TAB_SIZE // this allows easy overriding +#define SCREEN_TAB_SIZE (8) +#endif +#define SCREEN_TAB_W ((F)->size_w * (SCREEN_TAB_SIZE)) +#define F psvDebugScreenFontCurrent + +#define FROM_FULL_RGB(r,g,b ) ( ((b)<<16) | ((g)<<8) | (r) ) +#define CONVERT_RGB_BGR(rgb) rgb = ( (((rgb)&0x0000FF)<<16) | ((rgb)&0x00FF00) | (((rgb)&0xFF0000)>>16) ) + +#define CLEARSCRNBLOCK(H,toH,W,toW,color) for (int h = (H); h < (toH); h++) for (int w = (W); w < (toW); w++) ((uint32_t*)base)[h*(SCREEN_FB_WIDTH) + w] = (color); +#define CLEARSCRNLINES(H,toH,color) { uint32_t *pixel = (uint32_t *)base + ((H) * (SCREEN_FB_WIDTH)); int i = (((toH) - (H)) * (SCREEN_FB_WIDTH)); for (; i > 0; i--) *pixel++ = (color); } + +#define SAVE_STORAGES 16 + +static int initialized = 0; +static int mutex, coordX, coordY; +static int savedX[SAVE_STORAGES] = { 0 }, savedY[SAVE_STORAGES] = { 0 }; +static ColorState colors = { + 0, 0, // truecolor flags + 0, 0, // truecolors + 0, 0, 0, 0, 0, // ANSI/VTERM/GREYSCALE colors + 7, 22, 0, 22, 0, // default colors (ANSI/VTERM/GREYSCALE) +}; + +static PsvDebugScreenFont *psvDebugScreenFontCurrent = &psvDebugScreenFont; + +#ifdef __vita__ +#include +#include +#include +static SceUID displayblock; +static void* base; // pointer to frame buffer +#else +#define NO_psvDebugScreenInit +#ifndef psvDebugScreenInitReplacement +#define psvDebugScreenInitReplacement(...) +#endif +#define sceKernelLockMutex(m,v,x) m=v +#define sceKernelUnlockMutex(m,v) m=v +static char base[(SCREEN_FB_WIDTH) * (SCREEN_HEIGHT) * 4]; +#endif + +static uint32_t DARK_COLORS_BGR[8] = { + 0x000000, 0x000040, 0x004000, 0x004040, 0x400000, 0x400040, 0x404000, 0x808080, // 0-7 +}; + +// ANSI/VTERM/GREYSCALE palette: https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit +// modifications: +// - #8 is made darker (40<>80), so that "dark" white is still lighter than "bright" dark +static uint32_t ANSI_COLORS_BGR[256] = { + 0x000000, 0x000080, 0x008000, 0x008080, 0x800000, 0x800080, 0x808000, 0xc0c0c0, // 0-7 + 0x404040, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00, 0xffffff, // 8-15 + 0x000000, 0x5f0000, 0x870000, 0xaf0000, 0xd70000, 0xff0000, 0x005f00, 0x5f5f00, // 16-23 + 0x875f00, 0xaf5f00, 0xd75f00, 0xff5f00, 0x008700, 0x5f8700, 0x878700, 0xaf8700, // 24-31 + 0xd78700, 0xff8700, 0x00af00, 0x5faf00, 0x87af00, 0xafaf00, 0xd7af00, 0xffaf00, // 32-39 + 0x00d700, 0x5fd700, 0x87d700, 0xafd700, 0xd7d700, 0xffd700, 0x00ff00, 0x5fff00, // 40-47 + 0x87ff00, 0xafff00, 0xd7ff00, 0xffff00, 0x00005f, 0x5f005f, 0x87005f, 0xaf005f, // 48-55 + 0xd7005f, 0xff005f, 0x005f5f, 0x5f5f5f, 0x875f5f, 0xaf5f5f, 0xd75f5f, 0xff5f5f, // 56-63 + 0x00875f, 0x5f875f, 0x87875f, 0xaf875f, 0xd7875f, 0xff875f, 0x00af5f, 0x5faf5f, // 64-71 + 0x87af5f, 0xafaf5f, 0xd7af5f, 0xffaf5f, 0x00d75f, 0x5fd75f, 0x87d75f, 0xafd75f, // 72-79 + 0xd7d75f, 0xffd75f, 0x00ff5f, 0x5fff5f, 0x87ff5f, 0xafff5f, 0xd7ff5f, 0xffff5f, // 80-87 + 0x000087, 0x5f0087, 0x870087, 0xaf0087, 0xd70087, 0xff0087, 0x005f87, 0x5f5f87, // 88-95 + 0x875f87, 0xaf5f87, 0xd75f87, 0xff5f87, 0x008787, 0x5f8787, 0x878787, 0xaf8787, // 96-103 + 0xd78787, 0xff8787, 0x00af87, 0x5faf87, 0x87af87, 0xafaf87, 0xd7af87, 0xffaf87, // 104-111 + 0x00d787, 0x5fd787, 0x87d787, 0xafd787, 0xd7d787, 0xffd787, 0x00ff87, 0x5fff87, // 112-119 + 0x87ff87, 0xafff87, 0xd7ff87, 0xffff87, 0x0000af, 0x5f00af, 0x8700af, 0xaf00af, // 120-127 + 0xd700af, 0xff00af, 0x005faf, 0x5f5faf, 0x875faf, 0xaf5faf, 0xd75faf, 0xff5faf, // 128-135 + 0x0087af, 0x5f87af, 0x8787af, 0xaf87af, 0xd787af, 0xff87af, 0x00afaf, 0x5fafaf, // 136-143 + 0x87afaf, 0xafafaf, 0xd7afaf, 0xffafaf, 0x00d7af, 0x5fd7af, 0x87d7af, 0xafd7af, // 144-151 + 0xd7d7af, 0xffd7af, 0x00ffaf, 0x5fffaf, 0x87ffaf, 0xafffaf, 0xd7ffaf, 0xffffaf, // 152-159 + 0x0000d7, 0x5f00d7, 0x8700d7, 0xaf00d7, 0xd700d7, 0xff00d7, 0x005fd7, 0x5f5fd7, // 160-167 + 0x875fd7, 0xaf5fd7, 0xd75fd7, 0xff5fd7, 0x0087d7, 0x5f87d7, 0x8787d7, 0xaf87d7, // 168-175 + 0xd787d7, 0xff87d7, 0x00afd7, 0x5fafd7, 0x87afd7, 0xafafd7, 0xd7afd7, 0xffafd7, // 176-183 + 0x00d7d7, 0x5fd7d7, 0x87d7d7, 0xafd7d7, 0xd7d7d7, 0xffd7d7, 0x00ffd7, 0x5fffd7, // 184-191 + 0x87ffd7, 0xafffd7, 0xd7ffd7, 0xffffd7, 0x0000ff, 0x5f00ff, 0x8700ff, 0xaf00ff, // 192-199 + 0xd700ff, 0xff00ff, 0x005fff, 0x5f5fff, 0x875fff, 0xaf5fff, 0xd75fff, 0xff5fff, // 200-207 + 0x0087ff, 0x5f87ff, 0x8787ff, 0xaf87ff, 0xd787ff, 0xff87ff, 0x00afff, 0x5fafff, // 208-215 + 0x87afff, 0xafafff, 0xd7afff, 0xffafff, 0x00d7ff, 0x5fd7ff, 0x87d7ff, 0xafd7ff, // 216-223 + 0xd7d7ff, 0xffd7ff, 0x00ffff, 0x5fffff, 0x87ffff, 0xafffff, 0xd7ffff, 0xffffff, // 224-231 + 0x080808, 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e, // 232-239 + 0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e, // 240-247 + 0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee, // 248-255 +}; + +/* +* Reset foreground color to default +*/ +static void psvDebugScreenResetFgColor(void) { + colors.fgTrueColorFlag = 0; + colors.fgTrueColor = 0; + colors.fgIndex = colors.fgIndexDefault; + colors.fgIntensity = colors.fgIntensityDefault; +} + +/* +* Reset background color to default +*/ +static void psvDebugScreenResetBgColor(void) { + colors.bgTrueColorFlag = 0; + colors.bgTrueColor = 0; + colors.bgIndex = colors.bgIndexDefault; + colors.bgIntensity = colors.bgIntensityDefault; +} + +/* +* Reset inversion state to default +*/ +static void psvDebugScreenResetInversion(void) { + colors.inversion = colors.inversionDefault; +} + +/* +* Determine colors according to current color state +*/ +static void psvDebugScreenSetColors(void) { + uint32_t *color_fg, *color_bg; + + // special case: inversion + if (!colors.inversion) { + color_fg = &colors.color_fg; + color_bg = &colors.color_bg; + } else { + color_fg = &colors.color_bg; + color_bg = &colors.color_fg; + } + + // foregound color + if ((colors.fgIndex<=7) && (colors.fgIntensity==1)) { // ANSI palette with increased intensity + colors.fgIndex |= 0x8; + } else if ((colors.fgIndex<=15) && (colors.fgIntensity!=1)) { // ANSI palette with standard/decreased intensity + colors.fgIndex &= 0x7; + } + if (colors.fgTrueColorFlag) { + *color_fg = colors.fgTrueColor; + } else { + if ((colors.fgIndex<=7) && (colors.fgIntensity==2)) { // "ANSI" palette with decreased intensity + *color_fg = DARK_COLORS_BGR[colors.fgIndex]; + } else { // ANSI/VTERM/GREYSCALE palette + *color_fg = ANSI_COLORS_BGR[colors.fgIndex]; + } + } + *color_fg |= 0xFF000000; // opaque + + // backgound color + if ((colors.bgIndex<=7) && (colors.bgIntensity==1)) { // ANSI palette with increased intensity + colors.bgIndex |= 0x8; + } else if ((colors.bgIndex<=15) && (colors.bgIntensity!=1)) { // ANSI palette with standard/decreased intensity + colors.bgIndex &= 0x7; + } + if (colors.bgTrueColorFlag) { + *color_bg = colors.bgTrueColor; + } else { + if ((colors.bgIndex<=7) && (colors.bgIntensity==2)) { // "ANSI" palette with decreased intensity + *color_bg = DARK_COLORS_BGR[colors.bgIndex]; + } else { // ANSI/VTERM/GREYSCALE palette + *color_bg = ANSI_COLORS_BGR[colors.bgIndex]; + } + } + *color_bg |= 0xFF000000; // opaque +} + +/* +* Parse CSI sequences +*/ +static size_t psvDebugScreenEscape(const unsigned char *str) { + unsigned int i, argc, arg[32] = { 0 }; + unsigned int c; + uint32_t unit, mode; + int *colorTrueColorFlag; + uint32_t *colorTrueColor; + unsigned char *colorIndex, *colorIntensity; + for (i = 0, argc = 0; (argc < (sizeof(arg)/sizeof(*arg))) && (str[i] != '\0'); i++) { + switch (str[i]) { + // numeric char + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + arg[argc] = (arg[argc] * 10) + (str[i] - '0'); + continue; + // argument separator + case ';': argc++; continue; + // CSI commands + // save/restore position + case 's': + if (arg[0]size_h; return i; + case 'B': coordY += arg[0] * (F)->size_h; return i; + case 'C': coordX += arg[0] * (F)->size_w; return i; + case 'D': coordX -= arg[0] * (F)->size_w; return i; + // cursor movement to beginning of next/previous line(s) + case 'E': coordY += arg[0] * (F)->size_h; coordX = 0; return i; + case 'F': coordY -= arg[0] * (F)->size_h; coordX = 0; return i; + // cursor positioning + case 'G': coordX = (arg[0]-1) * (F)->size_w; return i; + case 'H': + case 'f': + coordY = (arg[0]-1) * (F)->size_h; + coordX = (arg[1]-1) * (F)->size_w; + return i; + // clear part of "J"=screen or "K"=Line, so J code re-uses part of K + case 'J': + case 'K': + if (arg[0]==0) { // from cursor to end of line/screen + CLEARSCRNBLOCK(coordY, coordY + (F)->size_h, coordX, (SCREEN_WIDTH), colors.color_bg); // line + if (str[i]=='J') CLEARSCRNLINES(coordY + (F)->size_h, (SCREEN_HEIGHT), colors.color_bg); // screen + } else if (arg[0]==1) { // from beginning of line/screen to cursor + CLEARSCRNBLOCK(coordY, coordY + (F)->size_h, 0, coordX, colors.color_bg); // line + if (str[i]=='J') CLEARSCRNLINES(0, coordY, colors.color_bg); // screen + } else if (arg[0]==2) { // whole line/screen + if (str[i]=='K') CLEARSCRNLINES(coordY, coordY + (F)->size_h, colors.color_bg) // line + else if (str[i]=='J') CLEARSCRNLINES(0, (SCREEN_HEIGHT), colors.color_bg); // screen + } + return i; + // color + case 'm': + for (c = 0; c <= argc; c++) { + switch (arg[c]) { + // reset all + case 0: + psvDebugScreenResetFgColor(); + psvDebugScreenResetBgColor(); + psvDebugScreenResetInversion(); + continue; + break; + // intensity + case 1: // increased = "bright" color + case 2: // decreased = "dark" color + case 22: // standard = "normal" color + colors.fgIntensity = arg[c]; + continue; + break; + // inversion + case 7: // enable + colors.inversion = 1; + continue; + break; + case 27: // disable + colors.inversion = 0; + continue; + break; + // set from color map or truecolor + case 38: // foreground color + case 48: // background color + mode = arg[c] / 10; + colorTrueColorFlag = mode&1 ? &colors.fgTrueColorFlag : &colors.bgTrueColorFlag; + if (arg[c+1]==5) { // 8-bit: [0-15][16-231][232-255] color map + *colorTrueColorFlag = 0; + colorIndex = mode&1 ? &colors.fgIndex : &colors.bgIndex; + *colorIndex = arg[c+2] & 0xFF; + colorIntensity = mode&1 ? &colors.fgIntensity : &colors.bgIntensity; + *colorIntensity = ((*colorIndex>=8) && (*colorIndex<=15)) ? 1 : 22; + c+=2; // extra arguments + } else if (arg[c+1]==2) { // 24-bit color space + *colorTrueColorFlag = 1; + colorTrueColor = mode&1 ? &colors.fgTrueColor : &colors.bgTrueColor; + *colorTrueColor = FROM_FULL_RGB(arg[c+2], arg[c+3], arg[c+4]); + c+=4; // extra arguments + } + continue; + break; + // default color + case 39: // foreground color + psvDebugScreenResetFgColor(); + continue; + break; + case 49: // background color + psvDebugScreenResetBgColor(); + continue; + break; + // custom color reset + default: + // ANSI colors (30-37, 40-47, 90-97, 100-107) + mode = arg[c] / 10; + if ((mode!=3) && (mode!=4) && (mode!=9) && (mode!=10)) continue; // skip unsupported modes + unit = arg[c] % 10; + if (unit>7) continue; // skip unsupported modes + colorTrueColorFlag = mode&1 ? &colors.fgTrueColorFlag : &colors.bgTrueColorFlag; + *colorTrueColorFlag = 0; + colorIndex = mode&1 ? &colors.fgIndex : &colors.bgIndex; + *colorIndex = unit; + colorIntensity = mode&1 ? &colors.fgIntensity : &colors.bgIntensity; + *colorIntensity = mode&8 ? 1 : 22; + break; + } + } + psvDebugScreenSetColors(); + return i; + } + } + return 0; +} + +__attribute__((destructor)) static void psvDebugScreenDestructor() { + psvDebugScreenFinish(); +} + +/* +* Initialize debug screen +*/ +int psvDebugScreenInit() { + psvDebugScreenResetFgColor(); + psvDebugScreenResetBgColor(); + psvDebugScreenResetInversion(); + psvDebugScreenSetColors(); + +#ifdef NO_psvDebugScreenInit + psvDebugScreenInitReplacement(); + initialized = 1; + return 0; // avoid linking non-initializer (prx) with sceDisplay/sceMemory +#else + mutex = sceKernelCreateMutex("log_mutex", 0, 0, NULL); + displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, (SCREEN_FB_SIZE), NULL); + if (displayblock < 0) + return displayblock; + sceKernelGetMemBlockBase(displayblock, (void**)&base); + SceDisplayFrameBuf frame = { sizeof(frame), base, (SCREEN_FB_WIDTH), 0, (SCREEN_WIDTH), (SCREEN_HEIGHT) }; + initialized = 1; + return sceDisplaySetFrameBuf(&frame, SCE_DISPLAY_SETBUF_NEXTFRAME); +#endif +} + +/* +* Finalize debug screen +*/ +int psvDebugScreenFinish() { + if (!initialized) + return -1; + + initialized = 0; + +#ifdef NO_psvDebugScreenInit + return 0; +#else + sceKernelDeleteMutex(mutex); + sceDisplaySetFrameBuf(NULL, SCE_DISPLAY_SETBUF_IMMEDIATE); + return sceKernelFreeMemBlock(displayblock); +#endif +} + +/* +* Draw text onto debug screen +*/ +int psvDebugScreenPuts(const char * _text) { + const unsigned char*text = (const unsigned char*)_text; + int c; + unsigned char t; + unsigned char drawDummy; + // + uint32_t *vram; + int bits_per_glyph = ((F)->width * (F)->height); + int bitmap_offset; + unsigned char *font; + int row; + int max_row; + int col; + unsigned char mask; + uint32_t *pixel; + + sceKernelLockMutex(mutex, 1, NULL); + for (c = 0; text[c] ; c++) { + t = text[c]; + // handle CSI sequence + if ((t == '\e') && (text[c+1] == '[')) { + c += psvDebugScreenEscape(text + c + 2) + 2; + if (coordX < 0) coordX = 0; // CSI position are 1-based, + if (coordY < 0) coordY = 0; // prevent 0-based coordinate from producing a negative X/Y + continue; + } + // handle non-printable characters #1 (line-dependent codes) + if (t == '\n') { + coordX = 0; + coordY += (F)->size_h; + continue; + } + if (t == '\r') { + coordX = 0; + continue; + } + // check if glyph fits in line + if ((coordX + (F)->width) > (SCREEN_WIDTH)) { + coordY += (F)->size_h; + coordX = 0; + } + // check if glyph fits in screen + if ((coordY + (F)->height) > (SCREEN_HEIGHT)) { + coordX = coordY = 0; + } + // handle non-printable characters #2 + if (t == '\t') { + coordX += (SCREEN_TAB_W) - (coordX % (SCREEN_TAB_W)); + continue; + } + + // draw glyph or dummy glyph (dotted line in the middle) + // works also with not byte-aligned glyphs + vram = ((uint32_t*)base) + coordX + (coordY * (SCREEN_FB_WIDTH)); + row = 0; + // check if glyph is available in font + if ((t > (F)->last) || (t < (F)->first)) { + drawDummy = 1; + bitmap_offset = 0; + font = NULL; + mask = 1 << 7; + } else { + drawDummy = 0; + bitmap_offset = (t - (F)->first) * bits_per_glyph; + font = &(F)->glyphs[ (bitmap_offset / 8) ]; + mask = 1 << 7; + for (col = (bitmap_offset % 8); col > 0; col--, mask >>= 1); + } + // special case: dummy glyph, clear to middle height + max_row = 0; + if (drawDummy) { + max_row = (F)->height / 2; + for (; row < max_row; row++, vram += (SCREEN_FB_WIDTH)) { + pixel = vram; + col = 0; + for (; col < (F)->size_w ; col++) { + *pixel++ = colors.color_bg; + } + } + } + // draw font glyph or dummy glyph + if (drawDummy) { + max_row++; + if (max_row > (F)->height) max_row = (F)->height; + } else { + max_row = (F)->height; + } + for (; row < max_row; row++, vram += (SCREEN_FB_WIDTH)) { + pixel = vram; + col = 0; + for (; col < (F)->width ; col++, mask >>= 1) { + if (drawDummy) { + *pixel++ = (col&1) ? colors.color_fg : colors.color_bg; + } else { + if (!mask) { font++; mask = 1 << 7; } // no more bits: we exhausted this byte + *pixel++ = (*font&mask) ? colors.color_fg : colors.color_bg; + } + } + // right margin + for (; col < (F)->size_w ; col++) + *pixel++ = colors.color_bg; + } + // draw bottom margin + max_row = (F)->size_h; + for (; row < (F)->size_h; row++, vram += (SCREEN_FB_WIDTH)) + for (pixel = vram, col = 0; col < (F)->size_w ; col++) + *pixel++ = colors.color_bg; + // advance X position + coordX += (F)->size_w; + } + sceKernelUnlockMutex(mutex, 1); + return c; +} + + +/* +* Printf text onto debug screen +*/ +__attribute__((__format__ (__printf__, 1, 2))) +int psvDebugScreenPrintf(const char *format, ...) { + char buf[4096]; + + va_list opt; + va_start(opt, format); + int ret = vsnprintf(buf, sizeof(buf), format, opt); + psvDebugScreenPuts(buf); + va_end(opt); + + return ret; +} + +/* +* Return copy of color state +*/ +void psvDebugScreenGetColorStateCopy(ColorState *copy) { + if (copy) { + memcpy(copy, &colors, sizeof(ColorState)); + CONVERT_RGB_BGR(copy->fgTrueColor); + CONVERT_RGB_BGR(copy->bgTrueColor); + CONVERT_RGB_BGR(copy->color_fg); + CONVERT_RGB_BGR(copy->color_bg); + } +} + +/* +* Return copy of pixel coordinates +*/ +void psvDebugScreenGetCoordsXY(int *x, int *y) { + if (x) *x = coordX; + if (y) *y = coordY; +} + +/* +* Set pixel coordinates +*/ +void psvDebugScreenSetCoordsXY(int *x, int *y) { + if (x) { + coordX = *x; + if (coordX < 0) coordX = 0; + } + if (y) { + coordY = *y; + if (coordY < 0) coordY = 0; + } +} + +/* +* Return pointer to current font +*/ +PsvDebugScreenFont *psvDebugScreenGetFont(void) { + return F; +} + +/* +* Set font +*/ +PsvDebugScreenFont *psvDebugScreenSetFont(PsvDebugScreenFont *font) { + if ((font) && (font->glyphs)) F = font; + return F; +} + +/* +* Return scaled-by-2 copy of font +*/ +PsvDebugScreenFont *psvDebugScreenScaleFont2x(PsvDebugScreenFont *source_font) { + // works also with not byte-aligned glyphs + PsvDebugScreenFont *target_font; + size_t size; + size_t align; + int glyph; + int row; + int col; + int count; + unsigned char *source_bitmap; + unsigned char source_mask; + unsigned char *target_bitmap, *target_bitmap2; + unsigned char target_mask, target_mask2; + int target_next_row_bytes, target_next_row_bits; + unsigned char pixel; + + if (!source_font) return NULL; + + // allocate target structure and bitmap + target_font = (PsvDebugScreenFont *)malloc(sizeof(PsvDebugScreenFont)); + memset(target_font, 0, sizeof(PsvDebugScreenFont)); + // copy and scale meta information + target_font->width = 2 * source_font->width; + target_font->height = 2 * source_font->height; + target_font->first = source_font->first; + target_font->last = source_font->last; + target_font->size_w = 2 * source_font->size_w; + target_font->size_h = 2 * source_font->size_h; + + // calculate size of target bitmap + size = target_font->width * target_font->height * (target_font->last - target_font->first + 1); + if (size <= 0) { + free(target_font); + return NULL; + } + align = size % 8; + size /= 8; + if (align) size++; + + // allocate and initialize target bitmap + target_font->glyphs = (unsigned char *)malloc(size); + memset(target_font->glyphs, 0, size); + + // scale source bitmap and store in target bitmap + source_bitmap = source_font->glyphs; + source_mask = 1 << 7; + // + target_bitmap = target_font->glyphs; + target_mask = 1 << 7; + target_next_row_bytes = target_font->width / 8; + target_next_row_bits = target_font->width % 8; + // + for (glyph = source_font->first; glyph <= source_font->last; glyph++) { + for (row = source_font->height; row > 0; row--) { + // Find beginning of next target row + target_bitmap2 = target_bitmap + target_next_row_bytes; // advance full bytes + target_mask2 = target_mask; // advance remaining bits + for (col = target_next_row_bits; col > 0; col--, target_mask2 >>= 1) { + if (!target_mask2) { target_bitmap2++; target_mask2 = 1 << 7; } // no more bits: we advance to the next target byte + } + // Get pixel from source bitmap + for (col = source_font->width; col > 0; col--, source_mask >>= 1) { + if (!source_mask) { source_bitmap++; source_mask = 1 << 7; } // no more bits: we advance to the next source byte + pixel = *source_bitmap & source_mask; + // Put pixels into target bitmap + for (count = 2; count > 0; count--) { + // duplicate column in origial row + if (!target_mask) { target_bitmap++; target_mask = 1 << 7; } // no more bits: we advance to the next target byte + if (pixel) *target_bitmap |= target_mask; + target_mask >>= 1; + // duplicate column in duplicated row + if (!target_mask2) { target_bitmap2++; target_mask2 = 1 << 7; } // no more bits: we advance to the next target byte + if (pixel) *target_bitmap2 |= target_mask2; + target_mask2 >>= 1; + } + } + // Next target row is directly behind duplicated row + target_bitmap = target_bitmap2; + target_mask = target_mask2; + } + } + + return target_font; +} + +#undef SCREEN_TAB_W +#undef F + +#endif diff --git a/src/debugScreen/debugScreen.h b/src/debugScreen/debugScreen.h new file mode 100755 index 0000000..2db1354 --- /dev/null +++ b/src/debugScreen/debugScreen.h @@ -0,0 +1,59 @@ +#ifndef DEBUG_SCREEN_H +#define DEBUG_SCREEN_H + +#include "debugScreen_custom.h" + +typedef struct ColorState { + int fgTrueColorFlag; // flag if truecolors or ANSI/VTERM/GREYSCALE colors are used + int bgTrueColorFlag; // flag if truecolors or ANSI/VTERM/GREYSCALE colors are used + // truecolors + uint32_t fgTrueColor; // color in RGB (internal BGR) + uint32_t bgTrueColor; // color in RGB (internal BGR) + // ANSI/VTERM/GREYSCALE colors + unsigned char fgIndex; // ANSI/VTERM/GREYSCALE color code (0-255) + unsigned char fgIntensity; // 22=normal, 1=increased ("bright"), 2=decreased ("dark") + unsigned char bgIndex; // ANSI/VTERM/GREYSCALE color code (0-255) + unsigned char bgIntensity; // 22=normal, 1=increased ("bright") + int inversion; // flag if bg/fg colors are inverted + + // default colors (ANSI/VTERM/GREYSCALE) + unsigned char fgIndexDefault; // default ANSI/VTERM/GREYSCALE color code + unsigned char fgIntensityDefault; // 22=normal, 1=increased, 2=decreased + unsigned char bgIndexDefault; // default ANSI/VTERM/GREYSCALE color code + unsigned char bgIntensityDefault; // 22=normal, 1=increased + int inversionDefault; // flag if bg/fg colors are inverted + + // current colors (e.g. inverted) + uint32_t color_fg; // color in RGB (internal BGR) + uint32_t color_bg; // color in RGB (internal BGR) +} ColorState; + +typedef struct PsvDebugScreenFont { + unsigned char *glyphs, width, height, first, last, size_w, size_h; // only values 0-255 +} PsvDebugScreenFont; + +#define SCREEN_WIDTH (960) // screen resolution x +#define SCREEN_HEIGHT (544) // screen resolution y + +#ifdef DEBUG_SCREEN_CODE_INCLUDE // not recommended for your own projects, but for sake of backward compatibility +#include "debugScreen.c" +#else +#ifdef __cplusplus +extern "C" { +#endif +int psvDebugScreenInit(); +int psvDebugScreenFinish(); +int psvDebugScreenPuts(const char * _text); +int psvDebugScreenPrintf(const char *format, ...); +void psvDebugScreenGetColorStateCopy(ColorState *copy); +void psvDebugScreenGetCoordsXY(int *x, int *y); +void psvDebugScreenSetCoordsXY(int *x, int *y); +PsvDebugScreenFont *psvDebugScreenGetFont(void); +PsvDebugScreenFont *psvDebugScreenSetFont(PsvDebugScreenFont *font); +PsvDebugScreenFont *psvDebugScreenScaleFont2x(PsvDebugScreenFont *source_font); +#ifdef __cplusplus +} +#endif +#endif + +#endif /* DEBUG_SCREEN_H */ diff --git a/src/debugScreen/debugScreenFont.builder.html b/src/debugScreen/debugScreenFont.builder.html new file mode 100644 index 0000000..fd40b10 --- /dev/null +++ b/src/debugScreen/debugScreenFont.builder.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+ diff --git a/src/debugScreen/debugScreenFont.c b/src/debugScreen/debugScreenFont.c new file mode 100755 index 0000000..d528d32 --- /dev/null +++ b/src/debugScreen/debugScreenFont.c @@ -0,0 +1,144 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * font.c - Debug Font. + * + * Copyright (c) 2005 Marcus R. Brown + * Copyright (c) 2005 James Forshaw + * Copyright (c) 2005 John Kelley + * + * $Id: font.c 540 2005-07-08 19:35:10Z warren $ + */ + +PsvDebugScreenFont psvDebugScreenFont = { glyphs:(unsigned char*) +"\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x42\xa5\x81\xa5\x99\x42\x3c" +"\x3c\x7e\xdb\xff\xff\xdb\x66\x3c\x6c\xfe\xfe\xfe\x7c\x38\x10\x00" +"\x10\x38\x7c\xfe\x7c\x38\x10\x00\x10\x38\x54\xfe\x54\x10\x38\x00" +"\x10\x38\x7c\xfe\xfe\x10\x38\x00\x00\x00\x00\x30\x30\x00\x00\x00" +"\xff\xff\xff\xe7\xe7\xff\xff\xff\x38\x44\x82\x82\x82\x44\x38\x00" +"\xc7\xbb\x7d\x7d\x7d\xbb\xc7\xff\x0f\x03\x05\x79\x88\x88\x88\x70" +"\x38\x44\x44\x44\x38\x10\x7c\x10\x30\x28\x24\x24\x28\x20\xe0\xc0" +"\x3c\x24\x3c\x24\x24\xe4\xdc\x18\x10\x54\x38\xee\x38\x54\x10\x00" +"\x10\x10\x10\x7c\x10\x10\x10\x10\x10\x10\x10\xff\x00\x00\x00\x00" +"\x00\x00\x00\xff\x10\x10\x10\x10\x10\x10\x10\xf0\x10\x10\x10\x10" +"\x10\x10\x10\x1f\x10\x10\x10\x10\x10\x10\x10\xff\x10\x10\x10\x10" +"\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\xff\x00\x00\x00\x00" +"\x00\x00\x00\x1f\x10\x10\x10\x10\x00\x00\x00\xf0\x10\x10\x10\x10" +"\x10\x10\x10\x1f\x00\x00\x00\x00\x10\x10\x10\xf0\x00\x00\x00\x00" +"\x81\x42\x24\x18\x18\x24\x42\x81\x01\x02\x04\x08\x10\x20\x40\x80" +"\x80\x40\x20\x10\x08\x04\x02\x01\x00\x10\x10\xff\x10\x10\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x00\x00\x20\x00" +"\x50\x50\x50\x00\x00\x00\x00\x00\x50\x50\xf8\x50\xf8\x50\x50\x00" +"\x20\x78\xa0\x70\x28\xf0\x20\x00\xc0\xc8\x10\x20\x40\x98\x18\x00" +"\x40\xa0\x40\xa8\x90\x98\x60\x00\x10\x20\x40\x00\x00\x00\x00\x00" +"\x10\x20\x40\x40\x40\x20\x10\x00\x40\x20\x10\x10\x10\x20\x40\x00" +"\x20\xa8\x70\x20\x70\xa8\x20\x00\x00\x20\x20\xf8\x20\x20\x00\x00" +"\x00\x00\x00\x00\x00\x20\x20\x40\x00\x00\x00\x78\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x60\x60\x00\x00\x00\x08\x10\x20\x40\x80\x00" +"\x70\x88\x98\xa8\xc8\x88\x70\x00\x20\x60\xa0\x20\x20\x20\xf8\x00" +"\x70\x88\x08\x10\x60\x80\xf8\x00\x70\x88\x08\x30\x08\x88\x70\x00" +"\x10\x30\x50\x90\xf8\x10\x10\x00\xf8\x80\xe0\x10\x08\x10\xe0\x00" +"\x30\x40\x80\xf0\x88\x88\x70\x00\xf8\x88\x10\x20\x20\x20\x20\x00" +"\x70\x88\x88\x70\x88\x88\x70\x00\x70\x88\x88\x78\x08\x10\x60\x00" +"\x00\x00\x20\x00\x00\x20\x00\x00\x00\x00\x20\x00\x00\x20\x20\x40" +"\x18\x30\x60\xc0\x60\x30\x18\x00\x00\x00\xf8\x00\xf8\x00\x00\x00" +"\xc0\x60\x30\x18\x30\x60\xc0\x00\x70\x88\x08\x10\x20\x00\x20\x00" +"\x70\x88\x08\x68\xa8\xa8\x70\x00\x20\x50\x88\x88\xf8\x88\x88\x00" +"\xf0\x48\x48\x70\x48\x48\xf0\x00\x30\x48\x80\x80\x80\x48\x30\x00" +"\xe0\x50\x48\x48\x48\x50\xe0\x00\xf8\x80\x80\xf0\x80\x80\xf8\x00" +"\xf8\x80\x80\xf0\x80\x80\x80\x00\x70\x88\x80\xb8\x88\x88\x70\x00" +"\x88\x88\x88\xf8\x88\x88\x88\x00\x70\x20\x20\x20\x20\x20\x70\x00" +"\x38\x10\x10\x10\x90\x90\x60\x00\x88\x90\xa0\xc0\xa0\x90\x88\x00" +"\x80\x80\x80\x80\x80\x80\xf8\x00\x88\xd8\xa8\xa8\x88\x88\x88\x00" +"\x88\xc8\xc8\xa8\x98\x98\x88\x00\x70\x88\x88\x88\x88\x88\x70\x00" +"\xf0\x88\x88\xf0\x80\x80\x80\x00\x70\x88\x88\x88\xa8\x90\x68\x00" +"\xf0\x88\x88\xf0\xa0\x90\x88\x00\x70\x88\x80\x70\x08\x88\x70\x00" +"\xf8\x20\x20\x20\x20\x20\x20\x00\x88\x88\x88\x88\x88\x88\x70\x00" +"\x88\x88\x88\x88\x50\x50\x20\x00\x88\x88\x88\xa8\xa8\xd8\x88\x00" +"\x88\x88\x50\x20\x50\x88\x88\x00\x88\x88\x88\x70\x20\x20\x20\x00" +"\xf8\x08\x10\x20\x40\x80\xf8\x00\x70\x40\x40\x40\x40\x40\x70\x00" +"\x00\x00\x80\x40\x20\x10\x08\x00\x70\x10\x10\x10\x10\x10\x70\x00" +"\x20\x50\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00" +"\x40\x20\x10\x00\x00\x00\x00\x00\x00\x00\x70\x08\x78\x88\x78\x00" +"\x80\x80\xb0\xc8\x88\xc8\xb0\x00\x00\x00\x70\x88\x80\x88\x70\x00" +"\x08\x08\x68\x98\x88\x98\x68\x00\x00\x00\x70\x88\xf8\x80\x70\x00" +"\x10\x28\x20\xf8\x20\x20\x20\x00\x00\x00\x68\x98\x98\x68\x08\x70" +"\x80\x80\xf0\x88\x88\x88\x88\x00\x20\x00\x60\x20\x20\x20\x70\x00" +"\x10\x00\x30\x10\x10\x10\x90\x60\x40\x40\x48\x50\x60\x50\x48\x00" +"\x60\x20\x20\x20\x20\x20\x70\x00\x00\x00\xd0\xa8\xa8\xa8\xa8\x00" +"\x00\x00\xb0\xc8\x88\x88\x88\x00\x00\x00\x70\x88\x88\x88\x70\x00" +"\x00\x00\xb0\xc8\xc8\xb0\x80\x80\x00\x00\x68\x98\x98\x68\x08\x08" +"\x00\x00\xb0\xc8\x80\x80\x80\x00\x00\x00\x78\x80\xf0\x08\xf0\x00" +"\x40\x40\xf0\x40\x40\x48\x30\x00\x00\x00\x90\x90\x90\x90\x68\x00" +"\x00\x00\x88\x88\x88\x50\x20\x00\x00\x00\x88\xa8\xa8\xa8\x50\x00" +"\x00\x00\x88\x50\x20\x50\x88\x00\x00\x00\x88\x88\x98\x68\x08\x70" +"\x00\x00\xf8\x10\x20\x40\xf8\x00\x18\x20\x20\x40\x20\x20\x18\x00" +"\x20\x20\x20\x00\x20\x20\x20\x00\xc0\x20\x20\x10\x20\x20\xc0\x00" +"\x40\xa8\x10\x00\x00\x00\x00\x00\x00\x00\x20\x50\xf8\x00\x00\x00" +"\x70\x88\x80\x80\x88\x70\x20\x60\x90\x00\x00\x90\x90\x90\x68\x00" +"\x10\x20\x70\x88\xf8\x80\x70\x00\x20\x50\x70\x08\x78\x88\x78\x00" +"\x48\x00\x70\x08\x78\x88\x78\x00\x20\x10\x70\x08\x78\x88\x78\x00" +"\x20\x00\x70\x08\x78\x88\x78\x00\x00\x70\x80\x80\x80\x70\x10\x60" +"\x20\x50\x70\x88\xf8\x80\x70\x00\x50\x00\x70\x88\xf8\x80\x70\x00" +"\x20\x10\x70\x88\xf8\x80\x70\x00\x50\x00\x00\x60\x20\x20\x70\x00" +"\x20\x50\x00\x60\x20\x20\x70\x00\x40\x20\x00\x60\x20\x20\x70\x00" +"\x50\x00\x20\x50\x88\xf8\x88\x00\x20\x00\x20\x50\x88\xf8\x88\x00" +"\x10\x20\xf8\x80\xf0\x80\xf8\x00\x00\x00\x6c\x12\x7e\x90\x6e\x00" +"\x3e\x50\x90\x9c\xf0\x90\x9e\x00\x60\x90\x00\x60\x90\x90\x60\x00" +"\x90\x00\x00\x60\x90\x90\x60\x00\x40\x20\x00\x60\x90\x90\x60\x00" +"\x40\xa0\x00\xa0\xa0\xa0\x50\x00\x40\x20\x00\xa0\xa0\xa0\x50\x00" +"\x90\x00\x90\x90\xb0\x50\x10\xe0\x50\x00\x70\x88\x88\x88\x70\x00" +"\x50\x00\x88\x88\x88\x88\x70\x00\x20\x20\x78\x80\x80\x78\x20\x20" +"\x18\x24\x20\xf8\x20\xe2\x5c\x00\x88\x50\x20\xf8\x20\xf8\x20\x00" +"\xc0\xa0\xa0\xc8\x9c\x88\x88\x8c\x18\x20\x20\xf8\x20\x20\x20\x40" +"\x10\x20\x70\x08\x78\x88\x78\x00\x10\x20\x00\x60\x20\x20\x70\x00" +"\x20\x40\x00\x60\x90\x90\x60\x00\x20\x40\x00\x90\x90\x90\x68\x00" +"\x50\xa0\x00\xa0\xd0\x90\x90\x00\x28\x50\x00\xc8\xa8\x98\x88\x00" +"\x00\x70\x08\x78\x88\x78\x00\xf8\x00\x60\x90\x90\x90\x60\x00\xf0" +"\x20\x00\x20\x40\x80\x88\x70\x00\x00\x00\x00\xf8\x80\x80\x00\x00" +"\x00\x00\x00\xf8\x08\x08\x00\x00\x84\x88\x90\xa8\x54\x84\x08\x1c" +"\x84\x88\x90\xa8\x58\xa8\x3c\x08\x20\x00\x00\x20\x20\x20\x20\x00" +"\x00\x00\x24\x48\x90\x48\x24\x00\x00\x00\x90\x48\x24\x48\x90\x00" +"\x28\x50\x20\x50\x88\xf8\x88\x00\x28\x50\x70\x08\x78\x88\x78\x00" +"\x28\x50\x00\x70\x20\x20\x70\x00\x28\x50\x00\x20\x20\x20\x70\x00" +"\x28\x50\x00\x70\x88\x88\x70\x00\x50\xa0\x00\x60\x90\x90\x60\x00" +"\x28\x50\x00\x88\x88\x88\x70\x00\x50\xa0\x00\xa0\xa0\xa0\x50\x00" +"\xfc\x48\x48\x48\xe8\x08\x50\x20\x00\x50\x00\x50\x50\x50\x10\x20" +"\xc0\x44\xc8\x54\xec\x54\x9e\x04\x10\xa8\x40\x00\x00\x00\x00\x00" +"\x00\x20\x50\x88\x50\x20\x00\x00\x88\x10\x20\x40\x80\x28\x00\x00" +"\x7c\xa8\xa8\x68\x28\x28\x28\x00\x38\x40\x30\x48\x48\x30\x08\x70" +"\x00\x00\x00\x00\x00\x00\xff\xff\xf0\xf0\xf0\xf0\x0f\x0f\x0f\x0f" +"\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x3c\x3c\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00" +"\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x0f\x0f\x0f\x0f\xf0\xf0\xf0\xf0" +"\xfc\xfc\xfc\xfc\xfc\xfc\xfc\xfc\x03\x03\x03\x03\x03\x03\x03\x03" +"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x11\x22\x44\x88\x11\x22\x44\x88" +"\x88\x44\x22\x11\x88\x44\x22\x11\xfe\x7c\x38\x10\x00\x00\x00\x00" +"\x00\x00\x00\x00\x10\x38\x7c\xfe\x80\xc0\xe0\xf0\xe0\xc0\x80\x00" +"\x01\x03\x07\x0f\x07\x03\x01\x00\xff\x7e\x3c\x18\x18\x3c\x7e\xff" +"\x81\xc3\xe7\xff\xff\xe7\xc3\x81\xf0\xf0\xf0\xf0\x00\x00\x00\x00" +"\x00\x00\x00\x00\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x00\x00\x00\x00" +"\x00\x00\x00\x00\xf0\xf0\xf0\xf0\x33\x33\xcc\xcc\x33\x33\xcc\xcc" +"\x00\x20\x20\x50\x50\x88\xf8\x00\x20\x20\x70\x20\x70\x20\x20\x00" +"\x00\x00\x00\x50\x88\xa8\x50\x00\xff\xff\xff\xff\xff\xff\xff\xff" +"\x00\x00\x00\x00\xff\xff\xff\xff\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0" +"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\xff\xff\xff\xff\x00\x00\x00\x00" +"\x00\x00\x68\x90\x90\x90\x68\x00\x30\x48\x48\x70\x48\x48\x70\xc0" +"\xf8\x88\x80\x80\x80\x80\x80\x00\xf8\x50\x50\x50\x50\x50\x98\x00" +"\xf8\x88\x40\x20\x40\x88\xf8\x00\x00\x00\x78\x90\x90\x90\x60\x00" +"\x00\x50\x50\x50\x50\x68\x80\x80\x00\x50\xa0\x20\x20\x20\x20\x00" +"\xf8\x20\x70\xa8\xa8\x70\x20\xf8\x20\x50\x88\xf8\x88\x50\x20\x00" +"\x70\x88\x88\x88\x50\x50\xd8\x00\x30\x40\x40\x20\x50\x50\x50\x20" +"\x00\x00\x00\x50\xa8\xa8\x50\x00\x08\x70\xa8\xa8\xa8\x70\x80\x00" +"\x38\x40\x80\xf8\x80\x40\x38\x00\x70\x88\x88\x88\x88\x88\x88\x00" +"\x00\xf8\x00\xf8\x00\xf8\x00\x00\x20\x20\xf8\x20\x20\x00\xf8\x00" +"\xc0\x30\x08\x30\xc0\x00\xf8\x00\x18\x60\x80\x60\x18\x00\xf8\x00" +"\x10\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xa0\x40" +"\x00\x20\x00\xf8\x00\x20\x00\x00\x00\x50\xa0\x00\x50\xa0\x00\x00" +"\x00\x18\x24\x24\x18\x00\x00\x00\x00\x30\x78\x78\x30\x00\x00\x00" +"\x00\x00\x00\x00\x30\x00\x00\x00\x3e\x20\x20\x20\xa0\x60\x20\x00" +"\xa0\x50\x50\x50\x00\x00\x00\x00\x40\xa0\x20\x40\xe0\x00\x00\x00" +"\x00\x38\x38\x38\x38\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00", +width :8, height:8, first:0, last:255, size_w:8, size_h:8}; \ No newline at end of file diff --git a/src/debugScreen/debugScreen_custom.h b/src/debugScreen/debugScreen_custom.h new file mode 100644 index 0000000..0910028 --- /dev/null +++ b/src/debugScreen/debugScreen_custom.h @@ -0,0 +1,17 @@ +#ifndef DEBUG_SCREEN_CUSTOM_H +#define DEBUG_SCREEN_CUSTOM_H + +//#define SCREEN_TAB_SIZE (8) + +// backward compatibility for sources based on older Vita SDK versions +//#define DEBUG_SCREEN_CODE_INCLUDE // not recommended for your own projects, but for sake of backward compatibility +#define psvDebugScreenSetFgColor(rgb) psvDebugScreenPrintf("\e[38;2;%lu;%lu;%lum", ((uint32_t)(rgb)>>16)&0xFF, ((uint32_t)(rgb)>>8)&0xFF, (uint32_t)(rgb)&0xFF) +#define psvDebugScreenSetBgColor(rgb) psvDebugScreenPrintf("\e[48;2;%lu;%lu;%lum", ((uint32_t)(rgb)>>16)&0xFF, ((uint32_t)(rgb)>>8)&0xFF, (uint32_t)(rgb)&0xFF) +#define psvDebugScreenClear(rgb) psvDebugScreenSetBgColor(rgb); psvDebugScreenPuts("\e[H\e[2J") + +// custom changes for non-Vita builds +#ifndef __vita__ +#define psvDebugScreenInitReplacement(...) setvbuf(stdout,NULL,_IONBF,0) +#endif + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..7e3389a --- /dev/null +++ b/src/main.c @@ -0,0 +1,91 @@ +#include +//#include + +#include +#include +#include + +#include "debugScreen.h" + +#define countof(A) sizeof(A)/sizeof(*A) +//#define MIN(A,B) ((A)<(B)?(A):(B)) +//#define MAX(A,B) ((A)>(B)?(A):(B)) +#define MIN_VOL 0 + +#define printf psvDebugScreenPrintf + +/* double gen_sqr(double p){return p>.5?-1.:1.;} */ +/* double gen_tri(double p){return p*2;} */ +/* double gen_nul(double p){return 0.;} */ +/* double gen_sin(double p){return sin(2*M_PI*p);} */ + +/* typedef double (*wav_gen)(double); */ + +/* void wave_set(int16_t*buffer, size_t size, wav_gen generator){ */ +/* for (size_t smpl = 0; smpl < size; ++smpl) */ +/* buffer[smpl] = 0x7FFF*generator((float)smpl/(float)size); */ +/* } */ + +int main(void) { + psvDebugScreenInit(); + + int freqs[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}; + int size = 256; + int freq = 8; + int mode = SCE_AUDIO_OUT_MODE_STEREO; + int vol[] = {SCE_AUDIO_VOLUME_0DB, SCE_AUDIO_VOLUME_0DB}; + int test = SCE_AUDIO_VOLUME_0DB; + + int port = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, size, freqs[freq], mode); + //sceAudioOutSetVolume(port, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, (int[]){vol, vol}); + + //int16_t wave_buf[SCE_AUDIO_MAX_LEN]={0}; + //wav_gen gen=gen_nul; + SceCtrlData ctrl_peek, ctrl_press; + do{ + ctrl_press = ctrl_peek; + sceCtrlPeekBufferPositive(0, &ctrl_peek, 1); + ctrl_press.buttons = ctrl_peek.buttons & ~ctrl_press.buttons; + + /* if(ctrl_press.buttons == SCE_CTRL_CIRCLE) */ + /* gen=gen_sin; */ + /* if(ctrl_press.buttons == SCE_CTRL_SQUARE) */ + /* gen=gen_sqr; */ + /* if(ctrl_press.buttons == SCE_CTRL_TRIANGLE) */ + /* gen=gen_tri; */ + /* if(ctrl_press.buttons == SCE_CTRL_CROSS) */ + /* gen=gen_nul; */ + /* if(ctrl_press.buttons & (SCE_CTRL_CROSS|SCE_CTRL_TRIANGLE|SCE_CTRL_SQUARE|SCE_CTRL_CIRCLE)) */ + /* wave_set(wave_buf,size,gen); */ + + /* if(ctrl_press.buttons == SCE_CTRL_RIGHT) */ + /* freq = MIN(countof(freqs)-1, freq+1); */ + /* if(ctrl_press.buttons == SCE_CTRL_LEFT) */ + /* freq = MAX(0, freq-1); */ + /* if(ctrl_press.buttons == SCE_CTRL_RTRIGGER) */ + /* size = MIN(SCE_AUDIO_MAX_LEN,size+1000); */ + /* if(ctrl_press.buttons == SCE_CTRL_LTRIGGER) */ + /* size = MAX(SCE_AUDIO_MIN_LEN,size-1000); */ + /* if(ctrl_press.buttons & (SCE_CTRL_RIGHT|SCE_CTRL_LEFT|SCE_CTRL_LTRIGGER|SCE_CTRL_RTRIGGER)){ */ + /* sceAudioOutSetConfig(port, size, freqs[freq], mode); */ + /* wave_set(wave_buf,size,gen); */ + /* } */ + + if(ctrl_press.buttons == SCE_CTRL_UP) + vol[0] = SCE_AUDIO_OUT_MAX_VOL; + if(ctrl_press.buttons == SCE_CTRL_DOWN) + vol[0] = MIN_VOL; + if(ctrl_press.buttons == SCE_CTRL_LEFT) + vol[1] = SCE_AUDIO_OUT_MAX_VOL; + if(ctrl_press.buttons == SCE_CTRL_RIGHT) + vol[1] = MIN_VOL; + if(ctrl_press.buttons & (SCE_CTRL_CROSS | SCE_CTRL_CIRCLE)) { + sceAudioOutSetVolume(port, SCE_AUDIO_VOLUME_FLAG_L_CH |SCE_AUDIO_VOLUME_FLAG_R_CH, vol);//(int[]){vol,vol}); + } + //sceAudioOutOutput(port, wave_buf); + printf("L vol:%-5i - R vol:%-5i hane \r", vol[0], vol[1]); + }while(ctrl_press.buttons != SCE_CTRL_START); + + sceAudioOutReleasePort(port); + return 0; +}