Initial Linux/Unix code
This commit is contained in:
parent
a0c8f9aa9e
commit
1b93e8e989
4
.gitignore
vendored
4
.gitignore
vendored
@ -10,4 +10,6 @@ src/NUL
|
||||
src/nvr/
|
||||
src/roms/
|
||||
/.vs
|
||||
/CMakeUserPresets.json
|
||||
/CMakeUserPresets.json
|
||||
/build
|
||||
/.vscode
|
||||
|
@ -123,4 +123,9 @@ add_subdirectory(sio)
|
||||
add_subdirectory(scsi)
|
||||
add_subdirectory(sound)
|
||||
add_subdirectory(video)
|
||||
add_subdirectory(win)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
add_subdirectory(win)
|
||||
else()
|
||||
add_subdirectory(unix)
|
||||
target_link_libraries(86Box glib-2.0)
|
||||
endif()
|
||||
|
12
src/include/86box/unix_sdl.h
Normal file
12
src/include/86box/unix_sdl.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _UNIX_SDL_H
|
||||
#define _UNIX_SDL_H
|
||||
extern void sdl_close(void);
|
||||
extern int sdl_inits();
|
||||
extern int sdl_inith();
|
||||
extern int sdl_initho();
|
||||
extern int sdl_pause(void);
|
||||
extern void sdl_resize(int x, int y);
|
||||
extern void sdl_enable(int enable);
|
||||
extern void sdl_set_fs(int fs);
|
||||
extern void sdl_reload(void);
|
||||
#endif
|
@ -17,4 +17,8 @@ add_library(slirp STATIC tinyglib.c arp_table.c bootp.c cksum.c dnssearch.c if.c
|
||||
ip_input.c ip_output.c mbuf.c misc.c sbuf.c slirp.c socket.c tcp_input.c
|
||||
tcp_output.c tcp_subr.c tcp_timer.c udp.c util.c version.c)
|
||||
|
||||
target_link_libraries(slirp wsock32 iphlpapi)
|
||||
#target_link_libraries(slirp wsock32 iphlpapi)
|
||||
#target_link_libraries(slirp)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
target_link_libraries(wsock32 iphlpapi)
|
||||
endif()
|
||||
|
5
src/unix/CMakeLists.txt
Normal file
5
src/unix/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
add_library(plat STATIC unix_thread.c unix_midi.c)
|
||||
add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c)
|
||||
target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64)
|
||||
target_link_libraries(ui dl)
|
||||
target_link_libraries(plat pthread)
|
502
src/unix/unix.c
Normal file
502
src/unix/unix.c
Normal file
@ -0,0 +1,502 @@
|
||||
#ifdef __linux__
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#define _LARGEFILE64_SOURCE 1
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <dlfcn.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_dynld.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/unix_sdl.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/unix_sdl.h>
|
||||
static int first_use = 1;
|
||||
static uint64_t StartingTime;
|
||||
static uint64_t Frequency;
|
||||
int rctrl_is_lalt;
|
||||
int update_icons;
|
||||
int kbd_req_capture;
|
||||
int hide_status_bar;
|
||||
int fixed_size_x = 640;
|
||||
int fixed_size_y = 480;
|
||||
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
|
||||
joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
int joysticks_present;
|
||||
SDL_mutex *blitmtx;
|
||||
|
||||
typedef struct sdl_blit_params
|
||||
{
|
||||
int x, y, y1, y2, w, h;
|
||||
} sdl_blit_params;
|
||||
|
||||
sdl_blit_params params = { 0, 0, 0, 0, 0, 0 };
|
||||
int blitreq = 0;
|
||||
|
||||
void* dynld_module(const char *name, dllimp_t *table)
|
||||
{
|
||||
dllimp_t* imp;
|
||||
void* modhandle = dlopen(name, RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (modhandle)
|
||||
{
|
||||
for (imp = table; imp->name != NULL; imp++)
|
||||
{
|
||||
if ((imp->func = dlsym(modhandle, imp->name)) == NULL)
|
||||
{
|
||||
dlclose(modhandle);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return modhandle;
|
||||
}
|
||||
|
||||
void
|
||||
plat_tempfile(char *bufp, char *prefix, char *suffix)
|
||||
{
|
||||
struct tm* calendertime;
|
||||
struct timeval t;
|
||||
time_t curtime;
|
||||
|
||||
if (prefix != NULL)
|
||||
sprintf(bufp, "%s-", prefix);
|
||||
else
|
||||
strcpy(bufp, "");
|
||||
gettimeofday(&t, NULL);
|
||||
curtime = time(NULL);
|
||||
calendertime = localtime(&curtime);
|
||||
sprintf(&bufp[strlen(bufp)], "%d%02d%02d-%02d%02d%02d-%03d%s", calendertime->tm_year, calendertime->tm_mon, calendertime->tm_mday, calendertime->tm_hour, calendertime->tm_min, calendertime->tm_sec, t.tv_usec / 1000, suffix);
|
||||
}
|
||||
|
||||
int
|
||||
plat_getcwd(char *bufp, int max)
|
||||
{
|
||||
return getcwd(bufp, max) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
plat_chdir(char* str)
|
||||
{
|
||||
return chdir(str);
|
||||
}
|
||||
|
||||
void dynld_close(void *handle)
|
||||
{
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
wchar_t* plat_get_string(int i)
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
|
||||
FILE *
|
||||
plat_fopen(const char *path, const char *mode)
|
||||
{
|
||||
return fopen(path, mode);
|
||||
}
|
||||
|
||||
FILE *
|
||||
plat_fopen64(const char *path, const char *mode)
|
||||
{
|
||||
return fopen(path, mode);
|
||||
}
|
||||
|
||||
int
|
||||
plat_path_abs(char *path)
|
||||
{
|
||||
return path[0] == '/';
|
||||
}
|
||||
|
||||
void
|
||||
plat_path_slash(char *path)
|
||||
{
|
||||
if ((path[strlen(path)-1] != '/')) {
|
||||
strcat(path, "/");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
plat_put_backslash(char *s)
|
||||
{
|
||||
int c = strlen(s) - 1;
|
||||
|
||||
if (s[c] != '/')
|
||||
s[c] = '/';
|
||||
}
|
||||
|
||||
/* Return the last element of a pathname. */
|
||||
char *
|
||||
plat_get_basename(const char *path)
|
||||
{
|
||||
int c = (int)strlen(path);
|
||||
|
||||
while (c > 0) {
|
||||
if (path[c] == '/')
|
||||
return((char *)&path[c]);
|
||||
c--;
|
||||
}
|
||||
|
||||
return((char *)path);
|
||||
}
|
||||
char *
|
||||
plat_get_filename(char *s)
|
||||
{
|
||||
int c = strlen(s) - 1;
|
||||
|
||||
while (c > 0) {
|
||||
if (s[c] == '/' || s[c] == '\\')
|
||||
return(&s[c+1]);
|
||||
c--;
|
||||
}
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
plat_get_extension(char *s)
|
||||
{
|
||||
int c = strlen(s) - 1;
|
||||
|
||||
if (c <= 0)
|
||||
return(s);
|
||||
|
||||
while (c && s[c] != '.')
|
||||
c--;
|
||||
|
||||
if (!c)
|
||||
return(&s[strlen(s)]);
|
||||
|
||||
return(&s[c+1]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plat_append_filename(char *dest, const char *s1, const char *s2)
|
||||
{
|
||||
strcpy(dest, s1);
|
||||
plat_path_slash(dest);
|
||||
strcat(dest, s2);
|
||||
}
|
||||
|
||||
int
|
||||
plat_dir_check(char *path)
|
||||
{
|
||||
struct stat dummy;
|
||||
if (stat(path, &dummy) < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return S_ISDIR(dummy.st_mode);
|
||||
}
|
||||
|
||||
int
|
||||
plat_dir_create(char *path)
|
||||
{
|
||||
return mkdir(path, S_IRWXU);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
plat_timer_read(void)
|
||||
{
|
||||
return SDL_GetPerformanceCounter();
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
plat_get_ticks_common(void)
|
||||
{
|
||||
uint64_t EndingTime, ElapsedMicroseconds;
|
||||
if (first_use) {
|
||||
Frequency = SDL_GetPerformanceFrequency();
|
||||
StartingTime = SDL_GetPerformanceCounter();
|
||||
first_use = 0;
|
||||
}
|
||||
EndingTime = SDL_GetPerformanceCounter();
|
||||
ElapsedMicroseconds = ((EndingTime - StartingTime) * 1000000) / Frequency;
|
||||
return ElapsedMicroseconds;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
plat_get_ticks(void)
|
||||
{
|
||||
return (uint32_t)(plat_get_ticks_common() / 1000);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
plat_get_micro_ticks(void)
|
||||
{
|
||||
return (uint32_t)plat_get_ticks_common();
|
||||
}
|
||||
|
||||
void plat_remove(char* path)
|
||||
{
|
||||
remove(path);
|
||||
}
|
||||
|
||||
void
|
||||
ui_sb_update_icon_state(int tag, int state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ui_sb_update_icon(int tag, int active)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
plat_delay_ms(uint32_t count)
|
||||
{
|
||||
SDL_Delay(count);
|
||||
}
|
||||
|
||||
void
|
||||
ui_sb_update_tip(int arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ui_sb_update_panes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
plat_get_dirname(char *dest, const char *path)
|
||||
{
|
||||
int c = (int)strlen(path);
|
||||
char *ptr;
|
||||
|
||||
ptr = (char *)path;
|
||||
|
||||
while (c > 0) {
|
||||
if (path[c] == '/' || path[c] == '\\') {
|
||||
ptr = (char *)&path[c];
|
||||
break;
|
||||
}
|
||||
c--;
|
||||
}
|
||||
|
||||
/* Copy to destination. */
|
||||
while (path < ptr)
|
||||
*dest++ = *path++;
|
||||
*dest = '\0';
|
||||
}
|
||||
volatile int cpu_thread_run = 1;
|
||||
void ui_sb_set_text_w(wchar_t *wstr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int stricmp(const char* s1, const char* s2)
|
||||
{
|
||||
return strcasecmp(s1, s2);
|
||||
}
|
||||
|
||||
int strnicmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
return strncasecmp(s1, s2, n);
|
||||
}
|
||||
|
||||
void
|
||||
main_thread(void *param)
|
||||
{
|
||||
uint32_t old_time, new_time;
|
||||
int drawits, frames;
|
||||
|
||||
framecountx = 0;
|
||||
//title_update = 1;
|
||||
old_time = SDL_GetTicks();
|
||||
drawits = frames = 0;
|
||||
while (!is_quit && cpu_thread_run) {
|
||||
/* See if it is time to run a frame of code. */
|
||||
new_time = SDL_GetTicks();
|
||||
drawits += (new_time - old_time);
|
||||
old_time = new_time;
|
||||
if (drawits > 0 && !dopause) {
|
||||
/* Yes, so do one frame now. */
|
||||
drawits -= 10;
|
||||
if (drawits > 50)
|
||||
drawits = 0;
|
||||
|
||||
/* Run a block of code. */
|
||||
pc_run();
|
||||
|
||||
/* Every 200 frames we save the machine status. */
|
||||
if (++frames >= 200 && nvr_dosave) {
|
||||
nvr_save();
|
||||
nvr_dosave = 0;
|
||||
frames = 0;
|
||||
}
|
||||
} else /* Just so we dont overload the host OS. */
|
||||
SDL_Delay(1);
|
||||
|
||||
/* If needed, handle a screen resize. */
|
||||
if (doresize && !video_fullscreen && !is_quit) {
|
||||
if (vid_resize & 2)
|
||||
plat_resize(fixed_size_x, fixed_size_y);
|
||||
else
|
||||
plat_resize(scrnsz_x, scrnsz_y);
|
||||
doresize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
is_quit = 1;
|
||||
}
|
||||
|
||||
thread_t* thMain = NULL;
|
||||
|
||||
void mouse_poll()
|
||||
{}
|
||||
|
||||
void
|
||||
do_start(void)
|
||||
{
|
||||
/* We have not stopped yet. */
|
||||
is_quit = 0;
|
||||
|
||||
/* Initialize the high-precision timer. */
|
||||
SDL_InitSubSystem(SDL_INIT_TIMER);
|
||||
timer_freq = SDL_GetPerformanceFrequency();
|
||||
|
||||
/* Start the emulator, really. */
|
||||
thMain = thread_create(main_thread, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
do_stop(void)
|
||||
{
|
||||
/* Claim the video blitter. */
|
||||
startblit();
|
||||
|
||||
sdl_close();
|
||||
|
||||
pc_close(thMain);
|
||||
|
||||
thMain = NULL;
|
||||
}
|
||||
|
||||
int ui_msgbox(int flags, void *message)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ui_msgbox_header(int flags, void *message, void* header)
|
||||
{
|
||||
// Parameters that are passed will crash the program so keep these off for the time being.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plat_get_exe_name(char *s, int size)
|
||||
{
|
||||
char* basepath = SDL_GetBasePath();
|
||||
snprintf(s, size, "%s/86box", basepath);
|
||||
}
|
||||
|
||||
void
|
||||
plat_power_off(void)
|
||||
{
|
||||
confirm_exit = 0;
|
||||
nvr_save();
|
||||
config_save();
|
||||
|
||||
/* Deduct a sufficiently large number of cycles that no instructions will
|
||||
run before the main thread is terminated */
|
||||
cycles -= 99999999;
|
||||
|
||||
cpu_thread_run = 0;
|
||||
}
|
||||
|
||||
wchar_t* ui_sb_bugui(wchar_t *str)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
extern void sdl_blit(int x, int y, int y1, int y2, int w, int h);
|
||||
|
||||
void ui_window_title(wchar_t* str) {}
|
||||
void ui_sb_set_ready(int ready) {}
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
SDL_Init(0);
|
||||
pc_init(argc, argv);
|
||||
if (! pc_init_modules()) {
|
||||
fprintf(stderr, "No ROMs found.\n");
|
||||
SDL_Quit();
|
||||
return 6;
|
||||
}
|
||||
blitmtx = SDL_CreateMutex();
|
||||
if (!blitmtx)
|
||||
{
|
||||
fprintf(stderr, "Failed to create blit mutex: %s", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
sdl_initho();
|
||||
|
||||
if (start_in_fullscreen)
|
||||
sdl_set_fs(1);
|
||||
|
||||
/* Fire up the machine. */
|
||||
pc_reset_hard_init();
|
||||
|
||||
/* Set the PAUSE mode depending on the renderer. */
|
||||
//plat_pause(0);
|
||||
|
||||
/* Initialize the rendering window, or fullscreen. */
|
||||
|
||||
|
||||
do_start();
|
||||
while (!is_quit)
|
||||
{
|
||||
if (SDL_PollEvent(&event))
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
do_stop();
|
||||
break;
|
||||
|
||||
}
|
||||
if (blitreq)
|
||||
{
|
||||
extern void sdl_blit(int x, int y, int y1, int y2, int w, int h);
|
||||
sdl_blit(params.x, params.y, params.y1, params.y2, params.w, params.h);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_DestroyMutex(blitmtx);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
char* plat_vidapi_name(int i)
|
||||
{
|
||||
return "default";
|
||||
}
|
||||
void joystick_init(void) {}
|
||||
void joystick_close(void) {}
|
||||
void joystick_process(void) {}
|
||||
void startblit()
|
||||
{
|
||||
SDL_LockMutex(blitmtx);
|
||||
}
|
||||
|
||||
void endblit()
|
||||
{
|
||||
SDL_UnlockMutex(blitmtx);
|
||||
}
|
264
src/unix/unix_cdrom.c
Normal file
264
src/unix/unix_cdrom.c
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Handle the platform-side of CDROM/ZIP/MO drives.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/cartridge.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/zip.h>
|
||||
#include <86box/scsi_disk.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
|
||||
|
||||
|
||||
void
|
||||
cassette_mount(char *fn, uint8_t wp)
|
||||
{
|
||||
pc_cas_set_fname(cassette, NULL);
|
||||
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);
|
||||
//media_menu_update_cassette();
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cassette_eject(void)
|
||||
{
|
||||
pc_cas_set_fname(cassette, NULL);
|
||||
memset(cassette_fname, 0x00, sizeof(cassette_fname));
|
||||
ui_sb_update_icon_state(SB_CASSETTE, 1);
|
||||
//media_menu_update_cassette();
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cartridge_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
cart_close(id);
|
||||
cart_load(id, fn);
|
||||
ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1);
|
||||
//media_menu_update_cartridge(id);
|
||||
ui_sb_update_tip(SB_CARTRIDGE | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cartridge_eject(uint8_t id)
|
||||
{
|
||||
cart_close(id);
|
||||
ui_sb_update_icon_state(SB_CARTRIDGE | id, 1);
|
||||
//media_menu_update_cartridge(id);
|
||||
ui_sb_update_tip(SB_CARTRIDGE | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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);
|
||||
//media_menu_update_floppy(id);
|
||||
ui_sb_update_tip(SB_FLOPPY | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
floppy_eject(uint8_t id)
|
||||
{
|
||||
fdd_close(id);
|
||||
ui_sb_update_icon_state(SB_FLOPPY | id, 1);
|
||||
//media_menu_update_floppy(id);
|
||||
ui_sb_update_tip(SB_FLOPPY | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plat_cdrom_ui_update(uint8_t id, uint8_t reload)
|
||||
{
|
||||
cdrom_t *drv = &cdrom[id];
|
||||
|
||||
if (drv->host_drive == 0) {
|
||||
ui_sb_update_icon_state(SB_CDROM|id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_CDROM|id, 0);
|
||||
}
|
||||
|
||||
//media_menu_update_cdrom(id);
|
||||
ui_sb_update_tip(SB_CDROM|id);
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_mount(uint8_t id, char *fn)
|
||||
{
|
||||
cdrom[id].prev_host_drive = cdrom[id].host_drive;
|
||||
strcpy(cdrom[id].prev_image_path, cdrom[id].image_path);
|
||||
if (cdrom[id].ops && cdrom[id].ops->exit)
|
||||
cdrom[id].ops->exit(&(cdrom[id]));
|
||||
cdrom[id].ops = NULL;
|
||||
memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path));
|
||||
cdrom_image_open(&(cdrom[id]), fn);
|
||||
/* Signal media change to the emulated machine. */
|
||||
if (cdrom[id].insert)
|
||||
cdrom[id].insert(cdrom[id].priv);
|
||||
cdrom[id].host_drive = (strlen(cdrom[id].image_path) == 0) ? 0 : 200;
|
||||
if (cdrom[id].host_drive == 200) {
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 0);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 1);
|
||||
}
|
||||
//media_menu_update_cdrom(id);
|
||||
ui_sb_update_tip(SB_CDROM | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
mo_eject(uint8_t id)
|
||||
{
|
||||
mo_t *dev = (mo_t *) mo_drives[id].priv;
|
||||
|
||||
mo_disk_close(dev);
|
||||
if (mo_drives[id].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
mo_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_MO | id, 1);
|
||||
//media_menu_update_mo(id);
|
||||
ui_sb_update_tip(SB_MO | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mo_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
mo_t *dev = (mo_t *) mo_drives[id].priv;
|
||||
|
||||
mo_disk_close(dev);
|
||||
mo_drives[id].read_only = wp;
|
||||
mo_load(dev, fn);
|
||||
mo_insert(dev);
|
||||
|
||||
ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1);
|
||||
//media_menu_update_mo(id);
|
||||
ui_sb_update_tip(SB_MO | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mo_reload(uint8_t id)
|
||||
{
|
||||
mo_t *dev = (mo_t *) mo_drives[id].priv;
|
||||
|
||||
mo_disk_reload(dev);
|
||||
if (strlen(mo_drives[id].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_MO|id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_MO|id, 0);
|
||||
}
|
||||
|
||||
//media_menu_update_mo(id);
|
||||
ui_sb_update_tip(SB_MO|id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
zip_eject(uint8_t id)
|
||||
{
|
||||
zip_t *dev = (zip_t *) zip_drives[id].priv;
|
||||
|
||||
zip_disk_close(dev);
|
||||
if (zip_drives[id].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
zip_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_ZIP | id, 1);
|
||||
//media_menu_update_zip(id);
|
||||
ui_sb_update_tip(SB_ZIP | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
zip_t *dev = (zip_t *) zip_drives[id].priv;
|
||||
|
||||
zip_disk_close(dev);
|
||||
zip_drives[id].read_only = wp;
|
||||
zip_load(dev, fn);
|
||||
zip_insert(dev);
|
||||
|
||||
ui_sb_update_icon_state(SB_ZIP | id, strlen(zip_drives[id].image_path) ? 0 : 1);
|
||||
//media_menu_update_zip(id);
|
||||
ui_sb_update_tip(SB_ZIP | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_reload(uint8_t id)
|
||||
{
|
||||
zip_t *dev = (zip_t *) zip_drives[id].priv;
|
||||
|
||||
zip_disk_reload(dev);
|
||||
if (strlen(zip_drives[id].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_ZIP|id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_ZIP|id, 0);
|
||||
}
|
||||
|
||||
//media_menu_update_zip(id);
|
||||
ui_sb_update_tip(SB_ZIP|id);
|
||||
|
||||
config_save();
|
||||
}
|
57
src/unix/unix_midi.c
Normal file
57
src/unix/unix_midi.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include <inttypes.h>
|
||||
void plat_midi_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void plat_midi_close(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void plat_midi_play_msg(uint8_t *msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void plat_midi_play_sysex(uint8_t *sysex, unsigned int len)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int plat_midi_write(uint8_t val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plat_midi_get_num_devs(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plat_midi_get_dev_name(int num, char *s)
|
||||
{
|
||||
s[0] = ' ';
|
||||
s[1] = 0;
|
||||
}
|
||||
|
||||
void plat_midi_input_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void plat_midi_input_close(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int plat_midi_in_get_num_devs(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plat_midi_in_get_dev_name(int num, char *s)
|
||||
{
|
||||
s[0] = ' ';
|
||||
s[1] = 0;
|
||||
}
|
420
src/unix/unix_sdl.c
Normal file
420
src/unix/unix_sdl.c
Normal file
@ -0,0 +1,420 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_messagebox.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.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>
|
||||
|
||||
#define RENDERER_FULL_SCREEN 1
|
||||
#define RENDERER_HARDWARE 2
|
||||
#define RENDERER_OPENGL 4
|
||||
|
||||
typedef struct sdl_blit_params
|
||||
{
|
||||
int x, y, y1, y2, w, h;
|
||||
} sdl_blit_params;
|
||||
extern sdl_blit_params params;
|
||||
extern int blitreq;
|
||||
|
||||
static SDL_Window *sdl_win = NULL;
|
||||
static SDL_Renderer *sdl_render = NULL;
|
||||
static SDL_Texture *sdl_tex = NULL;
|
||||
static int sdl_w, sdl_h;
|
||||
static int sdl_fs, sdl_flags = -1;
|
||||
static int cur_w, cur_h;
|
||||
static int cur_wx = 0, cur_wy = 0, cur_ww =0, cur_wh = 0;
|
||||
static volatile int sdl_enabled = 1;
|
||||
static SDL_mutex* sdl_mutex = NULL;
|
||||
int mouse_capture;
|
||||
|
||||
static void
|
||||
sdl_integer_scale(double *d, double *g)
|
||||
{
|
||||
double ratio;
|
||||
|
||||
if (*d > *g) {
|
||||
ratio = floor(*d / *g);
|
||||
*d = *g * ratio;
|
||||
} else {
|
||||
ratio = ceil(*d / *g);
|
||||
*d = *g / ratio;
|
||||
}
|
||||
}
|
||||
|
||||
void sdl_reinit_texture();
|
||||
|
||||
static void
|
||||
sdl_stretch(int *w, int *h, int *x, int *y)
|
||||
{
|
||||
double hw, gw, hh, gh, dx, dy, dw, dh, gsr, hsr;
|
||||
|
||||
hw = (double) sdl_w;
|
||||
hh = (double) sdl_h;
|
||||
gw = (double) *w;
|
||||
gh = (double) *h;
|
||||
hsr = hw / hh;
|
||||
|
||||
switch (video_fullscreen_scale) {
|
||||
case FULLSCR_SCALE_FULL:
|
||||
default:
|
||||
*w = sdl_w;
|
||||
*h = sdl_h;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
break;
|
||||
case FULLSCR_SCALE_43:
|
||||
case FULLSCR_SCALE_KEEPRATIO:
|
||||
if (video_fullscreen_scale == FULLSCR_SCALE_43)
|
||||
gsr = 4.0 / 3.0;
|
||||
else
|
||||
gsr = gw / gh;
|
||||
if (gsr <= hsr) {
|
||||
dw = hh * gsr;
|
||||
dh = hh;
|
||||
} else {
|
||||
dw = hw;
|
||||
dh = hw / gsr;
|
||||
}
|
||||
dx = (hw - dw) / 2.0;
|
||||
dy = (hh - dh) / 2.0;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
case FULLSCR_SCALE_INT:
|
||||
gsr = gw / gh;
|
||||
if (gsr <= hsr) {
|
||||
dw = hh * gsr;
|
||||
dh = hh;
|
||||
} else {
|
||||
dw = hw;
|
||||
dh = hw / gsr;
|
||||
}
|
||||
sdl_integer_scale(&dw, &gw);
|
||||
sdl_integer_scale(&dh, &gh);
|
||||
dx = (hw - dw) / 2.0;
|
||||
dy = (hh - dh) / 2.0;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdl_blit_shim(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
params.x = x;
|
||||
params.y = y;
|
||||
params.w = w;
|
||||
params.h = h;
|
||||
params.y1 = y1;
|
||||
params.y2 = y2;
|
||||
blitreq = 1;
|
||||
}
|
||||
|
||||
void
|
||||
sdl_blit(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
SDL_Rect r_src;
|
||||
int ret;
|
||||
|
||||
if (!sdl_enabled || (y1 == y2) || (h <= 0) || (render_buffer == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) {
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
r_src.x = 0;
|
||||
r_src.y = y1;
|
||||
r_src.w = w;
|
||||
r_src.h = y2 - y1;
|
||||
SDL_UpdateTexture(sdl_tex, &r_src, &(render_buffer->dat)[y1 * w], w * 4);
|
||||
video_blit_complete();
|
||||
|
||||
SDL_RenderClear(sdl_render);
|
||||
|
||||
r_src.x = 0;
|
||||
r_src.y = 0;
|
||||
r_src.w = w;
|
||||
r_src.h = h;
|
||||
|
||||
ret = SDL_RenderCopy(sdl_render, sdl_tex, &r_src, 0);
|
||||
if (ret)
|
||||
fprintf(stderr, "SDL: unable to copy texture to renderer (%s)\n", SDL_GetError());
|
||||
|
||||
SDL_RenderPresent(sdl_render);
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
sdl_destroy_window(void)
|
||||
{
|
||||
if (sdl_win != NULL) {
|
||||
SDL_DestroyWindow(sdl_win);
|
||||
sdl_win = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_destroy_texture(void)
|
||||
{
|
||||
/* SDL_DestroyRenderer also automatically destroys all associated textures. */
|
||||
if (sdl_render != NULL) {
|
||||
SDL_DestroyRenderer(sdl_render);
|
||||
sdl_render = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sdl_close(void)
|
||||
{
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
/* Unregister our renderer! */
|
||||
video_setblit(NULL);
|
||||
|
||||
if (sdl_enabled)
|
||||
sdl_enabled = 0;
|
||||
|
||||
if (sdl_mutex != NULL) {
|
||||
SDL_DestroyMutex(sdl_mutex);
|
||||
sdl_mutex = NULL;
|
||||
}
|
||||
|
||||
sdl_destroy_texture();
|
||||
sdl_destroy_window();
|
||||
|
||||
/* Quit. */
|
||||
SDL_Quit();
|
||||
sdl_flags = -1;
|
||||
}
|
||||
|
||||
static int old_capture = 0;
|
||||
|
||||
void
|
||||
sdl_enable(int enable)
|
||||
{
|
||||
if (sdl_flags == -1)
|
||||
return;
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
sdl_enabled = !!enable;
|
||||
|
||||
if (enable == 1) {
|
||||
SDL_SetWindowSize(sdl_win, cur_ww, cur_wh);
|
||||
sdl_reinit_texture();
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
sdl_select_best_hw_driver(void)
|
||||
{
|
||||
int i;
|
||||
SDL_RendererInfo renderInfo;
|
||||
|
||||
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i)
|
||||
{
|
||||
SDL_GetRenderDriverInfo(i, &renderInfo);
|
||||
if (renderInfo.flags & SDL_RENDERER_ACCELERATED) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, renderInfo.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdl_reinit_texture()
|
||||
{
|
||||
if (sdl_flags == -1)
|
||||
return;
|
||||
|
||||
sdl_destroy_texture();
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
||||
if (sdl_flags & RENDERER_HARDWARE) {
|
||||
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0");
|
||||
} else
|
||||
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
|
||||
|
||||
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
|
||||
}
|
||||
|
||||
void
|
||||
sdl_set_fs(int fs)
|
||||
{
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
sdl_enabled = 0;
|
||||
sdl_destroy_texture();
|
||||
SDL_SetWindowFullscreen(sdl_win, fs ? SDL_WINDOW_FULLSCREEN : 0);
|
||||
SDL_SetWindowMouseGrab(sdl_win, mouse_capture);
|
||||
|
||||
sdl_fs = fs;
|
||||
|
||||
if (fs)
|
||||
sdl_flags |= RENDERER_FULL_SCREEN;
|
||||
else
|
||||
sdl_flags &= ~RENDERER_FULL_SCREEN;
|
||||
|
||||
sdl_reinit_texture();
|
||||
sdl_enabled = 1;
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
sdl_resize(int x, int y)
|
||||
{
|
||||
int ww = 0, wh = 0, wx = 0, wy = 0;
|
||||
|
||||
if (video_fullscreen & 2)
|
||||
return;
|
||||
|
||||
if ((x == cur_w) && (y == cur_h))
|
||||
return;
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
ww = x;
|
||||
wh = y;
|
||||
|
||||
cur_w = x;
|
||||
cur_h = y;
|
||||
|
||||
cur_wx = wx;
|
||||
cur_wy = wy;
|
||||
cur_ww = ww;
|
||||
cur_wh = wh;
|
||||
|
||||
SDL_SetWindowSize(sdl_win, cur_ww, cur_wh);
|
||||
SDL_SetWindowPosition(sdl_win, cur_wx, cur_wy);
|
||||
|
||||
sdl_reinit_texture();
|
||||
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
void
|
||||
sdl_reload(void)
|
||||
{
|
||||
if (sdl_flags & RENDERER_HARDWARE)
|
||||
{
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0");
|
||||
sdl_reinit_texture();
|
||||
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
plat_vidapi(char* api)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sdl_init_common(int flags)
|
||||
{
|
||||
wchar_t temp[128];
|
||||
SDL_version ver;
|
||||
|
||||
/* Get and log the version of the DLL we are using. */
|
||||
SDL_GetVersion(&ver);
|
||||
fprintf(stderr, "SDL: version %d.%d.%d\n", ver.major, ver.minor, ver.patch);
|
||||
|
||||
/* Initialize the SDL system. */
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
fprintf(stderr, "SDL: initialization failed (%s)\n", SDL_GetError());
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (flags & RENDERER_HARDWARE) {
|
||||
if (flags & RENDERER_OPENGL) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL");
|
||||
}
|
||||
else
|
||||
sdl_select_best_hw_driver();
|
||||
}
|
||||
|
||||
sdl_mutex = SDL_CreateMutex();
|
||||
sdl_win = SDL_CreateWindow("86Box", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, scrnsz_x, scrnsz_y, SDL_WINDOW_OPENGL);
|
||||
sdl_set_fs(video_fullscreen & 1);
|
||||
if (!(video_fullscreen & 1))
|
||||
{
|
||||
if (vid_resize & 2)
|
||||
plat_resize(fixed_size_x, fixed_size_y);
|
||||
else
|
||||
plat_resize(scrnsz_x, scrnsz_y);
|
||||
}
|
||||
|
||||
/* Make sure we get a clean exit. */
|
||||
atexit(sdl_close);
|
||||
|
||||
/* Register our renderer! */
|
||||
video_setblit(sdl_blit_shim);
|
||||
|
||||
sdl_enabled = 1;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
sdl_inits()
|
||||
{
|
||||
return sdl_init_common(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdl_inith()
|
||||
{
|
||||
return sdl_init_common(RENDERER_HARDWARE);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdl_initho()
|
||||
{
|
||||
return sdl_init_common(RENDERER_HARDWARE | RENDERER_OPENGL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sdl_pause(void)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
plat_mouse_capture(int on)
|
||||
{
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
SDL_SetWindowMouseGrab(sdl_win, (SDL_bool)on);
|
||||
SDL_UnlockMutex(sdl_mutex);
|
||||
}
|
||||
|
||||
void plat_resize(int w, int h)
|
||||
{
|
||||
SDL_SetWindowSize(sdl_win, w, h);
|
||||
}
|
158
src/unix/unix_thread.c
Normal file
158
src/unix/unix_thread.c
Normal file
@ -0,0 +1,158 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/plat.h>
|
||||
|
||||
typedef struct event_pthread_t
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
int state;
|
||||
} event_pthread_t;
|
||||
|
||||
thread_t *thread_create(void (*thread_rout)(void *param), void *param)
|
||||
{
|
||||
pthread_t *thread = malloc(sizeof(pthread_t));
|
||||
|
||||
pthread_create(thread, NULL, (void*)thread_rout, param);
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
int
|
||||
thread_wait(thread_t *arg, int timeout)
|
||||
{
|
||||
return pthread_join(*(pthread_t*)(arg), NULL) != 0;
|
||||
}
|
||||
|
||||
event_t *thread_create_event()
|
||||
{
|
||||
event_pthread_t *event = malloc(sizeof(event_pthread_t));
|
||||
|
||||
pthread_cond_init(&event->cond, NULL);
|
||||
pthread_mutex_init(&event->mutex, NULL);
|
||||
event->state = 0;
|
||||
|
||||
return (event_t *)event;
|
||||
}
|
||||
|
||||
void thread_set_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
event->state = 1;
|
||||
pthread_cond_broadcast(&event->cond);
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
}
|
||||
|
||||
void thread_reset_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
event->state = 0;
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
}
|
||||
|
||||
int thread_wait_event(event_t *handle, int timeout)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
struct timespec abstime;
|
||||
|
||||
#if defined __linux__ || defined BSD
|
||||
clock_gettime(CLOCK_REALTIME, &abstime);
|
||||
#else
|
||||
struct timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
abstime.tv_sec = now.tv_sec;
|
||||
abstime.tv_nsec = now.tv_usec*1000UL;
|
||||
#endif
|
||||
abstime.tv_nsec += (timeout % 1000) * 1000000;
|
||||
abstime.tv_sec += (timeout / 1000);
|
||||
if (abstime.tv_nsec > 1000000000)
|
||||
{
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&event->mutex);
|
||||
if (timeout == -1)
|
||||
{
|
||||
while (!event->state)
|
||||
pthread_cond_wait(&event->cond, &event->mutex);
|
||||
}
|
||||
else if (!event->state)
|
||||
pthread_cond_timedwait(&event->cond, &event->mutex, &abstime);
|
||||
pthread_mutex_unlock(&event->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void thread_destroy_event(event_t *handle)
|
||||
{
|
||||
event_pthread_t *event = (event_pthread_t *)handle;
|
||||
|
||||
pthread_cond_destroy(&event->cond);
|
||||
pthread_mutex_destroy(&event->mutex);
|
||||
|
||||
free(event);
|
||||
}
|
||||
|
||||
void thread_sleep(int t)
|
||||
{
|
||||
usleep(t * 1000);
|
||||
}
|
||||
|
||||
|
||||
typedef struct pt_mutex_t
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
} pt_mutex_t;
|
||||
|
||||
mutex_t *thread_create_mutex(void)
|
||||
{
|
||||
pt_mutex_t *mutex = malloc(sizeof(pt_mutex_t));
|
||||
|
||||
pthread_mutex_init(&mutex->mutex, NULL);
|
||||
|
||||
return mutex;
|
||||
|
||||
}
|
||||
|
||||
mutex_t *
|
||||
thread_create_mutex_with_spin_count(unsigned int spin_count)
|
||||
{
|
||||
/* Setting spin count of a mutex is not possible with pthreads. */
|
||||
return thread_create_mutex();
|
||||
}
|
||||
|
||||
int thread_wait_mutex(mutex_t *_mutex)
|
||||
{
|
||||
if (_mutex == NULL) return(0);
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
return pthread_mutex_lock(&mutex->mutex) != 0;
|
||||
}
|
||||
|
||||
int thread_release_mutex(mutex_t *_mutex)
|
||||
{
|
||||
if (_mutex == NULL) return(0);
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
return pthread_mutex_unlock(&mutex->mutex) != 0;
|
||||
}
|
||||
|
||||
void thread_close_mutex(mutex_t *_mutex)
|
||||
{
|
||||
pt_mutex_t *mutex = (pt_mutex_t *)_mutex;
|
||||
|
||||
pthread_mutex_destroy(&mutex->mutex);
|
||||
|
||||
free(mutex);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user