添加PDCurses库的wasm演示程序

This commit is contained in:
HEYAHONG 2024-10-22 15:30:40 +08:00
parent ab0722b272
commit 2b53663f93
No known key found for this signature in database
GPG Key ID: 97E3E469FE2C920B
13 changed files with 1811 additions and 0 deletions

4
.gitmodules vendored
View File

@ -1,3 +1,7 @@
[submodule "@/src/3rdparty/HCppBox"]
path = @/src/3rdparty/HCppBox
url = ../HCppBox.git
[submodule "@/src/3rdparty/PDCurses"]
path = @/src/3rdparty/PDCurses
url = ../../HEYAHONG/PDCurses
branch = HYH

1
@/src/3rdparty/PDCurses vendored Submodule

@ -0,0 +1 @@
Subproject commit 7da8a329029424f2def3d08c5a2ed3be140f7b77

View File

@ -0,0 +1,191 @@
cmake_minimum_required(VERSION 3.20)
#
Set(PROJECT_NAME PDCurses)
#
set(PROJECT_MAJOR_VERSION_STR 1)
#
set(PROJECT_MINOR_VERSION_STR 0)
#
set(PROJECT_REVISION_VERSION_STR 0)
#
string(TIMESTAMP PROJECT_BUILD_TIME_SECOND "%s" UTC)
math(EXPR PROJECT_BUILD_VERSION_STR "${PROJECT_BUILD_TIME_SECOND}/60/60/24" OUTPUT_FORMAT DECIMAL)
#
set(PROJECT_VERSION_STR "${PROJECT_MAJOR_VERSION_STR}.${PROJECT_MINOR_VERSION_STR}.${PROJECT_REVISION_VERSION_STR}.${PROJECT_BUILD_VERSION_STR}")
#
set(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
Project(${PROJECT_NAME} VERSION "${PROJECT_VERSION_STR}")
Project(${PROJECT_NAME} C CXX)
# C++
set(CMAKE_CXX_STANDARD 14)
#Emscripten
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Emscripten")
set(WASM_BUILD ON)
message(STATUS "This is a wasm build!")
else()
set(WASM_BUILD OFF)
endif()
if(${WASM_BUILD})
set(CMAKE_EXECUTABLE_SUFFIX ".html")
add_compile_definitions(WASM_BUILD=1)
endif()
file(GLOB PDCURSES_PORT_C_CXX_FILES lib*.c lib*.h lib*.cpp)
add_library(${PROJECT_NAME} ${PDCURSES_PORT_C_CXX_FILES})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
if(${WASM_BUILD})
#
target_link_libraries(${PROJECT_NAME} -sASYNCIFY -sWASM_BIGINT=1 -sUSE_SDL=1 -sUSE_SDL_TTF=1 )
endif()
include(FindPkgConfig)
#线
FIND_PACKAGE(Threads REQUIRED)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
#PDCurses
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/PDCurses/pdcurses/ PDCursesCore EXCLUDE_FROM_ALL)
target_link_libraries(${PROJECT_NAME} PDCursesCore)
file(GLOB PDCURSES_SDL1_C_FILES ${CMAKE_CURRENT_SOURCE_DIR}/pdc*.c)
target_sources(PDCursesCore PRIVATE ${PDCURSES_SDL1_C_FILES})
if(${WASM_BUILD})
#
target_link_libraries(PDCursesCore -sWASM_BIGINT=1 -sUSE_SDL=1 -sUSE_SDL_TTF=1 )
endif()
#sdl
include(FindSDL)
if(${SDL_FOUND})
include_directories(${SDL_INCLUDE_DIRS})
target_link_libraries(PDCursesCore SDL::SDL)
endif()
#sdl_image
include(FindSDL_image)
if(${SDL_IMAGE_FOUND})
include_directories(${SDL_IMAGE_INCLUDE_DIRS})
target_link_libraries(PDCursesCore ${SDL_IMAGE_LIBRARIES})
endif()
#sdl_mixer
include(FindSDL_mixer)
if(${SDL_MIXER_FOUND})
include_directories(${SDL_MIXER_INCLUDE_DIRS})
target_link_libraries(PDCursesCore ${SDL_MIXER_LIBRARIES})
endif()
#sdl_net
include(FindSDL_net)
if(${SDL_NET_FOUND})
include_directories(${SDL_NET_INCLUDE_DIRS})
target_link_libraries(PDCursesCore ${SDL_NET_LIBRARIES})
endif()
#sdl_sound
include(FindSDL_sound)
if(${SDL_SOUND_FOUND})
include_directories(${SDL_SOUND_INCLUDE_DIRS})
target_link_libraries(PDCursesCore ${SDL_SOUND_LIBRARIES})
endif()
#sdl_ttf
include(FindSDL_ttf)
if(${SDL_TTF_FOUND})
include_directories(${SDL_TTF_INCLUDE_DIRS})
target_link_libraries(PDCursesCore ${SDL_TTF_LIBRARIES})
endif()
#common_fsloader
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../common/fsloader common_fsloader EXCLUDE_FROM_ALL)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} common_fsloader)
#common_font
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../common/font common_font)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} common_font)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Emscripten")
target_compile_definitions(PDCursesCore PUBLIC PDC_FORCE_UTF8=1 PDC_WIDE=1 PDC_FONT_PATH=\"/font/wqy-zenhei-slim.ttf\")
endif()
#3rdparty/HCppBox
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/HCppBox HCppBox EXCLUDE_FROM_ALL)
#HCppBoxHRC
hcppbox_enable(PDCursesCore)
hrc_enable(PDCursesCore)
include(GNUInstallDirs)
#Demos
set(DEMOS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/PDCurses/demos/)
add_executable(firework ${DEMOS_DIR}/firework.c )
target_link_libraries(firework ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/firework.html ${CMAKE_BINARY_DIR}/firework.data ${CMAKE_BINARY_DIR}/firework.js ${CMAKE_BINARY_DIR}/firework.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()
add_executable(ozdemo ${DEMOS_DIR}/ozdemo.c )
target_link_libraries(ozdemo ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/ozdemo.html ${CMAKE_BINARY_DIR}/ozdemo.data ${CMAKE_BINARY_DIR}/ozdemo.js ${CMAKE_BINARY_DIR}/ozdemo.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()
add_executable(ptest ${DEMOS_DIR}/ptest.c )
target_link_libraries(ptest ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/ptest.html ${CMAKE_BINARY_DIR}/ptest.data ${CMAKE_BINARY_DIR}/ptest.js ${CMAKE_BINARY_DIR}/ptest.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()
add_executable(rain ${DEMOS_DIR}/rain.c )
target_link_libraries(rain ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/rain.html ${CMAKE_BINARY_DIR}/rain.data ${CMAKE_BINARY_DIR}/rain.js ${CMAKE_BINARY_DIR}/rain.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()
add_executable(testcurs ${DEMOS_DIR}/testcurs.c )
target_link_libraries(testcurs ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/testcurs.html ${CMAKE_BINARY_DIR}/testcurs.data ${CMAKE_BINARY_DIR}/testcurs.js ${CMAKE_BINARY_DIR}/testcurs.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()
add_executable(tuidemo ${DEMOS_DIR}/tuidemo.c ${DEMOS_DIR}/tui.c )
target_link_libraries(tuidemo ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/tuidemo.html ${CMAKE_BINARY_DIR}/tuidemo.data ${CMAKE_BINARY_DIR}/tuidemo.js ${CMAKE_BINARY_DIR}/tuidemo.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()
add_executable(worm ${DEMOS_DIR}/worm.c )
target_link_libraries(worm ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/worm.html ${CMAKE_BINARY_DIR}/worm.data ${CMAKE_BINARY_DIR}/worm.js ${CMAKE_BINARY_DIR}/worm.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()
add_executable(xmas ${DEMOS_DIR}/xmas.c )
target_link_libraries(xmas ${PROJECT_NAME})
if(${WASM_BUILD})
INSTALL(FILES ${CMAKE_BINARY_DIR}/xmas.html ${CMAKE_BINARY_DIR}/xmas.data ${CMAKE_BINARY_DIR}/xmas.js ${CMAKE_BINARY_DIR}/xmas.wasm
DESTINATION /var/www/html/wasm/${PROJECT_NAME}/
)
endif()

View File

@ -0,0 +1 @@
//Dummy file

View File

@ -0,0 +1,131 @@
/* PDCurses */
#include "pdcsdl.h"
#include <stdlib.h>
#include <string.h>
/*man-start**************************************************************
clipboard
---------
### Synopsis
int PDC_getclipboard(char **contents, long *length);
int PDC_setclipboard(const char *contents, long length);
int PDC_freeclipboard(char *contents);
int PDC_clearclipboard(void);
### Description
PDC_getclipboard() gets the textual contents of the system's
clipboard. This function returns the contents of the clipboard in the
contents argument. It is the responsibility of the caller to free the
memory returned, via PDC_freeclipboard(). The length of the clipboard
contents is returned in the length argument.
PDC_setclipboard copies the supplied text into the system's
clipboard, emptying the clipboard prior to the copy.
PDC_clearclipboard() clears the internal clipboard.
### Return Values
indicator of success/failure of call.
PDC_CLIP_SUCCESS the call was successful
PDC_CLIP_MEMORY_ERROR unable to allocate sufficient memory for
the clipboard contents
PDC_CLIP_EMPTY the clipboard contains no text
PDC_CLIP_ACCESS_ERROR no clipboard support
### Portability
X/Open ncurses NetBSD
PDC_getclipboard - - -
PDC_setclipboard - - -
PDC_freeclipboard - - -
PDC_clearclipboard - - -
**man-end****************************************************************/
/* global clipboard contents, should be NULL if none set */
static char *pdc_SDL_clipboard = NULL;
int PDC_getclipboard(char **contents, long *length)
{
int len;
PDC_LOG(("PDC_getclipboard() - called\n"));
if (!pdc_SDL_clipboard)
return PDC_CLIP_EMPTY;
len = strlen(pdc_SDL_clipboard);
if ((*contents = malloc(len + 1)) == NULL)
return PDC_CLIP_MEMORY_ERROR;
strcpy(*contents, pdc_SDL_clipboard);
*length = len;
return PDC_CLIP_SUCCESS;
}
int PDC_setclipboard(const char *contents, long length)
{
PDC_LOG(("PDC_setclipboard() - called\n"));
if (pdc_SDL_clipboard)
{
free(pdc_SDL_clipboard);
pdc_SDL_clipboard = NULL;
}
if (contents)
{
if ((pdc_SDL_clipboard = malloc(length + 1)) == NULL)
return PDC_CLIP_MEMORY_ERROR;
strcpy(pdc_SDL_clipboard, contents);
}
return PDC_CLIP_SUCCESS;
}
int PDC_freeclipboard(char *contents)
{
PDC_LOG(("PDC_freeclipboard() - called\n"));
/* should we also free empty the system clipboard? probably not */
if (contents)
{
/* NOTE: We free the memory, but we can not set caller's pointer
to NULL, so if caller calls again then will try to access
free'd memory. We 1st overwrite memory with a string so if
caller tries to use free memory they won't get what they
expect & hopefully notice. */
/* memset(contents, 0xFD, strlen(contents)); */
if (strlen(contents) >= strlen("PDCURSES"))
strcpy(contents, "PDCURSES");
free(contents);
}
return PDC_CLIP_SUCCESS;
}
int PDC_clearclipboard(void)
{
PDC_LOG(("PDC_clearclipboard() - called\n"));
if (pdc_SDL_clipboard)
{
free(pdc_SDL_clipboard);
pdc_SDL_clipboard = NULL;
}
return PDC_CLIP_SUCCESS;
}

View File

@ -0,0 +1,542 @@
/* PDCurses */
#include "pdcsdl.h"
#include "hbox.h"
#include <stdlib.h>
#include <string.h>
#ifdef PDC_WIDE
# include "common/acsgr.h"
#else
# include "common/acs437.h"
#endif
#define MAXRECT 200 /* maximum number of rects to queue up before
an update is forced; the number was chosen
arbitrarily */
static SDL_Rect uprect[MAXRECT]; /* table of rects to update */
static chtype oldch = (chtype)(-1); /* current attribute */
static int rectcount = 0; /* index into uprect */
static short foregr = -2, backgr = -2; /* current foreground, background */
static bool blinked_off = FALSE;
/* do the real updates on a delay */
void PDC_update_rects(void)
{
if (rectcount)
{
/* if the maximum number of rects has been reached, we're
probably better off doing a full screen update */
if (rectcount == MAXRECT)
SDL_Flip(pdc_screen);
else
SDL_UpdateRects(pdc_screen, rectcount, uprect);
rectcount = 0;
}
}
/* set the font colors to match the chtype's attribute */
static void _set_attr(chtype ch)
{
attr_t sysattrs = SP->termattrs;
#ifdef PDC_WIDE
/*
TTF_SetFontStyle(pdc_ttffont,
( ((ch & A_BOLD) && (sysattrs & A_BOLD)) ?
TTF_STYLE_BOLD : 0) |
( ((ch & A_ITALIC) && (sysattrs & A_ITALIC)) ?
TTF_STYLE_ITALIC : 0) );
*/
#endif
ch &= (A_COLOR|A_BOLD|A_BLINK|A_REVERSE);
if (oldch != ch)
{
short newfg, newbg;
if (SP->mono)
return;
pair_content(PAIR_NUMBER(ch), &newfg, &newbg);
if ((ch & A_BOLD) && !(sysattrs & A_BOLD))
newfg |= 8;
if ((ch & A_BLINK) && !(sysattrs & A_BLINK))
newbg |= 8;
if (ch & A_REVERSE)
{
short tmp = newfg;
newfg = newbg;
newbg = tmp;
}
if (newfg != foregr)
{
#ifndef PDC_WIDE
SDL_SetPalette(pdc_font, SDL_LOGPAL,
pdc_color + newfg, pdc_flastc, 1);
#endif
foregr = newfg;
}
if (newbg != backgr)
{
#ifndef PDC_WIDE
if (newbg == -1)
SDL_SetColorKey(pdc_font, SDL_SRCCOLORKEY, 0);
else
{
if (backgr == -1)
SDL_SetColorKey(pdc_font, 0, 0);
SDL_SetPalette(pdc_font, SDL_LOGPAL,
pdc_color + newbg, 0, 1);
}
#endif
backgr = newbg;
}
oldch = ch;
}
}
#ifdef PDC_WIDE
/* Draw some of the ACS_* "graphics" */
bool _grprint(chtype ch, SDL_Rect dest)
{
Uint32 col = pdc_mapped[foregr];
int hmid = (pdc_fheight - pdc_fthick) >> 1;
int wmid = (pdc_fwidth - pdc_fthick) >> 1;
switch (ch)
{
case ACS_ULCORNER:
dest.h = pdc_fheight - hmid;
dest.y += hmid;
dest.w = pdc_fthick;
dest.x += wmid;
SDL_FillRect(pdc_screen, &dest, col);
dest.w = pdc_fwidth - wmid;
goto S1;
case ACS_LLCORNER:
dest.h = hmid;
dest.w = pdc_fthick;
dest.x += wmid;
SDL_FillRect(pdc_screen, &dest, col);
dest.w = pdc_fwidth - wmid;
dest.y += hmid;
goto S1;
case ACS_URCORNER:
dest.h = pdc_fheight - hmid;
dest.w = pdc_fthick;
dest.y += hmid;
dest.x += wmid;
SDL_FillRect(pdc_screen, &dest, col);
dest.w = wmid;
dest.x -= wmid;
goto S1;
case ACS_LRCORNER:
dest.h = hmid + pdc_fthick;
dest.w = pdc_fthick;
dest.x += wmid;
SDL_FillRect(pdc_screen, &dest, col);
dest.w = wmid;
dest.x -= wmid;
dest.y += hmid;
goto S1;
case ACS_LTEE:
dest.h = pdc_fthick;
dest.w = pdc_fwidth - wmid;
dest.x += wmid;
dest.y += hmid;
SDL_FillRect(pdc_screen, &dest, col);
dest.w = pdc_fthick;
dest.x -= wmid;
goto VLINE;
case ACS_RTEE:
dest.w = wmid;
case ACS_PLUS:
dest.h = pdc_fthick;
dest.y += hmid;
SDL_FillRect(pdc_screen, &dest, col);
VLINE:
dest.h = pdc_fheight;
dest.y -= hmid;
case ACS_VLINE:
dest.w = pdc_fthick;
dest.x += wmid;
goto DRAW;
case ACS_TTEE:
dest.h = pdc_fheight - hmid;
dest.w = pdc_fthick;
dest.x += wmid;
dest.y += hmid;
SDL_FillRect(pdc_screen, &dest, col);
dest.w = pdc_fwidth;
dest.x -= wmid;
goto S1;
case ACS_BTEE:
dest.h = hmid;
dest.w = pdc_fthick;
dest.x += wmid;
SDL_FillRect(pdc_screen, &dest, col);
dest.w = pdc_fwidth;
dest.x -= wmid;
case ACS_HLINE:
dest.y += hmid;
goto S1;
case ACS_S3:
dest.y += hmid >> 1;
goto S1;
case ACS_S7:
dest.y += hmid + (hmid >> 1);
goto S1;
case ACS_S9:
dest.y += pdc_fheight - pdc_fthick;
case ACS_S1:
S1:
dest.h = pdc_fthick;
case ACS_BLOCK:
DRAW:
SDL_FillRect(pdc_screen, &dest, col);
return TRUE;
default:
;
}
return FALSE; /* didn't draw it -- fall back to acs_map */
}
#endif
/* draw a cursor at (y, x) */
void PDC_gotoyx(int row, int col)
{
SDL_Rect src, dest;
chtype ch;
int oldrow, oldcol;
#ifdef PDC_WIDE
Uint16 chstr[2] = {0, 0};
#endif
PDC_LOG(("PDC_gotoyx() - called: row %d col %d from row %d col %d\n",
row, col, SP->cursrow, SP->curscol));
oldrow = SP->cursrow;
oldcol = SP->curscol;
/* clear the old cursor */
PDC_transform_line(oldrow, oldcol, 1, curscr->_y[oldrow] + oldcol);
if (!SP->visibility)
return;
/* draw a new cursor by overprinting the existing character in
reverse, either the full cell (when visibility == 2) or the
lowest quarter of it (when visibility == 1) */
ch = curscr->_y[row][col] ^ A_REVERSE;
_set_attr(ch);
src.h = (SP->visibility == 1) ? pdc_fheight >> 2 : pdc_fheight;
src.w = pdc_fwidth;
dest.y = (row + 1) * pdc_fheight - src.h + pdc_yoffset;
dest.x = col * pdc_fwidth + pdc_xoffset;
dest.h = src.h;
dest.w = src.w;
#ifdef PDC_WIDE
SDL_FillRect(pdc_screen, &dest, pdc_mapped[backgr]);
if (!(SP->visibility == 2 && (ch & A_ALTCHARSET && !(ch & 0xff80)) &&
_grprint(ch & (0x7f | A_ALTCHARSET), dest)))
{
if (ch & A_ALTCHARSET && !(ch & 0xff80))
ch = acs_map[ch & 0x7f];
chstr[0] = ch & A_CHARTEXT;
{
char utf8str[8]= {0};
hunicode_char_t unicodestr[3]= {chstr[0],chstr[1]};
hunicode_char_string_to_utf8(utf8str,sizeof(utf8str)-1,unicodestr);
pdc_font = TTF_RenderUTF8_Solid(pdc_ttffont, utf8str,
pdc_color[foregr]);
}
if (pdc_font)
{
int center = pdc_fwidth > pdc_font->w ?
(pdc_fwidth - pdc_font->w) >> 1 : 0;
src.x = 0;
src.y = pdc_fheight - src.h;
dest.x += center;
SDL_BlitSurface(pdc_font, &src, pdc_screen, &dest);
dest.x -= center;
SDL_FreeSurface(pdc_font);
pdc_font = NULL;
}
}
#else
if (ch & A_ALTCHARSET && !(ch & 0xff80))
ch = acs_map[ch & 0x7f];
src.x = (ch & 0xff) % 32 * pdc_fwidth;
src.y = (ch & 0xff) / 32 * pdc_fheight + (pdc_fheight - src.h);
SDL_BlitSurface(pdc_font, &src, pdc_screen, &dest);
#endif
if (oldrow != row || oldcol != col)
{
if (rectcount == MAXRECT)
PDC_update_rects();
uprect[rectcount++] = dest;
}
}
void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp)
{
SDL_Rect src, dest, lastrect;
int j;
#ifdef PDC_WIDE
Uint16 chstr[2] = {0, 0};
#endif
attr_t sysattrs = SP->termattrs;
short hcol = SP->line_color;
bool blink = blinked_off && (attr & A_BLINK) && (sysattrs & A_BLINK);
if (rectcount == MAXRECT)
PDC_update_rects();
#ifdef PDC_WIDE
src.x = 0;
src.y = 0;
#endif
src.h = pdc_fheight;
src.w = pdc_fwidth;
dest.y = pdc_fheight * lineno + pdc_yoffset;
dest.x = pdc_fwidth * x + pdc_xoffset;
dest.h = pdc_fheight;
dest.w = pdc_fwidth * len;
/* if the previous rect was just above this one, with the same width
and horizontal position, then merge the new one with it instead
of adding a new entry */
if (rectcount)
lastrect = uprect[rectcount - 1];
if (rectcount && lastrect.x == dest.x && lastrect.w == dest.w)
{
if (lastrect.y + lastrect.h == dest.y)
uprect[rectcount - 1].h = lastrect.h + pdc_fheight;
else if (lastrect.y != dest.y)
uprect[rectcount++] = dest;
}
else
uprect[rectcount++] = dest;
_set_attr(attr);
if (backgr == -1)
SDL_LowerBlit(pdc_tileback, &dest, pdc_screen, &dest);
#ifdef PDC_WIDE
else
SDL_FillRect(pdc_screen, &dest, pdc_mapped[backgr]);
#endif
if (hcol == -1)
hcol = foregr;
for (j = 0; j < len; j++)
{
chtype ch = srcp[j];
if (blink)
ch = ' ';
dest.w = pdc_fwidth;
if (ch & A_ALTCHARSET && !(ch & 0xff80))
{
#ifdef PDC_WIDE
if (_grprint(ch & (0x7f | A_ALTCHARSET), dest))
{
dest.x += pdc_fwidth;
continue;
}
#endif
ch = acs_map[ch & 0x7f];
}
#ifdef PDC_WIDE
ch &= A_CHARTEXT;
if (ch != ' ')
{
if (chstr[0] != ch)
{
chstr[0] = ch;
if (pdc_font)
SDL_FreeSurface(pdc_font);
{
char utf8str[8]= {0};
hunicode_char_t unicodestr[3]= {chstr[0],chstr[1]};
hunicode_char_string_to_utf8(utf8str,sizeof(utf8str)-1,unicodestr);
pdc_font = TTF_RenderUTF8_Solid(pdc_ttffont, utf8str,
pdc_color[foregr]);
}
}
if (pdc_font)
{
int center = pdc_fwidth > pdc_font->w ?
(pdc_fwidth - pdc_font->w) >> 1 : 0;
dest.x += center;
SDL_BlitSurface(pdc_font, &src, pdc_screen, &dest);
dest.x -= center;
}
}
#else
src.x = (ch & 0xff) % 32 * pdc_fwidth;
src.y = (ch & 0xff) / 32 * pdc_fheight;
SDL_LowerBlit(pdc_font, &src, pdc_screen, &dest);
#endif
if (!blink && (attr & (A_LEFT | A_RIGHT)))
{
dest.w = pdc_fthick;
if (attr & A_LEFT)
SDL_FillRect(pdc_screen, &dest, pdc_mapped[hcol]);
if (attr & A_RIGHT)
{
dest.x += pdc_fwidth - pdc_fthick;
SDL_FillRect(pdc_screen, &dest, pdc_mapped[hcol]);
dest.x -= pdc_fwidth - pdc_fthick;
}
}
dest.x += pdc_fwidth;
}
#ifdef PDC_WIDE
if (pdc_font)
{
SDL_FreeSurface(pdc_font);
pdc_font = NULL;
}
#endif
if (!blink && (attr & A_UNDERLINE))
{
dest.y += pdc_fheight - pdc_fthick;
dest.x = pdc_fwidth * x + pdc_xoffset;
dest.h = pdc_fthick;
dest.w = pdc_fwidth * len;
SDL_FillRect(pdc_screen, &dest, pdc_mapped[hcol]);
}
}
/* update the given physical line to look like the corresponding line in
curscr */
void PDC_transform_line(int lineno, int x, int len, const chtype *srcp)
{
attr_t old_attr, attr;
int i, j;
PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno));
old_attr = *srcp & (A_ATTRIBUTES ^ A_ALTCHARSET);
for (i = 1, j = 1; j < len; i++, j++)
{
attr = srcp[i] & (A_ATTRIBUTES ^ A_ALTCHARSET);
if (attr != old_attr)
{
_new_packet(old_attr, lineno, x, i, srcp);
old_attr = attr;
srcp += i;
x += i;
i = 0;
}
}
_new_packet(old_attr, lineno, x, i, srcp);
}
static Uint32 _blink_timer(Uint32 interval, void *param)
{
SDL_Event event;
event.type = SDL_USEREVENT;
SDL_PushEvent(&event);
return(interval);
}
void PDC_blink_text(void)
{
static SDL_TimerID blinker_id = 0;
int i, j, k;
oldch = (chtype)(-1);
if (!(SP->termattrs & A_BLINK))
{
SDL_RemoveTimer(blinker_id);
blinker_id = 0;
}
else if (!blinker_id)
{
blinker_id = SDL_AddTimer(500, _blink_timer, NULL);
blinked_off = TRUE;
}
blinked_off = !blinked_off;
for (i = 0; i < SP->lines; i++)
{
const chtype *srcp = curscr->_y[i];
for (j = 0; j < SP->cols; j++)
if (srcp[j] & A_BLINK)
{
k = j;
while (k < SP->cols && (srcp[k] & A_BLINK))
k++;
PDC_transform_line(i, j, k - j, srcp + j);
j = k;
}
}
oldch = (chtype)(-1);
}
void PDC_doupdate(void)
{
PDC_napms(1);
}

View File

@ -0,0 +1,30 @@
/* PDCurses */
#include "pdcsdl.h"
/* get the cursor size/shape */
int PDC_get_cursor_mode(void)
{
PDC_LOG(("PDC_get_cursor_mode() - called\n"));
return 0;
}
/* return number of screen rows */
int PDC_get_rows(void)
{
PDC_LOG(("PDC_get_rows() - called\n"));
return pdc_sheight / pdc_fheight;
}
/* return width of screen/viewport */
int PDC_get_columns(void)
{
PDC_LOG(("PDC_get_columns() - called\n"));
return pdc_swidth / pdc_fwidth;
}

View File

@ -0,0 +1,373 @@
/* PDCurses */
#include "pdcsdl.h"
#include <string.h>
static SDL_Event event;
static SDLKey oldkey;
static MOUSE_STATUS old_mouse_status;
static struct
{
SDLKey keycode;
bool numkeypad;
unsigned short normal;
unsigned short shifted;
unsigned short control;
unsigned short alt;
} key_table[] =
{
/* keycode keypad normal shifted control alt*/
{SDLK_LEFT, FALSE, KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT},
{SDLK_RIGHT, FALSE, KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT},
{SDLK_UP, FALSE, KEY_UP, KEY_SUP, CTL_UP, ALT_UP},
{SDLK_DOWN, FALSE, KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN},
{SDLK_HOME, FALSE, KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME},
{SDLK_END, FALSE, KEY_END, KEY_SEND, CTL_END, ALT_END},
{SDLK_PAGEUP, FALSE, KEY_PPAGE, KEY_SPREVIOUS,CTL_PGUP, ALT_PGUP},
{SDLK_PAGEDOWN,FALSE, KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN},
{SDLK_INSERT, FALSE, KEY_IC, KEY_SIC, CTL_INS, ALT_INS},
{SDLK_DELETE, FALSE, KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL},
{SDLK_F1, FALSE, KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37)},
{SDLK_F2, FALSE, KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38)},
{SDLK_F3, FALSE, KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39)},
{SDLK_F4, FALSE, KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40)},
{SDLK_F5, FALSE, KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41)},
{SDLK_F6, FALSE, KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42)},
{SDLK_F7, FALSE, KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43)},
{SDLK_F8, FALSE, KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44)},
{SDLK_F9, FALSE, KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45)},
{SDLK_F10, FALSE, KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46)},
{SDLK_F11, FALSE, KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47)},
{SDLK_F12, FALSE, KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48)},
{SDLK_F13, FALSE, KEY_F(13), KEY_F(25), KEY_F(37), KEY_F(49)},
{SDLK_F14, FALSE, KEY_F(14), KEY_F(26), KEY_F(38), KEY_F(50)},
{SDLK_F15, FALSE, KEY_F(15), KEY_F(27), KEY_F(39), KEY_F(51)},
{SDLK_BACKSPACE,FALSE, 0x08, 0x08, CTL_BKSP, ALT_BKSP},
{SDLK_TAB, FALSE, 0x09, KEY_BTAB, CTL_TAB, ALT_TAB},
{SDLK_PRINT, FALSE, KEY_PRINT, KEY_SPRINT, KEY_PRINT, KEY_PRINT},
{SDLK_PAUSE, FALSE, KEY_SUSPEND, KEY_SSUSPEND, KEY_SUSPEND, KEY_SUSPEND},
{SDLK_CLEAR, FALSE, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR},
{SDLK_BREAK, FALSE, KEY_BREAK, KEY_BREAK, KEY_BREAK, KEY_BREAK},
{SDLK_HELP, FALSE, KEY_HELP, KEY_SHELP, KEY_LHELP, KEY_HELP},
{SDLK_MENU, FALSE, KEY_OPTIONS, KEY_SOPTIONS, KEY_OPTIONS, KEY_OPTIONS},
{SDLK_ESCAPE, FALSE, 0x1B, 0x1B, 0x1B, ALT_ESC},
{SDLK_KP_ENTER,TRUE, PADENTER, PADENTER, CTL_PADENTER,ALT_PADENTER},
{SDLK_KP_PLUS, TRUE, PADPLUS, '+', CTL_PADPLUS, ALT_PADPLUS},
{SDLK_KP_MINUS,TRUE, PADMINUS, '-', CTL_PADMINUS,ALT_PADMINUS},
{SDLK_KP_MULTIPLY,TRUE,PADSTAR, '*', CTL_PADSTAR, ALT_PADSTAR},
{SDLK_KP_DIVIDE,TRUE, PADSLASH, '/', CTL_PADSLASH,ALT_PADSLASH},
{SDLK_KP_PERIOD,TRUE, PADSTOP, '.', CTL_PADSTOP, ALT_PADSTOP},
{SDLK_KP0, TRUE, PAD0, '0', CTL_PAD0, ALT_PAD0},
{SDLK_KP1, TRUE, KEY_C1, '1', CTL_PAD1, ALT_PAD1},
{SDLK_KP2, TRUE, KEY_C2, '2', CTL_PAD2, ALT_PAD2},
{SDLK_KP3, TRUE, KEY_C3, '3', CTL_PAD3, ALT_PAD3},
{SDLK_KP4, TRUE, KEY_B1, '4', CTL_PAD4, ALT_PAD4},
{SDLK_KP5, TRUE, KEY_B2, '5', CTL_PAD5, ALT_PAD5},
{SDLK_KP6, TRUE, KEY_B3, '6', CTL_PAD6, ALT_PAD6},
{SDLK_KP7, TRUE, KEY_A1, '7', CTL_PAD7, ALT_PAD7},
{SDLK_KP8, TRUE, KEY_A2, '8', CTL_PAD8, ALT_PAD8},
{SDLK_KP9, TRUE, KEY_A3, '9', CTL_PAD9, ALT_PAD9},
{0, 0, 0, 0, 0, 0}
};
void PDC_set_keyboard_binary(bool on)
{
PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
}
/* check if a key or mouse event is waiting */
bool PDC_check_key(void)
{
int haveevent = SDL_PollEvent(&event);
return haveevent;
}
static int _process_key_event(void)
{
int i, key = 0;
SP->key_modifiers = 0L;
SP->key_code = FALSE;
if (event.type == SDL_KEYUP)
{
if (SP->return_key_modifiers && event.key.keysym.sym == oldkey)
{
SP->key_code = TRUE;
switch (oldkey)
{
case SDLK_RSHIFT:
return KEY_SHIFT_R;
case SDLK_LSHIFT:
return KEY_SHIFT_L;
case SDLK_RCTRL:
return KEY_CONTROL_R;
case SDLK_LCTRL:
return KEY_CONTROL_L;
case SDLK_RALT:
return KEY_ALT_R;
case SDLK_LALT:
return KEY_ALT_L;
default:
break;
}
SP->key_code = FALSE;
}
return -1;
}
oldkey = event.key.keysym.sym;
if (event.key.keysym.mod & KMOD_NUM)
SP->key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
if (event.key.keysym.mod & KMOD_SHIFT)
SP->key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
if (event.key.keysym.mod & KMOD_CTRL)
SP->key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
if (event.key.keysym.mod & KMOD_ALT)
SP->key_modifiers |= PDC_KEY_MODIFIER_ALT;
for (i = 0; key_table[i].keycode; i++)
{
if (key_table[i].keycode == event.key.keysym.sym)
{
if ((event.key.keysym.mod & KMOD_SHIFT) ||
(key_table[i].numkeypad && (event.key.keysym.mod & KMOD_NUM)))
{
key = key_table[i].shifted;
}
else if (event.key.keysym.mod & KMOD_CTRL)
{
key = key_table[i].control;
}
else if (event.key.keysym.mod & KMOD_ALT)
{
key = key_table[i].alt;
}
/* To get here, we ignore all other modifiers */
else
key = key_table[i].normal;
SP->key_code = (key > 0x100);
break;
}
}
if (!key)
{
key = event.key.keysym.unicode;
if (key > 0x7f)
key = 0;
}
/* Handle ALT letters and numbers */
if (event.key.keysym.mod & KMOD_ALT)
{
if (key >= 'A' && key <= 'Z')
{
key += ALT_A - 'A';
SP->key_code = TRUE;
}
if (key >= 'a' && key <= 'z')
{
key += ALT_A - 'a';
SP->key_code = TRUE;
}
if (key >= '0' && key <= '9')
{
key += ALT_0 - '0';
SP->key_code = TRUE;
}
}
return key ? key : -1;
}
static int _process_mouse_event(void)
{
SDLMod keymods;
short shift_flags = 0;
memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS));
keymods = SDL_GetModState();
if (keymods & KMOD_SHIFT)
shift_flags |= BUTTON_SHIFT;
if (keymods & KMOD_CTRL)
shift_flags |= BUTTON_CONTROL;
if (keymods & KMOD_ALT)
shift_flags |= BUTTON_ALT;
if (event.type == SDL_MOUSEMOTION)
{
int i;
SP->mouse_status.x = (event.motion.x - pdc_xoffset) / pdc_fwidth;
SP->mouse_status.y = (event.motion.y - pdc_yoffset) / pdc_fheight;
if (!event.motion.state ||
(SP->mouse_status.x == old_mouse_status.x &&
SP->mouse_status.y == old_mouse_status.y))
return -1;
SP->mouse_status.changes = PDC_MOUSE_MOVED;
for (i = 0; i < 3; i++)
{
if (event.motion.state & SDL_BUTTON(i + 1))
{
SP->mouse_status.button[i] = BUTTON_MOVED | shift_flags;
SP->mouse_status.changes |= (1 << i);
}
}
}
else
{
short action = (event.button.state == SDL_PRESSED) ?
BUTTON_PRESSED : BUTTON_RELEASED;
Uint8 btn = event.button.button;
SP->mouse_status.x = (event.button.x - pdc_xoffset) / pdc_fwidth;
SP->mouse_status.y = (event.button.y - pdc_yoffset) / pdc_fheight;
/* handle scroll wheel */
if ((btn >= 4 && btn <= 7) && action == BUTTON_RELEASED)
{
switch (btn)
{
case 4:
SP->mouse_status.changes = PDC_MOUSE_WHEEL_UP;
break;
case 5:
SP->mouse_status.changes = PDC_MOUSE_WHEEL_DOWN;
break;
case 6:
SP->mouse_status.changes = PDC_MOUSE_WHEEL_LEFT;
break;
case 7:
SP->mouse_status.changes = PDC_MOUSE_WHEEL_RIGHT;
}
SP->key_code = TRUE;
return KEY_MOUSE;
}
if (btn < 1 || btn > 3)
return -1;
/* check for a click -- a press followed immediately by a release */
if (action == BUTTON_PRESSED && SP->mouse_wait)
{
SDL_Event rel;
napms(SP->mouse_wait);
if (SDL_PollEvent(&rel))
{
if (rel.type == SDL_MOUSEBUTTONUP && rel.button.button == btn)
action = BUTTON_CLICKED;
else
SDL_PushEvent(&rel);
}
}
btn--;
SP->mouse_status.button[btn] = action | shift_flags;
SP->mouse_status.changes = (1 << btn);
}
old_mouse_status = SP->mouse_status;
SP->key_code = TRUE;
return KEY_MOUSE;
}
/* return the next available key or mouse event */
int PDC_get_key(void)
{
switch (event.type)
{
case SDL_QUIT:
exit(1);
case SDL_VIDEORESIZE:
if (pdc_own_screen &&
(event.resize.h / pdc_fheight != LINES ||
event.resize.w / pdc_fwidth != COLS))
{
pdc_sheight = event.resize.h;
pdc_swidth = event.resize.w;
if (!SP->resized)
{
SP->resized = TRUE;
SP->key_code = TRUE;
return KEY_RESIZE;
}
}
break;
case SDL_MOUSEMOTION:
SDL_ShowCursor(SDL_ENABLE);
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
oldkey = SDLK_SPACE;
return _process_mouse_event();
case SDL_KEYUP:
case SDL_KEYDOWN:
PDC_mouse_set();
return _process_key_event();
case SDL_USEREVENT:
PDC_blink_text();
}
return -1;
}
/* discard any pending keyboard or mouse input -- this is the core
routine for flushinp() */
void PDC_flushinp(void)
{
PDC_LOG(("PDC_flushinp() - called\n"));
while (PDC_check_key());
}
bool PDC_has_mouse(void)
{
return TRUE;
}
int PDC_mouse_set(void)
{
SDL_ShowCursor(SP->_trap_mbe ? SDL_ENABLE : SDL_DISABLE);
return OK;
}
int PDC_modifiers_set(void)
{
return OK;
}

View File

@ -0,0 +1,368 @@
/* PDCurses */
#include "pdcsdl.h"
#include <stdlib.h>
#ifndef PDC_WIDE
#include "common/font437.h"
#endif
#include "common/iconbmp.h"
#ifdef PDC_WIDE
# ifndef PDC_FONT_PATH
# if defined(__APPLE__)
# define PDC_FONT_PATH "/System/Library/Fonts/Menlo.ttc"
# else
# define PDC_FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf"
# endif
# endif
TTF_Font *pdc_ttffont = NULL;
int pdc_font_size = 17;
#endif
SDL_Surface *pdc_screen = NULL, *pdc_font = NULL, *pdc_icon = NULL,
*pdc_back = NULL, *pdc_tileback = NULL;
int pdc_sheight = 0, pdc_swidth = 0, pdc_yoffset = 0, pdc_xoffset = 0;
SDL_Color pdc_color[PDC_MAXCOL];
Uint32 pdc_mapped[PDC_MAXCOL];
int pdc_fheight, pdc_fwidth, pdc_fthick, pdc_flastc;
bool pdc_own_screen;
static int max_height, max_width;
static void _clean(void)
{
#ifdef PDC_WIDE
if (pdc_ttffont)
{
TTF_CloseFont(pdc_ttffont);
TTF_Quit();
}
#endif
SDL_FreeSurface(pdc_tileback);
SDL_FreeSurface(pdc_back);
SDL_FreeSurface(pdc_icon);
SDL_FreeSurface(pdc_font);
SDL_Quit();
}
void PDC_retile(void)
{
if (pdc_tileback)
SDL_FreeSurface(pdc_tileback);
pdc_tileback = SDL_DisplayFormatAlpha(pdc_screen);
if (pdc_tileback == NULL)
return;
if (pdc_back)
{
SDL_Rect dest;
dest.y = 0;
while (dest.y < pdc_tileback->h)
{
dest.x = 0;
while (dest.x < pdc_tileback->w)
{
SDL_BlitSurface(pdc_back, 0, pdc_tileback, &dest);
dest.x += pdc_back->w;
}
dest.y += pdc_back->h;
}
SDL_BlitSurface(pdc_tileback, 0, pdc_screen, 0);
}
}
void PDC_scr_close(void)
{
PDC_LOG(("PDC_scr_close() - called\n"));
}
void PDC_scr_free(void)
{
}
static void _initialize_colors(void)
{
int i, r, g, b;
for (i = 0; i < 8; i++)
{
pdc_color[i].r = (i & COLOR_RED) ? 0xc0 : 0;
pdc_color[i].g = (i & COLOR_GREEN) ? 0xc0 : 0;
pdc_color[i].b = (i & COLOR_BLUE) ? 0xc0 : 0;
pdc_color[i + 8].r = (i & COLOR_RED) ? 0xff : 0x40;
pdc_color[i + 8].g = (i & COLOR_GREEN) ? 0xff : 0x40;
pdc_color[i + 8].b = (i & COLOR_BLUE) ? 0xff : 0x40;
}
/* 256-color xterm extended palette: 216 colors in a 6x6x6 color
cube, plus 24 shades of gray */
for (i = 16, r = 0; r < 6; r++)
for (g = 0; g < 6; g++)
for (b = 0; b < 6; b++, i++)
{
pdc_color[i].r = (r ? r * 40 + 55 : 0);
pdc_color[i].g = (g ? g * 40 + 55 : 0);
pdc_color[i].b = (b ? b * 40 + 55 : 0);
}
for (i = 232; i < 256; i++)
pdc_color[i].r = pdc_color[i].g = pdc_color[i].b = (i - 232) * 10 + 8;
for (i = 0; i < 256; i++)
pdc_mapped[i] = SDL_MapRGB(pdc_screen->format, pdc_color[i].r,
pdc_color[i].g, pdc_color[i].b);
}
/* open the physical screen -- miscellaneous initialization */
int PDC_scr_open(void)
{
PDC_LOG(("PDC_scr_open() - called\n"));
pdc_own_screen = !pdc_screen;
if (pdc_own_screen)
{
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)
{
fprintf(stderr, "Could not start SDL: %s\n", SDL_GetError());
return ERR;
}
atexit(_clean);
}
#ifdef PDC_WIDE
if (!pdc_ttffont)
{
const char *ptsz, *fname;
if (TTF_Init() == -1)
{
fprintf(stderr, "Could not start SDL_TTF: %s\n", SDL_GetError());
return ERR;
}
ptsz = getenv("PDC_FONT_SIZE");
if (ptsz != NULL)
pdc_font_size = atoi(ptsz);
if (pdc_font_size <= 0)
pdc_font_size = 18;
fname = getenv("PDC_FONT");
pdc_ttffont = TTF_OpenFont(fname ? fname : PDC_FONT_PATH,
pdc_font_size);
}
if (!pdc_ttffont)
{
fprintf(stderr, "Could not load font\n");
return ERR;
}
//TTF_SetFontKerning(pdc_ttffont, 0);
//TTF_SetFontHinting(pdc_ttffont, TTF_HINTING_MONO);
SP->mono = FALSE;
#else
if (!pdc_font)
{
const char *fname = getenv("PDC_FONT");
pdc_font = SDL_LoadBMP(fname ? fname : "pdcfont.bmp");
}
if (!pdc_font)
pdc_font = SDL_LoadBMP_RW(SDL_RWFromMem(font437, sizeof(font437)), 0);
if (!pdc_font)
{
fprintf(stderr, "Could not load font\n");
return ERR;
}
SP->mono = !pdc_font->format->palette;
#endif
if (!SP->mono && !pdc_back)
{
const char *bname = getenv("PDC_BACKGROUND");
pdc_back = SDL_LoadBMP(bname ? bname : "pdcback.bmp");
}
if (!SP->mono && (pdc_back || !pdc_own_screen))
{
SP->orig_attr = TRUE;
SP->orig_fore = COLOR_WHITE;
SP->orig_back = -1;
}
else
SP->orig_attr = FALSE;
#ifdef PDC_WIDE
TTF_SizeText(pdc_ttffont, "W", &pdc_fwidth, &pdc_fheight);
pdc_fthick = pdc_font_size / 20 + 1;
#else
pdc_fheight = pdc_font->h / 8;
pdc_fwidth = pdc_font->w / 32;
pdc_fthick = 1;
if (!SP->mono)
pdc_flastc = pdc_font->format->palette->ncolors - 1;
#endif
if (pdc_own_screen && !pdc_icon)
{
const char *iname = getenv("PDC_ICON");
pdc_icon = SDL_LoadBMP(iname ? iname : "pdcicon.bmp");
if (!pdc_icon)
pdc_icon = SDL_LoadBMP_RW(SDL_RWFromMem(iconbmp,
sizeof(iconbmp)), 0);
if (pdc_icon)
SDL_WM_SetIcon(pdc_icon, NULL);
}
if (pdc_own_screen)
{
const SDL_VideoInfo *info = SDL_GetVideoInfo();
max_height = info->current_h;
max_width = info->current_w;
const char *env = getenv("PDC_LINES");
pdc_sheight = (env ? atoi(env) : 25) * pdc_fheight;
env = getenv("PDC_COLS");
pdc_swidth = (env ? atoi(env) : 80) * pdc_fwidth;
pdc_screen = SDL_SetVideoMode(pdc_swidth, pdc_sheight, 0,
SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE);
}
else
{
if (!pdc_sheight)
pdc_sheight = pdc_screen->h - pdc_yoffset;
if (!pdc_swidth)
pdc_swidth = pdc_screen->w - pdc_xoffset;
}
if (!pdc_screen)
{
fprintf(stderr, "Couldn't create a surface: %s\n", SDL_GetError());
return ERR;
}
if (SP->orig_attr)
PDC_retile();
_initialize_colors();
SDL_EnableUNICODE(1);
PDC_mouse_set();
if (pdc_own_screen)
PDC_set_title("PDCurses");
SP->mouse_wait = PDC_CLICK_PERIOD;
SP->audible = FALSE;
SP->termattrs = A_COLOR | A_UNDERLINE | A_LEFT | A_RIGHT | A_REVERSE;
#ifdef PDC_WIDE
SP->termattrs |= A_ITALIC;
#endif
PDC_reset_prog_mode();
return OK;
}
/* the core of resize_term() */
int PDC_resize_screen(int nlines, int ncols)
{
if (!pdc_own_screen)
return ERR;
if (nlines && ncols)
{
while (nlines * pdc_fheight > max_height)
nlines--;
pdc_sheight = nlines * pdc_fheight;
while (ncols * pdc_fwidth > max_width)
ncols--;
pdc_swidth = ncols * pdc_fwidth;
}
SDL_FreeSurface(pdc_screen);
pdc_screen = SDL_SetVideoMode(pdc_swidth, pdc_sheight, 0,
SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE);
if (pdc_tileback)
PDC_retile();
return OK;
}
void PDC_reset_prog_mode(void)
{
PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
PDC_flushinp();
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
}
void PDC_reset_shell_mode(void)
{
PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
SDL_EnableKeyRepeat(0, 0);
PDC_flushinp();
}
void PDC_restore_screen_mode(int i)
{
}
void PDC_save_screen_mode(int i)
{
}
bool PDC_can_change_color(void)
{
return TRUE;
}
int PDC_color_content(short color, short *red, short *green, short *blue)
{
*red = DIVROUND(pdc_color[color].r * 1000, 255);
*green = DIVROUND(pdc_color[color].g * 1000, 255);
*blue = DIVROUND(pdc_color[color].b * 1000, 255);
return OK;
}
int PDC_init_color(short color, short red, short green, short blue)
{
pdc_color[color].r = DIVROUND(red * 255, 1000);
pdc_color[color].g = DIVROUND(green * 255, 1000);
pdc_color[color].b = DIVROUND(blue * 255, 1000);
pdc_mapped[color] = SDL_MapRGB(pdc_screen->format, pdc_color[color].r,
pdc_color[color].g, pdc_color[color].b);
return OK;
}

View File

@ -0,0 +1,35 @@
/* PDCurses */
#include <stdlib.h>
#include <SDL.h>
#ifdef PDC_WIDE
#include <SDL_ttf.h>
#endif
#include <curspriv.h>
#ifdef PDC_WIDE
PDCEX TTF_Font *pdc_ttffont;
PDCEX int pdc_font_size;
#endif
PDCEX SDL_Surface *pdc_screen, *pdc_font, *pdc_icon, *pdc_back;
PDCEX int pdc_sheight, pdc_swidth, pdc_yoffset, pdc_xoffset;
extern SDL_Surface *pdc_tileback; /* used to regenerate the background
of "transparent" cells */
extern SDL_Color pdc_color[PDC_MAXCOL]; /* colors for font palette */
extern Uint32 pdc_mapped[PDC_MAXCOL]; /* colors for FillRect(), as
used in _highlight() */
extern int pdc_fheight, pdc_fwidth; /* font height and width */
extern int pdc_fthick; /* thickness for highlights and
rendered ACS glyphs */
extern int pdc_flastc; /* font palette's last color
(treated as the foreground) */
extern bool pdc_own_screen; /* if pdc_screen was not set
before initscr(), PDCurses is
responsible for (owns) it */
PDCEX void PDC_update_rects(void);
PDCEX void PDC_retile(void);
extern void PDC_blink_text(void);

View File

@ -0,0 +1,105 @@
/* PDCurses */
#include "pdcsdl.h"
/*man-start**************************************************************
pdcsetsc
--------
### Synopsis
int PDC_set_blink(bool blinkon);
int PDC_set_bold(bool boldon);
void PDC_set_title(const char *title);
### Description
PDC_set_blink() toggles whether the A_BLINK attribute sets an actual
blink mode (TRUE), or sets the background color to high intensity
(FALSE). The default is platform-dependent (FALSE in most cases). It
returns OK if it could set the state to match the given parameter,
ERR otherwise.
PDC_set_bold() toggles whether the A_BOLD attribute selects an actual
bold font (TRUE), or sets the foreground color to high intensity
(FALSE). It returns OK if it could set the state to match the given
parameter, ERR otherwise.
PDC_set_title() sets the title of the window in which the curses
program is running. This function may not do anything on some
platforms.
### Portability
X/Open ncurses NetBSD
PDC_set_blink - - -
PDC_set_title - - -
**man-end****************************************************************/
int PDC_curs_set(int visibility)
{
int ret_vis;
PDC_LOG(("PDC_curs_set() - called: visibility=%d\n", visibility));
ret_vis = SP->visibility;
SP->visibility = visibility;
PDC_gotoyx(SP->cursrow, SP->curscol);
return ret_vis;
}
void PDC_set_title(const char *title)
{
PDC_LOG(("PDC_set_title() - called:<%s>\n", title));
SDL_WM_SetCaption(title, title);
}
int PDC_set_blink(bool blinkon)
{
if (!SP)
return ERR;
if (SP->color_started)
COLORS = PDC_MAXCOL;
if (blinkon)
{
if (!(SP->termattrs & A_BLINK))
{
SP->termattrs |= A_BLINK;
PDC_blink_text();
}
}
else
{
if (SP->termattrs & A_BLINK)
{
SP->termattrs &= ~A_BLINK;
PDC_blink_text();
}
}
return OK;
}
int PDC_set_bold(bool boldon)
{
if (!SP)
return ERR;
#ifdef PDC_WIDE
if (boldon)
SP->termattrs |= A_BOLD;
else
SP->termattrs &= ~A_BOLD;
return OK;
#else
return boldon ? ERR : OK;
#endif
}

View File

@ -0,0 +1,28 @@
/* PDCurses */
#include "pdcsdl.h"
void PDC_beep(void)
{
PDC_LOG(("PDC_beep() - called\n"));
}
void PDC_napms(int ms)
{
PDC_LOG(("PDC_napms() - called: ms=%d\n", ms));
PDC_update_rects();
while (ms > 50)
{
SDL_PumpEvents();
SDL_Delay(50);
ms -= 50;
}
SDL_PumpEvents();
SDL_Delay(ms);
}
const char *PDC_sysname(void)
{
return "SDL";
}

View File

@ -19,3 +19,5 @@ wasm路径<a href="/wasm/">wasm</a>。
- <a href="/wasm/helloworld/helloworld.html">helloworld</a>:C++语言的helloworld.
- <a href="/wasm/base_sdl/base_sdl.html">base_sdl</a>:WASM的SDL图形程序基础测试.
- <a href="/wasm/base_sdl2/base_sdl2.html">base_sdl2</a>:WASM的SDL2图形程序基础测试.
- <a href="/wasm/PDCurses/">PDCurses</a>:PDCurses库的demo程序可演示Curses程序早期终端的图形化程序。每一个html就是一个演示程序。