Do something sightly more interesting with covers

The coverpages need more information still
This commit is contained in:
Ilari Liusvaara 2013-01-08 06:39:32 +02:00
parent a0ed3252c2
commit 97ceb2e3d0
6 changed files with 181 additions and 39 deletions

View 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

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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
View 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++;
}
}