Skip to content

Commit

Permalink
RetroFW/RG350: Scale to non 320x240/480 screens
Browse files Browse the repository at this point in the history
  • Loading branch information
glebm committed Feb 24, 2020
1 parent 3a08562 commit 8c76bc1
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 109 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(DinguxCommander_SRCS
main.cpp
panel.cpp
resourceManager.cpp
screen.cpp
sdlutils.cpp
viewer.cpp
window.cpp
Expand Down Expand Up @@ -72,13 +73,17 @@ target_link_libraries(${BIN_TARGET} PRIVATE
)

if(TARGET_PLATFORM STREQUAL "retrofw")
target_compile_definitions(${BIN_TARGET} PRIVATE TARGET_PLATFORM_RETROFW)
include(CMake/retrofw_defs.cmake)
elseif(TARGET_PLATFORM STREQUAL "rg350")
target_compile_definitions(${BIN_TARGET} PRIVATE TARGET_PLATFORM_RG350)
include(CMake/rg350_defs.cmake)
endif()

foreach(
def_name
SCREEN_WIDTH
SCREEN_HEIGHT
PPU_X
PPU_Y
RES_DIR
Expand Down
21 changes: 11 additions & 10 deletions commander.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <sstream>
#include "commander.h"
#include "resourceManager.h"
#include "screen.h"
#include "sdlutils.h"
#include "def.h"
#include "dialog.h"
Expand All @@ -13,38 +14,38 @@

#define SPLITTER_LINE_W 1
#define X_LEFT 1
#define X_RIGHT SCREEN_WIDTH / 2 + SPLITTER_LINE_W + 1
#define X_RIGHT screen.w / 2 + SPLITTER_LINE_W + 1

namespace {

SDL_Surface *DrawBackground() {
SDL_Surface *bg = SDL_utils::createSurface(SCREEN_WIDTH * PPU_X, SCREEN_HEIGHT * PPU_Y);
SDL_Surface *bg = SDL_utils::createSurface(screen.w * screen.ppu_x, screen.h * screen.ppu_y);

// Stripes
const int stripes_h = SCREEN_HEIGHT - HEADER_H - FOOTER_H;
SDL_Rect rect = SDL_utils::Rect(0, 0, SCREEN_WIDTH * PPU_X, SCREEN_HEIGHT * PPU_Y);
const int stripes_h = screen.h - HEADER_H - FOOTER_H;
SDL_Rect rect = SDL_utils::Rect(0, 0, screen.w * screen.ppu_x, screen.h * screen.ppu_y);
const Uint32 bg_colors[2] = {SDL_MapRGB(bg->format, COLOR_BG_1), SDL_MapRGB(bg->format, COLOR_BG_2)};
const std::size_t num_lines = (stripes_h - 1) / LINE_HEIGHT + 1;
for (std::size_t i = 0; i < num_lines; ++i) {
rect.y = (Y_LIST + i * LINE_HEIGHT) * PPU_Y;
rect.y = (Y_LIST + i * LINE_HEIGHT) * screen.ppu_y;
SDL_FillRect(bg, &rect, bg_colors[i % 2]);
}

// Top and bottom bars
const auto bar_color = SDL_MapRGB(bg->format, COLOR_TITLE_BG);
rect = SDL_utils::Rect(0, 0, static_cast<decltype(SDL_Rect().w)>(bg->w), Y_LIST * PPU_Y);
rect = SDL_utils::Rect(0, 0, static_cast<decltype(SDL_Rect().w)>(bg->w), Y_LIST * screen.ppu_y);
SDL_FillRect(bg, &rect, bar_color);
rect.y = bg->h - FOOTER_H * PPU_Y;
rect.y = bg->h - FOOTER_H * screen.ppu_y;
SDL_FillRect(bg, &rect, bar_color);

// Line in the middle
rect = SDL_utils::Rect(SCREEN_WIDTH / 2 * PPU_X, 0, SPLITTER_LINE_W * PPU_X, Y_LIST * PPU_Y);
rect = SDL_utils::Rect(screen.w / 2 * screen.ppu_x, 0, SPLITTER_LINE_W * screen.ppu_x, Y_LIST * screen.ppu_y);
SDL_FillRect(bg, &rect, bg_colors[0]);
rect.y = rect.h;
rect.h = stripes_h * PPU_Y;
rect.h = stripes_h * screen.ppu_y;
SDL_FillRect(bg, &rect, bar_color);
rect.y += rect.h;
rect.h = FOOTER_H * PPU_Y;
rect.h = FOOTER_H * screen.ppu_y;
SDL_FillRect(bg, &rect, bg_colors[0]);

return bg;
Expand Down
6 changes: 3 additions & 3 deletions def.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@

#define FOOTER_H 13
#define FOOTER_PADDING_TOP 1
#define FOOTER_Y (SCREEN_HEIGHT - FOOTER_H)
#define FOOTER_Y (screen.h - FOOTER_H)

#define Y_LIST HEADER_H

#define LINE_HEIGHT 15
#define NB_VISIBLE_LINES ((SCREEN_HEIGHT - FOOTER_H - HEADER_H - 1) / LINE_HEIGHT + 1)
#define NB_FULLY_VISIBLE_LINES ((SCREEN_HEIGHT - FOOTER_H - HEADER_H) / LINE_HEIGHT)
#define NB_VISIBLE_LINES ((screen.h - FOOTER_H - HEADER_H - 1) / LINE_HEIGHT + 1)
#define NB_FULLY_VISIBLE_LINES ((screen.h - FOOTER_H - HEADER_H) / LINE_HEIGHT)

// Dialogs
#define DIALOG_BORDER 2
Expand Down
31 changes: 16 additions & 15 deletions dialog.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <iostream>
#include "dialog.h"
#include "screen.h"
#include "sdlutils.h"
#include "resourceManager.h"
#include "def.h"
Expand Down Expand Up @@ -98,38 +99,38 @@ void CDialog::init(void)
if (m_linesImg.back()->w > l_width)
l_width = m_linesImg.back()->w;
}
l_width /= PPU_X;
l_width /= screen.ppu_x;
// Cursor width
l_cursorWidth = l_width + 2 * DIALOG_MARGIN;
if (l_cursorWidth > SCREEN_WIDTH - 2 * DIALOG_BORDER)
l_cursorWidth = SCREEN_WIDTH - 2 * DIALOG_BORDER;
if (l_cursorWidth > screen.w - 2 * DIALOG_BORDER)
l_cursorWidth = screen.w - 2 * DIALOG_BORDER;
// Line clip
m_clip.h = m_linesImg.front()->h;
m_clip.w = (l_cursorWidth - DIALOG_MARGIN - 1) * PPU_X;
m_clip.w = (l_cursorWidth - DIALOG_MARGIN - 1) * screen.ppu_x;
// Adjust image width
l_width = l_width + 2 * DIALOG_MARGIN + 2 * DIALOG_BORDER;
if (l_width > SCREEN_WIDTH)
l_width = SCREEN_WIDTH;
if (l_width > screen.w)
l_width = screen.w;
// Create dialog image
const int m_image_h = m_lines.size() * LINE_HEIGHT + 2 * DIALOG_BORDER;
m_image = SDL_utils::createImage(l_width * PPU_X, m_image_h * PPU_Y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
m_image = SDL_utils::createImage(l_width * screen.ppu_x, m_image_h * screen.ppu_y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
{
SDL_Rect l_rect;
l_rect.x = DIALOG_BORDER * PPU_X;
l_rect.y = (DIALOG_BORDER + m_nbTitle * LINE_HEIGHT) * PPU_Y;
l_rect.w = m_image->w - 2 * DIALOG_BORDER * PPU_X;
l_rect.h = (m_image_h - 2 * DIALOG_BORDER - m_nbTitle * LINE_HEIGHT) * PPU_Y;
l_rect.x = DIALOG_BORDER * screen.ppu_x;
l_rect.y = (DIALOG_BORDER + m_nbTitle * LINE_HEIGHT) * screen.ppu_y;
l_rect.w = m_image->w - 2 * DIALOG_BORDER * screen.ppu_x;
l_rect.h = (m_image_h - 2 * DIALOG_BORDER - m_nbTitle * LINE_HEIGHT) * screen.ppu_y;
SDL_FillRect(m_image, &l_rect, SDL_MapRGB(m_image->format, COLOR_BG_1));
}
// Create cursor image
m_cursor1 = SDL_utils::createImage(l_cursorWidth * PPU_X, LINE_HEIGHT * PPU_Y, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1));
m_cursor2 = SDL_utils::createImage(l_cursorWidth * PPU_X, LINE_HEIGHT * PPU_Y, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_2));
m_cursor1 = SDL_utils::createImage(l_cursorWidth * screen.ppu_x, LINE_HEIGHT * screen.ppu_y, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1));
m_cursor2 = SDL_utils::createImage(l_cursorWidth * screen.ppu_x, LINE_HEIGHT * screen.ppu_y, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_2));
// Adjust dialog coordinates
if (!m_x)
m_x = (SCREEN_WIDTH - m_image->w / PPU_X) / 2;
m_x = (screen.w - m_image->w / screen.ppu_x) / 2;
if (!m_y)
{
m_y = (SCREEN_HEIGHT - m_image_h) / 2;
m_y = (screen.h - m_image_h) / 2;
}
else
{
Expand Down
69 changes: 35 additions & 34 deletions keyboard.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <iostream>
#include "keyboard.h"
#include "screen.h"
#include "sdlutils.h"
#include "resourceManager.h"
#include "def.h"
Expand Down Expand Up @@ -29,55 +30,55 @@ CKeyboard::CKeyboard(const std::string &p_inputText):
{
SDL_Rect l_rect;
// Create keyboard image
m_imageKeyboard = SDL_utils::createImage(265 * PPU_X, 84 * PPU_Y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
l_rect.x = 2 * PPU_X;
l_rect.y = 2 * PPU_Y;
l_rect.w = 261 * PPU_X;
l_rect.h = 80 * PPU_Y;
m_imageKeyboard = SDL_utils::createImage(265 * screen.ppu_x, 84 * screen.ppu_y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
l_rect.x = 2 * screen.ppu_x;
l_rect.y = 2 * screen.ppu_y;
l_rect.w = 261 * screen.ppu_x;
l_rect.h = 80 * screen.ppu_y;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_2));
// Keys
for (unsigned int l_y = 0; l_y < 3; ++l_y)
{
for (unsigned int l_x = 0; l_x < 13; ++l_x)
{
l_rect.x = (3 + 20 * l_x) * PPU_X;
l_rect.y = (3 + 20 * l_y) * PPU_Y;
l_rect.w = 19 * PPU_X;
l_rect.h = 18 * PPU_Y;
l_rect.x = (3 + 20 * l_x) * screen.ppu_x;
l_rect.y = (3 + 20 * l_y) * screen.ppu_y;
l_rect.w = 19 * screen.ppu_x;
l_rect.h = 18 * screen.ppu_y;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER));
l_rect.x += 1 * PPU_X;
l_rect.y += 1 * PPU_Y;
l_rect.w -= 2 * PPU_X;
l_rect.h -= 2 * PPU_Y;
l_rect.x += 1 * screen.ppu_x;
l_rect.y += 1 * screen.ppu_y;
l_rect.w -= 2 * screen.ppu_x;
l_rect.h -= 2 * screen.ppu_y;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
}
}
// Buttons Cancel and OK
l_rect.x = 3 * PPU_X;
l_rect.y = 63 * PPU_Y;
l_rect.w = 129 * PPU_X;
l_rect.h = 18 * PPU_Y;
l_rect.x = 3 * screen.ppu_x;
l_rect.y = 63 * screen.ppu_y;
l_rect.w = 129 * screen.ppu_x;
l_rect.h = 18 * screen.ppu_y;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER));
l_rect.x = 133 * PPU_X;
l_rect.x = 133 * screen.ppu_x;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER));
l_rect.w -= 2 * PPU_X;
l_rect.h -= 2 * PPU_Y;
l_rect.y += 1 * PPU_Y;
l_rect.x = 4 * PPU_X;
l_rect.w -= 2 * screen.ppu_x;
l_rect.h -= 2 * screen.ppu_y;
l_rect.y += 1 * screen.ppu_y;
l_rect.x = 4 * screen.ppu_x;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
l_rect.x = 134 * PPU_X;
l_rect.x = 134 * screen.ppu_x;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
// Create text field image
m_textField = SDL_utils::createImage(265 * PPU_X, 19 * PPU_Y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
l_rect.x = 2 * PPU_X;
l_rect.y = 2 * PPU_Y;
l_rect.w = 261 * PPU_X;
l_rect.h = 15 * PPU_Y;
m_textField = SDL_utils::createImage(265 * screen.ppu_x, 19 * screen.ppu_y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
l_rect.x = 2 * screen.ppu_x;
l_rect.y = 2 * screen.ppu_y;
l_rect.w = 261 * screen.ppu_x;
l_rect.h = 15 * screen.ppu_y;
SDL_FillRect(m_textField, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
}
// Create footer
m_footer = SDL_utils::createImage(SCREEN_WIDTH * PPU_X, FOOTER_H * PPU_Y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
SDL_utils::applyText(SCREEN_WIDTH >> 1, 1, m_footer, m_font, "A-Input B-Cancel START-OK L/R-Change Y-Backspace X-Space", Globals::g_colorTextTitle, {COLOR_TITLE_BG}, SDL_utils::T_TEXT_ALIGN_CENTER);
m_footer = SDL_utils::createImage(screen.w * screen.ppu_x, FOOTER_H * screen.ppu_y, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
SDL_utils::applyText(screen.w >> 1, 1, m_footer, m_font, "A-Input B-Cancel START-OK L/R-Change Y-Backspace X-Space", Globals::g_colorTextTitle, {COLOR_TITLE_BG}, SDL_utils::T_TEXT_ALIGN_CENTER);
}

CKeyboard::~CKeyboard(void)
Expand Down Expand Up @@ -159,10 +160,10 @@ void CKeyboard::render(const bool p_focus) const
l_rect.x = KB_X + 4 + (m_selected == 40) * 130;
l_rect.y = KB_Y + 64;
}
l_rect.x *= PPU_X;
l_rect.y *= PPU_Y;
l_rect.w *= PPU_X;
l_rect.h *= PPU_Y;
l_rect.x *= screen.ppu_x;
l_rect.y *= screen.ppu_y;
l_rect.w *= screen.ppu_x;
l_rect.h *= screen.ppu_y;
SDL_FillRect(Globals::g_screen, &l_rect, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1));
}
// Draw keys text
Expand Down
47 changes: 46 additions & 1 deletion main.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include "def.h"
#include "screen.h"
#include "sdlutils.h"
#include "resourceManager.h"
#include "commander.h"
Expand All @@ -18,6 +20,21 @@ const SDL_Color Globals::g_colorTextDir = {COLOR_TEXT_DIR};
const SDL_Color Globals::g_colorTextSelected = {COLOR_TEXT_SELECTED};
std::vector<CWindow *> Globals::g_windows;

namespace {

SDL_Surface *SetVideoMode(int width, int height, int bpp, std::uint32_t flags) {
fprintf(stderr, "Setting video mode %dx%d bpp=%u flags=0x%08X\n", width, height, bpp, flags);
fflush(stderr);
auto *result = SDL_SetVideoMode(width, height, bpp, flags);
const auto &current = *SDL_GetVideoInfo();
fprintf(stderr, "Video mode is now %dx%d bpp=%u flags=0x%08X\n",
current.current_w, current.current_h, current.vfmt->BitsPerPixel, SDL_GetVideoSurface()->flags);
fflush(stderr);
return result;
}

} // namespace

int main(int argc, char** argv)
{
// Avoid crash due to the absence of mouse
Expand All @@ -35,7 +52,35 @@ int main(int argc, char** argv)
SDL_ShowCursor(SDL_DISABLE);

// Screen
ScreenSurface = SDL_SetVideoMode(SCREEN_WIDTH * PPU_X, SCREEN_HEIGHT * PPU_Y, SCREEN_BPP, SURFACE_FLAGS);
const auto &best = *SDL_GetVideoInfo();
fprintf(stderr, "Best video mode reported as: %dx%d bpp=%d hw_available=%u\n",
best.current_w, best.current_h, best.vfmt->BitsPerPixel, best.hw_available);

// Detect non 320x240/480 screens.
#if defined(TARGET_PLATFORM_RETROFW) || defined(TARGET_PLATFORM_RG350)
if (best.current_w >= SCREEN_WIDTH * 2)
{
// E.g. 640x480. Upscale to the smaller of the two.
double scale = std::min(
best.current_w / static_cast<double>(SCREEN_WIDTH),
best.current_h / static_cast<double>(SCREEN_HEIGHT));
scale = std::min(scale, 2.0);
screen.ppu_x = screen.ppu_y = scale;
screen.w = best.current_w / scale;
screen.h = best.current_h / scale;
screen.actual_w = best.current_w;
screen.actual_h = best.current_h;
}
else if (best.current_w != SCREEN_WIDTH)
{
// E.g. RS07 with 480x272 screen.
screen.actual_w = screen.w = best.current_w;
screen.actual_h = screen.h = best.current_h;
screen.ppu_x = screen.ppu_y = 1;
}
#endif
ScreenSurface = SetVideoMode(screen.actual_w, screen.actual_h, SCREEN_BPP, SURFACE_FLAGS);

Globals::g_screen = ScreenSurface;
if (Globals::g_screen == NULL)
{
Expand Down
Loading

0 comments on commit 8c76bc1

Please sign in to comment.