Commit 34ec98f0 authored by deuce's avatar deuce
Browse files

SyncTERM changes:

Have SyncTERM save/restore the window size

Ciolib changes:
Hopefully fix streaming texture updates (ie: white screen)
- Request pixel data on expose rather than re-render texture
- This allows the rect update to copy the screen
Fix ALT-Enter fullscreen toggle
Ensure vstatlock is held when accessing cvstat
Add setwinsize() and setwinpos() to ciolib
Return window position from get_window_info() in SDL mode
SDL driver no longer supports setscaling() (use setwinsize())
Use ALT-<arrow> to change window scaling, not Meta
Add winwidth/winheight to vstat structure
parent 7c5f01f5
......@@ -136,6 +136,8 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_get_modepalette(uint32_t p[16]);
CIOLIBEXPORT int CIOLIBCALL ciolib_set_modepalette(uint32_t p[16]);
CIOLIBEXPORT void CIOLIBCALL ciolib_set_vmem(struct vmem_cell *cell, uint8_t ch, uint8_t attr, uint8_t font);
CIOLIBEXPORT void CIOLIBCALL ciolib_set_vmem_attr(struct vmem_cell *cell, uint8_t attr);
CIOLIBEXPORT void CIOLIBCALL ciolib_setwinsize(int width, int height);
CIOLIBEXPORT void CIOLIBCALL ciolib_setwinposition(int x, int y);
#if defined(WITH_SDL) || defined(WITH_SDL_AUDIO)
int sdl_video_initialized = 0;
......@@ -180,8 +182,8 @@ static int try_sdl_init(int mode)
cio_api.getcliptext=sdl_getcliptext;
#endif
cio_api.get_window_info=sdl_get_window_info;
cio_api.setscaling=sdl_setscaling;
cio_api.getscaling=sdl_getscaling;
cio_api.setwinsize=sdl_setwinsize;
cio_api.setwinposition=sdl_setwinposition;
cio_api.setpalette=bitmap_setpalette;
cio_api.attr2palette=bitmap_attr2palette;
cio_api.setpixel=bitmap_setpixel;
......@@ -2031,3 +2033,21 @@ ciolib_set_vmem_attr(struct vmem_cell *cell, uint8_t attr)
cell->legacy_attr = attr;
ciolib_attr2palette(attr, &cell->fg, &cell->bg);
}
/* Optional */
CIOLIBEXPORT void CIOLIBCALL ciolib_setwinsize(int w, int h)
{
CIOLIB_INIT();
if(cio_api.setwinsize)
cio_api.setwinsize(w, h);
}
/* Optional */
CIOLIBEXPORT void CIOLIBCALL ciolib_setwinposition(int x, int y)
{
CIOLIB_INIT();
if(cio_api.setwinposition)
cio_api.setwinposition(x, y);
}
......
......@@ -363,6 +363,8 @@ typedef struct {
uint32_t (*map_rgb)(uint16_t r, uint16_t g, uint16_t b);
void (*replace_font)(uint8_t id, char *name, void *data, size_t size);
int (*checkfont)(int font_num);
void (*setwinsize) (int width, int height);
void (*setwinposition) (int x, int y);
} cioapi_t;
CIOLIBEXPORTVAR cioapi_t cio_api;
......@@ -456,6 +458,8 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_attrfont(uint8_t attr);
CIOLIBEXPORT int CIOLIBCALL ciolib_checkfont(int font_num);
CIOLIBEXPORT void CIOLIBCALL ciolib_set_vmem(struct vmem_cell *cell, uint8_t ch, uint8_t attr, uint8_t font);
CIOLIBEXPORT void CIOLIBCALL ciolib_set_vmem_attr(struct vmem_cell *cell, uint8_t attr);
CIOLIBEXPORT void CIOLIBCALL ciolib_setwinsize(int width, int height);
CIOLIBEXPORT void CIOLIBCALL ciolib_setwinposition(int x, int y);
/* DoorWay specific stuff that's only applicable to ANSI mode. */
CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
......@@ -537,6 +541,8 @@ CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
#define checkfont(a) ciolib_checkfont(a)
#define set_vmem(a, b, c, d) ciolib_set_vmem(a, b, c, d)
#define set_vmem_attr(a, b) ciolib_set_vmem_attr(a, b)
#define setwinsize(a,b) ciolib_setwinsize(a,b)
#define setwinposition(a,b) ciolib_setwinposition(a,b)
#endif
#ifdef WITH_SDL
......
......@@ -201,8 +201,6 @@ const struct sdl_keyvals sdl_keyval[] =
{0, 0, 0, 0, 0} /** END **/
};
void sdl_setscaling(int new_value);
#if !defined(NO_X) && defined(__unix__)
#include "SDL_syswm.h"
......@@ -463,21 +461,25 @@ static int sdl_init_mode(int mode)
pthread_mutex_unlock(&vstatlock);
}
oldcols = cvstat.cols;
sdl_user_func(SDL_USEREVENT_FLUSH);
pthread_mutex_lock(&blinker_lock);
pthread_mutex_lock(&vstatlock);
oldcols = cvstat.cols;
bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height);
if(oldcols != vstat.cols) {
if(oldcols == 40)
vstat.scaling /= 2;
if(vstat.cols == 40)
vstat.scaling *= 2;
vstat.winwidth = ((double)cvstat.winwidth / cvstat.cols) * vstat.cols;
vstat.winheight = ((double)cvstat.winheight / cvstat.rows / cvstat.vmultiplier) * (vstat.rows * vstat.vmultiplier);
if (oldcols != vstat.cols) {
if (oldcols == 40)
vstat.winwidth /= 2;
if (vstat.cols == 40)
vstat.winwidth *= 2;
}
if(vstat.scaling < 1)
vstat.scaling = 1;
// TODO: Integer scale the window?
if (vstat.winwidth < vstat.charwidth * vstat.cols)
vstat.winwidth = vstat.charwidth * vstat.cols;
if (vstat.winheight < vstat.charheight * vstat.rows)
vstat.winheight = vstat.charheight * vstat.rows;
if(vstat.vmultiplier < 1)
vstat.vmultiplier = 1;
......@@ -557,16 +559,47 @@ int sdl_init(int mode)
return(-1);
}
void sdl_setscaling(int new_value)
void sdl_setwinsize_locked(int w, int h)
{
if (w > 16384)
w = 16384;
if (h > 16384)
h = 16384;
if (w < cvstat.charwidth * cvstat.cols)
w = cvstat.charwidth * cvstat.cols;
if (h < cvstat.charheight * cvstat.rows)
h = cvstat.charheight * cvstat.rows;
cvstat.winwidth = vstat.winwidth = w;
cvstat.winheight = vstat.winheight = h;
}
void sdl_setwinsize(int w, int h)
{
pthread_mutex_lock(&vstatlock);
cvstat.scaling = vstat.scaling = new_value;
sdl_setwinsize_locked(w, h);
pthread_mutex_unlock(&vstatlock);
}
int sdl_getscaling(void)
void sdl_setwinposition(int x, int y)
{
sdl.mutexP(win_mutex);
sdl.SetWindowPosition(win, x, y);
sdl.mutexV(win_mutex);
}
void sdl_getwinsize_locked(int *w, int *h)
{
if (w)
*w = cvstat.winwidth;
if (h)
*h = cvstat.winheight;
}
void sdl_getwinsize(int *w, int *h)
{
return cvstat.scaling;
pthread_mutex_lock(&vstatlock);
sdl_getwinsize_locked(w, h);
pthread_mutex_unlock(&vstatlock);
}
/* Called from main thread only */
......@@ -645,29 +678,32 @@ int sdl_hidemouse(void)
int sdl_get_window_info(int *width, int *height, int *xpos, int *ypos)
{
int ww, wh;
int wx, wy;
sdl.mutexP(win_mutex);
sdl.GetWindowSize(win, &ww, &wh);
if (width || height)
sdl.GetWindowSize(win, &ww, &wh);
if (xpos || ypos)
sdl.GetWindowPosition(win, &wx, &wy);
if(width)
*width=ww;
if(height)
*height=wh;
if(xpos)
*xpos=-1;
*xpos=wx;
if(ypos)
*ypos=-1;
*ypos=wy;
sdl.mutexV(win_mutex);
return(1);
}
static void setup_surfaces(void)
static void setup_surfaces_locked(void)
{
int char_width;
int char_height;
int flags=0;
SDL_Event ev;
int charwidth, charheight, cols, scaling, rows, vmultiplier;
int charwidth, charheight, cols, rows, vmultiplier;
if(fullscreen)
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
......@@ -678,16 +714,12 @@ static void setup_surfaces(void)
charwidth = cvstat.charwidth;
charheight = cvstat.charheight;
cols = cvstat.cols;
scaling = cvstat.scaling;
rows = cvstat.rows;
vmultiplier = cvstat.vmultiplier;
char_width=charwidth*cols*scaling;
char_height=charheight*rows*scaling*vmultiplier;
if (win == NULL) {
// SDL2: This is slow sometimes... not sure why.
if (sdl.CreateWindowAndRenderer(char_width, char_height, flags, &win, &renderer) == 0) {
if (sdl.CreateWindowAndRenderer(cvstat.winwidth, cvstat.winheight, flags, &win, &renderer) == 0) {
sdl.RenderClear(renderer);
texture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, charwidth*cols, charheight*rows);
}
......@@ -697,7 +729,8 @@ static void setup_surfaces(void)
}
}
else {
sdl.SetWindowSize(win, char_width, char_height);
sdl.SetWindowSize(win, cvstat.winwidth, cvstat.winheight);
texture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, charwidth*cols, charheight*rows);
}
if(win!=NULL) {
......@@ -711,12 +744,20 @@ static void setup_surfaces(void)
sdl.mutexV(win_mutex);
}
static void setup_surfaces(void)
{
pthread_mutex_lock(&vstatlock);
setup_surfaces_locked();
pthread_mutex_unlock(&vstatlock);
}
/* Called from event thread only */
static void sdl_add_key(unsigned int keyval)
{
if(keyval==0xa600) {
fullscreen=!fullscreen;
cio_api.mode=fullscreen?CIOLIB_MODE_SDL_FULLSCREEN:CIOLIB_MODE_SDL;
sdl.SetWindowFullscreen(win, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
setup_surfaces();
return;
}
......@@ -1191,7 +1232,13 @@ static int win_to_text_xpos(int winpos)
{
int ret;
ret = winpos/(cvstat.charwidth*cvstat.scaling)+1;
pthread_mutex_lock(&vstatlock);
ret = winpos/(((float)cvstat.winwidth)/cvstat.cols)+1;
if (ret > cvstat.cols)
ret = cvstat.cols;
if (ret < 1)
ret = 1;
pthread_mutex_unlock(&vstatlock);
return ret;
}
......@@ -1199,17 +1246,25 @@ static int win_to_text_ypos(int winpos)
{
int ret;
ret = winpos/(cvstat.charheight*cvstat.scaling*cvstat.vmultiplier)+1;
pthread_mutex_lock(&vstatlock);
ret = winpos/(((float)cvstat.winheight)/cvstat.rows)+1;
if (ret > cvstat.rows)
ret = cvstat.rows;
if (ret < 1)
ret = 1;
pthread_mutex_unlock(&vstatlock);
return ret;
}
static void sdl_video_event_thread(void *data)
{
SDL_Event ev;
int new_scaling = -1;
int old_scaling;
int old_w, old_h;
old_scaling = cvstat.scaling;
pthread_mutex_lock(&vstatlock);
old_w = cvstat.winwidth;
old_h = cvstat.winheight;
pthread_mutex_unlock(&vstatlock);
char *driver;
if((driver = sdl.GetCurrentVideoDriver())!=NULL) {
......@@ -1237,28 +1292,28 @@ static void sdl_video_event_thread(void *data)
while(1) {
if(sdl.WaitEventTimeout(&ev, 1)!=1) {
if (new_scaling != -1 || cvstat.scaling != old_scaling) {
if (new_scaling == -1)
new_scaling = cvstat.scaling;
sdl_setscaling(new_scaling);
new_scaling = -1;
if(cvstat.scaling < 1)
sdl_setscaling(1);
setup_surfaces();
old_scaling = cvstat.scaling;
pthread_mutex_lock(&vstatlock);
if (cvstat.winwidth != old_w || cvstat.winheight != old_h) {
sdl_setwinsize_locked(cvstat.winwidth, cvstat.winheight);
setup_surfaces_locked();
old_w = cvstat.winwidth;
old_h = cvstat.winheight;
sdl_getwinsize_locked(&cvstat.winwidth, &cvstat.winheight);
}
pthread_mutex_unlock(&vstatlock);
}
else {
switch (ev.type) {
case SDL_KEYDOWN: /* Keypress */
if ((ev.key.keysym.mod & KMOD_GUI) &&
if ((ev.key.keysym.mod & KMOD_ALT) &&
(ev.key.keysym.sym == SDLK_LEFT ||
ev.key.keysym.sym == SDLK_RIGHT ||
ev.key.keysym.sym == SDLK_UP ||
ev.key.keysym.sym == SDLK_DOWN)) {
int w, h;
sdl.mutexP(win_mutex);
sdl.GetWindowSize(win, &w, &h);
pthread_mutex_lock(&vstatlock);
w = cvstat.winwidth;
h = cvstat.winheight;
switch(ev.key.keysym.sym) {
case SDLK_LEFT:
if (w % (cvstat.charwidth * cvstat.cols)) {
......@@ -1275,7 +1330,7 @@ static void sdl_video_event_thread(void *data)
break;
case SDLK_UP:
if (h % (cvstat.charheight * cvstat.rows * cvstat.vmultiplier)) {
h = h - h % (cvstat.charheight * cvstat.rows);
h = h - h % (cvstat.charheight * cvstat.rows * cvstat.vmultiplier);
}
else {
h -= (cvstat.charheight * cvstat.rows * cvstat.vmultiplier);
......@@ -1287,8 +1342,13 @@ static void sdl_video_event_thread(void *data)
h = (h - h % (cvstat.charheight * cvstat.rows * cvstat.vmultiplier)) + (cvstat.charheight * cvstat.rows * cvstat.vmultiplier);
break;
}
sdl.SetWindowSize(win, w, h);
sdl.mutexP(win_mutex);
if (w > 16384 || h > 16384)
beep();
else {
cvstat.winwidth = w;
cvstat.winheight = h;
}
pthread_mutex_unlock(&vstatlock);
}
else
sdl_add_key(sdl_get_char_code(ev.key.keysym.sym, ev.key.keysym.mod));
......@@ -1349,9 +1409,8 @@ static void sdl_video_event_thread(void *data)
{
// SDL2: Something resized window
const char *newh;
if(ev.window.data1 > 0 && ev.window.data2 > 0) {
new_scaling = (int)(ev.window.data1/(cvstat.charwidth*cvstat.cols));
}
pthread_mutex_lock(&vstatlock);
if ((ev.window.data1 % (cvstat.charwidth * cvstat.cols)) || (ev.window.data2 % (cvstat.charheight * cvstat.rows)))
newh = "2";
else
......@@ -1364,15 +1423,11 @@ static void sdl_video_event_thread(void *data)
bitmap_drv_request_pixels();
}
sdl.mutexV(win_mutex);
pthread_mutex_unlock(&vstatlock);
break;
}
case SDL_WINDOWEVENT_EXPOSED:
{
sdl.mutexP(win_mutex);
sdl.RenderCopy(renderer, texture, NULL, NULL);
sdl.RenderPresent(renderer);
sdl.mutexV(win_mutex);
}
bitmap_drv_request_pixels();
break;
}
break;
......@@ -1402,11 +1457,30 @@ static void sdl_video_event_thread(void *data)
old_next = list->next;
if (list->next == NULL) {
void *pixels;
int pitch;
int row;
int tw, th;
src.x = 0;
src.y = 0;
src.w = list->rect.width;
src.h = list->rect.height;
sdl.UpdateTexture(texture, &src, list->data, list->rect.width * sizeof(uint32_t));
sdl.QueryTexture(texture, NULL, NULL, &tw, &th);
sdl.LockTexture(texture, &src, &pixels, &pitch);
if (pitch != list->rect.width * sizeof(list->data[0])) {
// If this happens, we need to copy a row at a time...
for (row = 0; row < list->rect.height && row < th; row++) {
if (pitch < list->rect.width * sizeof(list->data[0]))
memcpy(pixels, &list->data[list->rect.width * row], pitch);
else
memcpy(pixels, &list->data[list->rect.width * row], list->rect.width * sizeof(list->data[0]));
pixels = (void *)((char*)pixels + pitch);
}
}
else
memcpy(pixels, list->data, list->rect.width * list->rect.height * sizeof(list->data[0]));
sdl.UnlockTexture(texture);
sdl.RenderCopy(renderer, texture, &src, NULL);
}
bitmap_drv_free_rect(list);
......@@ -1446,9 +1520,11 @@ static void sdl_video_event_thread(void *data)
free(ev.user.data1);
break;
case SDL_USEREVENT_SETVIDMODE:
new_scaling = -1;
old_scaling = cvstat.scaling;
setup_surfaces();
pthread_mutex_lock(&vstatlock);
setup_surfaces_locked();
old_w = cvstat.winwidth;
old_h = cvstat.winheight;
pthread_mutex_unlock(&vstatlock);
sdl_ufunc_retval=0;
sdl.SemPost(sdl_ufunc_ret);
break;
......
......@@ -14,8 +14,6 @@ int sdl_screen_redraw(void);
void exit_sdl_con(void);
/* High-level stuff */
void sdl_setscaling(int new_value);
int sdl_getscaling(void);
int sdl_puttext(int sx, int sy, int ex, int ey, void *fill);
int sdl_gettext(int sx, int sy, int ex, int ey, void *fill);
int sdl_kbhit(void);
......@@ -37,6 +35,8 @@ int sdl_getfont(void);
int sdl_loadfont(char *filename);
int sdl_get_window_info(int *width, int *height, int *xpos, int *ypos);
int sdl_setpalette(uint32_t index, uint16_t r, uint16_t g, uint16_t b);
void sdl_setwinsize(int w, int h);
void sdl_setwinposition(int x, int y);
#ifdef __cplusplus
}
#endif
......
......@@ -200,6 +200,30 @@ int load_sdl_funcs(struct sdlfuncs *sdlf)
xp_dlclose(sdl_dll);
return(-1);
}
if((sdlf->SetWindowFullscreen=xp_dlsym(sdl_dll, SDL_SetWindowFullscreen))==NULL) {
xp_dlclose(sdl_dll);
return(-1);
}
if((sdlf->LockTexture=xp_dlsym(sdl_dll, SDL_LockTexture))==NULL) {
xp_dlclose(sdl_dll);
return(-1);
}
if((sdlf->UnlockTexture=xp_dlsym(sdl_dll, SDL_UnlockTexture))==NULL) {
xp_dlclose(sdl_dll);
return(-1);
}
if((sdlf->QueryTexture=xp_dlsym(sdl_dll, SDL_QueryTexture))==NULL) {
xp_dlclose(sdl_dll);
return(-1);
}
if((sdlf->GetWindowPosition=xp_dlsym(sdl_dll, SDL_GetWindowPosition))==NULL) {
xp_dlclose(sdl_dll);
return(-1);
}
if((sdlf->SetWindowPosition=xp_dlsym(sdl_dll, SDL_SetWindowPosition))==NULL) {
xp_dlclose(sdl_dll);
return(-1);
}
sdlf->gotfuncs=1;
sdl_funcs_loaded=1;
......
......@@ -56,6 +56,12 @@ struct sdlfuncs {
SDL_Keymod (HACK_HACK_HACK *GetModState) (void);
void (HACK_HACK_HACK *SetWindowSize) (SDL_Window *window, int w, int h);
void (HACK_HACK_HACK *DestroyTexture) (SDL_Texture *texture);
void (HACK_HACK_HACK *SetWindowFullscreen) (SDL_Window *window, Uint32 flags);
void (HACK_HACK_HACK *LockTexture) (SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch);
void (HACK_HACK_HACK *UnlockTexture) (SDL_Texture *texture);
void (HACK_HACK_HACK *QueryTexture) (SDL_Texture *texture, Uint32 *format, int *access, int *w, int *h);
void (HACK_HACK_HACK *GetWindowPosition) (SDL_Window *window, int *x, int *y);
void (HACK_HACK_HACK *SetWindowPosition) (SDL_Window *window, int x, int y);
int gotfuncs;
};
......
......@@ -95,6 +95,8 @@ struct video_stats {
int currattr;
int scaling;
int vmultiplier;
int winwidth;
int winheight;
uint32_t flags;
#define VIDMODES_FLAG_PALETTE_VMEM 1
uint32_t palette[16];
......
......@@ -1233,6 +1233,8 @@ void load_settings(struct syncterm_settings *set)
get_syncterm_filename(set->list_path, sizeof(set->list_path), SYNCTERM_PATH_LIST, FALSE);
iniReadString(inifile, "SyncTERM", "ListPath", set->list_path, set->list_path);
set->scaling_factor=iniReadInteger(inifile,"SyncTERM","ScalingFactor",0);
set->window_width=iniReadInteger(inifile,"SyncTERM","WindowWidth",0);
set->window_height=iniReadInteger(inifile,"SyncTERM","WindowHeight",0);
/* Modem settings */
iniReadString(inifile, "SyncTERM", "ModemInit", "AT&F&C1&D2", set->mdm.init_string);
......@@ -1278,6 +1280,7 @@ int main(int argc, char **argv)
char *last_bbs=NULL;
char *p, *lp;
int cvmode;
int ww, wh, sf;
const char syncterm_termcap[]="\n# terminfo database entry for SyncTERM\n"
"syncterm|SyncTERM,\n"
" am,bce,ccc,da,mir,msgr,ndscr,\n" // sam?
......@@ -1502,6 +1505,7 @@ int main(int argc, char **argv)
ciolib_reaper=FALSE;
seticon(syncterm_icon.pixel_data,syncterm_icon.width);
setscaling(settings.scaling_factor);
setwinsize(settings.window_width, settings.window_height);
textmode(text_mode);
gettextinfo(&txtinfo);
......@@ -1662,7 +1666,12 @@ int main(int argc, char **argv)
if (last_bbs)
free(last_bbs);
// Save changed settings
if(getscaling() > 0 && getscaling() != settings.scaling_factor) {
ww = wh = sf = -1;
get_window_info(&ww, &wh, NULL, NULL);
sf = getscaling();
if((sf > 0 && sf != settings.scaling_factor) ||
(ww > 0 && ww != settings.window_width) ||
(wh > 0 && wh != settings.window_height)) {
char inipath[MAX_PATH+1];
FILE *inifile;
str_list_t inicontents;
......@@ -1675,12 +1684,18 @@ int main(int argc, char **argv)
else {
inicontents=strListInit();
}
iniSetInteger(&inicontents,"SyncTERM","ScalingFactor",getscaling(),&ini_style);
if (sf > 0 && sf != settings.scaling_factor)
iniSetInteger(&inicontents,"SyncTERM","ScalingFactor",sf,&ini_style);
if (ww > 0 && ww != settings.window_width)
iniSetInteger(&inicontents,"SyncTERM","WindowWidth",ww,&ini_style);
if (wh > 0 && wh != settings.window_height)
iniSetInteger(&inicontents,"SyncTERM","WindowHeight",wh,&ini_style);
if((inifile=fopen(inipath,"w"))!=NULL) {
iniWriteFile(inifile,inicontents);
fclose(inifile);
}
}
uifcbail();
#ifdef _WINSOCKAPI_
if(WSAInitialized && WSACleanup()!=0)
......
......@@ -62,6 +62,8 @@ struct syncterm_settings {
int custom_cols;
int custom_rows;
int custom_fontheight;
int window_width;
int window_height;
};
extern char *inpath;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment