Merge branch '86Box:master' into PB68x-update

This commit is contained in:
Verloren50000
2025-10-28 09:39:15 +08:00
committed by GitHub
13 changed files with 5321 additions and 397 deletions

View File

@@ -1083,7 +1083,10 @@ usage:
/* Build the global configuration file path. */
if (global == NULL) {
plat_get_global_config_dir(global_cfg_path, sizeof(global_cfg_path));
path_append_filename(global_cfg_path, global_cfg_path, GLOBAL_CONFIG_FILE);
// avoid strcpy global_cfg_path over itself (valgrind says it's bad...)
// path_append_filename(global_cfg_path, global_cfg_path, GLOBAL_CONFIG_FILE);
path_slash(global_cfg_path);
strcat(global_cfg_path, GLOBAL_CONFIG_FILE);
} else {
strncpy(global_cfg_path, global, sizeof(global_cfg_path) - 1);
}

View File

@@ -0,0 +1,25 @@
#ifndef _UNIX_OSD_H
#define _UNIX_OSD_H
#include <SDL.h>
// state management
extern void osd_init(void);
extern void osd_deinit(void);
extern int osd_open(SDL_Event event);
extern int osd_close(SDL_Event event);
// keyboard event handler
extern int osd_handle(SDL_Event event);
// draw the osd interface, if it's open
extern void osd_present(void);
// future ui
extern void osd_ui_sb_update_icon_state(int tag, int state);
extern void osd_ui_sb_update_icon(int tag, int active);
extern void osd_ui_sb_update_icon_write(int tag, int active);
extern void osd_ui_sb_update_icon_wp(int tag, int state);
#endif /*_UNIX_OSD_H*/

File diff suppressed because it is too large Load Diff

View File

@@ -2316,7 +2316,38 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
if (start < map->base)
start = map->base;
for (i_c = i_s; i_c <= i_e; i_c += i_a) {
if (i_e == 0x00000000ULL) {
for (c = start; c < end; c += MEM_GRANULARITY_SIZE) {
/* CPU */
n = !!in_smm;
wp = _mem_wp[c >> MEM_GRANULARITY_BITS];
if (map->exec && mem_mapping_access_allowed(map->flags,
_mem_state[c >> MEM_GRANULARITY_BITS].states[n].x))
_mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base);
if (!wp && (map->write_b || map->write_w || map->write_l) &&
mem_mapping_access_allowed(map->flags,
_mem_state[c >> MEM_GRANULARITY_BITS].states[n].w))
write_mapping[c >> MEM_GRANULARITY_BITS] = map;
if ((map->read_b || map->read_w || map->read_l) &&
mem_mapping_access_allowed(map->flags,
_mem_state[c >> MEM_GRANULARITY_BITS].states[n].r))
read_mapping[c >> MEM_GRANULARITY_BITS] = map;
/* Bus */
n |= STATE_BUS;
wp = _mem_wp_bus[c >> MEM_GRANULARITY_BITS];
if (!wp && (map->write_b || map->write_w || map->write_l) &&
mem_mapping_access_allowed(map->flags,
_mem_state[c >> MEM_GRANULARITY_BITS].states[n].w))
write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map;
if ((map->read_b || map->read_w || map->read_l) &&
mem_mapping_access_allowed(map->flags,
_mem_state[c >> MEM_GRANULARITY_BITS].states[n].r))
read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map;
}
} else for (i_c = i_s; i_c <= i_e; i_c += i_a) {
for (c = (start + i_c); c < (end + i_c); c += MEM_GRANULARITY_SIZE) {
/* CPU */
n = (!!in_smm) || (is_cxsmm && (ccr1 & CCR1_SMAC));

View File

@@ -235,7 +235,7 @@ msgid "&New image..."
msgstr "&Nieuw imagebestand..."
msgid "&Existing image..."
msgstr "&Bestaande imagebestand..."
msgstr "&Bestaand imagebestand..."
msgid "Existing image (&Write-protected)..."
msgstr "Bestaand imagebestand (&Schrijfbeveiligd)..."

View File

@@ -1715,12 +1715,12 @@ OpenGLRenderer::render()
plat_tempfile(fn, NULL, (char*)".png");
strcat(path, fn);
unsigned char *rgb = (unsigned char *) calloc(1, (size_t) width * height * 3);
unsigned char *rgb = (unsigned char *) calloc(1, (size_t) width * height * 4);
glw.glFinish();
glw.glReadPixels(window_rect.x, window_rect.y, width, height, GL_RGB, GL_UNSIGNED_BYTE, rgb);
QImage image(rgb, width, height, QImage::Format_RGB888);
QImage image((uchar*)rgb, width, height, width * 3, QImage::Format_RGB888);
image.mirrored(false, true).save(path, "png");
monitors[r_monitor_index].mon_screenshots--;
free(rgb);

View File

@@ -44,6 +44,7 @@ endif()
add_library(ui OBJECT
unix_sdl.c
unix_osd.c
unix_cdrom.c
dummy_cdrom_ioctl.c
)

View File

@@ -41,6 +41,7 @@
#include <86box/device.h>
#include <86box/gameport.h>
#include <86box/unix_sdl.h>
#include <86box/unix_osd.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/nvr.h>
@@ -52,6 +53,8 @@
#define __USE_GNU 1 /* shouldn't be done, yet it is */
#include <pthread.h>
extern SDL_Window *sdl_win;
static int first_use = 1;
static uint64_t StartingTime;
static uint64_t Frequency;
@@ -72,6 +75,10 @@ SDL_threadID eventthread;
static int exit_event = 0;
static int fullscreen_pending = 0;
// Two keys to be pressed together to open the OSD, variables to make them configurable in future
static uint16_t osd_open_first_key = SDL_SCANCODE_RCTRL;
static uint16_t osd_open_second_key = SDL_SCANCODE_F11;
static const uint16_t sdl_to_xt[0x200] = {
[SDL_SCANCODE_ESCAPE] = 0x01,
[SDL_SCANCODE_1] = 0x02,
@@ -291,7 +298,7 @@ plat_get_string(int i)
case STRING_MONITOR_SLEEP:
return L"Monitor in sleep mode";
case STRING_EDID_TOO_LARGE:
return "EDID file \"%ls\" is too large.";
return L"EDID file \"%ls\" is too large.";
}
return L"";
}
@@ -480,22 +487,24 @@ plat_remove(char *path)
remove(path);
}
void
ui_sb_update_icon_state(UNUSED(int tag), UNUSED(int state))
void ui_sb_update_icon_state(int tag, int state)
{
/* No-op. */
osd_ui_sb_update_icon_state(tag, state);
}
void
ui_sb_update_icon(UNUSED(int tag), UNUSED(int active))
void ui_sb_update_icon(int tag, int active)
{
/* No-op. */
osd_ui_sb_update_icon(tag, active);
}
void
ui_sb_update_icon_write(UNUSED(int tag), UNUSED(int active))
void ui_sb_update_icon_write(int tag, int active)
{
/* No-op. */
osd_ui_sb_update_icon_write(tag, active);
}
void ui_sb_update_icon_wp(int tag, int state)
{
osd_ui_sb_update_icon_wp(tag, state);
}
void
@@ -541,7 +550,6 @@ path_get_dirname(char *dest, const char *path)
*dest++ = *path++;
*dest = '\0';
}
volatile int cpu_thread_run = 1;
void
ui_sb_set_text_w(UNUSED(wchar_t *wstr))
@@ -561,6 +569,8 @@ strnicmp(const char *s1, const char *s2, size_t n)
return strncasecmp(s1, s2, n);
}
volatile int cpu_thread_run = 1;
void
main_thread(UNUSED(void *param))
{
@@ -574,15 +584,20 @@ main_thread(UNUSED(void *param))
// title_update = 1;
old_time = SDL_GetTicks();
drawits = frames = 0;
while (!is_quit && cpu_thread_run) {
while (!is_quit && cpu_thread_run)
{
/* See if it is time to run a frame of code. */
new_time = SDL_GetTicks();
#ifdef USE_GDBSTUB
if (gdbstub_next_asap && (drawits <= 0))
drawits = 10;
else
#endif
drawits += (new_time - old_time);
#else
drawits += (new_time - old_time);
#endif
old_time = new_time;
if (drawits > 0 && !dopause) {
/* Yes, so do one frame now. */
@@ -599,15 +614,18 @@ main_thread(UNUSED(void *param))
nvr_dosave = 0;
frames = 0;
}
} else /* Just so we dont overload the host OS. */
}
else /* Just so we dont overload the host OS. */
SDL_Delay(1);
/* If needed, handle a screen resize. */
if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) {
if (vid_resize & 2)
plat_resize(fixed_size_x, fixed_size_y, 0);
else
plat_resize(scrnsz_x, scrnsz_y, 0);
atomic_store(&doresize_monitors[0], 1);
}
}
@@ -760,8 +778,6 @@ ui_sb_set_ready(UNUSED(int ready))
/* No-op. */
}
char *xargv[512];
// From musl.
char *
local_strsep(char **str, const char *sep)
@@ -922,7 +938,7 @@ plat_get_vmm_dir(char *outbuf, const size_t len)
}
bool
process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc)
process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, char **xargv, int cmdargc)
{
bool err = false;
@@ -958,6 +974,7 @@ process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc)
fn[strlen(fn) - 1] = '\0';
return err;
}
char *(*f_readline)(const char *) = NULL;
int (*f_add_history)(const char *) = NULL;
void (*f_rl_callback_handler_remove)(void) = NULL;
@@ -968,11 +985,6 @@ void (*f_rl_callback_handler_remove)(void) = NULL;
# define LIBEDIT_LIBRARY "libedit.so"
#endif
void ui_sb_update_icon_wp(int tag, int state)
{
/* No-op */
}
uint32_t
timer_onesec(uint32_t interval, UNUSED(void *param))
{
@@ -981,67 +993,50 @@ timer_onesec(uint32_t interval, UNUSED(void *param))
}
void
monitor_thread(UNUSED(void *param))
unix_executeLine(char *line)
{
#ifndef USE_CLI
if (isatty(fileno(stdin)) && isatty(fileno(stdout))) {
char *line = NULL;
size_t n;
if (line) {
char *xargv[512];
int cmdargc = 0;
char *linecpy, *linespn;
printf("86Box monitor console.\n");
while (!exit_event) {
if (feof(stdin))
linecpy = linespn = strdup(line);
linecpy[strcspn(linecpy, "\r\n")] = 0;
if (!linecpy) {
return;
}
if (f_add_history)
f_add_history(linecpy);
memset(xargv, 0, sizeof(xargv));
while (1) {
xargv[cmdargc++] = local_strsep(&linespn, " ");
if (xargv[cmdargc - 1] == NULL || cmdargc >= 512)
break;
#ifdef ENABLE_READLINE
if (f_readline)
line = f_readline("(86Box) ");
else {
#endif
printf("(86Box) ");
(void) !getline(&line, &n, stdin);
#ifdef ENABLE_READLINE
}
#endif
if (line) {
int cmdargc = 0;
char *linecpy;
line[strcspn(line, "\r\n")] = '\0';
linecpy = strdup(line);
if (!linecpy) {
free(line);
line = NULL;
continue;
}
if (f_add_history)
f_add_history(line);
memset(xargv, 0, sizeof(xargv));
while (1) {
xargv[cmdargc++] = local_strsep(&linecpy, " ");
if (xargv[cmdargc - 1] == NULL || cmdargc >= 512)
break;
}
cmdargc--;
if (strncasecmp(xargv[0], "help", 4) == 0) {
printf(
"fddload <id> <filename> <wp> - Load floppy disk image into drive <id>.\n"
"cdload <id> <filename> - Load CD-ROM image into drive <id>.\n"
"rdiskload <id> <filename> <wp> - Load removable disk image into removable disk drive <id>.\n"
"cartload <id> <filename> <wp> - Load cartridge image into cartridge drive <id>.\n"
"moload <id> <filename> <wp> - Load MO image into MO drive <id>.\n\n"
"fddeject <id> - eject disk from floppy drive <id>.\n"
"cdeject <id> - eject disc from CD-ROM drive <id>.\n"
"rdiskeject <id> - eject removable disk image from removable disk drive <id>.\n"
"carteject <id> - eject cartridge from drive <id>.\n"
"moeject <id> - eject image from MO drive <id>.\n\n"
"hardreset - hard reset the emulated system.\n"
"pause - pause the the emulated system.\n"
"fullscreen - toggle fullscreen.\n"
"version - print version and license information.\n"
"exit - exit 86Box.\n");
} else if (strncasecmp(xargv[0], "exit", 4) == 0) {
exit_event = 1;
} else if (strncasecmp(xargv[0], "version", 7) == 0) {
}
cmdargc--;
if (strncasecmp(xargv[0], "help", 4) == 0) {
printf(
"fddload <id> <filename> <wp> - Load floppy disk image into drive <id>.\n"
"cdload <id> <filename> - Load CD-ROM image into drive <id>.\n"
"rdiskload <id> <filename> <wp> - Load removable disk image into removable disk drive <id>.\n"
"cartload <id> <filename> <wp> - Load cartridge image into cartridge drive <id>.\n"
"moload <id> <filename> <wp> - Load MO image into MO drive <id>.\n\n"
"fddeject <id> - eject disk from floppy drive <id>.\n"
"cdeject <id> - eject disc from CD-ROM drive <id>.\n"
"rdiskeject <id> - eject removable disk image from removable disk drive <id>.\n"
"carteject <id> - eject cartridge from drive <id>.\n"
"moeject <id> - eject image from MO drive <id>.\n\n"
"hardreset - hard reset the emulated system.\n"
"pause - pause the the emulated system.\n"
"fullscreen - toggle fullscreen.\n"
"version - print version and license information.\n"
"exit - exit 86Box.\n");
} else if (strncasecmp(xargv[0], "exit", 4) == 0) {
exit_event = 1;
} else if (strncasecmp(xargv[0], "version", 7) == 0) {
# ifndef EMU_GIT_HASH
# define EMU_GIT_HASH "0000000"
# endif
@@ -1064,169 +1059,191 @@ monitor_thread(UNUSED(void *param))
# define DYNAREC_STR "no dynarec"
# endif
printf(
"%s v%s [%s] [%s, %s]\n\n"
"An emulator of old computers\n"
"Authors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), "
"Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), "
"Tiseno100, reenigne, and others.\n"
"With previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n"
"Released under the GNU General Public License version 2 or later. See LICENSE for more information.\n",
EMU_NAME, EMU_VERSION_FULL, EMU_GIT_HASH, ARCH_STR, DYNAREC_STR);
} else if (strncasecmp(xargv[0], "fullscreen", 10) == 0) {
video_fullscreen = video_fullscreen ? 0 : 1;
fullscreen_pending = 1;
} else if (strncasecmp(xargv[0], "pause", 5) == 0) {
plat_pause(dopause ^ 1);
printf("%s", dopause ? "Paused.\n" : "Unpaused.\n");
} else if (strncasecmp(xargv[0], "hardreset", 9) == 0) {
pc_reset_hard();
} else if (strncasecmp(xargv[0], "cdload", 6) == 0 && cmdargc >= 3) {
uint8_t id;
bool err = false;
char fn[PATH_MAX];
printf(
"%s v%s [%s] [%s, %s]\n\n"
"An emulator of old computers\n"
"Authors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), "
"Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), "
"Tiseno100, reenigne, and others.\n"
"With previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n"
"Released under the GNU General Public License version 2 or later. See LICENSE for more information.\n",
EMU_NAME, EMU_VERSION_FULL, EMU_GIT_HASH, ARCH_STR, DYNAREC_STR);
} else if (strncasecmp(xargv[0], "fullscreen", 10) == 0) {
video_fullscreen = video_fullscreen ? 0 : 1;
fullscreen_pending = 1;
} else if (strncasecmp(xargv[0], "pause", 5) == 0) {
plat_pause(dopause ^ 1);
printf("%s", dopause ? "Paused.\n" : "Unpaused.\n");
} else if (strncasecmp(xargv[0], "hardreset", 9) == 0) {
pc_reset_hard();
} else if (strncasecmp(xargv[0], "cdload", 6) == 0 && cmdargc >= 3) {
uint8_t id;
bool err = false;
char fn[PATH_MAX];
if (!xargv[2] || !xargv[1]) {
free(line);
free(linecpy);
line = NULL;
continue;
if (!xargv[2] || !xargv[1]) {
free(linecpy);
return;
}
id = atoi(xargv[1]);
memset(fn, 0, sizeof(fn));
if (xargv[2][0] == '\'' || xargv[2][0] == '"') {
int curarg = 2;
for (curarg = 2; curarg < cmdargc; curarg++) {
if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) {
err = true;
fprintf(stderr, "Path name too long.\n");
}
id = atoi(xargv[1]);
memset(fn, 0, sizeof(fn));
if (xargv[2][0] == '\'' || xargv[2][0] == '"') {
int curarg = 2;
for (curarg = 2; curarg < cmdargc; curarg++) {
if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) {
err = true;
fprintf(stderr, "Path name too long.\n");
}
strcat(fn, xargv[curarg] + (xargv[curarg][0] == '\'' || xargv[curarg][0] == '"'));
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"') {
break;
}
strcat(fn, " ");
else
{
strcat(fn, xargv[curarg] + (xargv[curarg][0] == '\'' || xargv[curarg][0] == '"'));
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"') {
break;
}
} else {
if (strlen(xargv[2]) < PATH_MAX) {
strcpy(fn, xargv[2]);
} else {
fprintf(stderr, "Path name too long.\n");
}
}
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting disc into CD-ROM drive %hhu: %s\n", id, fn);
cdrom_mount(id, fn);
}
} else if (strncasecmp(xargv[0], "fddeject", 8) == 0 && cmdargc >= 2) {
floppy_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "cdeject", 8) == 0 && cmdargc >= 2) {
cdrom_mount(atoi(xargv[1]), "");
} else if (strncasecmp(xargv[0], "moeject", 8) == 0 && cmdargc >= 2) {
mo_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "carteject", 8) == 0 && cmdargc >= 2) {
cartridge_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "rdiskeject", 8) == 0 && cmdargc >= 2) {
rdisk_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "fddload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(line);
free(linecpy);
line = NULL;
continue;
}
err = process_media_commands_3(&id, fn, &wp, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting disk into floppy drive %c: %s\n", id + 'A', fn);
floppy_mount(id, fn, wp);
}
} else if (strncasecmp(xargv[0], "moload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(line);
free(linecpy);
line = NULL;
continue;
}
err = process_media_commands_3(&id, fn, &wp, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting into mo drive %hhu: %s\n", id, fn);
mo_mount(id, fn, wp);
}
} else if (strncasecmp(xargv[0], "cartload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(line);
free(linecpy);
line = NULL;
continue;
}
err = process_media_commands_3(&id, fn, &wp, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting tape into cartridge holder %hhu: %s\n", id, fn);
cartridge_mount(id, fn, wp);
}
} else if (strncasecmp(xargv[0], "rdiskload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(line);
free(linecpy);
line = NULL;
continue;
}
err = process_media_commands_3(&id, fn, &wp, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting disk into removable disk drive %c: %s\n", id + 'A', fn);
rdisk_mount(id, fn, wp);
strcat(fn, " ");
}
}
free(line);
free(linecpy);
line = NULL;
} else {
if (strlen(xargv[2]) < PATH_MAX) {
strncpy(fn, xargv[2], PATH_MAX-1);
} else {
fprintf(stderr, "Path name too long.\n");
}
}
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting disc into CD-ROM drive %hhu: %s\n", id, fn);
cdrom_mount(id, fn);
}
} else if (strncasecmp(xargv[0], "fddeject", 8) == 0 && cmdargc >= 2) {
floppy_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "cdeject", 8) == 0 && cmdargc >= 2) {
cdrom_mount(atoi(xargv[1]), "");
} else if (strncasecmp(xargv[0], "moeject", 8) == 0 && cmdargc >= 2) {
mo_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "carteject", 8) == 0 && cmdargc >= 2) {
cartridge_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "rdiskeject", 8) == 0 && cmdargc >= 2) {
rdisk_eject(atoi(xargv[1]));
} else if (strncasecmp(xargv[0], "fddload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(linecpy);
return;
}
err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting disk into floppy drive %c: %s\n", id + 'A', fn);
floppy_mount(id, fn, wp);
}
} else if (strncasecmp(xargv[0], "moload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(linecpy);
return;
}
err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting into mo drive %hhu: %s\n", id, fn);
mo_mount(id, fn, wp);
}
} else if (strncasecmp(xargv[0], "cartload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(linecpy);
return;
}
err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting tape into cartridge holder %hhu: %s\n", id, fn);
cartridge_mount(id, fn, wp);
}
} else if (strncasecmp(xargv[0], "rdiskload", 7) == 0 && cmdargc >= 4) {
uint8_t id;
uint8_t wp;
bool err = false;
char fn[PATH_MAX];
memset(fn, 0, sizeof(fn));
if (!xargv[2] || !xargv[1]) {
free(linecpy);
return;
}
err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc);
if (!err) {
if (fn[strlen(fn) - 1] == '\''
|| fn[strlen(fn) - 1] == '"')
fn[strlen(fn) - 1] = '\0';
printf("Inserting disk into removable disk drive %c: %s\n", id + 'A', fn);
rdisk_mount(id, fn, wp);
}
}
free(linecpy);
}
}
void
monitor_thread(UNUSED(void *param))
{
#ifndef USE_CLI
if (isatty(fileno(stdin)) && isatty(fileno(stdout))) {
char *line = NULL;
size_t n;
printf("86Box monitor console.\n");
while (!exit_event)
{
if (feof(stdin))
break;
#ifdef ENABLE_READLINE
if (f_readline)
line = f_readline("(86Box) ");
else {
#endif
printf("(86Box) ");
(void) !getline(&line, &n, stdin);
#ifdef ENABLE_READLINE
}
#endif
unix_executeLine(line);
free(line);
line = NULL;
}
}
#endif
@@ -1283,106 +1300,41 @@ main(int argc, char **argv)
plat_pause(0);
/* Initialize the rendering window, or fullscreen. */
do_start();
#ifndef USE_CLI
thread_create(monitor_thread, NULL);
#endif
SDL_AddTimer(1000, timer_onesec, NULL);
while (!is_quit) {
while (!is_quit)
{
static int mouse_inside = 0;
static int osd_first_key_pressed = 0;
static int flag_osd_open = 0;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
exit_event = 1;
break;
case SDL_MOUSEWHEEL:
while (SDL_PollEvent(&event))
{
if (flag_osd_open == 1)
{
// route almost everything to the OSD
switch (event.type)
{
case SDL_QUIT:
{
if (mouse_capture || video_fullscreen) {
if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
event.wheel.x *= -1;
event.wheel.y *= -1;
}
SDL_LockMutex(mousemutex);
mouse_set_z(event.wheel.y);
SDL_UnlockMutex(mousemutex);
}
exit_event = 1;
break;
}
case SDL_MOUSEMOTION:
{
if (mouse_capture || video_fullscreen) {
SDL_LockMutex(mousemutex);
mouse_scale(event.motion.xrel, event.motion.yrel);
SDL_UnlockMutex(mousemutex);
}
break;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
if ((event.button.button == SDL_BUTTON_LEFT)
&& !(mouse_capture || video_fullscreen)
&& event.button.state == SDL_RELEASED
&& mouse_inside) {
plat_mouse_capture(1);
break;
}
if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) {
plat_mouse_capture(0);
break;
}
if (mouse_capture || video_fullscreen) {
int buttonmask = 0;
switch (event.button.button) {
case SDL_BUTTON_LEFT:
buttonmask = 1;
break;
case SDL_BUTTON_RIGHT:
buttonmask = 2;
break;
case SDL_BUTTON_MIDDLE:
buttonmask = 4;
break;
case SDL_BUTTON_X1:
buttonmask = 8;
break;
case SDL_BUTTON_X2:
buttonmask = 16;
break;
}
SDL_LockMutex(mousemutex);
if (event.button.state == SDL_PRESSED)
mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask);
else
mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask);
SDL_UnlockMutex(mousemutex);
}
break;
}
case SDL_RENDER_DEVICE_RESET:
case SDL_RENDER_TARGETS_RESET:
case SDL_RENDER_DEVICE_RESET:
case SDL_RENDER_TARGETS_RESET:
{
extern void sdl_reinit_texture(void);
printf("reinit tex\n");
sdl_reinit_texture();
break;
}
case SDL_KEYDOWN:
case SDL_KEYUP:
{
uint16_t xtkey = 0;
switch (event.key.keysym.scancode) {
default:
xtkey = sdl_to_xt[event.key.keysym.scancode];
break;
}
keyboard_input(event.key.state == SDL_PRESSED, xtkey);
}
case SDL_WINDOWEVENT:
case SDL_WINDOWEVENT:
{
switch (event.window.event) {
case SDL_WINDOWEVENT_ENTER:
@@ -1392,9 +1344,190 @@ main(int argc, char **argv)
mouse_inside = 0;
break;
}
break;
}
default:
{
// route everything else
flag_osd_open = osd_handle(event);
if (flag_osd_open == 0)
{
// close it
osd_close(event);
}
break;
}
}
}
else
{
switch (event.type)
{
case SDL_QUIT:
exit_event = 1;
break;
case SDL_MOUSEWHEEL:
{
if (mouse_capture || video_fullscreen) {
if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
event.wheel.x *= -1;
event.wheel.y *= -1;
}
SDL_LockMutex(mousemutex);
mouse_set_z(event.wheel.y);
SDL_UnlockMutex(mousemutex);
}
break;
}
case SDL_MOUSEMOTION:
{
if (mouse_capture || video_fullscreen) {
SDL_LockMutex(mousemutex);
mouse_scale(event.motion.xrel, event.motion.yrel);
SDL_UnlockMutex(mousemutex);
}
break;
}
/* Touch events */
case SDL_FINGERDOWN:
{
// Trap these but ignore them for now
break;
}
case SDL_FINGERUP:
{
// Trap these but ignore them for now
break;
}
case SDL_FINGERMOTION:
{
// See SDL_TouchFingerEvent
if (mouse_capture || video_fullscreen) {
SDL_LockMutex(mousemutex);
// Real multiplier is the window size
int w, h;
SDL_GetWindowSize(sdl_win, &w, &h);
mouse_scale((int)(event.tfinger.dx * w), (int)(event.tfinger.dy * h));
SDL_UnlockMutex(mousemutex);
}
break;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
if ((event.button.button == SDL_BUTTON_LEFT)
&& !(mouse_capture || video_fullscreen)
&& event.button.state == SDL_RELEASED
&& mouse_inside) {
plat_mouse_capture(1);
break;
}
if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) {
plat_mouse_capture(0);
break;
}
if (mouse_capture || video_fullscreen) {
int buttonmask = 0;
switch (event.button.button) {
case SDL_BUTTON_LEFT:
buttonmask = 1;
break;
case SDL_BUTTON_RIGHT:
buttonmask = 2;
break;
case SDL_BUTTON_MIDDLE:
buttonmask = 4;
break;
case SDL_BUTTON_X1:
buttonmask = 8;
break;
case SDL_BUTTON_X2:
buttonmask = 16;
break;
default:
printf("Unknown mouse button %d\n", event.button.button);
}
SDL_LockMutex(mousemutex);
if (event.button.state == SDL_PRESSED)
mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask);
else
mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask);
SDL_UnlockMutex(mousemutex);
}
break;
}
case SDL_RENDER_DEVICE_RESET:
case SDL_RENDER_TARGETS_RESET:
{
extern void sdl_reinit_texture(void);
sdl_reinit_texture();
break;
}
case SDL_KEYDOWN:
case SDL_KEYUP:
{
uint16_t xtkey = 0;
if (event.key.keysym.scancode == osd_open_first_key)
{
if (event.type == SDL_KEYDOWN)
osd_first_key_pressed = 1;
else
osd_first_key_pressed = 0;
}
else if (osd_first_key_pressed && event.type == SDL_KEYDOWN && event.key.keysym.scancode == osd_open_second_key)
{
// open OSD!
flag_osd_open = osd_open(event);
// we can assume alt-gr has been released, tell this also to the virtual machine
osd_first_key_pressed = 0;
keyboard_input(0, sdl_to_xt[osd_open_first_key]);
break;
}
else
{
// invalidate osd_first_key_pressed is something happens between its keydown and keydown for G
osd_first_key_pressed = 0;
}
switch (event.key.keysym.scancode) {
default:
xtkey = sdl_to_xt[event.key.keysym.scancode];
break;
}
keyboard_input(event.key.state == SDL_PRESSED, xtkey);
break;
}
case SDL_WINDOWEVENT:
{
switch (event.window.event) {
case SDL_WINDOWEVENT_ENTER:
mouse_inside = 1;
break;
case SDL_WINDOWEVENT_LEAVE:
mouse_inside = 0;
break;
}
break;
}
default:
{
// printf("Unhandled SDL event: %d\n", event.type);
break;
}
}
}
}
if (blitreq) {
extern void sdl_blit(int x, int y, int w, int h);
sdl_blit(params.x, params.y, params.w, params.h);

View File

@@ -43,13 +43,14 @@ cassette_mount(char *fn, uint8_t wp)
memset(cassette_fname, 0, sizeof(cassette_fname));
cassette_ui_writeprot = wp;
pc_cas_set_fname(cassette, fn);
if (fn != NULL)
memcpy(cassette_fname, fn, MIN(511, strlen(fn)));
ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0);
#if 0
media_menu_update_cassette();
#endif
ui_sb_update_tip(SB_CASSETTE);
config_save();
}
@@ -58,11 +59,11 @@ cassette_eject(void)
{
pc_cas_set_fname(cassette, NULL);
memset(cassette_fname, 0x00, sizeof(cassette_fname));
ui_sb_update_icon_state(SB_CASSETTE, 1);
#if 0
media_menu_update_cassette();
#endif
ui_sb_update_tip(SB_CASSETTE);
config_save();
}
@@ -71,11 +72,11 @@ cartridge_mount(uint8_t id, char *fn, UNUSED(uint8_t wp))
{
cart_close(id);
cart_load(id, fn);
ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1);
#if 0
media_menu_update_cartridge(id);
#endif
ui_sb_update_tip(SB_CARTRIDGE | id);
config_save();
}
@@ -83,11 +84,11 @@ void
cartridge_eject(uint8_t id)
{
cart_close(id);
ui_sb_update_icon_state(SB_CARTRIDGE | id, 1);
#if 0
media_menu_update_cartridge(id);
#endif
ui_sb_update_tip(SB_CARTRIDGE | id);
config_save();
}
@@ -97,11 +98,11 @@ floppy_mount(uint8_t id, char *fn, uint8_t wp)
fdd_close(id);
ui_writeprot[id] = wp;
fdd_load(id, fn);
ui_sb_update_icon_state(SB_FLOPPY | id, strlen(floppyfns[id]) ? 0 : 1);
#if 0
media_menu_update_floppy(id);
#endif
ui_sb_update_tip(SB_FLOPPY | id);
config_save();
}
@@ -109,11 +110,11 @@ void
floppy_eject(uint8_t id)
{
fdd_close(id);
ui_sb_update_icon_state(SB_FLOPPY | id, 1);
#if 0
media_menu_update_floppy(id);
#endif
ui_sb_update_tip(SB_FLOPPY | id);
config_save();
}
@@ -128,34 +129,16 @@ plat_cdrom_ui_update(uint8_t id, UNUSED(uint8_t reload))
ui_sb_update_icon_state(SB_CDROM | id, 0);
}
#if 0
media_menu_update_cdrom(id);
#endif
ui_sb_update_tip(SB_CDROM | id);
}
void
cdrom_mount(uint8_t id, char *fn)
{
strcpy(cdrom[id].prev_image_path, cdrom[id].image_path);
if (cdrom[id].ops && cdrom[id].ops->close)
cdrom[id].ops->close(cdrom[id].local);
cdrom[id].ops = NULL;
memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path));
if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '\\'))
fn[strlen(fn) - 1] = '/';
image_open(&(cdrom[id]), fn);
/* Signal media change to the emulated machine. */
if (cdrom[id].insert)
cdrom[id].insert(cdrom[id].priv);
if (cdrom[id].image_path[0] == 0x00)
ui_sb_update_icon_state(SB_CDROM | id, 0);
else
ui_sb_update_icon_state(SB_CDROM | id, 1);
#if 0
media_menu_update_cdrom(id);
#endif
ui_sb_update_tip(SB_CDROM | id);
int ret = cdrom_load( &(cdrom[id]), fn, 0);
plat_cdrom_ui_update(id, 0);
config_save();
}
@@ -171,9 +154,7 @@ mo_eject(uint8_t id)
}
ui_sb_update_icon_state(SB_MO | id, 1);
#if 0
media_menu_update_mo(id);
#endif
ui_sb_update_tip(SB_MO | id);
config_save();
}
@@ -188,9 +169,7 @@ mo_mount(uint8_t id, char *fn, uint8_t wp)
mo_load(dev, fn, 0);
ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1);
#if 0
media_menu_update_mo(id);
#endif
ui_sb_update_tip(SB_MO | id);
config_save();
@@ -208,9 +187,6 @@ mo_reload(uint8_t id)
ui_sb_update_icon_state(SB_MO | id, 0);
}
#if 0
media_menu_update_mo(id);
#endif
ui_sb_update_tip(SB_MO | id);
config_save();
@@ -228,10 +204,9 @@ rdisk_eject(uint8_t id)
}
ui_sb_update_icon_state(SB_RDISK | id, 1);
#if 0
media_menu_update_rdisk(id);
#endif
ui_sb_update_tip(SB_RDISK | id);
config_save();
}
@@ -245,9 +220,7 @@ rdisk_mount(uint8_t id, char *fn, uint8_t wp)
rdisk_load(dev, fn, 0);
ui_sb_update_icon_state(SB_RDISK | id, strlen(rdisk_drives[id].image_path) ? 0 : 1);
#if 0
media_menu_update_rdisk(id);
#endif
ui_sb_update_tip(SB_RDISK | id);
config_save();
@@ -265,9 +238,6 @@ rdisk_reload(uint8_t id)
ui_sb_update_icon_state(SB_RDISK | id, 0);
}
#if 0
media_menu_update_rdisk(id);
#endif
ui_sb_update_tip(SB_RDISK | id);
config_save();

563
src/unix/unix_osd.c Normal file
View File

@@ -0,0 +1,563 @@
#include <SDL.h>
#include <SDL_messagebox.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/param.h>
/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */
#undef HAVE_STDARG_H
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/plat.h>
#include <86box/plat_dynld.h>
#include <86box/video.h>
#include <86box/ui.h>
#include <86box/version.h>
#include <86box/unix_sdl.h>
#include <86box/unix_osd.h>
#include <86box/unix_osd_font.h>
static int SCREEN_W = 640;
static int SCREEN_H = 480;
static int BOX_W = 240;
static int BOX_H = 160;
#define LINE_HEIGHT 16
#define TITLE_HEIGHT 16
#define CHAR_W 8
#define CHAR_H 8
// this makes the osd embeddable in the 86box main sdl loop
#define OSD_INSIDE_MAIN_LOOP
// interface to SDL environment
extern SDL_Window *sdl_win;
extern SDL_Renderer *sdl_render;
extern SDL_mutex *sdl_mutex;
// interface back to main unix monitor implementation
extern void unix_executeLine(char *line);
// interface to the currently set window title, this can't be seen normally in a fullscreen setup
extern wchar_t sdl_win_title[512];
char sdl_win_title_mb[512] = "";
static SDL_Texture *font_texture = NULL;
typedef enum {
STATE_MENU,
STATE_FILESELECT_FLOPPY,
STATE_FILESELECT_CD,
STATE_FILESELECT_RDISK,
STATE_FILESELECT_CART,
STATE_FILESELECT_MO
} AppState;
static const char *menu_items[] = {
"fddload - Load floppy disk image",
"cdload - Load CD-ROM image",
"rdiskload - Load removable disk image",
"cartload - Load cartridge image",
"moload - Load MO image",
"fddeject - eject disk from floppy drive",
"cdeject - eject disc from CD-ROM drive",
"rdiskeject - eject removable disk",
"carteject - eject cartridge",
"moeject - eject image from MO drive",
"hardreset - hard reset the emulated system",
// "pause - pause the the emulated system",
"fullscreen - toggle fullscreen",
"version - print version and license information",
"exit - exit 86Box",
"close OSD"
};
#define MENU_ITEMS (sizeof(menu_items) / sizeof(menu_items[0]))
// chars per cols and rows
static int font_cols = 16;
static int selected = 0;
static int file_selected = 0;
static int scroll_offset = 0;
static int osd_is_open = 0;
static AppState state = STATE_MENU;
static char files[100][1024];
static int file_count = 0;
static int max_visible = 0;
void reset_iso_files(void)
{
file_selected = 0;
scroll_offset = 0;
file_count = 0;
memset(files, 0, sizeof(files));
}
static int endswith(char *s1, char *mask)
{
int ss = strlen(s1);
int sm = strlen(mask);
return ss >= sm && strncasecmp(s1+ss-sm, mask, sm) == 0;
}
int load_iso_files(char *basedir, char files[][1024], int max_files, char *mask)
{
DIR *d;
struct dirent *dir;
int count = file_count;
d = opendir(basedir);
if (!d)
return file_count;
while ((dir = readdir(d)) != NULL && count < max_files)
{
if (endswith(dir->d_name, mask))
{
strcpy(files[count], basedir);
strcat(files[count], "/");
strcat(files[count], dir->d_name);
count++;
}
}
closedir(d);
return count;
}
void draw_text(SDL_Renderer *renderer, const char *text, int x, int y, SDL_Color color)
{
if (!font_texture)
return;
SDL_SetTextureColorMod(font_texture, color.r, color.g, color.b);
int i = 0;
while (text[i])
{
unsigned char c = text[i];
int tx = (c % font_cols) * CHAR_W;
int ty = (c / font_cols) * CHAR_H;
SDL_Rect src = {tx, ty, CHAR_W, CHAR_H};
SDL_Rect dst = {x + i * CHAR_W, y, CHAR_W, CHAR_H};
SDL_RenderCopy(renderer, font_texture, &src, &dst);
i++;
}
}
void draw_box_with_border(SDL_Renderer *renderer, SDL_Rect box)
{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderDrawRect(renderer, &box);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_Rect inner = {box.x + 2, box.y + 2, box.w - 4, box.h - 4};
SDL_RenderDrawRect(renderer, &inner);
SDL_SetRenderDrawColor(renderer, 0, 0, 128, 255);
SDL_RenderFillRect(renderer, &inner);
}
void draw_menu(SDL_Renderer *renderer, int selected)
{
int x0 = (SCREEN_W - BOX_W) / 2;
int y0 = (SCREEN_H - BOX_H) / 2;
SDL_Rect box = {x0, y0, BOX_W, BOX_H};
draw_box_with_border(renderer, box);
draw_text(renderer, "MAIN MENU", x0 + 20, y0 + 5, (SDL_Color){255,255,255,255});
wcstombs(sdl_win_title_mb, sdl_win_title, 256);
draw_text(renderer, sdl_win_title_mb, x0 + 120, y0 + 5, (SDL_Color){255,255,255,255});
for (int i = 0; i < MENU_ITEMS; i++)
{
int tx = x0 + 20;
int ty = y0 + TITLE_HEIGHT + i * LINE_HEIGHT;
SDL_Color textColor;
SDL_Rect bgRect = {tx - 5, ty - 2, BOX_W - 20, LINE_HEIGHT};
if (i == selected) {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderFillRect(renderer, &bgRect);
textColor = (SDL_Color){0, 0, 0, 255};
} else {
textColor = (SDL_Color){255, 255, 0, 255};
}
draw_text(renderer, menu_items[i], tx, ty, textColor);
}
#ifndef OSD_INSIDE_MAIN_LOOP
SDL_RenderPresent(renderer);
#endif
}
void draw_file_selector(SDL_Renderer *renderer,
char *title,
char files[][1024], int file_count,
int selected, int scroll_offset, int max_visible)
{
int x0 = (SCREEN_W - BOX_W) / 2;
int y0 = (SCREEN_H - BOX_H) / 2;
SDL_Rect box = {x0, y0, BOX_W, BOX_H};
draw_box_with_border(renderer, box);
draw_text(renderer, title, x0 + 20, y0 + 5, (SDL_Color){255,255,255,255});
if (file_count == 0) {
draw_text(renderer, "No files.",
x0 + 20, y0 + TITLE_HEIGHT + 10,
(SDL_Color){255, 255, 0, 255});
} else {
for (int i = 0; i < max_visible && (i + scroll_offset) < file_count; i++) {
int index = i + scroll_offset;
int tx = x0 + 20;
int ty = y0 + TITLE_HEIGHT + i * LINE_HEIGHT;
SDL_Color textColor;
SDL_Rect bgRect = {tx - 5, ty - 2, 200, LINE_HEIGHT};
if (index == selected) {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderFillRect(renderer, &bgRect);
textColor = (SDL_Color){0, 0, 0, 255};
} else {
textColor = (SDL_Color){255, 255, 0, 255};
}
draw_text(renderer, files[index], tx, ty, textColor);
}
}
#ifndef OSD_INSIDE_MAIN_LOOP
SDL_RenderPresent(renderer);
#endif
}
void osd_init(void)
{
// debug: fprintf(stderr, "OSD INIT\n");
if (font_texture == NULL)
{
// debug: fprintf(stderr, "OSD INIT FONT\n");
// Carica font bitmap (font.bmp 128x128, 16x16 caratteri, 8x8 ciascuno)
SDL_RWops *rwop = SDL_RWFromConstMem(_________font_bmp, _________font_bmp_len);
if (!rwop)
{
fprintf(stderr, "Cannot create a new SDL RW stream: %s\n", SDL_GetError());
return;
}
// auto-closes the stream
SDL_Surface *font_surface = SDL_LoadBMP_RW(rwop, 1);
if (!font_surface) {
fprintf(stderr, "Cannot create a surface using RW stream: %s\n", SDL_GetError());
return;
}
// Imposta trasparenza sul nero puro
SDL_SetColorKey(font_surface, SDL_TRUE, SDL_MapRGB(font_surface->format, 0, 0, 0));
font_texture = SDL_CreateTextureFromSurface(sdl_render, font_surface);
SDL_FreeSurface(font_surface);
}
}
void osd_deinit(void)
{
// nothing to do
// debug: fprintf(stderr, "OSD DEINIT\n");
// will be implicitly freed on exit
// SDL_DestroyTexture(font_texture);
font_texture = NULL;
}
int osd_open(SDL_Event event)
{
// ok opened
// debug: fprintf(stderr, "OSD OPEN\n");
SDL_GetWindowSize(sdl_win, &SCREEN_W, &SCREEN_H);
BOX_W = (SCREEN_W / 4) * 3;
BOX_H = (SCREEN_H / 4) * 3;
max_visible = (BOX_H - TITLE_HEIGHT) / LINE_HEIGHT;
osd_is_open = 1;
return 1;
}
int osd_close(SDL_Event event)
{
// ok closed
// debug: fprintf(stderr, "OSD CLOSE\n");
osd_is_open = 0;
return 1;
}
static void osd_cmd_run(char *c)
{
char *l = calloc(strlen(c)+2, 1);
strcpy(l, c);
unix_executeLine(l);
free(l);
}
void osd_present(void)
{
// shortcut
if (!osd_is_open)
return;
#ifndef OSD_INSIDE_MAIN_LOOP
SDL_LockMutex(sdl_mutex);
#endif
if (state == STATE_MENU) {
draw_menu(sdl_render, selected);
}
else if (state == STATE_FILESELECT_FLOPPY) {
draw_file_selector(sdl_render, "SELECT FLOPPY IMAGE", files, file_count, file_selected, scroll_offset, max_visible);
}
else if (state == STATE_FILESELECT_CD) {
draw_file_selector(sdl_render, "SELECT CD ISO IMAGE", files, file_count, file_selected, scroll_offset, max_visible);
}
else if (state == STATE_FILESELECT_RDISK) {
draw_file_selector(sdl_render, "SELECT REMOVABLE DISK IMAGE", files, file_count, file_selected, scroll_offset, max_visible);
}
else if (state == STATE_FILESELECT_CART) {
draw_file_selector(sdl_render, "SELECT CARTRIDGE IMAGE", files, file_count, file_selected, scroll_offset, max_visible);
}
else if (state == STATE_FILESELECT_MO) {
draw_file_selector(sdl_render, "SELECT MO IMAGE", files, file_count, file_selected, scroll_offset, max_visible);
}
#ifndef OSD_INSIDE_MAIN_LOOP
SDL_UnlockMutex(sdl_mutex);
#endif
}
int osd_handle(SDL_Event event)
{
// debug: fprintf(stderr, "OSD HANDLE\n");
if (event.type == SDL_KEYUP)
{
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
if (state == STATE_MENU)
{
// Close the OSD
// debug: fprintf(stderr, "OSD HANDLE: escape\n");
return 0;
}
else
{
// Back to Main and keep it open
state = STATE_MENU;
return 1;
}
}
if (state == STATE_MENU)
{
switch (event.key.keysym.sym)
{
case SDLK_UP:
selected = (selected - 1 + MENU_ITEMS) % MENU_ITEMS;
break;
case SDLK_DOWN:
selected = (selected + 1) % MENU_ITEMS;
break;
case SDLK_RETURN:
case SDLK_KP_ENTER:
switch (selected)
{
case 0 : // "fddload - Load floppy disk image",
reset_iso_files();
file_count = load_iso_files(".", files, 100, ".img");
file_count = load_iso_files("/mnt", files, 100, ".img");
file_count = load_iso_files("/mnt/usbkey", files, 100, ".img");
state = STATE_FILESELECT_FLOPPY;
break;
case 1 : // "cdload - Load CD-ROM image",
reset_iso_files();
file_count = load_iso_files(".", files, 100, ".iso");
file_count = load_iso_files("/mnt", files, 100, ".iso");
file_count = load_iso_files("/mnt/usbkey", files, 100, ".iso");
state = STATE_FILESELECT_CD;
break;
case 2 : // "rdiskload - Load removable disk image",
reset_iso_files();
file_count = load_iso_files(".", files, 100, ".img");
file_count = load_iso_files("/mnt", files, 100, ".img");
file_count = load_iso_files("/mnt/usbkey", files, 100, ".img");
state = STATE_FILESELECT_RDISK;
break;
case 3 : // "cartload - Load cartridge image",
reset_iso_files();
file_count = load_iso_files(".", files, 100, ".img");
file_count = load_iso_files("/mnt", files, 100, ".img");
file_count = load_iso_files("/mnt/usbkey", files, 100, ".img");
state = STATE_FILESELECT_CART;
break;
case 4 : // "moload - Load MO image",
reset_iso_files();
file_count = load_iso_files(".", files, 100, ".img");
file_count = load_iso_files("/mnt", files, 100, ".img");
file_count = load_iso_files("/mnt/usbkey", files, 100, ".img");
state = STATE_FILESELECT_MO;
break;
case 5 : // "fddeject - eject disk from floppy drive",
osd_cmd_run("fddeject 0");
return 0;
case 6 : // "cdeject - eject disc from CD-ROM drive",
osd_cmd_run("cdeject 0");
return 0;
case 7 : // "rdiskeject - eject removable disk",
osd_cmd_run("rdiskeject 0");
return 0;
case 8 : // "carteject - eject cartridge",
osd_cmd_run("carteject 0");
return 0;
case 9 : // "moeject - eject image from MO drive",
osd_cmd_run("moeject 0");
return 0;
case 10 : // "hardreset - hard reset the emulated system",
osd_cmd_run("hardreset");
return 0;
/* better not pause ourself, we will be unable to get out of it
case 11 : // "pause - pause the the emulated system",
osd_cmd_run("pause");
return 0;
*/
case 11 : // "fullscreen - toggle fullscreen",
osd_cmd_run("fullscreen");
return 0;
case 12 : // "version - print version and license information",
osd_cmd_run("version");
return 0;
case 13 : // "exit - exit 86Box",
osd_cmd_run("exit");
return 0;
case 14 : // "close OSD"
// return zero does directly close the OSD
return 0;
}
break;
}
}
else if (state == STATE_FILESELECT_FLOPPY || state == STATE_FILESELECT_CD || state == STATE_FILESELECT_RDISK || state == STATE_FILESELECT_CART || state == STATE_FILESELECT_MO)
{
if (file_count == 0)
{
// no files, there is nothing else to do
if (event.key.keysym.sym == SDLK_ESCAPE) {
state = STATE_MENU;
}
}
else
{
switch (event.key.keysym.sym) {
case SDLK_UP:
if (file_selected > 0) {
file_selected--;
if (file_selected < scroll_offset) {
scroll_offset--;
}
}
break;
case SDLK_DOWN:
if (file_selected < file_count - 1) {
file_selected++;
if (file_selected >= scroll_offset + max_visible) {
scroll_offset++;
}
}
break;
case SDLK_RETURN:
case SDLK_KP_ENTER:
{
char cmd[1280] = "";
if (state == STATE_FILESELECT_FLOPPY)
sprintf(cmd, "fddload 0 %s 0", files[file_selected]);
if (state == STATE_FILESELECT_CD)
sprintf(cmd, "cdload 0 %s", files[file_selected]);
if (state == STATE_FILESELECT_RDISK)
sprintf(cmd, "rdiskload 0 %s 0", files[file_selected]);
if (state == STATE_FILESELECT_CART)
sprintf(cmd, "cartload 0 %s 0", files[file_selected]);
if (state == STATE_FILESELECT_MO)
sprintf(cmd, "moload 0 %s 0", files[file_selected]);
unix_executeLine(cmd);
state = STATE_MENU;
}
return 0;
case SDLK_ESCAPE:
state = STATE_MENU;
break;
}
}
}
}
// Keep it open
return 1;
}
void osd_ui_sb_update_icon_state(UNUSED(int tag), UNUSED(int state))
{
}
void osd_ui_sb_update_icon(UNUSED(int tag), UNUSED(int active))
{
}
void osd_ui_sb_update_icon_write(UNUSED(int tag), UNUSED(int active))
{
}
void osd_ui_sb_update_icon_wp(UNUSED(int tag), UNUSED(int state))
{
}

View File

@@ -16,6 +16,7 @@
#include <86box/video.h>
#include <86box/ui.h>
#include <86box/version.h>
#include <86box/unix_osd.h>
#include <86box/unix_sdl.h>
#define RENDERER_FULL_SCREEN 1
@@ -45,7 +46,7 @@ static int cur_wy = 0;
static int cur_ww = 0;
static int cur_wh = 0;
static volatile int sdl_enabled = 1;
static SDL_mutex *sdl_mutex = NULL;
SDL_mutex *sdl_mutex = NULL;
int mouse_capture;
int title_set = 0;
int resize_pending = 0;
@@ -189,6 +190,9 @@ sdl_real_blit(SDL_Rect *r_src)
if (ret)
fprintf(stderr, "SDL: unable to copy texture to renderer (%s)\n", SDL_GetError());
// give the osd an opportunity to draw itself
osd_present();
SDL_RenderPresent(sdl_render);
}
@@ -214,6 +218,7 @@ sdl_blit(int x, int y, int w, int h)
sdl_resize(resize_w, resize_h);
resize_pending = 0;
}
r_src.x = x;
r_src.y = y;
r_src.w = w;
@@ -314,6 +319,7 @@ sdl_select_best_hw_driver(void)
void
sdl_reinit_texture(void)
{
osd_deinit();
sdl_destroy_texture();
if (sdl_flags & RENDERER_HARDWARE) {
@@ -324,6 +330,7 @@ sdl_reinit_texture(void)
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
osd_init();
}
void
@@ -412,6 +419,10 @@ sdl_init_common(int flags)
return (0);
}
// Ensure mouse and touchpads behaves the same for us, dunno if these really do something
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "1");
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "1");
if (flags & RENDERER_HARDWARE) {
if (flags & RENDERER_OPENGL) {
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL");

View File

@@ -1975,9 +1975,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
break;
case 0x8190:
virge->streams.sec_ctrl = val;
virge->streams.dda_horiz_accumulator = val & 0xfff;
if (val & 0x1000)
virge->streams.dda_horiz_accumulator |= ~0xfff;
virge->streams.dda_horiz_accumulator = val & 0x7ff;
if (val & 0x800)
virge->streams.dda_horiz_accumulator |= ~0x7ff;
virge->streams.sdif = (val >> 24) & 7;
break;
@@ -1990,9 +1990,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
if (val & 0x800)
virge->streams.k1_horiz_scale |= ~0x7ff;
virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff;
if ((val >> 16) & 0x800)
virge->streams.k2_horiz_scale |= ~0x7ff;
virge->streams.k2_horiz_scale = (val >> 16) & 0x3ff;
if ((val >> 16) & 0x400)
virge->streams.k2_horiz_scale |= ~0x3ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
@@ -2048,14 +2048,14 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
virge->streams.k1_vert_scale |= ~0x7ff;
break;
case 0x81e4:
virge->streams.k2_vert_scale = val & 0x7ff;
if (val & 0x800)
virge->streams.k2_vert_scale |= ~0x7ff;
virge->streams.k2_vert_scale = val & 0x3ff;
if (val & 0x400)
virge->streams.k2_vert_scale |= ~0x3ff;
break;
case 0x81e8:
virge->streams.dda_vert_accumulator = val & 0xfff;
if (val & 0x1000)
virge->streams.dda_vert_accumulator |= ~0xfff;
virge->streams.dda_vert_accumulator = val & 0x7ff;
if (val & 0x800)
virge->streams.dda_vert_accumulator |= ~0x7ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;