mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-04-11 16:37:45 -04:00
- Move all devkitpro includes before the Rockbox ones so that the macros which are both conflicting and unused can be undef'd - Remove unused result variables - Exclude an unused function from being compiled for this target - Fix hex number formatting - Fix the return value of dummy functions - Fix macro redefinition in the plugins keypad config - Remove duplicate button mapping - Turn off -Wchar-subscripts as it's already handled in Rockbox's ctype.h Change-Id: I3f5a3d492c585f233277a380feaea5fe877a044f
250 lines
6.6 KiB
C
250 lines
6.6 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2006 Dan Everton
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <3ds/gfx.h>
|
|
#ifdef RGB565
|
|
#undef RGB565
|
|
#endif
|
|
|
|
#include <3ds/allocator/linear.h>
|
|
#include <3ds/console.h>
|
|
#include <3ds/services/cfgu.h>
|
|
|
|
#include "debug.h"
|
|
#include "system.h"
|
|
#include "button-ctru.h"
|
|
#include "screendump.h"
|
|
#include "lcd-target.h"
|
|
|
|
/*#define LOGF_ENABLE*/
|
|
#include "logf.h"
|
|
|
|
fb_data *dev_fb = 0;
|
|
|
|
static u8 system_model = CFG_MODEL_3DS;
|
|
|
|
typedef struct
|
|
{
|
|
int width, height;
|
|
} dimensions_t;
|
|
|
|
int get_dest_offset(int x, int y, int dest_width)
|
|
{
|
|
return dest_width - y - 1 + dest_width * x;
|
|
}
|
|
|
|
int get_source_offset(int x, int y, int source_width)
|
|
{
|
|
return x + y * source_width;
|
|
}
|
|
|
|
void copy_framebuffer_16(u16 *dest, const dimensions_t dest_dim, const u16 *source, const dimensions_t source_dim)
|
|
{
|
|
int rows = MIN(dest_dim.width, source_dim.height);
|
|
int cols = MIN(dest_dim.height, source_dim.width);
|
|
for (int y = 0; y < rows; ++y) {
|
|
for (int x = 0; x < cols; ++x) {
|
|
const u16 *s = source + get_source_offset(x, y, source_dim.width);
|
|
u16 *d = dest + get_dest_offset(x, y, dest_dim.width);
|
|
*d = *s;
|
|
}
|
|
}
|
|
}
|
|
|
|
void copy_framebuffer_24(u8 *dest, const dimensions_t dest_dim, const u8 *source, const dimensions_t source_dim)
|
|
{
|
|
int rows = MIN(dest_dim.width, source_dim.height);
|
|
int cols = MIN(dest_dim.height, source_dim.width);
|
|
for (int y = 0; y < rows; ++y) {
|
|
for (int x = 0; x < cols; ++x) {
|
|
const u8 *s = source + get_source_offset(x, y, source_dim.width) * 3;
|
|
u8 *d = dest + get_dest_offset(x, y, dest_dim.width) * 3;
|
|
d[0] = s[0];
|
|
d[1] = s[1];
|
|
d[2] = s[2];
|
|
}
|
|
}
|
|
}
|
|
|
|
void copy_framebuffer_32(u32 *dest, const dimensions_t dest_dim, const u32 *source, const dimensions_t source_dim)
|
|
{
|
|
int rows = MIN(dest_dim.width, source_dim.height);
|
|
int cols = MIN(dest_dim.height, source_dim.width);
|
|
for (int y = 0; y < rows; ++y) {
|
|
for (int x = 0; x < cols; ++x) {
|
|
const u32 *s = source + get_source_offset(x, y, source_dim.width);
|
|
u32 *d = dest + get_dest_offset(x, y, dest_dim.width);
|
|
*d = *s;
|
|
}
|
|
}
|
|
}
|
|
|
|
void update_framebuffer(void)
|
|
{
|
|
u16 fb_width, fb_height;
|
|
u32 bufsize;
|
|
u8* fb = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &fb_width, &fb_height);
|
|
bufsize = fb_width * fb_height * 2;
|
|
|
|
/* lock_window_mutex() */
|
|
|
|
if (FB_DATA_SZ == 2) {
|
|
copy_framebuffer_16((void *)fb, (dimensions_t){ fb_width, fb_height },
|
|
(u16 *)dev_fb, (dimensions_t){ LCD_WIDTH, LCD_HEIGHT });
|
|
}
|
|
else if (FB_DATA_SZ == 3) {
|
|
copy_framebuffer_24((void *)fb, (dimensions_t){ fb_width, fb_height },
|
|
(u8 *)dev_fb, (dimensions_t){ LCD_WIDTH, LCD_HEIGHT });
|
|
}
|
|
else {
|
|
copy_framebuffer_32((void *)fb, (dimensions_t){ fb_width, fb_height },
|
|
(u32 *)dev_fb, (dimensions_t){ LCD_WIDTH, LCD_HEIGHT });
|
|
}
|
|
|
|
// Flush and swap framebuffers
|
|
/* gfxFlushBuffers(); */
|
|
GSPGPU_FlushDataCache(fb, bufsize);
|
|
gfxSwapBuffers();
|
|
gspWaitForVBlank();
|
|
|
|
/* unlock_window_mutex() */
|
|
}
|
|
|
|
/* lcd-as-memframe.c */
|
|
extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src,
|
|
int width, int height);
|
|
|
|
void lcd_update_rect(int x, int y, int width, int height)
|
|
{
|
|
fb_data *dst, *src;
|
|
|
|
if (x + width > LCD_WIDTH)
|
|
width = LCD_WIDTH - x; /* Clip right */
|
|
if (x < 0)
|
|
width += x, x = 0; /* Clip left */
|
|
if (width <= 0)
|
|
return; /* nothing left to do */
|
|
|
|
if (y + height > LCD_HEIGHT)
|
|
height = LCD_HEIGHT - y; /* Clip bottom */
|
|
if (y < 0)
|
|
height += y, y = 0; /* Clip top */
|
|
if (height <= 0)
|
|
return; /* nothing left to do */
|
|
|
|
dst = LCD_FRAMEBUF_ADDR(x, y);
|
|
src = FBADDR(x,y);
|
|
|
|
/* Copy part of the Rockbox framebuffer to the second framebuffer */
|
|
if (width < LCD_WIDTH)
|
|
{
|
|
/* Not full width - do line-by-line */
|
|
lcd_copy_buffer_rect(dst, src, width, height);
|
|
}
|
|
else
|
|
{
|
|
/* Full width - copy as one line */
|
|
lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
|
|
}
|
|
|
|
update_framebuffer();
|
|
}
|
|
|
|
void lcd_update(void)
|
|
{
|
|
/* update a full screen rect */
|
|
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
|
}
|
|
|
|
void sys_console_init(void)
|
|
{
|
|
gfxInit(GSP_BGR8_OES, GSP_RGB565_OES, false);
|
|
consoleInit(GFX_TOP, NULL);
|
|
}
|
|
|
|
void lcd_init_device(void)
|
|
{
|
|
gfxSetDoubleBuffering(GFX_BOTTOM, true);
|
|
|
|
/* hidInit(); */
|
|
|
|
u16 fb_width, fb_height;
|
|
gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &fb_width, &fb_height);
|
|
u32 bufsize = fb_width * fb_height * 2;
|
|
|
|
dev_fb = (fb_data *) linearAlloc(bufsize);
|
|
if (dev_fb == NULL) {
|
|
logf("could not allocate dev_fb size %d bytes\n",
|
|
bufsize);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
memset(dev_fb, 0x00, bufsize);
|
|
|
|
/* Set dpi value from system model */
|
|
CFGU_GetSystemModel(&system_model);
|
|
}
|
|
|
|
void lcd_shutdown(void)
|
|
{
|
|
if (dev_fb) {
|
|
linearFree(dev_fb);
|
|
dev_fb = 0;
|
|
}
|
|
|
|
/* hidExit(); */
|
|
gfxExit();
|
|
}
|
|
|
|
int lcd_get_dpi(void)
|
|
{
|
|
/* link: https://www.reddit.com/r/nintendo/comments/2uzk5y/informative_post_about_dpi_on_the_new_3ds/ */
|
|
/* all values for bottom lcd */
|
|
float dpi = 96.0f;
|
|
switch(system_model) {
|
|
case CFG_MODEL_3DS:
|
|
dpi = 132.45f;
|
|
break;
|
|
case CFG_MODEL_3DSXL:
|
|
dpi = 95.69f;
|
|
break;
|
|
case CFG_MODEL_N3DS:
|
|
dpi = 120.1f;
|
|
break;
|
|
case CFG_MODEL_2DS:
|
|
dpi = 132.45f;
|
|
break;
|
|
case CFG_MODEL_N3DSXL:
|
|
dpi = 95.69f;
|
|
break;
|
|
case CFG_MODEL_N2DSXL:
|
|
dpi = 95.69f;
|
|
break;
|
|
default:
|
|
break;
|
|
};
|
|
return (int) roundf(dpi);
|
|
}
|
|
|