mirror of https://github.com/OpenRCT2/OpenRCT2.git
add hardware display
This commit is contained in:
parent
25c5c8cbaa
commit
0013310f0d
|
@ -3487,3 +3487,4 @@ STR_5150 :Enable debugging tools
|
|||
STR_5151 :,
|
||||
STR_5152 :.
|
||||
STR_5153 :RCT1 colour scheme
|
||||
STR_5154 :Hardware display
|
||||
|
|
|
@ -161,6 +161,7 @@ config_property_definition _generalDefinitions[] = {
|
|||
{ offsetof(general_configuration, window_height), "window_height", CONFIG_VALUE_TYPE_SINT32, -1, NULL },
|
||||
{ offsetof(general_configuration, window_snap_proximity), "window_snap_proximity", CONFIG_VALUE_TYPE_UINT8, 5, NULL },
|
||||
{ offsetof(general_configuration, window_width), "window_width", CONFIG_VALUE_TYPE_SINT32, -1, NULL },
|
||||
{ offsetof(general_configuration, hardware_display), "hardware_display", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
};
|
||||
|
||||
config_property_definition _interfaceDefinitions[] = {
|
||||
|
|
|
@ -130,6 +130,7 @@ typedef struct {
|
|||
uint16 language;
|
||||
uint8 window_snap_proximity;
|
||||
uint8 autosave_frequency;
|
||||
uint8 hardware_display;
|
||||
} general_configuration;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -77,6 +77,7 @@ void platform_free();
|
|||
void platform_update_palette(char* colours, int start_index, int num_colours);
|
||||
void platform_set_fullscreen_mode(int mode);
|
||||
void platform_set_cursor(char cursor);
|
||||
void platform_refresh_video();
|
||||
void platform_process_messages();
|
||||
int platform_scancode_to_rct_keycode(int sdl_key);
|
||||
void platform_start_text_input(char* buffer, int max_length);
|
||||
|
|
|
@ -45,12 +45,16 @@ int gNumResolutions = 0;
|
|||
resolution *gResolutions = NULL;
|
||||
int gResolutionsAllowAnyAspectRatio = 0;
|
||||
|
||||
SDL_Window *gWindow;
|
||||
SDL_Window *gWindow = NULL;
|
||||
SDL_Renderer *gRenderer = NULL;
|
||||
SDL_Texture *gBufferTexture = NULL;
|
||||
SDL_Color gPalette[256];
|
||||
|
||||
static SDL_Surface *_surface;
|
||||
static SDL_Palette *_palette;
|
||||
static int _screenBufferSize;
|
||||
static void *_screenBuffer;
|
||||
static int _screenBufferPitch;
|
||||
static SDL_Cursor* _cursors[CURSOR_COUNT];
|
||||
static const int _fullscreen_modes[] = { 0, SDL_WINDOW_FULLSCREEN, SDL_WINDOW_FULLSCREEN_DESKTOP };
|
||||
static unsigned int _lastGestureTimestamp;
|
||||
|
@ -162,28 +166,63 @@ void platform_get_closest_resolution(int inWidth, int inHeight, int *outWidth, i
|
|||
|
||||
void platform_draw()
|
||||
{
|
||||
// Lock the surface before setting its pixels
|
||||
if (SDL_MUSTLOCK(_surface))
|
||||
if (SDL_LockSurface(_surface) < 0) {
|
||||
RCT2_ERROR("locking failed %s", SDL_GetError());
|
||||
return;
|
||||
int width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16);
|
||||
int height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16);
|
||||
|
||||
if (gConfigGeneral.hardware_display) {
|
||||
void *pixels;
|
||||
int pitch;
|
||||
if (SDL_LockTexture(gBufferTexture, NULL, &pixels, &pitch) == 0) {
|
||||
uint8 *dst = pixels;
|
||||
uint8 *src = (uint8*)_screenBuffer;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
uint8 paletteIndex = *src;
|
||||
SDL_Color colour = gPalette[paletteIndex];
|
||||
|
||||
dst[0] = 255;
|
||||
dst[1] = colour.b;
|
||||
dst[2] = colour.g;
|
||||
dst[3] = colour.r;
|
||||
|
||||
src += 1;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
src += _screenBufferPitch - width;
|
||||
dst += pitch - (width * 4);
|
||||
}
|
||||
SDL_UnlockTexture(gBufferTexture);
|
||||
}
|
||||
|
||||
// Copy pixels from the virtual screen buffer to the surface
|
||||
memcpy(_surface->pixels, _screenBuffer, _surface->pitch * _surface->h);
|
||||
SDL_RenderCopy(gRenderer, gBufferTexture, NULL, NULL);
|
||||
SDL_RenderPresent(gRenderer);
|
||||
} else {
|
||||
// Lock the surface before setting its pixels
|
||||
if (SDL_MUSTLOCK(_surface)) {
|
||||
if (SDL_LockSurface(_surface) < 0) {
|
||||
log_error("locking failed %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the surface
|
||||
if (SDL_MUSTLOCK(_surface))
|
||||
SDL_UnlockSurface(_surface);
|
||||
// Copy pixels from the virtual screen buffer to the surface
|
||||
memcpy(_surface->pixels, _screenBuffer, _surface->pitch * _surface->h);
|
||||
|
||||
// Copy the surface to the window
|
||||
if (SDL_BlitSurface(_surface, NULL, SDL_GetWindowSurface(gWindow), NULL)) {
|
||||
RCT2_ERROR("SDL_BlitSurface %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
if (SDL_UpdateWindowSurface(gWindow)) {
|
||||
RCT2_ERROR("SDL_UpdateWindowSurface %s", SDL_GetError());
|
||||
exit(1);
|
||||
// Unlock the surface
|
||||
if (SDL_MUSTLOCK(_surface))
|
||||
SDL_UnlockSurface(_surface);
|
||||
|
||||
// Copy the surface to the window
|
||||
if (SDL_BlitSurface(_surface, NULL, SDL_GetWindowSurface(gWindow), NULL)) {
|
||||
log_fatal("SDL_BlitSurface %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
if (SDL_UpdateWindowSurface(gWindow)) {
|
||||
log_fatal("SDL_UpdateWindowSurface %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,25 +233,12 @@ static void platform_resize(int width, int height)
|
|||
void *newScreenBuffer;
|
||||
uint32 flags;
|
||||
|
||||
if (_surface != NULL)
|
||||
SDL_FreeSurface(_surface);
|
||||
if (_palette != NULL)
|
||||
SDL_FreePalette(_palette);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) = width;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) = height;
|
||||
|
||||
_surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0);
|
||||
_palette = SDL_AllocPalette(256);
|
||||
platform_refresh_video();
|
||||
|
||||
if (!_surface || !_palette) {
|
||||
RCT2_ERROR("%p || %p == NULL %s", _surface, _palette, SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (SDL_SetSurfacePalette(_surface, _palette)) {
|
||||
RCT2_ERROR("SDL_SetSurfacePalette failed %s", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
newScreenBufferSize = _surface->pitch * _surface->h;
|
||||
newScreenBufferSize = _screenBufferPitch * height;
|
||||
newScreenBuffer = malloc(newScreenBufferSize);
|
||||
if (_screenBuffer == NULL) {
|
||||
memset(newScreenBuffer, 0, newScreenBufferSize);
|
||||
|
@ -226,16 +252,13 @@ static void platform_resize(int width, int height)
|
|||
_screenBuffer = newScreenBuffer;
|
||||
_screenBufferSize = newScreenBufferSize;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) = width;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) = height;
|
||||
|
||||
screenDPI = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
|
||||
screenDPI->bits = _screenBuffer;
|
||||
screenDPI->x = 0;
|
||||
screenDPI->y = 0;
|
||||
screenDPI->width = width;
|
||||
screenDPI->height = height;
|
||||
screenDPI->pitch = _surface->pitch - _surface->w;
|
||||
screenDPI->pitch = _screenBufferPitch - width;
|
||||
|
||||
RCT2_GLOBAL(0x009ABDF0, uint8) = 6;
|
||||
RCT2_GLOBAL(0x009ABDF1, uint8) = 3;
|
||||
|
@ -268,27 +291,28 @@ static void platform_resize(int width, int height)
|
|||
|
||||
void platform_update_palette(char* colours, int start_index, int num_colours)
|
||||
{
|
||||
SDL_Color base[256];
|
||||
SDL_Surface *surface;
|
||||
int i;
|
||||
|
||||
surface = SDL_GetWindowSurface(gWindow);
|
||||
if (!surface) {
|
||||
RCT2_ERROR("SDL_GetWindowSurface failed %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
base[i].r = colours[2];
|
||||
base[i].g = colours[1];
|
||||
base[i].b = colours[0];
|
||||
base[i].a = 0;
|
||||
gPalette[i].r = colours[2];
|
||||
gPalette[i].g = colours[1];
|
||||
gPalette[i].b = colours[0];
|
||||
gPalette[i].a = 0;
|
||||
colours += 4;
|
||||
}
|
||||
|
||||
if (SDL_SetPaletteColors(_palette, base, 0, 256)) {
|
||||
RCT2_ERROR("SDL_SetPaletteColors failed %s", SDL_GetError());
|
||||
exit(1);
|
||||
if (!gConfigGeneral.hardware_display) {
|
||||
surface = SDL_GetWindowSurface(gWindow);
|
||||
if (!surface) {
|
||||
log_fatal("SDL_GetWindowSurface failed %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (_palette != NULL && SDL_SetPaletteColors(_palette, gPalette, 0, 256)) {
|
||||
log_fatal("SDL_SetPaletteColors failed %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,10 +545,12 @@ static void platform_create_window()
|
|||
int width, height;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
RCT2_ERROR("SDL_Init %s", SDL_GetError());
|
||||
log_fatal("SDL_Init %s", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0);
|
||||
|
||||
platform_load_cursors();
|
||||
RCT2_CALLPROC_EBPSAFE(0x0068371D);
|
||||
|
||||
|
@ -711,4 +737,41 @@ int platform_get_cursor_pos(int* x, int* y)
|
|||
GetCursorPos(&point);
|
||||
*x = point.x;
|
||||
*y = point.y;
|
||||
}
|
||||
|
||||
void platform_refresh_video()
|
||||
{
|
||||
int width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16);
|
||||
int height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16);
|
||||
|
||||
if (gConfigGeneral.hardware_display) {
|
||||
if (gRenderer == NULL)
|
||||
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
||||
if (gBufferTexture != NULL)
|
||||
SDL_DestroyTexture(gBufferTexture);
|
||||
|
||||
gBufferTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
_screenBufferPitch = width;
|
||||
} else {
|
||||
if (_surface != NULL)
|
||||
SDL_FreeSurface(_surface);
|
||||
if (_palette != NULL)
|
||||
SDL_FreePalette(_palette);
|
||||
|
||||
_surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0);
|
||||
_palette = SDL_AllocPalette(256);
|
||||
|
||||
if (!_surface || !_palette) {
|
||||
log_fatal("%p || %p == NULL %s", _surface, _palette, SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (SDL_SetSurfacePalette(_surface, _palette)) {
|
||||
log_fatal("SDL_SetSurfacePalette failed %s", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
_screenBufferPitch = _surface->pitch;
|
||||
}
|
||||
}
|
|
@ -68,6 +68,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
|
|||
WIDX_GRIDLINES_CHECKBOX,
|
||||
WIDX_CONSTRUCTION_MARKER,
|
||||
WIDX_CONSTRUCTION_MARKER_DROPDOWN,
|
||||
WIDX_HARDWARE_DISPLAY_CHECKBOX,
|
||||
|
||||
WIDX_LANGUAGE,
|
||||
WIDX_LANGUAGE_DROPDOWN,
|
||||
|
@ -126,6 +127,7 @@ static rct_widget window_options_widgets[] = {
|
|||
{ WWT_CHECKBOX, 0, 10, 299, 99, 110, STR_GRIDLINES, STR_GRIDLINES_TIP },
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 113, 124, STR_NONE, STR_NONE }, // construction marker
|
||||
{ WWT_DROPDOWN_BUTTON, 0, 288, 298, 114, 123, 876, STR_NONE },
|
||||
{ WWT_CHECKBOX, 0, 10, 290, 129, 140, 5154, STR_NONE },
|
||||
|
||||
// Culture / units tab
|
||||
{ WWT_DROPDOWN, 0, 155, 299, 53, 64, STR_NONE, STR_NONE }, // language
|
||||
|
@ -266,6 +268,7 @@ void window_options_open()
|
|||
(1ULL << WIDX_HEIGHT_LABELS_DROPDOWN) |
|
||||
(1ULL << WIDX_TILE_SMOOTHING_CHECKBOX) |
|
||||
(1ULL << WIDX_GRIDLINES_CHECKBOX) |
|
||||
(1ULL << WIDX_HARDWARE_DISPLAY_CHECKBOX) |
|
||||
(1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX) |
|
||||
(1ULL << WIDX_AUTOSAVE) |
|
||||
(1ULL << WIDX_AUTOSAVE_DROPDOWN) |
|
||||
|
@ -364,6 +367,12 @@ static void window_options_mouseup()
|
|||
w->viewport->flags &= ~VIEWPORT_FLAG_GRIDLINES;
|
||||
}
|
||||
break;
|
||||
case WIDX_HARDWARE_DISPLAY_CHECKBOX:
|
||||
gConfigGeneral.hardware_display ^= 1;
|
||||
platform_refresh_video();
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_SAVE_PLUGIN_DATA_CHECKBOX:
|
||||
gConfigGeneral.save_plugin_data ^= 1;
|
||||
config_save_default();
|
||||
|
@ -708,6 +717,12 @@ static void window_options_invalidate()
|
|||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_GRIDLINES_CHECKBOX);
|
||||
|
||||
// show hardware display
|
||||
if (gConfigGeneral.hardware_display)
|
||||
w->pressed_widgets |= (1ULL << WIDX_HARDWARE_DISPLAY_CHECKBOX);
|
||||
else
|
||||
w->pressed_widgets &= ~(1ULL << WIDX_HARDWARE_DISPLAY_CHECKBOX);
|
||||
|
||||
// construction marker: celsius/fahrenheit
|
||||
window_options_widgets[WIDX_CONSTRUCTION_MARKER].image = STR_WHITE + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER, uint8);
|
||||
|
||||
|
@ -719,6 +734,7 @@ static void window_options_invalidate()
|
|||
window_options_widgets[WIDX_GRIDLINES_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_widgets[WIDX_CONSTRUCTION_MARKER].type = WWT_DROPDOWN;
|
||||
window_options_widgets[WIDX_CONSTRUCTION_MARKER_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
window_options_widgets[WIDX_HARDWARE_DISPLAY_CHECKBOX].type = WWT_CHECKBOX;
|
||||
break;
|
||||
case WINDOW_OPTIONS_PAGE_CULTURE:
|
||||
// currency: pounds, dollars, etc. (10 total)
|
||||
|
|
Loading…
Reference in New Issue