mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
763 lines
23 KiB
C
763 lines
23 KiB
C
/* -*- compile-command: "cd ../wasm && make MEMDEBUG=TRUE install"; -*- */
|
|
/*
|
|
* Copyright 2021 by Eric House (xwords@eehouse.org). All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_ttf.h>
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
#include "comtypes.h"
|
|
#include "strutils.h"
|
|
#include "wasmdraw.h"
|
|
#include "dbgutil.h"
|
|
|
|
typedef struct FontRec{
|
|
struct FontRec* next;
|
|
int size;
|
|
TTF_Font* font;
|
|
} FontRec;
|
|
|
|
typedef struct _WasmDrawCtx {
|
|
DrawCtxVTable* vtable;
|
|
SDL_Renderer* renderer;
|
|
SDL_Surface* surface;
|
|
SDL_Texture* texture;
|
|
|
|
FontRec* fonts;
|
|
|
|
SDL_Surface* arrowDown;
|
|
SDL_Surface* arrowRight;
|
|
SDL_Surface* origin;
|
|
|
|
int trayOwner;
|
|
bool inTrade;
|
|
TileValueType tvType;
|
|
|
|
MPSLOT;
|
|
} WasmDrawCtx;
|
|
|
|
static SDL_Color sBonusColors[4] = {
|
|
{0xAF, 0xAF, 0x00, 0xFF},
|
|
{0x00, 0xAF, 0xAF,0xFF},
|
|
{0xAF, 0x00, 0xAF,0xFF},
|
|
{0xAF, 0xAF, 0xAF,0xFF},
|
|
};
|
|
|
|
static XP_UCHAR* sBonusSummaries[] = {
|
|
"2L",
|
|
"2W",
|
|
"3L",
|
|
"3W",
|
|
};
|
|
|
|
static SDL_Color sPlayerColors[] = {
|
|
{0x00, 0x00, 0x00, 0xFF}, /* black */
|
|
{0xFF, 0x00, 0x00, 0xFF}, /* red */
|
|
{0x00, 0x00, 0xFF, 0xFF}, /* blue */
|
|
{0x00, 0x8F, 0x00, 0xFF}, /* green */
|
|
};
|
|
|
|
enum { BLACK,
|
|
WHITE,
|
|
COLOR_FOCUS,
|
|
COLOR_NOTILE,
|
|
COLOR_TILE_BACK,
|
|
COLOR_BONUSHINT,
|
|
COLOR_BACK,
|
|
|
|
N_COLORS,
|
|
};
|
|
|
|
static TTF_Font*
|
|
fontFor( WasmDrawCtx* wdctx, int height )
|
|
{
|
|
TTF_Font* result = NULL;
|
|
for ( FontRec* rec = wdctx->fonts; !!rec; rec = rec->next ) {
|
|
if ( rec->size == height ) {
|
|
result = rec->font;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !result ) {
|
|
FontRec* rec = XP_MALLOC( wdctx->mpool, sizeof(*rec) );
|
|
rec->next = wdctx->fonts;
|
|
wdctx->fonts = rec;
|
|
|
|
rec->size = height;
|
|
rec->font = TTF_OpenFont( "assets_dir/DejaVuSansCondensed.ttf", height );
|
|
result = rec->font;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static SDL_Color sOtherColors[N_COLORS] = {
|
|
{0x00, 0x00, 0x00, 0xFF}, /* BLACK */
|
|
{0xFF, 0xFF, 0xFF, 0xFF}, /* WHITE */
|
|
{0x70, 0x70, 0xFF, 0xFF}, /* COLOR_FOCUS, */
|
|
{0xFF, 0xFF, 0xFF, 0xFF}, /* COLOR_NOTILE, */
|
|
{0xFF, 0xFF, 0x99, 0xFF}, /* COLOR_TILE_BACK, */
|
|
{0x7F, 0x7F, 0x7F, 0xFF},/* COLOR_BONUSHINT, */
|
|
{0xFF, 0xFF, 0xFF, 0xFF}, /* COLOR_BACK, */
|
|
};
|
|
|
|
static void
|
|
rectXPToSDL( SDL_Rect* sdlr, const XP_Rect* rect )
|
|
{
|
|
sdlr->x = rect->left;
|
|
sdlr->y = rect->top;
|
|
sdlr->w = rect->width;
|
|
sdlr->h = rect->height;
|
|
}
|
|
|
|
static void
|
|
clearRect( WasmDrawCtx* wdctx, const XP_Rect* rect )
|
|
{
|
|
Uint8 red, green, blue, alpha;
|
|
SDL_GetRenderDrawColor( wdctx->renderer, &red, &green, &blue, &alpha );
|
|
const SDL_Color* back = &sOtherColors[COLOR_BACK];
|
|
SDL_SetRenderDrawColor( wdctx->renderer, back->r, back->g, back->b, back->a );
|
|
|
|
SDL_Rect sdlr;
|
|
rectXPToSDL( &sdlr, rect );
|
|
SDL_RenderFillRect( wdctx->renderer, &sdlr );
|
|
|
|
SDL_SetRenderDrawColor( wdctx->renderer, red, green, blue, alpha );
|
|
}
|
|
|
|
static void
|
|
setPlayerColor( WasmDrawCtx* wdctx, int owner )
|
|
{
|
|
SDL_Color colorParts = sPlayerColors[owner];
|
|
SDL_SetRenderDrawColor( wdctx->renderer, colorParts.r, colorParts.g,
|
|
colorParts.b, colorParts.a );
|
|
}
|
|
|
|
static void
|
|
fillRect( WasmDrawCtx* wdctx, const XP_Rect* rect, const SDL_Color* colorParts )
|
|
{
|
|
SDL_Rect sdlr;
|
|
rectXPToSDL( &sdlr, rect );
|
|
Uint8 red, green, blue, alpha;
|
|
|
|
SDL_GetRenderDrawColor( wdctx->renderer, &red, &green, &blue, &alpha );
|
|
SDL_SetRenderDrawColor( wdctx->renderer, colorParts->r, colorParts->g,
|
|
colorParts->b, colorParts->a );
|
|
SDL_RenderFillRect( wdctx->renderer, &sdlr );
|
|
SDL_SetRenderDrawColor( wdctx->renderer, red, green, blue, alpha );
|
|
}
|
|
|
|
static void
|
|
frameRect( WasmDrawCtx* wdctx, const XP_Rect* rect )
|
|
{
|
|
SDL_Rect sdlr;
|
|
rectXPToSDL( &sdlr, rect );
|
|
const SDL_Color* black = &sOtherColors[BLACK];
|
|
SDL_SetRenderDrawColor( wdctx->renderer, black->r, black->g,
|
|
black->b, black->a );
|
|
SDL_RenderDrawRect( wdctx->renderer, &sdlr );
|
|
}
|
|
|
|
static void
|
|
measureText( WasmDrawCtx* wdctx, const XP_UCHAR* text, int fontHeight,
|
|
int* widthP, int* heightP )
|
|
{
|
|
SDL_Color black = { 0, 0, 0, 255 };
|
|
TTF_Font* font = fontFor( wdctx, fontHeight );
|
|
SDL_Surface* surface = TTF_RenderUTF8_Blended( font, text, black );
|
|
SDL_Texture* texture = SDL_CreateTextureFromSurface( wdctx->renderer,
|
|
surface );
|
|
SDL_QueryTexture( texture, NULL, NULL, widthP, heightP );
|
|
|
|
SDL_FreeSurface( surface );
|
|
SDL_DestroyTexture( texture );
|
|
}
|
|
|
|
static void
|
|
textInRect( WasmDrawCtx* wdctx, const XP_UCHAR* text, const XP_Rect* rect,
|
|
const SDL_Color* color )
|
|
{
|
|
TTF_Font* font = fontFor( wdctx, rect->height );
|
|
|
|
XP_Rect tmpR = *rect;
|
|
|
|
SDL_Color black = { 0, 0, 0, 255 };
|
|
if ( NULL == color ) {
|
|
color = &black;
|
|
}
|
|
SDL_Surface* surface = TTF_RenderUTF8_Blended( font, text, *color );
|
|
SDL_Texture* texture = SDL_CreateTextureFromSurface( wdctx->renderer, surface );
|
|
SDL_FreeSurface( surface );
|
|
|
|
int width, height;
|
|
SDL_QueryTexture( texture, NULL, NULL, &width, &height );
|
|
tmpR.width = XP_MIN( width, tmpR.width );
|
|
tmpR.left += (rect->width - tmpR.width) / 2;
|
|
tmpR.height = XP_MIN( height, tmpR.height );
|
|
|
|
SDL_Rect sdlr;
|
|
rectXPToSDL( &sdlr, &tmpR );
|
|
SDL_RenderCopy( wdctx->renderer, texture, NULL, &sdlr );
|
|
SDL_DestroyTexture( texture );
|
|
}
|
|
|
|
static void
|
|
imgInRect( WasmDrawCtx* wdctx, SDL_Surface* img, const XP_Rect* rect )
|
|
{
|
|
SDL_Texture* texture = SDL_CreateTextureFromSurface( wdctx->renderer, img );
|
|
SDL_Rect sdlr;
|
|
rectXPToSDL( &sdlr, rect );
|
|
SDL_RenderCopy( wdctx->renderer, texture, NULL, &sdlr );
|
|
SDL_DestroyTexture( texture );
|
|
}
|
|
|
|
static void
|
|
drawTile( WasmDrawCtx* wdctx, const XP_UCHAR* face, int val,
|
|
int owner, const XP_Rect* rect, CellFlags flags )
|
|
{
|
|
clearRect( wdctx, rect );
|
|
if ( 0 == (CELL_ISEMPTY & flags) ) {
|
|
frameRect( wdctx, rect );
|
|
|
|
XP_Rect tmp = *rect;
|
|
tmp.width = 3 * tmp.width / 4;
|
|
tmp.height = 3 * tmp.height / 4;
|
|
textInRect( wdctx, face, &tmp, &sPlayerColors[owner] );
|
|
|
|
if ( 0 <= val ) {
|
|
XP_Rect tmp = *rect;
|
|
tmp.width = tmp.width / 4;
|
|
tmp.left += tmp.width * 3;
|
|
tmp.height = tmp.height / 4;
|
|
tmp.top += tmp.height * 3;
|
|
XP_UCHAR buf[4];
|
|
XP_SNPRINTF( buf, VSIZE(buf), "%d", val );
|
|
textInRect( wdctx, buf, &tmp, &sPlayerColors[owner] );
|
|
}
|
|
|
|
if ( 0 != (flags & (CELL_PENDING|CELL_RECENT)) ) {
|
|
XP_Rect tmp = *rect;
|
|
for ( int ii = 0; ii < 3; ++ii ) {
|
|
insetRect( &tmp, 1, 1 );
|
|
frameRect( wdctx, &tmp );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
wasm_draw_dictChanged( DrawCtx* dctx, XWEnv xwe, XP_S16 playerNum,
|
|
const DictionaryCtxt* dict )
|
|
{
|
|
LOG_FUNC();
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_beginDraw( DrawCtx* dctx, XWEnv xwe )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
SDL_RenderPresent( wdctx->renderer );
|
|
return XP_TRUE;
|
|
}
|
|
|
|
static void
|
|
wasm_draw_destroyCtxt( DrawCtx* dctx, XWEnv xwe )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
|
|
FontRec* next = NULL;
|
|
for ( FontRec* rec = wdctx->fonts; !!rec; rec = next ) {
|
|
TTF_CloseFont( rec->font );
|
|
next = rec->next;
|
|
XP_FREE( wdctx->mpool, rec );
|
|
}
|
|
|
|
SDL_FreeSurface( wdctx->arrowDown );
|
|
SDL_FreeSurface( wdctx->arrowRight );
|
|
SDL_FreeSurface( wdctx->origin );
|
|
SDL_FreeSurface( wdctx->surface );
|
|
SDL_DestroyRenderer(wdctx->renderer);
|
|
|
|
XP_FREEP( wdctx->mpool, &wdctx->vtable );
|
|
XP_FREEP( wdctx->mpool, &wdctx );
|
|
}
|
|
|
|
static void
|
|
wasm_draw_endDraw( DrawCtx* dctx, XWEnv xwe )
|
|
{
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_boardBegin( DrawCtx* dctx, XWEnv xwe,
|
|
const XP_Rect* rect,
|
|
XP_U16 hScale, XP_U16 vScale,
|
|
DrawFocusState dfs, TileValueType tvType )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
wdctx->tvType = tvType;
|
|
return XP_TRUE;
|
|
}
|
|
|
|
static void
|
|
wasm_draw_objFinished( DrawCtx* dctx, XWEnv xwe, BoardObjectType typ,
|
|
const XP_Rect* rect,
|
|
DrawFocusState dfs )
|
|
{
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_vertScrollBoard(DrawCtx* dctx, XWEnv xwe, XP_Rect* rect,
|
|
XP_S16 dist, DrawFocusState dfs )
|
|
{
|
|
LOG_FUNC();
|
|
return XP_FALSE;
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_trayBegin( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
XP_U16 owner, XP_S16 score,
|
|
DrawFocusState dfs )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
wdctx->trayOwner = owner;
|
|
return XP_TRUE;
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_scoreBegin( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
XP_U16 numPlayers,
|
|
const XP_S16* const scores,
|
|
XP_S16 remCount, DrawFocusState dfs )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
clearRect( wdctx, rect );
|
|
return XP_TRUE;
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_measureRemText( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
XP_S16 nTilesLeft, XP_U16* widthP, XP_U16* heightP )
|
|
{
|
|
XP_Bool drawIt = 0 <= nTilesLeft;
|
|
if ( drawIt ) {
|
|
XP_UCHAR buf[4];
|
|
XP_SNPRINTF( buf, VSIZE(buf), "%d", nTilesLeft );
|
|
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
int width, height;
|
|
measureText( wdctx, buf, rect->height/2, &width, &height );
|
|
*widthP = XP_MIN( width * 5 / 3, rect->width );
|
|
*heightP = XP_MIN( height, rect->height );
|
|
}
|
|
return drawIt;
|
|
}
|
|
|
|
static void
|
|
wasm_draw_drawRemText( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rInner,
|
|
const XP_Rect* rOuter,
|
|
XP_S16 nTilesLeft, XP_Bool focussed )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
XP_UCHAR buf[4];
|
|
XP_SNPRINTF( buf, VSIZE(buf), "%d", nTilesLeft );
|
|
fillRect( wdctx, rOuter, &sOtherColors[BLACK] );
|
|
textInRect( wdctx, buf, rInner, &sOtherColors[WHITE] );
|
|
}
|
|
|
|
static void
|
|
formatScoreText(XP_UCHAR* out, int outLen, const DrawScoreInfo* dsi )
|
|
{
|
|
const char* name = dsi->name;
|
|
int score = dsi->totalScore;
|
|
int offset = XP_SNPRINTF( out, outLen, "%s:%d", name, score );
|
|
|
|
int nTilesLeft = dsi->nTilesLeft;
|
|
if ( (nTilesLeft < MAX_TRAY_TILES) && (nTilesLeft > 0) ) {
|
|
XP_SNPRINTF( out + offset, outLen-offset, ":%d", nTilesLeft );
|
|
}
|
|
}
|
|
|
|
static void
|
|
wasm_draw_measureScoreText( DrawCtx* dctx, XWEnv xwe,
|
|
const XP_Rect* rect,
|
|
const DrawScoreInfo* dsi,
|
|
XP_U16* widthP, XP_U16* heightP )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
XP_UCHAR buf[32];
|
|
formatScoreText( buf, sizeof(buf), dsi );
|
|
|
|
|
|
int fontHeight = rect->height;
|
|
if ( !dsi->isTurn ) {
|
|
fontHeight = fontHeight * 2 / 5;
|
|
}
|
|
int width, height;
|
|
measureText( wdctx, buf, fontHeight, &width, &height );
|
|
|
|
*widthP = XP_MIN( width, rect->height );
|
|
*heightP = XP_MIN( height, rect->height );
|
|
}
|
|
|
|
static void
|
|
wasm_draw_score_drawPlayer( DrawCtx* dctx, XWEnv xwe,
|
|
const XP_Rect* rInner,
|
|
const XP_Rect* rOuter,
|
|
XP_U16 gotPct,
|
|
const DrawScoreInfo* dsi )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
XP_UCHAR buf[32];
|
|
formatScoreText( buf, sizeof(buf), dsi );
|
|
textInRect( wdctx, buf, rInner, &sPlayerColors[dsi->playerNum] );
|
|
}
|
|
|
|
static void
|
|
wasm_draw_score_pendingScore( DrawCtx* dctx, XWEnv xwe,
|
|
const XP_Rect* rect,
|
|
XP_S16 score, XP_U16 playerNum,
|
|
XP_Bool curTurn, CellFlags flags )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
clearRect( wdctx, rect );
|
|
|
|
XP_Rect tmp = *rect;
|
|
tmp.height /= 2;
|
|
textInRect( wdctx, "Pts:", &tmp, NULL );
|
|
tmp.top += tmp.height;
|
|
XP_UCHAR buf[16];
|
|
if ( score >= 0 ) {
|
|
XP_SNPRINTF( buf, VSIZE(buf), "%.3d", score );
|
|
} else {
|
|
XP_STRNCPY( buf, "???", VSIZE(buf) );
|
|
}
|
|
textInRect( wdctx, buf, &tmp, NULL );
|
|
}
|
|
|
|
static void
|
|
wasm_draw_drawTimer( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
XP_U16 player, XP_S16 secondsLeft,
|
|
XP_Bool turnDone )
|
|
{
|
|
LOG_FUNC();
|
|
}
|
|
|
|
static void
|
|
markBlank( WasmDrawCtx* wdctx, const XP_Rect* rect, const SDL_Color* backColor )
|
|
{
|
|
}
|
|
|
|
static void
|
|
drawCrosshairs( WasmDrawCtx* wdctx, const XP_Rect* rect, CellFlags flags )
|
|
{
|
|
const SDL_Color* color = &sOtherColors[COLOR_FOCUS];
|
|
if ( 0 != (flags & CELL_CROSSHOR) ) {
|
|
XP_Rect hairRect = *rect;
|
|
insetRect( &hairRect, 0, hairRect.height / 3 );
|
|
fillRect( wdctx, &hairRect, color );
|
|
}
|
|
if ( 0 != (flags & CELL_CROSSVERT) ) {
|
|
XP_Rect hairRect = *rect;
|
|
insetRect( &hairRect, hairRect.width / 3, 0 );
|
|
fillRect( wdctx, &hairRect, color );
|
|
}
|
|
}
|
|
|
|
static void
|
|
setForTrade( const WasmDrawCtx* wdctx, SDL_Color* color )
|
|
{
|
|
if ( wdctx->inTrade ) {
|
|
color->a >>= 2;
|
|
}
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_drawCell( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
/* at least one of these two will be
|
|
null */
|
|
const XP_UCHAR* text, const XP_Bitmaps* bitmaps,
|
|
Tile tile, XP_U16 value,
|
|
XP_S16 owner, /* -1 means don't use */
|
|
XWBonusType bonus, HintAtts hintAtts,
|
|
CellFlags flags )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
XP_Bool empty = 0 != (flags & (CELL_DRAGSRC|CELL_ISEMPTY));
|
|
XP_Bool pending = 0 != (flags & CELL_PENDING);
|
|
XP_Bool recent = 0 != (flags & CELL_RECENT);
|
|
XP_UCHAR* bonusStr = NULL;
|
|
|
|
/* if ( wdctx->inTrade ) { */
|
|
/* fillRectOther( rect, CommonPrefs.COLOR_BACKGRND ); */
|
|
/* } */
|
|
|
|
if ( owner < 0 ) {
|
|
owner = 0;
|
|
}
|
|
|
|
SDL_Color foreColor = sPlayerColors[owner];
|
|
SDL_Color backColor;
|
|
if ( 0 != (flags & CELL_ISCURSOR) ) {
|
|
backColor = sOtherColors[COLOR_FOCUS];
|
|
} else if ( empty ) {
|
|
if ( 0 == bonus ) {
|
|
backColor = sOtherColors[COLOR_NOTILE];
|
|
} else {
|
|
backColor = sBonusColors[bonus-1];
|
|
bonusStr = sBonusSummaries[bonus-1];
|
|
}
|
|
} else if ( pending || recent ) {
|
|
foreColor = sOtherColors[WHITE];
|
|
backColor = sOtherColors[BLACK];
|
|
} else {
|
|
backColor = sOtherColors[COLOR_TILE_BACK];
|
|
}
|
|
|
|
setForTrade( wdctx, &backColor );
|
|
fillRect( wdctx, rect, &backColor );
|
|
|
|
if ( empty ) {
|
|
if ( (CELL_ISSTAR & flags) != 0 ) {
|
|
imgInRect( wdctx, wdctx->origin, rect );
|
|
} else if ( NULL != bonusStr ) {
|
|
const SDL_Color color = sOtherColors[COLOR_BONUSHINT];
|
|
/* m_fillPaint.setColor( adjustColor(color) ); */
|
|
/* Rect brect = new Rect( rect ); */
|
|
/* brect.inset( 0, brect.height()/10 ); */
|
|
/* drawCentered( bonusStr, brect, m_fontDims ); */
|
|
textInRect( wdctx, bonusStr, rect, &color );
|
|
}
|
|
} else {
|
|
XP_UCHAR valBuf[4];
|
|
XP_SNPRINTF( valBuf, sizeof(valBuf), "%d", value );
|
|
const XP_UCHAR* valueStr = valBuf;
|
|
switch ( wdctx->tvType ) {
|
|
case TVT_BOTH:
|
|
break;
|
|
case TVT_FACES:
|
|
valueStr = NULL;
|
|
break;
|
|
case TVT_VALUES:
|
|
text = valueStr;
|
|
valueStr = NULL;
|
|
break;
|
|
}
|
|
XP_Rect tmpRect = *rect;
|
|
if ( !!valueStr ) {
|
|
tmpRect.width = tmpRect.width * 4 / 5;
|
|
tmpRect.height = tmpRect.height * 4 / 5;
|
|
}
|
|
setForTrade( wdctx, &foreColor );
|
|
textInRect( wdctx, text, &tmpRect, &foreColor );
|
|
if ( !!valueStr ) {
|
|
XP_Rect tmpRect = *rect;
|
|
tmpRect.left += tmpRect.width * 1 / 2;
|
|
tmpRect.top += tmpRect.height * 1 / 2;
|
|
tmpRect.width /= 2;
|
|
tmpRect.height /= 2;
|
|
textInRect( wdctx, valueStr, &tmpRect, &foreColor );
|
|
}
|
|
}
|
|
|
|
if ( (CELL_ISBLANK & flags) != 0 ) {
|
|
markBlank( wdctx, rect, &backColor );
|
|
}
|
|
|
|
// frame the cell
|
|
frameRect( wdctx, rect );
|
|
|
|
drawCrosshairs( wdctx, rect, flags );
|
|
return XP_TRUE;
|
|
}
|
|
|
|
static void
|
|
wasm_draw_invertCell( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect )
|
|
{
|
|
LOG_FUNC();
|
|
}
|
|
|
|
static XP_Bool
|
|
wasm_draw_drawTile( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
/* at least 1 of these 2 will be
|
|
null*/
|
|
const XP_UCHAR* text,
|
|
const XP_Bitmaps* bitmaps,
|
|
XP_S16 val, CellFlags flags )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
drawTile( wdctx, text, val, wdctx->trayOwner, rect, flags );
|
|
return XP_TRUE;
|
|
}
|
|
|
|
#ifdef POINTER_SUPPORT
|
|
static XP_Bool
|
|
wasm_draw_drawTileMidDrag( DrawCtx* dctx, XWEnv xwe,
|
|
const XP_Rect* rect,
|
|
/* at least 1 of these 2 will
|
|
be null*/
|
|
const XP_UCHAR* text,
|
|
const XP_Bitmaps* bitmaps,
|
|
XP_U16 val, XP_U16 owner,
|
|
CellFlags flags )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
drawTile( wdctx, text, val, wdctx->trayOwner, rect, flags );
|
|
return XP_TRUE;
|
|
}
|
|
#endif
|
|
|
|
static XP_Bool
|
|
wasm_draw_drawTileBack( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
CellFlags flags )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
drawTile( wdctx, "?", -1, wdctx->trayOwner, rect, flags );
|
|
return XP_TRUE;
|
|
}
|
|
|
|
static void
|
|
wasm_draw_drawTrayDivider( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect,
|
|
CellFlags flags )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
XP_Rect copy = *rect;
|
|
fillRect( wdctx, ©, &sOtherColors[WHITE] );
|
|
insetRect( ©, copy.width / 4, 1 );
|
|
fillRect( wdctx, ©, &sPlayerColors[wdctx->trayOwner] );
|
|
}
|
|
|
|
static void
|
|
wasm_draw_clearRect( DrawCtx* dctx, XWEnv xwe, const XP_Rect* rect )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
clearRect( wdctx, rect );
|
|
}
|
|
|
|
static void
|
|
wasm_draw_drawBoardArrow ( DrawCtx* dctx, XWEnv xwe,
|
|
const XP_Rect* rect,
|
|
XWBonusType bonus, XP_Bool vert,
|
|
HintAtts hintAtts, CellFlags flags )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
const XP_UCHAR* str = vert ? "|" : "-";
|
|
SDL_Surface* img = vert ? wdctx->arrowDown : wdctx->arrowRight;
|
|
|
|
imgInRect( wdctx, img, rect );
|
|
}
|
|
|
|
static void
|
|
createSurface( WasmDrawCtx* wdctx, int width, int height )
|
|
{
|
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
|
uint32_t rmask = 0xff000000;
|
|
uint32_t gmask = 0x00ff0000;
|
|
uint32_t bmask = 0x0000ff00;
|
|
uint32_t amask = 0x000000ff;
|
|
#else
|
|
uint32_t rmask = 0x000000ff;
|
|
uint32_t gmask = 0x0000ff00;
|
|
uint32_t bmask = 0x00ff0000;
|
|
uint32_t amask = 0xff000000;
|
|
#endif
|
|
if ( !!wdctx->surface ) {
|
|
SDL_FreeSurface( wdctx->surface );
|
|
}
|
|
if ( !!wdctx->renderer ) {
|
|
SDL_DestroyRenderer(wdctx->renderer);
|
|
}
|
|
wdctx->surface = SDL_CreateRGBSurface( 0, width, height, 32,
|
|
rmask, gmask, bmask, amask );
|
|
wdctx->renderer = SDL_CreateSoftwareRenderer( wdctx->surface );
|
|
// wdctx->texture = SDL_CreateTextureFromSurface( wdctx->renderer, wdctx->surface );
|
|
}
|
|
|
|
void
|
|
wasm_draw_render( DrawCtx* dctx, SDL_Renderer* dest )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
|
|
SDL_Texture* texture =
|
|
SDL_CreateTextureFromSurface( dest, wdctx->surface );
|
|
SDL_RenderCopyEx( dest, texture, NULL, NULL, 0,
|
|
NULL, SDL_FLIP_NONE );
|
|
SDL_DestroyTexture( texture );
|
|
}
|
|
|
|
void
|
|
wasm_draw_setInTrade( DrawCtx* dctx, bool inTrade )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
wdctx->inTrade = inTrade;
|
|
}
|
|
|
|
DrawCtx*
|
|
wasm_draw_make( MPFORMAL int width, int height )
|
|
{
|
|
// XP_LOGFF( "(width: %d, height: %d)", width, height );
|
|
WasmDrawCtx* wdctx = XP_CALLOC( mpool, sizeof(*wdctx) );
|
|
MPASSIGN( wdctx->mpool, mpool );
|
|
|
|
wdctx->arrowDown = IMG_Load( "assets_dir/ic_downarrow.png" );
|
|
wdctx->arrowRight = IMG_Load( "assets_dir/ic_rightarrow.png" );
|
|
wdctx->origin = IMG_Load( "assets_dir/ic_origin.png" );
|
|
|
|
wdctx->vtable = XP_MALLOC( mpool, sizeof(*wdctx->vtable) );
|
|
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_clearRect, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_dictChanged, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_beginDraw, wasm );
|
|
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_clearRect, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_dictChanged, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_beginDraw, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_destroyCtxt, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_endDraw, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_boardBegin, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_objFinished, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_vertScrollBoard, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_trayBegin, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_scoreBegin, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_measureRemText, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawRemText, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_measureScoreText, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_score_drawPlayer, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_score_pendingScore, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawTimer, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawCell, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_invertCell, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawTile, wasm );
|
|
#ifdef POINTER_SUPPORT
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawTileMidDrag, wasm );
|
|
#endif
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawTileBack, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawTrayDivider, wasm );
|
|
SET_VTABLE_ENTRY( wdctx->vtable, draw_drawBoardArrow, wasm );
|
|
|
|
createSurface( wdctx, width, height );
|
|
|
|
return (DrawCtx*)wdctx;
|
|
}
|
|
|
|
void
|
|
wasm_draw_resize( DrawCtx* dctx, int width, int height )
|
|
{
|
|
WasmDrawCtx* wdctx = (WasmDrawCtx*)dctx;
|
|
createSurface( wdctx, width, height );
|
|
}
|