diff options
author | Manoj Srivastava <srivasta@debian.org> | 2020-05-27 16:31:00 -0700 |
---|---|---|
committer | Manoj Srivastava <srivasta@debian.org> | 2020-05-27 16:31:00 -0700 |
commit | d7533e931cfb49a68dc8e6e3f524d49e364cef83 (patch) | |
tree | 06d31523b9647d3de8ce8888f6e83d24f046aa82 /src/main-sdl.c | |
parent | 4e9b9c402ed95bf9a17fd6d795bc49bb4128a6fa (diff) |
New upstream version 2.41-ah~0.git.20200131
Diffstat (limited to 'src/main-sdl.c')
-rw-r--r-- | src/main-sdl.c | 2113 |
1 files changed, 0 insertions, 2113 deletions
diff --git a/src/main-sdl.c b/src/main-sdl.c deleted file mode 100644 index e9aec927..00000000 --- a/src/main-sdl.c +++ /dev/null @@ -1,2113 +0,0 @@ -/* Copyright (C) 2003-2004 Neil Stevens <neil@hakubi.us> - // Copyright (C) 2004 Ethan Stump <estump@seas.upenn.edu> - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - // copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - // - // Except as contained in this notice, the name(s) of the author(s) shall not be - // used in advertising or otherwise to promote the sale, use or other dealings - // in this Software without prior written authorization from the author(s). - */ - -#include "loadsave.h" -#include "main.h" -#include "util.h" -#include "variable.h" - -#include <SDL.h> -#include <SDL_image.h> -#include <SDL_ttf.h> - -#include <assert.h> -#include <math.h> - -/************************************************* - GLOBAL SDL-ToME PROPERTIES - *************************************************/ - -/* Default window properties - used if none are available -from other places*/ -#define DEF_SCREEN_WIDTH 800 -#define DEF_SCREEN_HEIGHT 600 -#define DEF_SCREEN_BPP 16 - -/*Main window properties that may be loaded at runtime from -a preference file or environmental variables. However, -default values (defined above) can be used. */ -static int arg_width = DEF_SCREEN_WIDTH; -static int arg_height = DEF_SCREEN_HEIGHT; -static int arg_bpp = DEF_SCREEN_BPP; - -/**************/ - -/* Default font properties - used unless otherwise changed. -These properties are the size and also default font to load. */ -#define DEF_FONT_SIZE 14 -#define DEF_FONT_FILE "VeraMono.ttf" - -/* The font properties that may perhaps be changed at runtime, -due to environmental variables, preference files, or in-program -commands.*/ -static int arg_font_size = DEF_FONT_SIZE; -static char arg_font_name[64] = DEF_FONT_FILE; - -/**************/ - -/* The number of term_data structures to set aside mem for */ -#define MAX_CONSOLE_COUNT 8 - -/* The number of consoles that are actually being used. -This number could be changed via preference files, environmental -variables, command-line arguments, or possibly even in-game -keypresses or menu-selections. */ -static int arg_console_count = 1; - -/* When rendering multiple terminals, each is drawn with a -surrounding border. This value controls the width of this -border */ -#define BORDER_THICKNESS 1 - -/**************/ - -/* flag signifying whether the game is in full screen */ -static bool_ arg_full_screen = FALSE; - -/* a flag to show whether window properties have been -set or not... if so, the properties can be dumped -upon quit*/ -static bool_ window_properties_set = FALSE; - -/************************************************* - GLOBAL SDL-ToME VARIABLES - *************************************************/ - -/* the main screen to draw to */ -static SDL_Surface *screen; - -/* the video settings for the system */ -static const SDL_VideoInfo *videoInfo; - -/* a flag to suspend updating of the screen; -this is in place so that when a large area is being -redrawn -- like when doing a Term_redraw() or when -redoing the entire screen -- all of the changes -can be stored up before doing an update. This -should cut down on screen flicker */ -static bool_ suspendUpdate = FALSE; - -/* some helper surfaces that are used for rendering -characters */ -static SDL_Surface *worksurf; -static SDL_Surface *crayon; - -/* the cursor surface */ -static SDL_Surface *cursor = NULL; - -/* the array of pre-rendered characters -(see loadAndRenderFont() below) */ -SDL_Surface *text[128]; - -/* the actual TTF_Font used (XXX should get rid of this)*/ -TTF_Font *font=0; - -/* the width and height of the uniformly-sized pre-rendered -characters */ -int t_width = 0, t_height = 0; - - -/************************************************* - COLOR SETUP - *************************************************/ - -/* Simple black, mapped using the format of the main screen */ -int screen_black; - -/* The color to use for the cursor */ -static int cursor_color = 0; -/* default cursor color is a semi-transparent yellow */ -#define DEF_CURSOR_COLOR 255,255,0,128 - -/* The array of colors, mapped to the format of the crayon surface, -since this is ultimately the surface that color is begin applied to */ -static int color_data[16]; - -/* The following macro is for color defining... - Note that the color is fully opaque... */ -#define COLOR(r,g,b) \ - SDL_MapRGBA(crayon->format,r,g,b,SDL_ALPHA_OPAQUE) - -/*These color macros will setup the colors to use, but must be called after - the SDL video has been set. That way SDL can correct for any funky video - setttings. */ - -#define BLACK COLOR( 0, 0, 0) /* 0*/ -#define WHITE COLOR(255,255,255) /* 1*/ -#define MID_GREY COLOR(128,128,128) /* 2*/ -#define BRIGHT_ORANGE COLOR(255,128, 0) /* 3*/ -#define RED COLOR(192, 0, 0) /* 4*/ -#define GREEN COLOR( 0,128, 64) /* 5*/ -#define BRIGHT_BLUE COLOR( 0, 0,255) /* 6*/ -#define DARK_ORANGE COLOR(128, 64, 0) /* 7*/ -#define DARK_GREY COLOR( 64, 64, 64) /* 8*/ -#define BRIGHT_GREY COLOR(192,192,192) /* 9*/ -#define PURPLE COLOR(255, 0,255) /*10*/ -#define YELLOW COLOR(255,255, 0) /*11*/ -#define BRIGHT_RED COLOR(255, 0, 0) /*12*/ -#define BRIGHT_GREEN COLOR( 0,255, 0) /*13*/ -#define AQUAMARINE COLOR( 0,255,255) /*14*/ -#define BROWN COLOR(192,128, 64) /*15*/ - -/************************************************* - TERMINAL DATA STRUCTURE SETUP - *************************************************/ - -/* Forward declare */ -typedef struct _term_data term_data; - -/* A structure for each "term" */ -struct _term_data -{ - term t; /* the term structure, defined in z-term.h */ - cptr name; /* name of this term sub-window */ - - uint rows, cols; /* row/column count */ - SDL_Rect rect; /* the bounding rectangle for the entire box; - includes border and empty space as well */ - /* this rectangle is in screen coordinates */ - - int border_thick; /* thickness of border to draw around window */ - int border_color; /* current color of the border */ - uint cushion_x_top, cushion_x_bot, cushion_y_top, cushion_y_bot; - /* empty space cushion between border and tiles */ - - uint tile_width; /* the width of each tile (graphic or otherwise)*/ - uint tile_height; /* the height of each tile (graphic or otherwise)*/ - - SDL_Surface *surf; /* the surface that graphics for this screen are - rendered to before blitting to main screen */ - int black,white,purple; /* basic colors keyed to this terminal's surface */ - -}; - -/* The array of term data structures */ -static term_data data[MAX_CONSOLE_COUNT]; - -/* Ordered array of pointers to term data structures, placed in order of -priority: lowest is on top of all others, the higher the index, the further -back into the screen that it is drawn */ -static term_data *term_order[MAX_CONSOLE_COUNT]; - -/************************************************* - FILE-SPECIFIC MACROS - *************************************************/ - -/* Debug macros! */ -#define DB(str) \ - printf("main-sdl: %s\n",str); - -/* Prints out the RGBA values of a given color */ -#define TYPECOLOR32(color) printf(" R:%d\tG:%d\tB:%d\tA:%d\t\n",\ - color>>24,(color&0x00ff0000)>>16,\ - (color&0x0000ff00)>>8,(color&0x000000ff)) - -#define TYPECOLOR16(color) printf(" R:%d\tG:%d\tB:%d\tA:%d\t\n",\ - (color&0xf000)>>12,(color&0x0f00)>>8,\ - (color&0x00f0)>>4,(color&0x000f)) - -/* SDL Surface locking and unlocking */ -#define SDL_LOCK(surf) \ - if (SDL_MUSTLOCK(surf) ){ \ - if (SDL_LockSurface(surf) < 0) { \ - printf("Can't lock the screen: %s\n", SDL_GetError()); \ - exit(1); \ - } \ - } - -#define SDL_UNLOCK(surf) \ - if (SDL_MUSTLOCK(surf) ){ \ - SDL_UnlockSurface(surf); \ - } - -/* Wrapped SDL_UpdateRects function, to take into -account the fact that updates may be suspended by -the suspendUpdate flag... this macro should be used -whenever a rect needs updated */ -#define SDL_UPDATE(rect) \ - if (!suspendUpdate) \ - SDL_UpdateRects(screen,1,&rect) - -/* A complete screen redraw macro */ -#define SDL_REDRAW_SCREEN \ - SDL_UpdateRect(screen,0,0,arg_width,arg_height) - -/************************************************* - QUITTING - *************************************************/ - -/* function prototype */ -void dumpWindowSettings(void); - -/* SDL Quitting function... declare a few functions first.*/ -void killFontAndAlphabet(void); -static void sdl_quit(cptr string) -{ - printf("sdl_quit called.\n"); - printf("message: %s\n",string); - /* Need to take care of font and rendered characters */ - killFontAndAlphabet(); - if (TTF_WasInit()) - TTF_Quit(); - /* Then exit SDL */ - SDL_Quit(); - - /* Dump the window properties, if available */ - if (window_properties_set) - dumpWindowSettings(); - - /* And now for the default quit behavior */ - quit_aux = 0; - quit(string); -} - -/************************************************* - FONT SUPPORT FUNCTIONS - *************************************************/ - -/* function prototype for creating surfaces */ -SDL_Surface *createSurface(int width, int height); - -/* killFontAndAlphabet will effectively de-initialize the font system; -it does this by closing the font and destroying any pre-rendered -text in memory */ -void killFontAndAlphabet(void) -{ - int i; - /* need to close a font and free all of its corresponding pre-rendered - surfaces */ - if (font) - { - TTF_CloseFont(font); - font = 0; - } - for (i=0;i<128;i++) - { - if(text[i]) - { - SDL_FreeSurface(text[i]); - text[i] = NULL; - } - } -} - -/* loadAndRenderFont is responsible for loading and initializing -a font. First, SDL_ttf calls are made to load and set the style -for the desired font. Next, a character alphabet is rendered and -each character is placed onto a uniformly-sized surface within -the text[] array. Whenever text is needed for displaying on-screen, -this array is referenced and the desired character picture is used. */ -void loadAndRenderFont(char *fname, int size) -{ - int minx,maxx,miny,maxy,advance,i,midline = 0; - char filename[PATH_MAX + 1]; - char fontdir[PATH_MAX + 1]; - SDL_Color base_color = {255,255,255,255}; - SDL_Surface *temp_surf; - SDL_Rect tgt = {0,0,0,0}; - - - /* Assuming that the filename is valid,open the font */ - path_build(fontdir, PATH_MAX, ANGBAND_DIR_XTRA, "font"); - path_build(filename, PATH_MAX, fontdir, fname); - font = TTF_OpenFont(filename,size); - if (font == NULL) - sdl_quit("Error loading that font!"); - /* Set the font style to normal */ - TTF_SetFontStyle(font,TTF_STYLE_NORMAL); - - /* Collect some measurements on this font - - arbitrarily choose the letter 'a' to get width*/ - TTF_GlyphMetrics(font,'a',&minx,&maxx,&miny,&maxy,&advance); - /* the width of each character tile */ - t_width = advance; - /* the height of each character tile */ - t_height = TTF_FontHeight(font); - /* position of the y=0 line in each tile */ - midline = TTF_FontAscent(font); - - /* now... render each of the individual characters */ - for (i=0;i<128;i++) - { - /* make a pretty blended glyph */ - temp_surf=TTF_RenderGlyph_Blended(font,i,base_color); - /* and make sure that we got it right! */ - if (temp_surf == NULL) - sdl_quit("Glyph failed to render!"); - /* get the metrics of this particular glyph so we can position it */ - TTF_GlyphMetrics(font,i,&minx,&maxx,&miny,&maxy,&advance); - /* copy rendered glyph into text queue, at the right position*/ - tgt.x = minx; - tgt.y = midline-maxy; - /* but first... we'll need a surface in the text queue to blit to! */ - text[i] = createSurface(t_width,t_height); - /* turn OFF src-alpha... results in brute - copy of the RGBA contents of surf */ - SDL_SetAlpha(temp_surf,0,0); - SDL_BlitSurface(temp_surf,NULL,text[i],&tgt); - /* turn OFF src-alpha since we'll be using worksurf for blitting */ - SDL_SetAlpha(text[i],0,0); - /* kill the surface to patch up memory leaks */ - SDL_FreeSurface(temp_surf); - } -} - -/* KEYPRESS_STRING repeatedly sends characters to the terminal -XXX - should implement routine from maim-sdl.c, it's sooo much -cleaner */ -#define KEYPRESS_STRING(str) \ -strcpy(buf,str); \ -n = buf; \ -while (*n != '\0') { \ - Term_keypress((int)(*(n++))); \ -} - -/* function prototype */ -void manipulationMode(void); -void redrawAllTerminals(void); -/* This is the main event handling routine that will be called -whenever an event is pulled off of the queue (in Term_xtra_sdl())*/ -void handleEvent(SDL_Event *event) -{ - static char buf[24]; /* a buffer used when passing key names */ - char *n; /* and a pointer to manipulate this buffer */ - - switch( event->type ) - { - case SDL_KEYDOWN: - { - /* handle key presses */ - - /* I'm reading that as long as the upper 9 bits of the unicode - * value are zero, then the lower 7 bits are direct ASCII characters. - * Furthermore, it seems that all basic keys return non-zero values - * for the lower 7 bits, but function keys and other various things - * return 0000000 for the lower 7 bits. - * Basically, if the lower 7 bits are zero, do something special - * (like start a macro), but otherwise just pass along the ASCII - * code! - */ - byte ascii_part = event->key.keysym.unicode & 0x00ff; - - /* gimme the key name */ - printf("Key is: %s\n",SDL_GetKeyName(event->key.keysym.sym)); - - /* allow for full screen toggling! */ - if ((event->key.keysym.sym == SDLK_RETURN) && \ - (SDL_GetModState() & KMOD_ALT)) - { - SDL_WM_ToggleFullScreen(screen); - /* toggle the internal full screen flag */ - arg_full_screen = (arg_full_screen ? FALSE : TRUE); - } - - /* entry into window manipulation mode */ - if ((event->key.keysym.sym == SDLK_RETURN) && \ - (SDL_GetModState() & KMOD_CTRL)) - { - DB("Manipulation mode!"); - manipulationMode(); - } - - /*printf("ascii_part: %d\n",ascii_part);*/ - if (ascii_part) - { - /* We have now determined that the ASCII part is not '0', so - we can safely pass along the ASCII value! */ - Term_keypress(ascii_part); - } - else - { - /* We want to ignore keypresses that are simply the modifier - keys*/ - if (!( (event->key.keysym.sym == SDLK_RSHIFT) | - (event->key.keysym.sym == SDLK_LSHIFT) | - (event->key.keysym.sym == SDLK_RALT) | - (event->key.keysym.sym == SDLK_LALT) | - (event->key.keysym.sym == SDLK_RCTRL) | - (event->key.keysym.sym == SDLK_LCTRL) )) - { - - /* now build a macro string using the modifiers together - with the key that was just pressed*/ - - /* As for the formatting... - * We pass the key press and modifiers as follows: - * \[ctrl-alt-shift-"key name"] - * following the previously established convention... - * - * All of the things that happen are defined in pref-sdl.prf - */ - - KEYPRESS_STRING("\["); /*Output the first part... */ - /* See if a control key is down */ - if (event->key.keysym.mod & KMOD_CTRL) - { - KEYPRESS_STRING("ctrl-"); - } - /* See if an alt key is down */ - if (event->key.keysym.mod & KMOD_ALT) - { - KEYPRESS_STRING("alt-"); - } - /* See if a shift key is down */ - if (event->key.keysym.mod & KMOD_SHIFT) - { - KEYPRESS_STRING("shift-"); - } - - /* Add in the name of whatever key was pressed */ - KEYPRESS_STRING(SDL_GetKeyName(event->key.keysym.sym)); - - /* and end it... */ - KEYPRESS_STRING("]"); - } - } - break; - } - case SDL_QUIT: - { - /* handle quit requests */ - DB("Emergency Blit"); - redrawAllTerminals(); - /*sdl_quit("Quitting!\n");*/ - break; - } - default: - { - break; - } - } -} - -/* declare the screen clearing function used below */ -void eraseTerminal(); -void drawTermStuff(term_data *td, SDL_Rect *rect); -static errr Term_xtra_sdl(int n, int v) -{ - static SDL_Event event; - term_data *td; - - - /* Analyze */ - switch (n) - { - case TERM_XTRA_EVENT: - { - if (v) - { - /* Perform event checking with blocking */ - SDL_WaitEvent( &event ); - handleEvent( &event ); - } else { - /* Perform event checking without blocking */ - if (SDL_PollEvent(&event)){ - /* We found an event! */ - handleEvent(&event); - } - } - return(0); - } - - case TERM_XTRA_FLUSH: - { - /* Keep doing events until the queue is empty! */ - while (SDL_PollEvent(&event)) - { - handleEvent(&event); - } - return (0); - } - - case TERM_XTRA_CLEAR: - { - /* Clear the terminal */ - DB("TERM_XTRA_CLEAR"); - suspendUpdate = TRUE; - eraseTerminal(); - return (0); - } - - case TERM_XTRA_SHAPE: - { - /* - * Set the cursor visibility XXX XXX XXX - * - * This action should change the visibility of the cursor, - * if possible, to the requested value (0=off, 1=on) - * - * This action is optional, but can improve both the - * efficiency (and attractiveness) of the program. - */ - - return (0); - } - - case TERM_XTRA_FRESH: - { - /* - * Flush output XXX XXX XXX - * - * This action should make sure that all "output" to the - * window will actually appear on the window. - * - * This action is optional, assuming that "Term_text_xxx()" - * (and similar functions) draw directly to the screen. - */ - - /* If terminal display has been held for any reason, - then update the whole thing now!*/ - DB("TERM_XTRA_FRESH"); - if (suspendUpdate) - { - DB(" update WAS suspended... updating now"); - td = (term_data*)(Term->data); - suspendUpdate = FALSE; - drawTermStuff(td,NULL); - } - return (0); - } - - case TERM_XTRA_NOISE: - { - /* - * Make a noise XXX XXX XXX - * - * This action should produce a "beep" noise. - * - * This action is optional, but convenient. - */ - - return (1); - } - - case TERM_XTRA_BORED: - { - /* Perform event checking without blocking */ - if (SDL_PollEvent(&event)){ - /* We found an event! */ - handleEvent(&event); - } - return(0); - } - - case TERM_XTRA_REACT: - { - /* - * React to global changes XXX XXX XXX - * - * For example, this action can be used to react to - * changes in the global "color_table[256][4]" array. - * - * This action is optional, but can be very useful for - * handling "color changes" and the "arg_sound" and/or - * "arg_graphics" options. - */ - return (1); - } - - case TERM_XTRA_ALIVE: - { - /* - * Change the "hard" level XXX XXX XXX - * - * This action is used if the program changes "aliveness" - * by being either "suspended" (v=0) or "resumed" (v=1) - * This action is optional, unless the computer uses the - * same "physical screen" for multiple programs, in which - * case this action should clean up to let other programs - * use the screen, or resume from such a cleaned up state. - * - * This action is currently only used by "main-gcu.c", - * on UNIX machines, to allow proper "suspending". - */ - - return (1); - } - - case TERM_XTRA_LEVEL: - { - /* - * Change the "soft" level XXX XXX XXX - * - * This action is used when the term window changes "activation" - * either by becoming "inactive" (v=0) or "active" (v=1) - * - * This action can be used to do things like activate the proper - * font / drawing mode for the newly active term window. This - * action should NOT change which window has the "focus", which - * window is "raised", or anything like that. - * - * This action is optional if all the other things which depend - * on what term is active handle activation themself, or if only - * one "term_data" structure is supported by this file. - */ - - return (1); - } - - } - - /* Unknown or Unhandled action */ - return (1); -} - -/************************************************* - GRAPHICS ROUTINES - *************************************************/ - -/* wrapper routine for creating an RGB surface with given height and - width that corresponds to desired color depth and respects the system - pixel format */ -SDL_Surface *createSurface(int width, int height) -{ - SDL_Surface *surf; - int surface_type; - - if (videoInfo->hw_available) - surface_type = SDL_HWSURFACE; - else - surface_type = SDL_SWSURFACE; - - /* XXX need to make RGBA masks correspond to system pixel format! */ - switch (arg_bpp) - { - case 8: - { - /* I really don't know if 8 bpp is even possible, but here it is */ - surf = SDL_CreateRGBSurface(surface_type,width,\ - height,8,0xc0,0x30,0x0c,0x03); - break; - } - case 16: - { - surf = SDL_CreateRGBSurface(surface_type,width,\ - height,16,0xf000,0x0f00,0x00f0,0x000f); - break; - } - case 24: - { - surf = SDL_CreateRGBSurface(surface_type,width,\ - height,24,0xfc0000,0x03f000,0x000fc0,0x000030); - break; - } - case 32: - { - surf = SDL_CreateRGBSurface(surface_type,width,\ - height,32,0xff000000,0x00ff0000,0x0000ff00,0x000000ff); - break; - } - default: - { - surf = NULL; - break; - } - } - - if (surf == NULL) - sdl_quit("Bad Surface Creation!"); - - return surf; -} - -/* Take a rectangle in terminal coordinates and then transform it into -screen coordinates; td is the term_data that this rect belongs to */ -void term_to_screen(SDL_Rect *termrect, term_data *td) -{ - termrect->x += td->rect.x; - termrect->y += td->rect.y; -} - -/* Do the opposite, take a rectangle in screen coordinates and transform -it into the terminal coordinates of the given term_data */ -void screen_to_term(SDL_Rect *scrrect, term_data *td) -{ - scrrect->x -= td->rect.x; - scrrect->y -= td->rect.y; -} - -/* A macro that determines if the 'top' rectangle completely occludes the -'bottom' rectangle */ -#define BLOCKS(top,bottom) \ -( (top.x <= bottom.x) & ((top.x+top.w)>=(bottom.x+bottom.w)) & \ - (top.y <= bottom.y) & ((top.y+top.h)>=(bottom.y+bottom.h)) ) - -#define INTERSECT(r1,r2) \ -!( ( (r1.x > (r2.x+r2.w)) | (r2.x > (r1.x+r1.w)) ) & \ - ( (r1.y > (r2.y+r2.h)) | (r2.y > (r1.y+r1.h)) ) ) - -/* A function to calculate the intersection of two rectangles. Takes base -rectangle and then updates it to include only the rectangles that intersect -with the test rectangle. If there is an intersection, the function returns -TRUE and base now contains the intersecting rectangle. If there is no -intersection, then the function returns FALSE */ -bool_ intersectRects(SDL_Rect *base, SDL_Rect *test) -{ - if (INTERSECT((*base),(*test))) - { - /* Scoot the x-coordinates for the left side*/ - if ( test->x > base->x ) - { - base->w -= test->x - base->x; - base->x = test->x; - } - /* Scoot the x-coordinates for the right side*/ - if ( (test->x + test->w) < (base->x + base->w) ) - { - base->w = test->x + test->w - base->x; - } - /* Scoot the upper y-coordinates */ - if ( test->y > base->y ) - { - base->h -= test->y - base->y; - base->y = test->y; - } - /* Scoot the lower y-coordinates */ - if ( (test->y + test->h) < (base->y + base->h) ) - { - base->h = test->y + test->h - base->y; - } - return TRUE; - } - else - { - return FALSE; - } -} - -/* A function to calculate the join of two rectangles; the first argument is -changed to the joined rectangle */ -SDL_Rect joinRects(SDL_Rect *r1, SDL_Rect *r2) -{ - SDL_Rect out = {0,0,0,0}; - - if ( (r1 != NULL) & (r2 != NULL) ) - { - /* Lower x-coordinate */ - if ( r2->x < r1->x ) - out.x = r2->x; - else - out.x = r1->x; - /* Upper x-coordinate */ - if ( (r2->x+r2->w) > (r1->x+r1->w) ) - out.w = (r2->x+r2->w) - out.x; - else - out.w = (r1->x+r1->w) - out.x; - /* Lower y-coordinate */ - if ( r2->y < r1->y ) - out.y = r2->y; - else - out.y = r1->y; - if ( (r2->y+r2->h) > (r1->y+r1->h) ) - out.h = (r2->y+r2->h) - out.y; - else - out.h = (r1->y+r1->h) - out.y; - } - return out; -} - -/* Given a term_data (and its associated screen) and a rectangle in terminal -coordinates (with NULL signifying to take the whole terminal surface), blit -graphics from the term_data surface to the screen, using the term_data's rect -to indicate how terminal coordinates transform into screen coordinates. -This is complicated, however, by the possibility that the indicated area may be -occluded by overlaying terminals. In this case, if the target area is -completely occluded, nothing will be done. If partially occluded, it will be -drawn, but occluding terminals will then re-blit to re-cover the area. */ -void drawTermStuff(term_data *td, SDL_Rect *rect) -{ - int n = 0, i; - bool_ block = FALSE, cover = FALSE; - SDL_Rect spot, isect_term, isect_scr; - - /* first of all, if updating is suspended, do nothing! */ - if (!suspendUpdate) - { - /* find out which number in the ordered stack of screens that this - terminal is */ - while ((term_order[n] != td) & (n < MAX_CONSOLE_COUNT)) - { - n++; - } - if (n == MAX_CONSOLE_COUNT) - printf("Could not find terminal in display list...\n"); - /* now loop through and see if any terminals completely occlude - the desired spot; if num=0, note that this will be skipped */ - if (rect == NULL) - { - /* Grab the whole terminal screen */ - spot.x = 0; spot.y = 0; - spot.w = td->surf->w; spot.h = td->surf->h; - } - else - { - /* Just copy the given area */ - spot.x = rect->x; spot.y = rect->y; - spot.w = rect->w; spot.h = rect->h; - } - term_to_screen(&spot,td); - i = n; - while (i--) - { - if (BLOCKS(term_order[i]->rect,spot)) - { - /* Higher terminal completely occludes this spot */ - block = TRUE; - DB(" Blocks!"); - } - else if (INTERSECT(term_order[i]->rect,spot)) - { - /* Partial occlusion */ - cover = TRUE; - DB(" Covers!"); - } - } - /* If any of the higher terminals blocked, then don't do - anything */ - if (!block) - { - /*printf("Blitting to %d %d %d %d\n",spot.x,spot.y,spot.w,spot.h);*/ - /* First of all, draw the graphics */ - SDL_BlitSurface(td->surf,rect,screen,&spot); - if (cover) - { - printf("covering..."); - /* There are covering terminals, so go through and blit all - partially occluding ones */ - while (n--) - { - /* copy spot to find the intersect */ - isect_scr.x = spot.x; isect_scr.y = spot.y; - isect_scr.w = spot.w; isect_scr.h = spot.h; - if (intersectRects(&isect_scr,&(term_order[n]->rect))) - { - /* this terminal intersects... re-blit */ - /* first, convert to term coordinates */ - isect_term.x = isect_scr.x; isect_term.y = isect_scr.y; - isect_term.w = isect_scr.w; isect_term.h = isect_scr.h; - screen_to_term(&isect_term,term_order[n]); - /* blit from term coordinates to screen coordinates */ - SDL_BlitSurface(term_order[n]->surf,&isect_term,\ - screen,&isect_scr); - } - } - } - /* Now update what was drawn */ - DB("Update"); - SDL_UpdateRects(screen,1,&spot); - } - } -} - -/* utility routine for creating and setting the color of the cursor; -it could be useful for setting a new cursor color if desired. -Could later be expanded to do other stuff with the cursor, -like a hollow rectangle a la main-win.c or even a graphic */ -void createCursor(byte r, byte g, byte b, byte a) -{ - /* free the cursor if it exists */ - if (cursor != NULL) - SDL_FreeSurface(cursor); - - /* and create it anew! (or the first time) */ - cursor = createSurface(t_width,t_height); - - /* be sure to use alpha channel when blitting! */ - SDL_SetAlpha(cursor,SDL_SRCALPHA,0); - - /* just set the color for now - drawing rectangles - needs surface locking for some setups */ - cursor_color = SDL_MapRGBA(cursor->format,r,g,b,a); - SDL_LOCK(cursor); - SDL_FillRect(cursor,NULL,cursor_color); - SDL_UNLOCK(cursor); -} - -/* Cursor Display routine - just blits the global cursor -surface onto the correct location */ -static errr Term_curs_sdl(int x, int y) -{ - term_data *td = (term_data*)(Term->data); - static SDL_Rect base; - - /* calculate the position to place the cursor */ - base.x = td->surf->clip_rect.x + x*t_width; - base.y = td->surf->clip_rect.y + y*t_height; - base.w = t_width; - base.h = t_height; - - /* blit the cursor over top of the given spot; - note that surface should not be locked - (see note in Term_text_sdl() below) */ - SDL_BlitSurface(cursor,NULL,td->surf,&base); - - /* Now draw to the main screen */ - drawTermStuff(td,&base); - /* Success */ - return (0); -} - -/* Perform a full clear of active terminal; redraw the borders.*/ -void eraseTerminal(void) -{ - static SDL_Rect base; - term_data *td = (term_data*)(Term->data); - - /* temporarily remove clipping rectangle */ - SDL_SetClipRect(td->surf,NULL); - - SDL_LOCK(td->surf); - /* flood terminal with border color */ - SDL_FillRect(td->surf,NULL,td->border_color); - - /* get smaller rectangle to hollow out window */ - base.x = td->border_thick; - base.y = td->border_thick; - base.w = td->rect.w - 2*td->border_thick; - base.h = td->rect.h - 2*td->border_thick; - - /* hollow out terminal */ - SDL_FillRect(td->surf,&base,td->black); - - SDL_UNLOCK(screen); - - /* reset clipping rectangle */ - base.x += td->cushion_x_top; - base.y += td->cushion_y_top; - base.w -= td->cushion_x_top + td->cushion_x_bot; - base.h -= td->cushion_y_top + td->cushion_y_bot; - SDL_SetClipRect(td->surf,&base); - printf("Clip rect: %d %d %d %d\n",base.x,base.y,base.w,base.h); - /* And... UPDATE the whole thing */ - drawTermStuff(td,NULL); - -} - -/* - * Draw some text on the screen - * - * This function should actually display an array of characters - * starting at the given location, using the given "attribute", - * and using the given string of characters, which contains - * exactly "n" characters and which is NOT null-terminated. - * - * You may assume "valid" input if the window is properly sized. - * - * You must be sure that the string, when written, erases anything - * (including any visual cursor) that used to be where the text is - * drawn. On many machines this happens automatically, on others, - * you must first call "Term_wipe_xxx()" to clear the area. - * - * In color environments, you should activate the color contained - * in "color_data[a & 0x0F]", if needed, before drawing anything. - * - * You may ignore the "attribute" if you are only supporting a - * monochrome environment, since this routine is normally never - * called to display "black" (invisible) text, including the - * default "spaces", and all other colors should be drawn in - * the "normal" color in a monochrome environment. - * - * Note that if you have changed the "attr_blank" to something - * which is not black, then this function must be able to draw - * the resulting "blank" correctly. - * - */ -static errr Term_text_sdl(int x, int y, int n, byte a, const char *cp) -{ - term_data *td = (term_data*)(Term->data); - static SDL_Rect base; - SDL_Rect base_back; - int i = n; - char old = 0; - - /* calculate place to clear off and draw to */ - base.x = td->surf->clip_rect.x + x*td->tile_width; - base.y = td->surf->clip_rect.y + y*td->tile_height; - base.w = n*td->tile_width; - base.h = td->tile_height; - - base_back = base; - - SDL_LOCK(screen); - - /* blank the drawing area */ - SDL_FillRect(td->surf, &base, td->black); - - SDL_UNLOCK(screen); - - /* Note that SDL docs specify that SDL_BlitSurface should not be called - on locked surfaces... since the character printing routine below revolves - around blitting, the surface has been unlocked first*/ - - /* loop through the input string, drawing characters */ - i = n; - old = 0; - while (i--) - { - /* Output the character... */ - /* If character has not changed, then just blit the old surface into - the new location to save effort*/ - if (*cp == old) - { - /* the desired character/color combo is already on the work surf */ - /* just blit it! */ - SDL_BlitSurface(worksurf,NULL,td->surf,&base); - } else { - /* copy the desired character onto working surface */ - assert(*cp >= 0); // Make sure cast is valid - SDL_BlitSurface(text[(size_t)(*cp)],NULL,worksurf,NULL); - /* color our crayon surface with the desired color */ - SDL_FillRect(crayon,NULL,color_data[a&0x0f]); - /* apply the color to the character on the working surface */ - SDL_BlitSurface(crayon,NULL,worksurf,NULL); - /* and blit it onto our screen! */ - SDL_BlitSurface(worksurf,NULL,td->surf,&base); - } - /* Move to the next position */ - base.x += t_width; - /* Store the old character */ - old = *cp; - /* Increment the character pointer */ - cp++; - } - - /* And update */ - drawTermStuff(td,&base_back); - - /* Success */ - return (0); -} - -/************************************************* - SPECIAL TERMINAL WINDOW MANIPULATION ROUTINES - *************************************************/ - -/* macro for bounding a value between two given values */ -#define BOUND(val,low,high) \ -if (val < low) \ -{ \ - val = low; \ -} \ -else if (val > high) \ -{ \ - val = high; \ -} - -/* two macros to get the adjusted maximums for window -positions... eg the screen width minus the width of the -window is the maximum x-position that the window can -be set at. */ -#define MAX_X(td) \ -( arg_width - td->rect.w ) - -#define MAX_Y(td) \ -( arg_height - td->rect.h ) - -/* another two macros that give maximum window widths -based on screen size and current window position together -width tile widths/heights */ -#define MAX_WIDTH(td) \ -( (int)floorf((arg_width - td->rect.x - 2*td->border_thick - \ - td->cushion_x_bot - td->cushion_x_top )/td->tile_width)) - -#define MAX_HEIGHT(td) \ -( (int)floorf((arg_height - td->rect.y - 2*td->border_thick - \ - td->cushion_y_bot - td->cushion_y_top )/td->tile_height)) - -/* update the width and height of given term's rectangle by simply -multiplying the tile count by tile size and adding in cushions and -borders */ -#define UPDATE_SIZE(td) \ - td->rect.w = (td->cols)*td->tile_width + td->cushion_x_top \ - + td->cushion_x_bot + 2*td->border_thick; \ - td->rect.h = (td->rows)*td->tile_height + td->cushion_y_top \ - + td->cushion_y_bot + 2*td->border_thick - -void recompose(void); - -/* Resize the active terminal with new width and height. -Note that his involves a complicated sequence of events... -Details to follow below! */ -void resizeTerminal(int width, int height) -{ - term_data *td = (term_data*)(Term->data); - - /* First of all, bound the input width and height to satisfy - these conditions: - - The main ToME window should be at least 80 cols, 24 rows - - no part of each window should be drawn off screen.... - I'm including borders in this restriction! - But no bounds checking needs to take place if the input width - and height are unchanged.... - */ - - if (td == &data[0]) - { - /* The active terminal is the main ToME window... - don't let the width get below 80, don't let the heights below - 24, and don't let it leak off of the edge! */ - if (width != td->cols) - { - BOUND(width,80,MAX_WIDTH(td)); - } - if (height != td->rows) - { - BOUND(height,24,MAX_HEIGHT(td)); - } - } - else - { - /* This is not the main window... just make sure it - doesn't shrink to nothing or go past the edge */ - if (width != td->cols) - { - BOUND(width,1,MAX_WIDTH(td)); - } - if (height != td->rows) - { - BOUND(height,1,MAX_HEIGHT(td)); - } - } - - /* Okay, now make sure that something has ACTUALLY changed - before doing anything */ - if ((width != td->cols) || (height != td->rows)) - { - - /* Now, ask zterm to please resize the term structure! */ - Term_resize(width,height); - - /* Reactivate, since Term_resize seems to activate the - main window again...*/ - Term_activate(&td->t); - - /* It might not have resized completely to the new - size we wanted (some windows have size limits it seems, - like the message window). So, update our structure with - the size that were actually obtained.*/ - td->cols = Term->wid; - td->rows = Term->hgt; - - /* And recalculate the sizes */ - UPDATE_SIZE(td); - - /* Create a new surface that can hold the updated size */ - SDL_FreeSurface(td->surf); - td->surf = createSurface(td->rect.w,td->rect.h); - - /* Now we should be in business for a complete redraw! */ - Term_redraw(); - - /* Re-blit everything so it looks good */ - recompose(); - - /* That's it! */ - } -} - -/* Move the terminal around... a much simpler action that involves -just changing the pos_x/pos_y values and redrawing!*/ -void moveTerminal(int x, int y) -{ - term_data *td = (term_data*)(Term->data); - - /* Now, the window is being shifted about... much simpler - situation to handle! But of course, the window must not - drift too far or else parts will be hanging off the screen - and may lead to errors - bound the input positions to - prevent this unfortunate situation... do nothing if the - input is no different than the current */ - if (x != td->rect.x) - { - BOUND(x,0,MAX_X(td)); - } - if (y != td->rect.y) - { - BOUND(y,0,MAX_Y(td)); - } - - /* Okay, now make sure that something changed before doing - anything */ - if ((x != td->rect.x) || (y != td->rect.y)) - { - /* Now update OUR structure */ - td->rect.x = x; - td->rect.y = y; - - /* Then do a reblit to see the results */ - recompose(); - - /* That's it! */ - } -} - -/* Routine to bring a given term_data to the top of the drawing stack */ -void bringToTop(int current) -{ - term_data *td; - int n = 0; - int i; - - /* Get the pointer to the desired term_data from the data structure */ - td = &data[current]; - - printf("Current stack: \n"); - for (i=0;i<arg_console_count;i++) - { - printf(" %d: %p\n",i,term_order[i]); - } - printf("\n"); - - /* Find the number in the term_order stack */ - while ((term_order[n] != td) & (n < MAX_CONSOLE_COUNT)) - { - n++; - } - if (n == MAX_CONSOLE_COUNT) - printf("Could not find terminal in display list...\n"); - - printf("Order is %d\n",n); - - /* Now move all lower-indexed pointers up one index */ - while (n) - { - printf(" move %d to %d\n",n-1,n); - printf(" %p\n",term_order[n-1]); - printf(" %p\n",term_order[n]); - term_order[n] = term_order[n-1]; - n--; - } - /* And stick this term_data pointer on top */ - term_order[0] = td; - - printf("Final stack: \n"); - for (i=0;i<arg_console_count;i++) - { - printf(" %d: %p\n",i,term_order[i]); - } - printf("\n"); - -} - -/* This utility routine will cycle the active term to the -next available in the data[] array. It will then do a -redraw of this term so that it is ready to be manipulated. -The input is the current active terminal, and the output is -the new active terminal */ -int cycleTerminal(int current) -{ - /* redraw the current term to get rid of its purple - border */ - data[current].border_color = data[current].white; - Term_redraw(); - - /* increment the terminal number*/ - current++; - /* now do a little modulo cycle action and - activate the next term! */ - current %= arg_console_count; - Term_activate(&(data[current].t)); - - /* before redrawing, set the border color to purple to - indicate that this terminal is being manipulated*/ - data[current].border_color = data[current].purple; - - /* then bring this terminal to the top of the order, so it is drawn on - top during manipulation mode */ - bringToTop(current); - - /* and do a complete redraw */ - Term_redraw(); - - /* return the current terminal... */ - return current; -} - -/* This routine will simply re-blit all of the surfaces onto the main screen, -respecting the current term_order */ -void recompose(void) -{ - int i = arg_console_count; - /* do a complete screen wipe */ - SDL_LOCK(screen); - SDL_FillRect(screen,NULL,screen_black); - SDL_UNLOCK(screen); - - /* cycle through the term_order */ - while (i--) - { - SDL_BlitSurface(term_order[i]->surf,NULL,screen,&(term_order[i]->rect)); - } - - /* Update everything */ - SDL_REDRAW_SCREEN; -} - -/* This utility routine will completely blank the screen and -then cycle through all terminals, performing a Term_redraw() -on each and every term that is being used (according to -arg_term_count that is). The terminals will be redrawn -last-to-first, so that the main is over top of everything */ -void redrawAllTerminals(void) -{ - int i = arg_console_count; - DB("Total redraw"); - /* do a complete screen wipe */ - SDL_LOCK(screen); - SDL_FillRect(screen,NULL,screen_black); - SDL_UNLOCK(screen); - - while (i--) - { - /* Re-order the terminals */ - term_order[i] = &data[i]; - } - - i = arg_console_count; - /* cycle down through each terminal */ - while (i--) - { - /* Activate this terminal */ - Term_activate(&(data[i].t)); - - /* Make its border white since manipulation mode is over */ - data[i].border_color = data[i].white; - - /* And redraw it */ - Term_redraw(); - } - /* Loop will end on i=0 ! */ - - printf("Current stack: \n"); - for (i=0;i<arg_console_count;i++) - { - printf(" %d: %p\n",i,term_order[i]); - } - printf("\n"); - - /* now update the screen completely, just in case*/ - SDL_REDRAW_SCREEN; -} - -/* This is the special event handling function for doing -terminal window manipulation! When special manipulation -mode is activated, execution goes here. This special mode -has its own keypresses. To begin with, the main terminal -border is highlighted (in purple) to indicate that it is -being manipulated. The following keypresses are accepted: --Space: switches between editing modes. The system begins - in position editing mode, and Enter will toggle size - (row/col) editing mode. --Arrows: increments/decrements the position/size in an - intuitive way! ;) Some modifiers are accepted in order - to speed things up on very high resolution screens: - . with shift down, increment is five - . with ctrl down, increment is ten - . with both, increment is fifty! - Of course, no movement or resize can cause the window - to leave the confines of the screen, so using the big - jump is safe. --Enter: cycles to the next available terminal to edit. --Escape: quits manipulation mode, performing one final - redraw to take into account all changes. -*/ -void manipulationMode(void) -{ - term_data *td; - SDL_Event event; - bool_ done = FALSE, moveMode = TRUE; - int mouse_x, mouse_y; - int value = 0, delta_x = 0, delta_y = 0; - int current_term; - - /* Begin by redrawing the main terminal with its - purple border to signify that it is being edited*/ - - /* start with the main terminal */ - current_term = 0; - - /* get the pointer */ - td = &data[0]; - - /* before redrawing, set the border color to purple to - indicate that this terminal is being manipulated*/ - td->border_color = td->purple; - - /* and do a complete redraw */ - DB("Term_redraw"); - Term_redraw(); - - /* Now keep looping until Esc has been pressed. */ - while (!done) - { - /* Get the keypress event */ - SDL_WaitEvent(&event); - /* Make sure that it is a keypress */ - if (event.type == SDL_KEYDOWN) - { - /* Act on the keypress! */ - switch (event.key.keysym.sym) - { - case SDLK_ESCAPE: - { - /* Escape has been pressed, so we're done!*/ - done = TRUE; - break; - } - case SDLK_SPACE: - { - /* Space has been pressed: toggle move mode */ - moveMode = ( moveMode ? FALSE : TRUE ); - break; - } - case SDLK_RETURN: - { - /* Return... cycle the terminals! - update the current_term appropriately*/ - current_term = cycleTerminal(current_term); - - /* Get the new term_data */ - td = &data[current_term]; - - break; - } - case SDLK_RIGHT: - case SDLK_LEFT: - case SDLK_DOWN: - case SDLK_UP: - { - /* Increase either the x-position or column - width - multiply according to modifiers */ - value = 1; - if (SDL_GetModState() & KMOD_SHIFT) - { - /* shift is down... a muliplier of 5 */ - value *= 5; - } - if (SDL_GetModState() & KMOD_CTRL) - { - /* control is down... multiply by 10 */ - value *= 10; - } - - /* Now, behavior depends on which key was pressed - and whether we are in moveMode resize mode... */ - - /* First, set the delta_x/y based on key */ - if (event.key.keysym.sym == SDLK_RIGHT) - { - delta_x = 1; - delta_y = 0; - } - if (event.key.keysym.sym == SDLK_LEFT) - { - delta_x = -1; - delta_y = 0; - } - if (event.key.keysym.sym == SDLK_DOWN) - { - delta_x = 0; - delta_y = 1; - } - if (event.key.keysym.sym == SDLK_UP) - { - delta_x = 0; - delta_y = -1; - } - - /* Now either moveTerminal() or - resizeTerminal() based on value of - moveMode! */ - if (moveMode) - { - moveTerminal(td->rect.x + value*delta_x,\ - td->rect.y + value*delta_y); - } - else - { - resizeTerminal(td->cols + value*delta_x,\ - td->rows + value*delta_y); - } - break; - } - default: - { - break; - } - } - } - else if (event.type == SDL_MOUSEBUTTONDOWN) - { - /* Store the coordinates where the button was pressed */ - mouse_x = event.button.x; - mouse_y = event.button.y; - } - else if (event.type == SDL_MOUSEMOTION) - { - /* Mouse is moving... maybe move or resize the window, based - on the state of the mouse buttons */ - - /* To keep the motion quick, temporarily ignore all mouse motion - events until window moving is complete */ - SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE); - - if(event.motion.state & SDL_BUTTON(1)) - { - /* the left mouse button is down, move the window, - do a differential based on where the button was pressed */ - moveTerminal(td->rect.x + (event.motion.x - mouse_x), \ - td->rect.y + (event.motion.y - mouse_y)); - /* save the most current mouse location */ - SDL_GetMouseState(&mouse_x,&mouse_y); - } - - if(event.motion.state & SDL_BUTTON(3)) - { - /* the right mouse button is down, so resize the window; - do a differential, but divide the number by the tile sizes */ - - /* see if at least one whole tile width/height has been - reached */ - int delta_cols, delta_rows; - delta_cols = (int)floorf(\ - (float)(event.motion.x - mouse_x)/td->tile_width); - delta_rows = (int)floorf(\ - (float)(event.motion.y - mouse_y)/td->tile_height); - if ( delta_cols || delta_rows ) - { - /* something changed, so update */ - resizeTerminal(td->cols + delta_cols, \ - td->rows + delta_rows); - /* save the most current mouse location */ - SDL_GetMouseState(&mouse_x,&mouse_y); - } - } - - /* Deal with mouse motion again */ - SDL_EventState(SDL_MOUSEMOTION,SDL_ENABLE); - - } - } - /* Perform the last redraw to take all changes - into account */ - redrawAllTerminals(); -} - -/************************************************* - INITIALIZATION ROUTINES - *************************************************/ - -static errr term_data_init(term_data *td, int i) -{ - term *t = &(td->t); - char env_var[80]; - cptr val; - - - /***** load position, size information */ - - int cols, rows, x, y; - - /* grab the column and row counts from - environmental variables for now */ - sprintf(env_var,"TOME_NUM_COLS_%d",i); - val = getenv(env_var); - /* make sure it is valid */ - if (val != NULL) - { - cols = atoi(val); - /* now make sure that the main window will - have at least 80x24 */ - if (td == &data[0]) - { - /* can't really pick an upper bound without - knowing what the position is... oh well. */ - BOUND(cols,80,255); - } - } - else - { - /* no environmental variable... have to guess - something. If it's the main window, choose - the minimum. */ - if (td == &data[0]) - cols = 80; - else - cols = 5; - } - /* do the rows */ - sprintf(env_var,"TOME_NUM_ROWS_%d",i); - val = getenv(env_var); - /* make sure it is valid */ - if (val != NULL) - { - rows = atoi(val); - /* now make sure that the main window will - have at least 80x24 */ - if (td == &data[0]) - { - /* can't really pick an upper bound without - knowing what the position is... oh well. */ - BOUND(rows,24,128); - } - } - else - { - /* no environmental variable... have to guess - something. If it's the main window, choose - the minimum. */ - if (td == &data[0]) - rows = 24; - else - rows = 3; - } - /* store these values in the term_data structure */ - td->rows = rows; - td->cols = cols; - - /* the position will be loaded from environmental - variables as well - for the time being*/ - /* x-location */ - sprintf(env_var,"TOME_X_POS_%d",i); - val = getenv(env_var); - /* make sure it is valid */ - if (val != NULL) - { - x = atoi(val); - /* now do intelligent position checking */ - BOUND(x,0,MAX_X(td)); - } - else - { - /* no variable, choose something */ - x = 20*i; - } - /* y-location */ - sprintf(env_var,"TOME_Y_POS_%d",i); - val = getenv(env_var); - /* make sure it is valid */ - if (val != NULL) - { - y = atoi(val); - /* position checking again */ - BOUND(y,0,MAX_Y(td)); - } - else - { - /* no variable */ - y = 20*i; - } - /* and store these values into the structure */ - td->rect.x = x; - td->rect.y = y; - - /*********** term structure initializing */ - - /* Initialize the term - gets: pointer to address, number of columns, number of rows, number - of keypresses to queue up (guess 24?)*/ - term_init(t, cols, rows, 24); - - /* Use a "soft" cursor */ - t->soft_cursor = TRUE; - - /* Hooks */ - t->xtra_hook = Term_xtra_sdl; - t->curs_hook = Term_curs_sdl; - t->text_hook = Term_text_sdl; - - /* Save the data */ - t->data = td; - - /* Activate (important) */ - Term_activate(t); - - /************* finish term_data intializing */ - - /* name of this term window */ - td->name = angband_term_name[i]; - - /* For now, all font is the same size... use global t_width/height */ - td->tile_width = t_width; - td->tile_height = t_height; - - td->cushion_x_top = 1; - td->cushion_x_bot = 1; - td->cushion_y_top = 1; - td->cushion_y_bot = 1; - - /* Now calculate the total width and height*/ - UPDATE_SIZE(td); - - /* Create a surface to draw to */ - td->surf = createSurface(td->rect.w,td->rect.h); - SDL_SetAlpha(td->surf,0,0); - - /* Key some colors to this surface */ - td->black = SDL_MapRGB(td->surf->format, 0, 0, 0); - td->white = SDL_MapRGB(td->surf->format,255,255,255); - td->purple = SDL_MapRGB(td->surf->format,255, 0,255); - - /* Turn on a border, thickness specified by BORDER_THICKNESS */ - td->border_thick = BORDER_THICKNESS; - - /* make the default terminal border color to be white */ - td->border_color = td->white; - - - printf("Init-int term: %d\n",i); - - /* Success */ - return (0); -} - -/* dumpWindowSettings is responsible for exporting all current -values of the window positions, etc. to the screen, so that -the user can see what the final values were after tweaking */ -void dumpWindowSettings(void) -{ - char name[80]; - char value[8]; - int i; - - DB("Dumping settings"); - printf("---------------------------\n"); - /* cycle through each available terminal */ - for (i=0; i<arg_console_count; i++) - { - printf("Terminal %d:\n",i); - /* get the name, and value of each value to dump */ - sprintf(name,"TOME_X_POS_%d",i); - sprintf(value,"%d",data[i].rect.x); - printf("%s=%s\n",name,value); - - sprintf(name,"TOME_Y_POS_%d",i); - sprintf(value,"%d",data[i].rect.y); - printf("%s=%s\n",name,value); - - sprintf(name,"TOME_NUM_COLS_%d",i); - sprintf(value,"%d",data[i].cols); - printf("%s=%s\n",name,value); - - sprintf(name,"TOME_NUM_ROWS_%d",i); - sprintf(value,"%d",data[i].rows); - printf("%s=%s\n",name,value); - - /* Simple! */ - printf("\n"); - } -} - -/* The main-sdl initialization routine! -This routine processes arguments, opens the SDL -window, loads fonts, etc. */ -int init_sdl(int argc, char **argv) -{ - int i; - char filename[PATH_MAX + 1]; - const char file_sep = '.'; - /* Flags to pass to SDL_SetVideoMode */ - int videoFlags; - - /* Before sdl_quit could possible be called, need to make sure that the text - array is zeroed, so that sdl_quit->killFontAndAlphabet() doesn't try to free - SDL_Surfaces that don't exist ! */ - memset(text,0,sizeof(text)); - - /* Also, clear out the term order array */ - memset(term_order,0,sizeof(term_order)); - - /* initialize SDL */ - if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) - { - sdl_quit("Video initialization failed!"); - } - DB("SDL Initialized!"); - - /* get video info, to be used for determining if hardware acceleration is - available, pixel format, etc.... */ - videoInfo = SDL_GetVideoInfo(); - - /* Environment calls to retrieve specific settings... - Note that these can be overridden by the command-line - arguments that are handled below */ - if(getenv("TOME_CONSOLE_COUNT")) - arg_console_count = atoi(getenv("TOME_CONSOLE_COUNT")); - if(getenv("TOME_SCREEN_WIDTH")) - arg_width = atoi(getenv("TOME_SCREEN_WIDTH")); - if(getenv("TOME_SCREEN_HEIGHT")) - arg_height = atoi(getenv("TOME_SCREEN_HEIGHT")); - if(getenv("TOME_SCREEN_BPP")) - arg_bpp = atoi(getenv("TOME_SCREEN_BPP")); - if(getenv("TOME_FONT_SIZE")) - arg_font_size = atoi(getenv("TOME_FONT_SIZE")); - - /* Argument handling routine; - the argv pointer is already pointing at the '--' - argument, so just start from there, parsing each - option as it comes along */ - for (i=1; i < argc ; i++) - { - /* Set the number of consoles to handle - (ie the number of windows) */ - if (0 == strcmp(argv[i], "-n")) - { - if (++i == argc) - { - printf("Argument missing for option -n\n"); - return -1; - } - - arg_console_count = atoi(argv[i]); - if (arg_console_count <= 0 || \ - arg_console_count > MAX_CONSOLE_COUNT) - { - printf("Invalid console count given.\n"); - arg_console_count = 1; - } - } - /* Set the SDL window/screen width in pixels */ - else if (0 == strcmp(argv[i], "-w")) - { - if (++i == argc) - { - printf("Argument missing for option -w\n"); - return -1; - } - - arg_width = atoi(argv[i]); - } - /* Set the SDL window/screen height in pixels */ - else if (0 == strcmp(argv[i], "-h")) - { - if (++i == argc) - { - printf("Argument missing for option -h\n"); - return -1; - } - - arg_height = atoi(argv[i]); - } - /* Set the SDL window/screen color depth - (in bits per pixel -- only 8,16,32 are okay) */ - else if (0 == strcmp(argv[i], "-bpp")) - { - if (++i == argc) - { - printf("Argument missing for option -bpp\n"); - return -1; - } - - arg_bpp = atoi(argv[i]); - if ( (arg_bpp != 8) && (arg_bpp != 16) \ - && (arg_bpp != 24) && (arg_bpp != 32) ) - { - printf("Invalid color depth. Must be either 8, 16, or 32 bpp!\n"); - return -1; - } - } - /* switch into full-screen at startup */ - else if (0 == strcmp(argv[i], "-fs")) - { - DB("Full-screen enabled!"); - arg_full_screen = TRUE; - } - /* change the font size */ - else if (0 == strcmp(argv[i], "-s")) - { - if (++i == argc) - { - printf("Argument missing for option -s\n"); - printf("Please specify font size!\n"); - return -1; - } - - arg_font_size = atoi(argv[i]); - } - /* change the font to use */ - else if (0 == strcmp(argv[i], "-f")) - { - /* Can we please not be so MS Windows-specific? One of the main goals - of SDL in ToME was to be more portable. These file name hacks are - only the idiom of that one OS, though. -- Neil */ - DB("Getting font name"); - if (++i == argc) - { - printf("Argument missing for option -f\n"); - printf("Please specify a true-type font found in /lib/xtra/font!\n"); - return -1; - } - - /* tokenize the font name so that no .ttf extension - is required */ - strcpy(arg_font_name,\ - strtok(argv[i],&file_sep)); - - /* and append the extension */ - strcat(arg_font_name,".ttf"); - - /* print a little debug message, so - user sees what font was actually selected */ - printf("\tUsing font: %s\n",arg_font_name); - - /* maybe check to see if file is even - existant in /lib/xtra/font */ - } - - } /* end argument handling */ - - /* Make sure that the engine will shutdown SDL properly*/ - quit_aux = sdl_quit; - - /* Use the ToME logo and set the window name */ - filename[PATH_MAX] = 0; - path_build(filename, PATH_MAX, ANGBAND_DIR_XTRA, "graf/icon.png"); - SDL_WM_SetIcon(IMG_Load(filename), 0); - SDL_WM_SetCaption("ToME", "tome"); - - /* SDL video settings, dependent on whether hardware is available */ - if (videoInfo->hw_available) - videoFlags = SDL_HWSURFACE; - else - videoFlags = SDL_SWSURFACE; - - /* now set the video mode that has been configured */ - screen = SDL_SetVideoMode( arg_width, arg_height, arg_bpp, videoFlags ); - - /* Verify there is a surface */ - if ( !screen ) - { - DB("No screen!"); - sdl_quit("Failed to set SDL Surface."); - } - - DB("Video Mode Set!"); - - /* now switch into full screen if asked for */ - if (arg_full_screen) - SDL_WM_ToggleFullScreen(screen); - - DB("SDL Window Created!"); - - /* Now ready the fonts! */ - - DB("initializing SDL_ttf"); - if(TTF_Init()==-1) { - printf("TTF_Init: %s\n", TTF_GetError()); - sdl_quit("Bah"); - } - - DB("loading font..."); - - /* load and render the font */ - loadAndRenderFont(arg_font_name,arg_font_size); - - /* Initialize the working surface and crayon surface used for rendering - text in different colors. */ - - worksurf = createSurface(t_width,t_height); - crayon = createSurface(t_width,t_height); - - /* The working surface will blit using alpha values... */ - SDL_SetAlpha(worksurf,SDL_SRCALPHA,0); - - /* Set up the colors using the great little color macros! */ - color_data[0] = BLACK; - color_data[1] = WHITE; - color_data[2] = MID_GREY; - color_data[3] = BRIGHT_ORANGE; - color_data[4] = RED; - color_data[5] = GREEN; - color_data[6] = BRIGHT_BLUE; - color_data[7] = DARK_ORANGE; - color_data[8] = DARK_GREY; - color_data[9] = BRIGHT_GREY; - color_data[10] = PURPLE; - color_data[11] = YELLOW; - color_data[12] = BRIGHT_RED; - color_data[13] = BRIGHT_GREEN; - color_data[14] = AQUAMARINE; - color_data[15] = BROWN; - - /* And setup the cursor, using the default color... - XXX - in the future, this should (and will) be loaded from prefs */ - createCursor(DEF_CURSOR_COLOR); - - /* Initialize the windows, or whatever that means in this case. - Do this in reverse order so that the main window is on top.*/ - suspendUpdate = TRUE; /* draw everything at the end */ - i = arg_console_count; - while (i--) - { - term_data *td = &data[i]; - - /* Initialize the term_data */ - term_data_init(td, i); - - /* Save global entry */ - angband_term[i] = Term; - - /* Add into term_order */ - term_order[i] = td; - - } - - /* And setup the basic screen colors -- these are keyed to the format of - the main terminal surface */ - screen_black = SDL_MapRGB(screen->format, 0, 0, 0); - - suspendUpdate = FALSE; /* now draw everything */ - redrawAllTerminals(); - /*SDL_REDRAW_SCREEN;*/ - - /* now that the windows have been set, their settings can - be dumped upon quit! */ - window_properties_set = TRUE; - - /* Enable UNICODE keysyms - needed for current eventHandling routine */ - SDL_EnableUNICODE(1); - - /* Enable key repeat! */ - SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL); - - /* main-sdl initialized! */ - return 0; -} - -int main(int argc, char *argv[]) -{ - return main_real( - argc, - argv, - "sdl", - init_sdl, - " -- -n # Number of virtual consoles to use\n" - " -- -w # Request screen width in pixels\n" - " -- -h # Request screen height in pixels\n" - " -- -bpp # Request screen color depth in bits\n" - " -- -fs Start with full-screen display\n" - " -- -s # Request font size\n" - " -- -f <font> Request true-type font by name\n"); -} |