Do something sightly more interesting with covers
The coverpages need more information still
This commit is contained in:
parent
a0ed3252c2
commit
97ceb2e3d0
6 changed files with 181 additions and 39 deletions
14
include/interface/cover.hpp
Normal file
14
include/interface/cover.hpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef _interface_cover__hpp__included__
|
||||
#define _interface_cover__hpp__included__
|
||||
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
|
||||
void cover_render_character(void* fb, unsigned x, unsigned y, uint32_t ch, uint32_t fg, uint32_t bg, size_t w,
|
||||
size_t h, size_t istride, size_t pstride);
|
||||
void cover_render_string(void* fb, unsigned x, unsigned y, const std::string& str, uint32_t fg, uint32_t bg,
|
||||
size_t w, size_t h, size_t istride, size_t pstride);
|
||||
void cover_next_position(uint32_t ch, unsigned& x, unsigned& y);
|
||||
void cover_next_position(const std::string& ch, unsigned& x, unsigned& y);
|
||||
|
||||
#endif
|
|
@ -14,6 +14,7 @@
|
|||
#include "core/framebuffer.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "interface/cover.hpp"
|
||||
#include "interface/romtype.hpp"
|
||||
#include "interface/setting.hpp"
|
||||
#include "interface/callbacks.hpp"
|
||||
|
@ -951,6 +952,23 @@ namespace
|
|||
return r;
|
||||
}
|
||||
|
||||
void redraw_cover_fbinfo()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
|
||||
cover_fbmem[i] = 0;
|
||||
std::string ident = _bsnes_core.core_identifier();
|
||||
cover_render_string(cover_fbmem, 0, 0, ident, 0x7FFFF, 0x00000, 512, 448, 2048, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
void cover_render_character(void* fb, unsigned x, unsigned y, uint32_t ch, uint32_t fg, uint32_t bg, size_t w,
|
||||
size_t h, size_t istride, size_t pstride);
|
||||
void cover_render_string(void* fb, unsigned x, unsigned y, const std::string& str, uint32_t fg, uint32_t bg,
|
||||
size_t w, size_t h, size_t istride, size_t pstride);
|
||||
void cover_next_position(uint32_t ch, unsigned& x, unsigned& y);
|
||||
void cover_next_position(const std::string& ch, unsigned& x, unsigned& y);
|
||||
*/
|
||||
|
||||
core_core_params _bsnes_core = {
|
||||
//Identify core.
|
||||
[]() -> std::string {
|
||||
|
@ -1174,6 +1192,7 @@ again2:
|
|||
//Cover page.
|
||||
[]() -> framebuffer_raw& {
|
||||
static framebuffer_raw x(cover_fbinfo);
|
||||
redraw_cover_fbinfo();
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
@ -1489,16 +1508,6 @@ again2:
|
|||
void snesdbg_on_break() {}
|
||||
void snesdbg_on_trace() {}
|
||||
#endif
|
||||
|
||||
//Init the fbmem.
|
||||
struct fbmem_initializer
|
||||
{
|
||||
fbmem_initializer()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(cover_fbmem)/sizeof(cover_fbmem[0]); i++)
|
||||
cover_fbmem[i] = 0x7FC00;
|
||||
}
|
||||
} fbmem_initializer;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "core/framebuffer.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "interface/callbacks.hpp"
|
||||
#include "interface/cover.hpp"
|
||||
#include "interface/romtype.hpp"
|
||||
#include "library/pixfmt-rgb32.hpp"
|
||||
#include "library/string.hpp"
|
||||
|
@ -41,6 +42,7 @@ namespace
|
|||
extern core_type type_dmg;
|
||||
extern core_type type_gbc;
|
||||
extern core_type type_gbc_gba;
|
||||
extern core_core_params _gambatte_core;
|
||||
bool rtc_fixed;
|
||||
time_t rtc_fixed_val;
|
||||
gambatte::GB* instance;
|
||||
|
@ -326,6 +328,14 @@ namespace
|
|||
return s;
|
||||
}
|
||||
|
||||
void redraw_cover_fbinfo()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
|
||||
cover_fbmem[i] = 0x00000000;
|
||||
std::string ident = _gambatte_core.core_identifier();
|
||||
cover_render_string(cover_fbmem, 0, 0, ident, 0xFFFFFF, 0x00000, 480, 432, 1920, 4);
|
||||
}
|
||||
|
||||
unsigned world_compatible[] = {0, UINT_MAX};
|
||||
core_region_params _region_world = {
|
||||
"world", "World", 1, 0, false, {35112, 2097152, 16742706, 626688}, world_compatible
|
||||
|
@ -503,6 +513,7 @@ namespace
|
|||
//Cover page.
|
||||
[]() -> framebuffer_raw& {
|
||||
static framebuffer_raw x(cover_fbinfo);
|
||||
redraw_cover_fbinfo();
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
@ -560,16 +571,6 @@ namespace
|
|||
return;
|
||||
instance->saveState(x, cmp_save);
|
||||
});
|
||||
|
||||
//Init the fbmem.
|
||||
struct fbmem_initializer
|
||||
{
|
||||
fbmem_initializer()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(cover_fbmem)/sizeof(cover_fbmem[0]); i++)
|
||||
cover_fbmem[i] = 0x00FF0000;
|
||||
}
|
||||
} fbmem_initializer;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -385,15 +385,6 @@ void do_load_state(struct moviefile& _movie, int lmode)
|
|||
mprefix._set = true;
|
||||
}
|
||||
movb.get_movie() = newmovie;
|
||||
//Paint the screen.
|
||||
{
|
||||
framebuffer_raw tmp;
|
||||
if(will_load_state) {
|
||||
tmp.load(_movie.screenshot);
|
||||
redraw_framebuffer(tmp);
|
||||
} else
|
||||
redraw_framebuffer(our_rom->rtype->draw_cover());
|
||||
}
|
||||
//Activate RW mode if needed.
|
||||
if(lmode == LOAD_STATE_RW)
|
||||
movb.get_movie().readonly_mode(false);
|
||||
|
@ -404,6 +395,15 @@ void do_load_state(struct moviefile& _movie, int lmode)
|
|||
movb.get_movie().readonly_mode(false);
|
||||
if(lmode == LOAD_STATE_CURRENT && !current_mode)
|
||||
movb.get_movie().readonly_mode(false);
|
||||
//Paint the screen.
|
||||
{
|
||||
framebuffer_raw tmp;
|
||||
if(will_load_state) {
|
||||
tmp.load(_movie.screenshot);
|
||||
redraw_framebuffer(tmp);
|
||||
} else
|
||||
redraw_framebuffer(our_rom->rtype->draw_cover());
|
||||
}
|
||||
information_dispatch::do_mode_change(movb.get_movie().readonly_mode());
|
||||
if(our_rom->rtype)
|
||||
messages << "ROM Type " << our_rom->rtype->get_hname() << " region " << our_rom->region->get_hname()
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "core/rom.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "interface/cover.hpp"
|
||||
#include "interface/romtype.hpp"
|
||||
#include "library/pixfmt-rgb16.hpp"
|
||||
#include "library/portfn.hpp"
|
||||
|
@ -135,6 +136,10 @@ namespace
|
|||
//Cover page.
|
||||
[]() -> framebuffer_raw& {
|
||||
static framebuffer_raw x(null_fbinfo);
|
||||
for(size_t i = 0; i < sizeof(null_cover_fbmem)/sizeof(null_cover_fbmem[0]); i++)
|
||||
null_cover_fbmem[i] = 0x0000;
|
||||
std::string message = "NO ROM LOADED";
|
||||
cover_render_string(null_cover_fbmem, 204, 220, message, 0xFFFF, 0x0000, 512, 448, 1024, 2);
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
@ -168,16 +173,6 @@ namespace
|
|||
|
||||
core_type* current_rom_type = &type_null;
|
||||
core_region* current_region = &null_region;
|
||||
|
||||
//Init the fbmem.
|
||||
struct fbmem_initializer
|
||||
{
|
||||
fbmem_initializer()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(null_cover_fbmem)/sizeof(null_cover_fbmem[0]); i++)
|
||||
null_cover_fbmem[i] = 0xFC00;
|
||||
}
|
||||
} fbmem_initializer;
|
||||
}
|
||||
|
||||
loaded_slot::loaded_slot() throw(std::bad_alloc)
|
||||
|
|
123
src/interface/cover.cpp
Normal file
123
src/interface/cover.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include "interface/cover.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
#include "library/utf8.hpp"
|
||||
#include "fonts/wrapper.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
template<size_t pstride>
|
||||
void cover_render_character(void* fb, unsigned x, unsigned y, uint32_t ch, uint32_t fg, uint32_t bg,
|
||||
size_t w, size_t h, size_t istride)
|
||||
{
|
||||
unsigned char* _fg = reinterpret_cast<unsigned char*>(&fg);
|
||||
unsigned char* _bg = reinterpret_cast<unsigned char*>(&bg);
|
||||
if(x >= w || y >= h)
|
||||
return;
|
||||
const bitmap_font::glyph& g = main_font.get_glyph(ch);
|
||||
unsigned maxw = min((size_t)(g.wide ? 16 : 8), (size_t)(w - x));
|
||||
unsigned maxh = min((size_t)16, (size_t)(h - y));
|
||||
unsigned char* cellbase = reinterpret_cast<unsigned char*>(fb) + y * istride + pstride * x;
|
||||
if(g.wide) {
|
||||
//Wide character.
|
||||
for(size_t y2 = 0; y2 < maxh; y2++) {
|
||||
uint32_t d = g.data[y2 >> 1];
|
||||
d >>= 16 - ((y2 & 1) << 4);
|
||||
for(size_t j = 0; j < maxw; j++) {
|
||||
uint32_t b = 15 - j;
|
||||
if(((d >> b) & 1) != 0) {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _fg[k];
|
||||
} else {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _bg[k];
|
||||
}
|
||||
}
|
||||
cellbase += istride;
|
||||
}
|
||||
} else {
|
||||
//Narrow character.
|
||||
for(size_t y2 = 0; y2 < maxh; y2++) {
|
||||
uint32_t d = g.data[y2 >> 2];
|
||||
d >>= 24 - ((y2 & 3) << 3);
|
||||
for(size_t j = 0; j < maxw; j++) {
|
||||
uint32_t b = 7 - j;
|
||||
if(((d >> b) & 1) != 0) {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _fg[k];
|
||||
} else {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _bg[k];
|
||||
}
|
||||
}
|
||||
cellbase += istride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cover_render_character(void* fb, unsigned x, unsigned y, uint32_t ch, uint32_t fg, uint32_t bg, size_t w,
|
||||
size_t h, size_t istride, size_t pstride)
|
||||
{
|
||||
if(pstride == 2)
|
||||
cover_render_character<2>(fb, x, y, ch, fg, bg, w, h, istride);
|
||||
if(pstride == 3)
|
||||
cover_render_character<3>(fb, x, y, ch, fg, bg, w, h, istride);
|
||||
if(pstride == 4)
|
||||
cover_render_character<4>(fb, x, y, ch, fg, bg, w, h, istride);
|
||||
}
|
||||
|
||||
void cover_render_string(void* fb, unsigned x, unsigned y, const std::string& str, uint32_t fg, uint32_t bg,
|
||||
size_t w, size_t h, size_t istride, size_t pstride)
|
||||
{
|
||||
size_t spos = 0;
|
||||
size_t slen = str.length();
|
||||
uint16_t state = utf8_initial_state;
|
||||
while(true) {
|
||||
int ch = (spos < slen) ? (unsigned char)str[spos] : - 1;
|
||||
int32_t u = utf8_parse_byte(ch, state);
|
||||
if(u < 0) {
|
||||
if(ch < 0)
|
||||
break;
|
||||
spos++;
|
||||
continue;
|
||||
}
|
||||
cover_render_character(fb, x, y, u, fg, bg, w, h, istride, pstride);
|
||||
cover_next_position(u, x, y);
|
||||
spos++;
|
||||
}
|
||||
}
|
||||
|
||||
void cover_next_position(uint32_t ch, unsigned& x, unsigned& y)
|
||||
{
|
||||
unsigned ox = x;
|
||||
unsigned oy = y;
|
||||
if(ch == 9)
|
||||
x = (x + 63) >> 6 << 6;
|
||||
else if(ch == 10) {
|
||||
x = 0;
|
||||
y = y + 16;
|
||||
} else {
|
||||
const bitmap_font::glyph& g = main_font.get_glyph(ch);
|
||||
x = x + (g.wide ? 16 : 8);
|
||||
}
|
||||
}
|
||||
|
||||
void cover_next_position(const std::string& str, unsigned& x, unsigned& y)
|
||||
{
|
||||
size_t spos = 0;
|
||||
size_t slen = str.length();
|
||||
uint16_t state = utf8_initial_state;
|
||||
while(true) {
|
||||
int ch = (spos < slen) ? (unsigned char)str[spos] : - 1;
|
||||
int32_t u = utf8_parse_byte(ch, state);
|
||||
if(u < 0) {
|
||||
if(ch < 0)
|
||||
break;
|
||||
spos++;
|
||||
continue;
|
||||
}
|
||||
cover_next_position(u, x, y);
|
||||
spos++;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue