mirror of
https://github.com/vanilla-wiiu/vanilla.git
synced 2026-10-28 09:43:51 +00:00
update display brightness - initial implementation
This commit is contained in:
1 parent
ff354e4176
commit
b21181c675
16 files changed
+315
-98
No files matched your search
@@ -297,6 +297,10 @@ list(APPEND VANILLA_GUI_SRC
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
list(APPEND VANILLA_GUI_SRC
|
||||
ui/ui_sdl_linux.c
|
||||
)
|
||||
|
||||
# Link with DRM if available
|
||||
option(VANILLA_BUILD_USE_DRM "Enable DRM video output" ON)
|
||||
if (VANILLA_BUILD_USE_DRM)
|
||||
|
||||
@@ -93,6 +93,9 @@ void vpi_config_save()
|
||||
sprintf(buf, "%i", vpi_config.force_software_decode);
|
||||
xmlTextWriterWriteElement(writer, BAD_CAST "swdec", BAD_CAST buf);
|
||||
|
||||
sprintf(buf, "%f", vpi_config.screen_brightness);
|
||||
xmlTextWriterWriteElement(writer, BAD_CAST "brightness", BAD_CAST buf);
|
||||
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "controls");
|
||||
if (vpi_config.keymap) {
|
||||
xmlTextWriterStartElement(writer, BAD_CAST "keys");
|
||||
@@ -184,6 +187,7 @@ void vpi_config_init()
|
||||
vpi_config_reset_default_controls_internal();
|
||||
vpi_config.cursor_in_fullscreen = 0;
|
||||
vpi_config.autoconnect = -1;
|
||||
vpi_config.screen_brightness = 1.0f;
|
||||
|
||||
// Load from file
|
||||
char config_fn[1024];
|
||||
@@ -250,6 +254,8 @@ void vpi_config_init()
|
||||
vpi_config.fullscreen = atoi((const char *) child->children->content);
|
||||
} else if (!strcmp((const char *) child->name, "swdec")) {
|
||||
vpi_config.force_software_decode = atoi((const char *) child->children->content);
|
||||
} else if (!strcmp((const char *) child->name, "brightness")) {
|
||||
vpi_config.screen_brightness = atof((const char *) child->children->content);
|
||||
} else if (!strcmp((const char *) child->name, "controls")) {
|
||||
xmlNodePtr section = child->children;
|
||||
while(section){
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef struct {
|
||||
int fast_drm;
|
||||
int force_software_decode;
|
||||
int autoconnect;
|
||||
float screen_brightness;
|
||||
} vpi_config_t;
|
||||
|
||||
extern vpi_config_t vpi_config;
|
||||
|
||||
@@ -97,6 +97,7 @@ int SDL_main(int argc, const char **argv)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
vui_brightness_set(vui, vpi_config.screen_brightness);
|
||||
vpi_menu_init(vui);
|
||||
|
||||
while (vui_update_sdl(vui)) {
|
||||
|
||||
@@ -1041,6 +1041,19 @@ void *vpi_event_loop(void *arg)
|
||||
case VANILLA_EVENT_MIC:
|
||||
vui_mic_enabled_set(vui, event.data[0]);
|
||||
break;
|
||||
case VANILLA_EVENT_BRIGHTNESS:
|
||||
{
|
||||
// Clamp to valid values from console
|
||||
uint8_t value = CLAMP(event.data[0], 1, 5);
|
||||
|
||||
// Normalize to 0.0 - 1.0
|
||||
float b = value / 5.0f;
|
||||
|
||||
vpi_config.screen_brightness = b;
|
||||
vpi_config_save();
|
||||
vui_brightness_set(vui, b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vanilla_free_event(&event);
|
||||
|
||||
@@ -1041,3 +1041,10 @@ void vui_mic_callback_set(vui_context_t *ctx, vui_mic_callback_t callback, void
|
||||
ctx->mic_callback = callback;
|
||||
ctx->mic_callback_data = userdata;
|
||||
}
|
||||
|
||||
void vui_brightness_set(vui_context_t *ctx, float brightness)
|
||||
{
|
||||
if (ctx->brightness_set_handler) {
|
||||
ctx->brightness_set_handler(ctx, brightness, ctx->brightness_set_handler_data);
|
||||
}
|
||||
}
|
||||
@@ -182,4 +182,9 @@ vui_power_state_t vui_power_state_get(vui_context_t *ctx, int *percent);
|
||||
void vui_mic_enabled_set(vui_context_t *ctx, int enabled);
|
||||
void vui_mic_callback_set(vui_context_t *ctx, vui_mic_callback_t callback, void *userdata);
|
||||
|
||||
/**
|
||||
* Miscellaneous functions
|
||||
*/
|
||||
void vui_brightness_set(vui_context_t *ctx, float brightness); // Expects brightness between 0.0f and 1.0f
|
||||
|
||||
#endif // VANILLA_PI_UI_H
|
||||
@@ -104,6 +104,7 @@ typedef int (*vui_font_height_handler_t)(vui_font_size_t size, void *userdata);
|
||||
typedef void (*vui_text_open_handler_t)(vui_context_t *ctx, int textedit, int open, void *userdata);
|
||||
typedef vui_power_state_t (*vui_power_state_handler_t)(vui_context_t *ctx, int *percent);
|
||||
typedef void (*vui_audio_enabled_handler_t)(vui_context_t *ctx, int enabled, void *userdata);
|
||||
typedef void (*vui_brightness_set_handler_t)(vui_context_t *ctx, float value, void *userdata);
|
||||
|
||||
typedef struct vui_context_t {
|
||||
void *platform_data;
|
||||
@@ -155,6 +156,8 @@ typedef struct vui_context_t {
|
||||
void *audio_enabled_handler_data;
|
||||
vui_bool_callback_t fullscreen_enabled_handler;
|
||||
void *fullscreen_enabled_handler_data;
|
||||
vui_brightness_set_handler_t brightness_set_handler;
|
||||
void *brightness_set_handler_data;
|
||||
|
||||
int default_button_map[VPI_CONFIG_BUTTONMAP_SIZE];
|
||||
int default_axis_map[VPI_CONFIG_AXISMAP_SIZE];
|
||||
|
||||
+121
-82
@@ -45,6 +45,12 @@
|
||||
#include "platform_nx_imu.h"
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID) || defined(__ANDROID__)
|
||||
// TODO
|
||||
#elif defined(__linux__)
|
||||
#include "ui_sdl_linux.h"
|
||||
#endif
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define PW_CHAR_SIZE 20
|
||||
#define PW_CHAR_PAD 2
|
||||
@@ -332,6 +338,24 @@ void vui_sdl_fullscreen_enabled_handler(vui_context_t *ctx, int enabled, void *u
|
||||
SDL_ShowCursor(vpi_config.cursor_in_fullscreen || !enabled);
|
||||
}
|
||||
|
||||
void vui_sdl_brightness_set_handler(vui_context_t *ctx, float brightness, void *userdata)
|
||||
{
|
||||
vpilog("SETTING BRIGHTNESS TO %.1f\n", brightness);
|
||||
|
||||
vui_sdl_context_t *sdl_ctx = (vui_sdl_context_t *) ctx->platform_data;
|
||||
|
||||
#if defined(ANDROID) || defined(__ANDROID__)
|
||||
// TODO
|
||||
#elif defined(__linux__)
|
||||
if (vui_sdl_linux_set_brightness(brightness) == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fallback
|
||||
SDL_SetWindowBrightness(sdl_ctx->window, brightness);
|
||||
}
|
||||
|
||||
void vui_sdl_get_key_mapping_handler(vui_context_t *ctx, int vanilla_btn, void *userdata)
|
||||
{
|
||||
|
||||
@@ -841,6 +865,8 @@ int vui_init_sdl(vui_context_t *ctx, int fullscreen)
|
||||
|
||||
ctx->fullscreen_enabled_handler = vui_sdl_fullscreen_enabled_handler;
|
||||
|
||||
ctx->brightness_set_handler = vui_sdl_brightness_set_handler;
|
||||
|
||||
if (TTF_Init()) {
|
||||
vpilog("Failed to TTF_Init\n");
|
||||
return -1;
|
||||
@@ -1894,30 +1920,6 @@ int vui_update_sdl(vui_context_t *vui)
|
||||
}
|
||||
#endif // VANILLA_CUDA_AVAILABLE
|
||||
|
||||
// Draw vui to a custom texture
|
||||
vui_draw_sdl(vui, renderer);
|
||||
|
||||
// Flatten layers
|
||||
int el[MAX_BUTTON_COUNT];
|
||||
int el_count = 0;
|
||||
for (int i = 0; i < vui->layers; i++) {
|
||||
if (vui->layer_enabled[i]) {
|
||||
el[el_count] = i;
|
||||
el_count++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = el_count - 1; i > 0; i--) {
|
||||
SDL_Texture *bg = sdl_ctx->layer_data[el[i-1]];
|
||||
SDL_Texture *fg = sdl_ctx->layer_data[el[i]];
|
||||
|
||||
SDL_SetRenderTarget(renderer, bg);
|
||||
SDL_SetTextureColorMod(fg, vui->layer_opacity[i] * 0xFF, vui->layer_opacity[i] * 0xFF, vui->layer_opacity[i] * 0xFF);
|
||||
SDL_SetTextureAlphaMod(fg, vui->layer_opacity[i] * 0xFF);
|
||||
SDL_RenderCopy(renderer, fg, NULL, NULL);
|
||||
}
|
||||
|
||||
main_tex = sdl_ctx->layer_data[0];
|
||||
} else {
|
||||
pthread_mutex_lock(&vpi_present_frame_mutex);
|
||||
if (vpi_present_frame
|
||||
@@ -2013,78 +2015,115 @@ int vui_update_sdl(vui_context_t *vui)
|
||||
}
|
||||
|
||||
if (handle_final_blit) {
|
||||
// Draw toast on screen if necessary
|
||||
const int TOAST_PADDING = 12;
|
||||
int cur_toast;
|
||||
vpi_get_toast(&cur_toast, 0, 0, 0);
|
||||
if (cur_toast != sdl_ctx->last_shown_toast) {
|
||||
// Get toast information
|
||||
char toast_str[VPI_TOAST_MAX_LEN];
|
||||
vpi_get_toast(&cur_toast, toast_str, sizeof(toast_str), &sdl_ctx->toast_expiry);
|
||||
// Draw vui to a custom texture
|
||||
if (!vui->game_mode) {
|
||||
vui_draw_sdl(vui, renderer);
|
||||
|
||||
sdl_ctx->last_shown_toast = cur_toast;
|
||||
// Flatten layers
|
||||
{
|
||||
int el[MAX_BUTTON_COUNT];
|
||||
int el_count = 0;
|
||||
for (int i = 0; i < vui->layers; i++) {
|
||||
if (vui->layer_enabled[i]) {
|
||||
el[el_count] = i;
|
||||
el_count++;
|
||||
}
|
||||
}
|
||||
|
||||
const int toast_w = vui->screen_width/2;
|
||||
for (int i = el_count - 1; i > 0; i--) {
|
||||
SDL_Texture *bg = sdl_ctx->layer_data[el[i-1]];
|
||||
SDL_Texture *fg = sdl_ctx->layer_data[el[i]];
|
||||
|
||||
SDL_Color c;
|
||||
c.r = c.g = c.b = 0x40;
|
||||
c.a = 0xFF;
|
||||
SDL_SetRenderTarget(renderer, bg);
|
||||
SDL_SetTextureColorMod(fg, vui->layer_opacity[i] * 0xFF, vui->layer_opacity[i] * 0xFF, vui->layer_opacity[i] * 0xFF);
|
||||
SDL_SetTextureAlphaMod(fg, vui->layer_opacity[i] * 0xFF);
|
||||
SDL_RenderCopy(renderer, fg, NULL, NULL);
|
||||
}
|
||||
|
||||
SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped(sdl_ctx->sysfont_small, toast_str, c, toast_w - TOAST_PADDING - TOAST_PADDING);
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
|
||||
const int toast_h = surface->h + TOAST_PADDING + TOAST_PADDING;
|
||||
sdl_ctx->toast_tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, toast_w, toast_h);
|
||||
SDL_SetTextureBlendMode(sdl_ctx->toast_tex, SDL_BLENDMODE_BLEND);
|
||||
|
||||
SDL_SetRenderTarget(renderer, sdl_ctx->toast_tex);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xF0);
|
||||
const int TOAST_BORDER_RADIUS = TOAST_PADDING;
|
||||
for (int y = 0; y < toast_h; y++) {
|
||||
const int x_inset = calculate_x_inset(y, toast_h, TOAST_BORDER_RADIUS);
|
||||
SDL_RenderDrawLine(renderer, x_inset, y, toast_w - x_inset, y);
|
||||
if (vui->game_mode) {
|
||||
// TODO: Composite onto game texture
|
||||
// SDL_SetRenderTarget(renderer, main_tex);
|
||||
// SDL_RenderCopy(renderer, sdl_ctx->layer_data[0], NULL, NULL);
|
||||
} else {
|
||||
// Just return our texture
|
||||
main_tex = sdl_ctx->layer_data[0];
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Rect dst_rect;
|
||||
dst_rect.x = dst_rect.y = TOAST_PADDING;
|
||||
dst_rect.w = surface->w;
|
||||
dst_rect.h = surface->h;
|
||||
SDL_RenderCopy(renderer, texture, 0, &dst_rect);
|
||||
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
if (sdl_ctx->toast_tex) {
|
||||
// Draw toast to screen
|
||||
SDL_SetRenderTarget(renderer, main_tex);
|
||||
|
||||
// Get texture size
|
||||
int toast_w, toast_h;
|
||||
SDL_QueryTexture(sdl_ctx->toast_tex, 0, 0, &toast_w, &toast_h);
|
||||
// Draw toast on screen if necessary
|
||||
{
|
||||
const int TOAST_PADDING = 12;
|
||||
int cur_toast;
|
||||
vpi_get_toast(&cur_toast, 0, 0, 0);
|
||||
if (cur_toast != sdl_ctx->last_shown_toast) {
|
||||
// Get toast information
|
||||
char toast_str[VPI_TOAST_MAX_LEN];
|
||||
vpi_get_toast(&cur_toast, toast_str, sizeof(toast_str), &sdl_ctx->toast_expiry);
|
||||
|
||||
// Calculate dst rect
|
||||
SDL_Rect dst_rect;
|
||||
dst_rect.w = toast_w;
|
||||
dst_rect.h = toast_h;
|
||||
dst_rect.y = vui->screen_height - dst_rect.h - TOAST_PADDING - TOAST_PADDING;
|
||||
dst_rect.x = vui->screen_width/2 - toast_w/2;
|
||||
sdl_ctx->last_shown_toast = cur_toast;
|
||||
|
||||
SDL_RenderCopy(renderer, sdl_ctx->toast_tex, 0, &dst_rect);
|
||||
const int toast_w = vui->screen_width/2;
|
||||
|
||||
// Handle expiry
|
||||
struct timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
if (now.tv_sec*1000000+now.tv_usec >= sdl_ctx->toast_expiry.tv_sec*1000000+sdl_ctx->toast_expiry.tv_usec) {
|
||||
SDL_DestroyTexture(sdl_ctx->toast_tex);
|
||||
sdl_ctx->toast_tex = 0;
|
||||
SDL_Color c;
|
||||
c.r = c.g = c.b = 0x40;
|
||||
c.a = 0xFF;
|
||||
|
||||
SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped(sdl_ctx->sysfont_small, toast_str, c, toast_w - TOAST_PADDING - TOAST_PADDING);
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
|
||||
const int toast_h = surface->h + TOAST_PADDING + TOAST_PADDING;
|
||||
sdl_ctx->toast_tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, toast_w, toast_h);
|
||||
SDL_SetTextureBlendMode(sdl_ctx->toast_tex, SDL_BLENDMODE_BLEND);
|
||||
|
||||
SDL_SetRenderTarget(renderer, sdl_ctx->toast_tex);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xF0);
|
||||
const int TOAST_BORDER_RADIUS = TOAST_PADDING;
|
||||
for (int y = 0; y < toast_h; y++) {
|
||||
const int x_inset = calculate_x_inset(y, toast_h, TOAST_BORDER_RADIUS);
|
||||
SDL_RenderDrawLine(renderer, x_inset, y, toast_w - x_inset, y);
|
||||
}
|
||||
|
||||
SDL_Rect dst_rect;
|
||||
dst_rect.x = dst_rect.y = TOAST_PADDING;
|
||||
dst_rect.w = surface->w;
|
||||
dst_rect.h = surface->h;
|
||||
SDL_RenderCopy(renderer, texture, 0, &dst_rect);
|
||||
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
if (sdl_ctx->toast_tex) {
|
||||
// Draw toast to screen
|
||||
SDL_SetRenderTarget(renderer, main_tex);
|
||||
|
||||
// Get texture size
|
||||
int toast_w, toast_h;
|
||||
SDL_QueryTexture(sdl_ctx->toast_tex, 0, 0, &toast_w, &toast_h);
|
||||
|
||||
// Calculate dst rect
|
||||
SDL_Rect dst_rect;
|
||||
dst_rect.w = toast_w;
|
||||
dst_rect.h = toast_h;
|
||||
dst_rect.y = vui->screen_height - dst_rect.h - TOAST_PADDING - TOAST_PADDING;
|
||||
dst_rect.x = vui->screen_width/2 - toast_w/2;
|
||||
|
||||
SDL_RenderCopy(renderer, sdl_ctx->toast_tex, 0, &dst_rect);
|
||||
|
||||
// Handle expiry
|
||||
struct timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
if (now.tv_sec*1000000+now.tv_usec >= sdl_ctx->toast_expiry.tv_sec*1000000+sdl_ctx->toast_expiry.tv_usec) {
|
||||
SDL_DestroyTexture(sdl_ctx->toast_tex);
|
||||
sdl_ctx->toast_tex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate our destination rectangle
|
||||
|
||||
SDL_SetRenderTarget(renderer, NULL);
|
||||
|
||||
int out_w, out_h;
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "ui_sdl_linux.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ui_util.h"
|
||||
|
||||
#define VUI_LINUX_BACKLIGHT_ROOT "/sys/class/backlight"
|
||||
#define VUI_LINUX_BACKLIGHT_DEFAULT "backlight"
|
||||
#define VUI_LINUX_BACKLIGHT_PATH_SIZE 4096
|
||||
|
||||
static int vui_sdl_linux_set_backlight_device(const char *device, float brightness)
|
||||
{
|
||||
char path[VUI_LINUX_BACKLIGHT_PATH_SIZE];
|
||||
unsigned int max_brightness;
|
||||
unsigned int value;
|
||||
int path_length;
|
||||
int write_failed;
|
||||
int close_failed;
|
||||
FILE *file;
|
||||
|
||||
if (!isfinite(brightness)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
brightness = CLAMP(brightness, 0.0f, 1.0f);
|
||||
|
||||
// Attempt to read max_brightness information
|
||||
path_length = snprintf(path, sizeof(path), "%s/%s/max_brightness", VUI_LINUX_BACKLIGHT_ROOT, device);
|
||||
if (path_length < 0 || path_length >= (int) sizeof(path)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
file = fopen(path, "r");
|
||||
if (!file) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fscanf(file, "%u", &max_brightness) != 1 || !max_brightness) {
|
||||
fclose(file);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
// Now that we have max_brightness, attempt to set actual brightness to a percentage of max brightness
|
||||
value = lroundf(brightness * max_brightness);
|
||||
|
||||
path_length = snprintf(path, sizeof(path), "%s/%s/brightness", VUI_LINUX_BACKLIGHT_ROOT, device);
|
||||
if (path_length < 0 || path_length >= (int) sizeof(path)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
file = fopen(path, "w");
|
||||
if (!file) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_failed = fprintf(file, "%u\n", value) < 0;
|
||||
close_failed = fclose(file) != 0;
|
||||
if (write_failed || close_failed) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vui_sdl_linux_set_brightness(float brightness)
|
||||
{
|
||||
DIR *directory;
|
||||
struct dirent *entry;
|
||||
|
||||
// See if "backlight" device exists (should exist on Nintendo Switch)
|
||||
if (access(VUI_LINUX_BACKLIGHT_ROOT "/" VUI_LINUX_BACKLIGHT_DEFAULT, F_OK) == 0) {
|
||||
return vui_sdl_linux_set_backlight_device(VUI_LINUX_BACKLIGHT_DEFAULT, brightness);
|
||||
}
|
||||
|
||||
// Otherwise, iterate over directory to find next best device to set brightness on
|
||||
directory = opendir(VUI_LINUX_BACKLIGHT_ROOT);
|
||||
if (!directory) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((entry = readdir(directory))) {
|
||||
if (entry->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vui_sdl_linux_set_backlight_device(entry->d_name, brightness) == 0) {
|
||||
closedir(directory);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(directory);
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef VANILLA_PI_UI_SDL_LINUX_H
|
||||
#define VANILLA_PI_UI_SDL_LINUX_H
|
||||
|
||||
int vui_sdl_linux_set_brightness(float brightness);
|
||||
|
||||
#endif // VANILLA_PI_UI_SDL_LINUX_H
|
||||
@@ -9,6 +9,8 @@ void vui_strncpy(char *dst, const char *src, size_t max_dst_size);
|
||||
size_t vui_utf8_cp_len(const char *s);
|
||||
char *vui_utf8_advance(char *s);
|
||||
|
||||
#define CLAMP(x, low, high) (((x) < (low)) ? (low) : ((x) > (high)) ? (high) : (x))
|
||||
|
||||
static inline int intmin(int a, int b) { return a < b ? a : b; }
|
||||
static inline int intmax(int a, int b) { return a > b ? a : b; }
|
||||
static inline int64_t int64min(int64_t a, int64_t b) { return a < b ? a : b; }
|
||||
|
||||
+31
-5
@@ -60,7 +60,7 @@ void send_generic_response(int skt, CmdHeader *response)
|
||||
void handle_generic_packet(gamepad_context_t *info, int skt, GenericPacket *request)
|
||||
{
|
||||
GenericCmdHeader *gen_cmd = &request->generic_cmd_header;
|
||||
vanilla_log("magic: %x, flags: %x, service ID: %u, method ID: %u", gen_cmd->magic_0x7E, gen_cmd->flags, gen_cmd->service_id, gen_cmd->method_id);
|
||||
// vanilla_log("magic: %x, flags: %x, service ID: %u, method ID: %u", gen_cmd->magic_0x7E, gen_cmd->flags, gen_cmd->service_id, gen_cmd->method_id);
|
||||
|
||||
// Prepare response
|
||||
GenericPacket response;
|
||||
@@ -170,13 +170,39 @@ void handle_generic_packet(gamepad_context_t *info, int skt, GenericPacket *requ
|
||||
}
|
||||
case METHOD_ID_PERIPHERAL_UPDATE_EEPROM:
|
||||
{
|
||||
vanilla_log("5,12 - index: %u, length: %u", response.payload[0], response.payload[1]);
|
||||
response.generic_cmd_header.error_code = 0;
|
||||
uint8_t index = request->payload[0];
|
||||
uint8_t length = request->payload[1];
|
||||
|
||||
vanilla_log("5,12 - index: %u, length: %u", index, length);
|
||||
|
||||
uint16_t our_crc = crc16(request->payload + 2, length - 2);
|
||||
uint16_t their_crc = le16toh(*(uint16_t *)(request->payload + 2 + length - 2));
|
||||
|
||||
if (our_crc != their_crc) {
|
||||
// TODO: Report some kind of error to the console?
|
||||
} else {
|
||||
// Update our EEPROM
|
||||
switch (index) {
|
||||
case 0x10:
|
||||
{
|
||||
// Console wants to change our brightness
|
||||
// vanilla_log("Change brightness to %x", request->payload[2]);
|
||||
uint8_t b = request->payload[2];
|
||||
push_event(info->event_loop, VANILLA_EVENT_BRIGHTNESS, &b, sizeof(b));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
vanilla_log("Console attempted write to unknown EEPROM offset: 0x%x", index);
|
||||
}
|
||||
|
||||
// Report success
|
||||
response.generic_cmd_header.error_code = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case METHOD_ID_PERIPHERAL_SET_REMOCON:
|
||||
{
|
||||
vanilla_log("5,24 - str1: %s, str2: %s", response.payload, response.payload + 5);
|
||||
vanilla_log("5,24 - str1: %s, str2: %s", request->payload, request->payload + 5);
|
||||
response.generic_cmd_header.error_code = 0;
|
||||
break;
|
||||
}
|
||||
@@ -227,7 +253,7 @@ void handle_time_packet(int skt, TimePacket *request)
|
||||
|
||||
void handle_command_packet(gamepad_context_t *info, int skt, CmdHeader *request)
|
||||
{
|
||||
vanilla_log("packet_type: %u, query_type: %u, payload_size: 0x%X", request->packet_type, request->query_type, request->payload_size);
|
||||
// vanilla_log("packet_type: %u, query_type: %u, payload_size: 0x%X", request->packet_type, request->query_type, request->payload_size);
|
||||
switch (request->packet_type)
|
||||
{
|
||||
case PACKET_TYPE_REQUEST:
|
||||
|
||||
@@ -20,15 +20,6 @@
|
||||
#include "vanilla.h"
|
||||
#include "util.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows has no htobe32, and is always virtually little-endiam
|
||||
#define htobe32(x) htonl(x)
|
||||
#elif defined(__APPLE__)
|
||||
// macOS has no htobe32
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define htobe32(x) OSSwapHostToBigInt32(x)
|
||||
#endif // __APPLE__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned magic : 4;
|
||||
|
||||
+10
-1
@@ -10,6 +10,15 @@
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#define CLAMP(x, min, max) (MIN(MAX(x, min), max))
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows has no htobe32, and is always virtually little-endiam
|
||||
#define htobe32(x) htonl(x)
|
||||
#elif defined(__APPLE__)
|
||||
// macOS has no htobe32
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define htobe32(x) OSSwapHostToBigInt32(x)
|
||||
#endif // __APPLE__
|
||||
|
||||
size_t read_line_from_fd(int fd, char *output, size_t max_output_size);
|
||||
size_t read_line_from_file(FILE *file, char *output, size_t max_output_size);
|
||||
size_t get_max_path_length();
|
||||
@@ -26,4 +35,4 @@ uint16_t crc16(const void* data, size_t len);
|
||||
|
||||
void print_hex(const void *data, size_t len);
|
||||
|
||||
#endif // VANILLA_UTIL_H
|
||||
#endif // VANILLA_UTIL_H
|
||||
+2
-1
@@ -74,7 +74,8 @@ enum VanillaEvent
|
||||
VANILLA_EVENT_VIBRATE,
|
||||
VANILLA_EVENT_SYNC,
|
||||
VANILLA_EVENT_ERROR,
|
||||
VANILLA_EVENT_MIC
|
||||
VANILLA_EVENT_MIC,
|
||||
VANILLA_EVENT_BRIGHTNESS
|
||||
};
|
||||
|
||||
enum VanillaRegion
|
||||
|
||||
Reference in new issue
Block a user