rest of what I just meant to commit.

This commit is contained in:
Eric House 2013-01-05 16:08:47 -08:00
parent 4af30c534c
commit e0dc83ed70
10 changed files with 217 additions and 109 deletions

View file

@ -78,19 +78,21 @@ checkIsText( MemPoolEntry* entry )
{
unsigned char* txt = (unsigned char*)entry->ptr;
XP_U32 len = entry->size;
char* result = NULL;
while ( len-- ) {
unsigned char c = *txt++;
if ( c < 32 || c > 127 ) {
if ( len == 0 && c == '\0' ) {
return (char*)entry->ptr;
} else {
return (char*)NULL;
if ( 0 < len ) {
while ( len-- ) {
unsigned char c = *txt++;
if ( c < 32 || c > 127 ) {
if ( len == 0 && c == '\0' ) {
result = (char*)entry->ptr;
}
break;
}
}
}
return (char*)NULL;
return result;
} /* checkIsText */
#endif

View file

@ -1,6 +1,6 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
/* -*-mode: compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
/*
* Copyright 2000-2012 by Eric House (xwords@eehouse.org). All rights
* Copyright 2000-2013 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -18,10 +18,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <sqlite3.h>
#include "comtypes.h"
#include "gamesdb.h"
#include "main.h"
#define DB_NAME "games.db"
@ -51,3 +49,42 @@ closeGamesDB( sqlite3* pDb )
sqlite3_close( pDb );
XP_LOGF( "%s finished", __func__ );
}
void
writeToDB( XWStreamCtxt* stream, void* closure )
{
int result;
CommonGlobals* cGlobals = (CommonGlobals*)closure;
sqlite3_int64 rowid = cGlobals->rowid;
sqlite3* pDb = cGlobals->pDb;
XP_U16 len = stream_getSize( stream );
sqlite3_stmt* stmt = NULL;
if ( 0 == rowid ) { /* new row; need to insert blob first */
const char* txt = "INSERT INTO games (game) VALUES (?)";
result = sqlite3_prepare_v2( pDb, txt, -1, &stmt, NULL );
XP_ASSERT( SQLITE_OK == result );
result = sqlite3_bind_zeroblob( stmt, 1 /*col 0 ??*/, len );
XP_ASSERT( SQLITE_OK == result );
result = sqlite3_step( stmt );
XP_ASSERT( SQLITE_DONE == result );
rowid = sqlite3_last_insert_rowid( pDb );
XP_LOGF( "%s: new rowid: %lld", __func__, rowid );
cGlobals->rowid = rowid;
sqlite3_finalize( stmt );
}
sqlite3_blob* blob;
result = sqlite3_blob_open( pDb, "main", "games", "game",
rowid, 1 /*flags: writeable*/, &blob );
XP_ASSERT( SQLITE_OK == result );
const XP_U8* ptr = stream_getPtr( stream );
result = sqlite3_blob_write( blob, ptr, len, 0 );
XP_ASSERT( SQLITE_OK == result );
result = sqlite3_blob_close( blob );
XP_ASSERT( SQLITE_OK == result );
if ( !!stmt ) {
sqlite3_finalize( stmt );
}
}

View file

@ -23,7 +23,11 @@
#include <sqlite3.h>
#include "comtypes.h"
sqlite3* openGamesDB( void );
void closeGamesDB( sqlite3* dbp );
void writeToDB( XWStreamCtxt* stream, void* closure );
#endif

View file

@ -395,8 +395,6 @@ createOrLoadObjects( GtkAppGlobals* globals )
XP_Bool opened = XP_FALSE;
#ifndef XWFEATURE_STANDALONE_ONLY
DeviceRole serverRole = globals->cGlobals.params->serverRole;
XP_Bool isServer = serverRole != SERVER_ISCLIENT;
#endif
LaunchParams* params = globals->cGlobals.params;
@ -500,15 +498,20 @@ createOrLoadObjects( GtkAppGlobals* globals )
params->gi.allowHintRect = params->allowHintRect;
#endif
if ( params->needsNewGame ) {
new_game_impl( globals, XP_FALSE );
#ifndef XWFEATURE_STANDALONE_ONLY
} else if ( !isServer ) {
XWStreamCtxt* stream =
mem_stream_make( MEMPOOL params->vtMgr, &globals->cGlobals, CHANNEL_NONE,
sendOnClose );
server_initClientConnection( globals->cGlobals.game.server,
stream );
} else {
DeviceRole serverRole = globals->cGlobals.params->gi.serverRole;
if ( serverRole == SERVER_ISCLIENT ) {
XWStreamCtxt* stream =
mem_stream_make( MEMPOOL params->vtMgr,
&globals->cGlobals, CHANNEL_NONE,
sendOnClose );
server_initClientConnection( globals->cGlobals.game.server,
stream );
}
#endif
}
}
@ -670,9 +673,12 @@ handle_client_event( GtkWidget *widget, GdkEventClient *event,
#endif
static void
quit( void )
destroy_window( GtkWidget* XP_UNUSED(widget), gpointer data )
{
gtk_main_quit();
LOG_FUNC();
GtkAppGlobals* globals = (GtkAppGlobals*)data;
saveGame( &globals->cGlobals );
// gtk_main_quit();
}
static void
@ -786,9 +792,9 @@ new_game_impl( GtkAppGlobals* globals, XP_Bool fireConnDlg )
comms_getInitialAddr( &addr, RELAY_NAME_DEFAULT, RELAY_PORT_DEFAULT );
}
success = newGameDialog( globals, &addr, XP_TRUE, fireConnDlg );
CurGameInfo* gi = &globals->cGlobals.params->gi;
success = newGameDialog( globals, gi, &addr, XP_TRUE, fireConnDlg );
if ( success ) {
CurGameInfo* gi = &globals->cGlobals.params->gi;
#ifndef XWFEATURE_STANDALONE_ONLY
XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT;
#endif
@ -803,22 +809,22 @@ new_game_impl( GtkAppGlobals* globals, XP_Bool fireConnDlg )
if ( !game_reset( MEMPOOL &globals->cGlobals.game, gi,
globals->cGlobals.params->util,
&globals->cGlobals.cp, &procs ) ) {
if ( NULL == globals->draw ) {
globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area,
globals );
}
game_makeNewGame( MEMPOOL &globals->cGlobals.game, gi,
globals->cGlobals.params->util,
(DrawCtx*)globals->draw,
&globals->cGlobals.cp, &procs,
globals->cGlobals.params->gameSeed );
ModelCtxt* model = globals->cGlobals.game.model;
if ( NULL == model_getDictionary( model ) ) {
DictionaryCtxt* dict =
linux_dictionary_make( MEMPOOL globals->cGlobals.params,
gi->dictName, XP_TRUE );
model_setDictionary( model, dict );
}
/* if ( NULL == globals->draw ) { */
/* globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area, */
/* globals ); */
/* } */
/* game_makeNewGame( MEMPOOL &globals->cGlobals.game, gi, */
/* globals->cGlobals.params->util, */
/* (DrawCtx*)globals->draw, */
/* &globals->cGlobals.cp, &procs, */
/* globals->cGlobals.params->gameSeed ); */
/* ModelCtxt* model = globals->cGlobals.game.model; */
/* if ( NULL == model_getDictionary( model ) ) { */
/* DictionaryCtxt* dict = */
/* linux_dictionary_make( MEMPOOL globals->cGlobals.params, */
/* gi->dictName, XP_TRUE ); */
/* model_setDictionary( model, dict ); */
/* } */
}
#ifndef XWFEATURE_STANDALONE_ONLY
@ -858,7 +864,8 @@ game_info( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
/* Anything to do if OK is clicked? Changed names etc. already saved. Try
server_do in case one's become a robot. */
if ( newGameDialog( globals, &addr, XP_FALSE, XP_FALSE ) ) {
CurGameInfo* gi = &globals->cGlobals.params->gi;
if ( newGameDialog( globals, gi, &addr, XP_FALSE, XP_FALSE ) ) {
if ( server_do( globals->cGlobals.game.server ) ) {
board_draw( globals->cGlobals.game.board );
}
@ -868,11 +875,13 @@ game_info( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
static void
load_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* XP_UNUSED(globals) )
{
XP_ASSERT(0);
} /* load_game */
static void
save_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* XP_UNUSED(globals) )
{
XP_ASSERT(0);
} /* save_game */
#ifdef XWFEATURE_CHANGEDICT
@ -1478,7 +1487,7 @@ gtk_util_notifyGameOver( XW_UtilCtxt* uc, XP_S16 quitter )
if ( cGlobals->params->quitAfter >= 0 ) {
sleep( cGlobals->params->quitAfter );
quit();
destroy_window( NULL, globals );
} else if ( cGlobals->params->undoWhenDone ) {
server_handleUndo( cGlobals->game.server, 0 );
board_draw( cGlobals->game.board );
@ -2298,25 +2307,25 @@ handle_sigintterm( int XP_UNUSED(sig) )
gtk_main_quit();
}
int
board_main( LaunchParams* params )
{
GtkAppGlobals globals;
initGlobals( &globals, params );
/* int */
/* board_main( LaunchParams* params ) */
/* { */
/* GtkAppGlobals globals; */
/* initGlobals( &globals, params ); */
if ( !!params->pipe && !!params->fileName ) {
read_pipe_then_close( &globals.cGlobals, NULL );
} else {
gtk_widget_show( globals.window );
/* if ( !!params->pipe && !!params->fileName ) { */
/* read_pipe_then_close( &globals.cGlobals, NULL ); */
/* } else { */
/* gtk_widget_show( globals.window ); */
gtk_main();
}
/* MONCONTROL(1); */
/* gtk_main(); */
/* } */
/* /\* MONCONTROL(1); *\/ */
cleanup( &globals );
/* cleanup( &globals ); */
return 0;
} /* gtkmain */
/* return 0; */
/* } */
void
initGlobals( GtkAppGlobals* globals, LaunchParams* params )
@ -2379,7 +2388,7 @@ initGlobals( GtkAppGlobals* globals, LaunchParams* params )
gtk_widget_show( vbox );
g_signal_connect( G_OBJECT (window), "destroy",
G_CALLBACK( quit ), &globals );
G_CALLBACK( destroy_window ), globals );
menubar = makeMenus( globals );
gtk_box_pack_start( GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
@ -2387,7 +2396,7 @@ initGlobals( GtkAppGlobals* globals, LaunchParams* params )
#ifndef XWFEATURE_STANDALONE_ONLY
dropCheck = gtk_check_button_new_with_label( "drop incoming messages" );
g_signal_connect( GTK_OBJECT(dropCheck),
"toggled", G_CALLBACK(drop_msg_toggle), &globals );
"toggled", G_CALLBACK(drop_msg_toggle), globals );
gtk_box_pack_start( GTK_BOX(vbox), dropCheck, FALSE, TRUE, 0);
gtk_widget_show( dropCheck );
#endif
@ -2479,7 +2488,21 @@ freeGlobals( GtkAppGlobals* globals )
XP_Bool
makeNewGame( GtkAppGlobals* globals )
{
return new_game_impl( globals, XP_FALSE );
CommsAddrRec addr;
if ( !!globals->cGlobals.game.comms ) {
comms_getAddr( globals->cGlobals.game.comms, &addr );
} else {
comms_getInitialAddr( &addr, RELAY_NAME_DEFAULT, RELAY_PORT_DEFAULT );
}
CurGameInfo* gi = &globals->cGlobals.params->gi;
XP_Bool success = newGameDialog( globals, gi, &addr, XP_TRUE, XP_FALSE );
if ( success && !!gi->dictName && !globals->cGlobals.params->dict ) {
globals->cGlobals.params->dict =
linux_dictionary_make( MEMPOOL globals->cGlobals.params,
gi->dictName, XP_TRUE );
}
return success;
}
#endif /* PLATFORM_GTK */

View file

@ -25,22 +25,20 @@
#include "gtkboard.h"
#include "linuxmain.h"
enum { NAME_ITEM, N_ITEMS };
enum { ROW_ITEM, N_ITEMS };
typedef struct _GTKGamesGlobals {
sqlite3* pDb;
GtkAppGlobals globals;
LaunchParams* params;
} GTKGamesGlobals;
static void
init_games_list( GtkWidget* list )
{
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn* column =
gtk_tree_view_column_new_with_attributes( "Games", renderer,
"text", NAME_ITEM, NULL );
"row", ROW_ITEM, NULL );
gtk_tree_view_append_column( GTK_TREE_VIEW(list), column );
GtkListStore* store = gtk_list_store_new( N_ITEMS, G_TYPE_STRING );
gtk_tree_view_set_model( GTK_TREE_VIEW(list), GTK_TREE_MODEL(store) );
@ -53,33 +51,66 @@ handle_newgame_button( GtkWidget* XP_UNUSED(widget), void* closure )
GTKGamesGlobals* gg = (GTKGamesGlobals*)closure;
XP_LOGF( "%s called", __func__ );
GtkAppGlobals* globals = malloc( sizeof(*globals) );
gg->params->needsNewGame = XP_FALSE;
initGlobals( globals, gg->params );
if ( !makeNewGame( globals ) ) {
freeGlobals( globals );
} else {
GtkWidget* gameWindow = globals->window;
globals->cGlobals.pDb = gg->pDb;
gtk_widget_show( gameWindow );
}
}
static void
handle_quit_button( GtkWidget* XP_UNUSED(widget), gpointer data )
{
GTKGamesGlobals* gg = (GTKGamesGlobals*)data;
gg = gg;
gtk_main_quit();
}
static void
handle_destroy( GtkWidget* XP_UNUSED(widget), gpointer data )
{
LOG_FUNC();
GTKGamesGlobals* gg = (GTKGamesGlobals*)data;
gg = gg;
gtk_main_quit();
}
static GtkWidget*
makeGamesWindow( GTKGamesGlobals* gg )
{
GtkWidget* window;
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
g_signal_connect( G_OBJECT(window), "destroy",
G_CALLBACK(handle_destroy), gg );
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_add( GTK_CONTAINER(window), vbox );
gtk_widget_show( vbox );
GtkWidget* list = gtk_tree_view_new();
gtk_container_add( GTK_CONTAINER(vbox), list );
init_games_list( list );
gtk_widget_show( list );
GtkWidget* hbox = gtk_hbox_new( FALSE, 0 );
gtk_widget_show( hbox );
gtk_container_add( GTK_CONTAINER(vbox), hbox );
GtkWidget* button = gtk_button_new_with_label( "New Game" );
gtk_container_add( GTK_CONTAINER(vbox), button );
gtk_container_add( GTK_CONTAINER(hbox), button );
g_signal_connect( GTK_OBJECT(button), "clicked",
G_CALLBACK(handle_newgame_button), gg );
gtk_widget_show( button );
button = gtk_button_new_with_label( "Quit" );
gtk_container_add( GTK_CONTAINER(hbox), button );
g_signal_connect( GTK_OBJECT(button), "clicked",
G_CALLBACK(handle_quit_button), gg );
gtk_widget_show( button );
gtk_widget_show( window );
return window;

View file

@ -1,6 +1,6 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE"; -*- */
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
/*
* Copyright 2001-2008 by Eric House (xwords@eehouse.org). All rights
* Copyright 2001-2013 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -33,6 +33,7 @@
typedef struct GtkNewGameState {
GtkAppGlobals* globals;
CurGameInfo* gi;
NewGameCtx* newGameCtxt;
CommsAddrRec addr;
@ -248,7 +249,7 @@ makeNewGameDialog( GtkNewGameState* state )
nPlayersCombo = gtk_combo_box_new_text();
state->nPlayersCombo = nPlayersCombo;
gi = &state->globals->cGlobals.params->gi;
gi = state->gi;
for ( ii = 0; ii < MAX_NUM_PLAYERS; ++ii ) {
char buf[2] = { ii + '1', '\0' };
@ -352,16 +353,21 @@ makeNewGameDialog( GtkNewGameState* state )
gtk_box_pack_start( GTK_BOX(hbox), dictCombo, FALSE, TRUE, 0 );
GSList* dicts = listDicts( state->globals->cGlobals.params );
for ( GSList* iter = dicts; !!iter; iter = iter->next ) {
gtk_combo_box_append_text( GTK_COMBO_BOX(dictCombo), iter->data );
GSList* iter;
for ( iter = dicts, ii = 0; !!iter; iter = iter->next, ++ii ) {
const gchar* name = iter->data;
gtk_combo_box_append_text( GTK_COMBO_BOX(dictCombo), name );
if ( !!gi->dictName && !strcmp( name, gi->dictName ) ) {
gtk_combo_box_set_active( GTK_COMBO_BOX(dictCombo), ii );
}
}
g_slist_free( dicts );
if ( !!gi->dictName ) {
gtk_box_pack_start( GTK_BOX(hbox),
gtk_label_new(gi->dictName),
FALSE, TRUE, 0 );
}
/* if ( !!gi->dictName ) { */
/* gtk_box_pack_start( GTK_BOX(hbox), */
/* gtk_label_new(gi->dictName), */
/* FALSE, TRUE, 0 ); */
/* } */
gtk_widget_show( hbox );
@ -538,13 +544,14 @@ gtk_newgame_attr_set( void* closure, NewGameAttr attr, NGValue value )
}
gboolean
newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame,
XP_Bool fireConnDlg )
newGameDialog( GtkAppGlobals* globals, CurGameInfo* gi, CommsAddrRec* addr,
XP_Bool isNewGame, XP_Bool fireConnDlg )
{
GtkNewGameState state;
XP_MEMSET( &state, 0, sizeof(state) );
state.globals = globals;
state.gi = gi;
state.newGameCtxt = newg_make( MPPARM(globals->cGlobals.params
->util->mpool)
isNewGame,
@ -564,25 +571,22 @@ newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame,
state.revert = FALSE;
state.loaded = XP_FALSE;
state.nCols = globals->cGlobals.params->gi.boardSize;
state.role = globals->cGlobals.params->gi.serverRole;
state.nCols = gi->boardSize;
state.role = gi->serverRole;
XP_MEMCPY( &state.addr, addr, sizeof(state.addr) );
dialog = makeNewGameDialog( &state );
newg_load( state.newGameCtxt,
&globals->cGlobals.params->gi );
newg_load( state.newGameCtxt, gi );
state.loaded = XP_TRUE;
gtk_main();
if ( !state.cancelled && !state.revert ) {
if ( newg_store( state.newGameCtxt, &globals->cGlobals.params->gi,
XP_TRUE ) ) {
globals->cGlobals.params->gi.boardSize = state.nCols;
if ( newg_store( state.newGameCtxt, gi, XP_TRUE ) ) {
gi->boardSize = state.nCols;
replaceStringIfDifferent( globals->cGlobals.params->util->mpool,
&globals->cGlobals.params->gi.dictName,
state.dict );
&gi->dictName, state.dict );
} else {
/* Do it again if we warned user of inconsistency. */
state.revert = XP_TRUE;

View file

@ -1,6 +1,6 @@
/* -*- compile-command: "make MEMDEBUG=TRUE"; -*- */
/* -*- compile-command: "make MEMDEBUG=TRUE -j3"; -*- */
/*
* Copyright 2000-2009 by Eric House (xwords@eehouse.org). All rights
* Copyright 2000-2013 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -26,8 +26,9 @@
#include "gtkboard.h"
gboolean newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr,
XP_Bool isNewGame, XP_Bool fireConnDlg );
gboolean newGameDialog( GtkAppGlobals* globals, CurGameInfo* gi,
CommsAddrRec* addr, XP_Bool isNewGame,
XP_Bool fireConnDlg );
#endif /* _GTKNEWGAME_H_ */
#endif /* PLATFORM_GTK */

View file

@ -57,6 +57,7 @@
#include "linuxudp.h"
#include "dictiter.h"
#include "main.h"
#include "gamesdb.h"
#ifdef PLATFORM_NCURSES
# include "cursesmain.h"
#endif
@ -130,7 +131,8 @@ streamFromDB( CommonGlobals* cGlobals, void* closure )
XP_U8 buf[size];
res = sqlite3_blob_read( ppBlob, buf, size, 0 );
if ( SQLITE_OK == res ) {
stream = mem_stream_make( MPPARM(params->util->mpool) params->vtMgr,
stream = mem_stream_make( MPPARM(params->util->mpool)
params->vtMgr,
closure, CHANNEL_NONE, NULL );
stream_putBytes( stream, buf, size );
}
@ -255,23 +257,26 @@ strFromStream( XWStreamCtxt* stream )
void
saveGame( CommonGlobals* cGlobals )
{
if ( !!cGlobals->params->fileName ) {
LOG_FUNC();
if ( !!cGlobals->params->fileName || !!cGlobals->pDb ) {
XP_Bool doSave = XP_TRUE;
if ( 0 < cGlobals->params->saveFailPct
/* don't fail to save first time! */
&& file_exists( cGlobals->params->fileName ) ) {
XP_Bool newGame = !file_exists( cGlobals->params->fileName )
|| 0 == cGlobals->rowid;
/* don't fail to save first time! */
if ( 0 < cGlobals->params->saveFailPct && !newGame ) {
XP_U16 pct = XP_RANDOM() % 100;
doSave = pct >= cGlobals->params->saveFailPct;
}
if ( doSave ) {
XWStreamCtxt* outStream;
MemStreamCloseCallback onClose = !!cGlobals->pDb?
writeToDB : writeToFile;
outStream =
mem_stream_make_sized( MPPARM(cGlobals->params->util->mpool)
cGlobals->params->vtMgr,
cGlobals->lastStreamSize,
cGlobals, 0, writeToFile );
cGlobals, 0, onClose );
stream_open( outStream );
game_saveToStream( &cGlobals->game,
@ -1507,14 +1512,13 @@ listDicts( const LaunchParams *params )
return result;
}
void
static void
initParams( LaunchParams* params )
{
memset( params, 0, sizeof(*params) );
params->util = malloc( sizeof(params->util) );
XP_MEMSET( params->util, 0, sizeof(params->util) );
params->util = calloc( 1, sizeof(*params->util) );
/* XP_MEMSET( params->util, 0, sizeof(params->util) ); */
#ifdef MEM_DEBUG
params->util->mpool = mpool_make();
@ -1529,11 +1533,11 @@ initParams( LaunchParams* params )
#endif
}
void
static void
freeParams( LaunchParams* params )
{
vtmgr_destroy( MPPARM(params->util->mpool) params->vtMgr );
linux_util_vt_destroy( params->util );
vtmgr_destroy( MPPARM(params->util->mpool) params->vtMgr );
mpool_destroy( params->util->mpool );
@ -1596,8 +1600,6 @@ main( int argc, char** argv )
#endif
initParams( &mainParams );
/* fprintf( stdout, "press <RET> to start\n" ); */
/* (void)fgetc( stdin ); */
/* defaults */
#ifdef XWFEATURE_RELAY

View file

@ -94,7 +94,7 @@ void setOneSecondTimer( CommonGlobals* cGlobals );
# define setOneSecondTimer( cGlobals )
#endif
void initParams( LaunchParams* params );
void freeParams( LaunchParams* params );
/* void initParams( LaunchParams* params ); */
/* void freeParams( LaunchParams* params ); */
#endif

View file

@ -25,6 +25,8 @@
# include <bluetooth/bluetooth.h> /* for bdaddr_t, which should move */
#endif
#include <sqlite3.h>
#include "comtypes.h"
#include "util.h"
#include "game.h"
@ -167,9 +169,11 @@ struct CommonGlobals {
CommonPrefs cp;
XWGame game;
sqlite3_int64 rowid;
XP_U16 lastNTilesToUse;
XP_U16 lastStreamSize;
XP_Bool manualFinal; /* use asked for final scores */
sqlite3* pDb;
SocketChangedFunc socketChanged;
void* socketChangedClosure;