diff --git a/CMakeLists.txt b/CMakeLists.txt index c1e839d..7ff1b64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ include_directories(platform libs) include_directories( ${SDL2_INCLUDE_DIRS}) -add_compile_options(-funsigned-char) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -funsigned-char") enable_testing() add_subdirectory(libs) add_subdirectory(platform) diff --git a/Windows/Music.cpp b/Windows/Music.cpp index 3c75b96..d4673a7 100644 --- a/Windows/Music.cpp +++ b/Windows/Music.cpp @@ -42,7 +42,7 @@ HRESULT MusicPlayer::InitBuffer(IDirectSound8 *ds8, int *linvoltable) wfex.nAvgBytesPerSec=wfex.nSamplesPerSec*wfex.nBlockAlign; wfex.wFormatTag=WAVE_FORMAT_PCM; wfex.nChannels=2; - + DSBUFFERDESC desc; desc.dwSize=sizeof(desc); desc.dwBufferBytes=BUFFER_SIZE; @@ -70,7 +70,7 @@ HRESULT MusicPlayer::Play() memset(ptr,0,size); _ds8Buffer->Unlock(ptr,size,NULL,NULL); _ds8Buffer->SetVolume(_linvoltable[_volume]); - HRESULT res=_ds8Buffer->Play(0,0,DSBPLAY_LOOPING); + HRESULT res=_ds8Buffer->Play(0,0,DSBPLAY_LOOPING); _crossfadebytes=0; _minorpos=0; return res; @@ -80,7 +80,7 @@ class AutoCloseCriticalSection { LPCRITICAL_SECTION lcrit; public: - AutoCloseCriticalSection(LPCRITICAL_SECTION l):lcrit(l) + AutoCloseCriticalSection(LPCRITICAL_SECTION l):lcrit(l) { EnterCriticalSection(lcrit); } @@ -91,15 +91,15 @@ public: }; int MusicPlayer::Open(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms) -{ - AutoCloseCriticalSection lsect(&_lock); +{ + AutoCloseCriticalSection lsect(&_lock); if (numchannels<1 || numchannels>2) return -1; if (bitspersamp!=8 && bitspersamp!=16) return -1; _stereo=numchannels==2; _bit16=bitspersamp==16; _speed=samplerate*1024/44100; if (_speed<128) return -1; - _opened=true; + _opened=true; return 0; } @@ -139,12 +139,12 @@ void MusicPlayer::Close() { DWORD status; _ds8Buffer->GetStatus(&status); - _ds8Buffer->Play(0,0,DSBPLAY_LOOPING); + _ds8Buffer->Play(0,0,DSBPLAY_LOOPING); EnterCriticalSection(&_lock); - if ((status & DSBSTATUS_PLAYING)==0) - _ds8Buffer->Stop(); + if ((status & DSBSTATUS_PLAYING)==0) + _ds8Buffer->Stop(); } - + if (_crossfadebytes==0) { DWORD xfadepos=GetSafeXFadePos(); @@ -168,16 +168,16 @@ void MusicPlayer::Close() _ds8Buffer->Unlock(ptr[0],sz[0],ptr[1],sz[1]); } _crossfadebytes=xfadesz; - _lastWritePos=xfadepos; + _lastWritePos=xfadepos; } _opened=false; LeaveCriticalSection(&_lock); } int MusicPlayer::Write(const char *buf, int len) -{ +{ EnterCriticalSection(&_lock); - if (!_opened) + if (!_opened) { LeaveCriticalSection(&_lock); return 1; @@ -192,7 +192,7 @@ int MusicPlayer::Write(const char *buf, int len) while (len>0) { short sample[2]; - + if (_bit16) if (_stereo) { @@ -215,7 +215,7 @@ int MusicPlayer::Write(const char *buf, int len) sample[0]=(*buf)*256; sample[1]=(*buf)*256; } - while (remainspace<4) + while (remainspace<4) { if (stage<1) { @@ -245,7 +245,7 @@ int MusicPlayer::Write(const char *buf, int len) stage=0; remainspace=locksz[stage]; wrtptr=lockptr[stage]; - } + } } if (_crossfadebytes) { @@ -261,7 +261,7 @@ int MusicPlayer::Write(const char *buf, int len) if (_crossfadebytes<4) _crossfadebytes=0;else _crossfadebytes-=4; } else - memcpy(wrtptr,sample,4); + wrtptr = sample; wrtptr=(void *)((char *)wrtptr+4); remainspace-=4; _minorpos+=_speed; @@ -305,9 +305,9 @@ void MusicPlayer::SetVolume(int volume) { if (volume<0) return; _ds8Buffer->SetVolume(_linvoltable[volume]); - if (volume==0) + if (volume==0) Pause(1); - else + else Pause(0); } @@ -333,7 +333,7 @@ void MusDecoder::AttachOutput(IWAOutput *o) bool MusDecoder::Play(const char *filename) { DWORD res=0; - if (filename[0]=='?') + if (filename[0]=='?') { if (_output->Open(44100,1,8,-1,-1)<0) { @@ -447,7 +447,7 @@ UINT MusDecoder::SilentWritterThread() } _playing=false; return 0; - + } WinAmpDecoder::WinAmpDecoder() @@ -477,7 +477,7 @@ bool WinAmpDecoder::Play(const char *filename) { _currPlugin=0; return false; - } + } int playtm=_currPlugin->GetOutputTime(); int nexttm=playtm; int c=0; @@ -489,7 +489,7 @@ bool WinAmpDecoder::Play(const char *filename) void WinAmpDecoder::Stop() { - if (_currPlugin==0) return; + if (_currPlugin==0) return; _currPlugin->Stop(); _currPlugin->AttachOutput(0); _currPlugin=0; @@ -502,6 +502,6 @@ bool WinAmpDecoder::IsPlaying() } void WinAmpDecoder::SetVolume(int volume, int main) -{ +{ _currPlugin->SetVolume(volume); -} \ No newline at end of file +} diff --git a/game/dialogy.c b/game/dialogy.c index 6de19f4..d23d006 100644 --- a/game/dialogy.c +++ b/game/dialogy.c @@ -216,7 +216,7 @@ static void error(char *text) sprintf(buff,"%s v odstavci %d\r\nLocal_pgf=%d / DIALOG : %d / SENTENCE : %d\r\n",text,last_pgf+local_pgf,local_pgf,local_pgf/128,last_pgf); // MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); SEND_LOG("(DIALOGS) Dialog error detected at %d:%d",local_pgf/128,last_pgf); - SEND_LOG("(DIALOGS) Error description: %s",text,0); + SEND_LOG("(DIALOGS) Error description: %s",text); } static void show_dialog_picture() @@ -906,7 +906,7 @@ static void exit_dialog() norefresh=0; } starting_shop=-1; - SEND_LOG("(DIALOGS) Exiting dialog...",0,0); + SEND_LOG("(DIALOGS) Exiting dialog..."); } @@ -955,7 +955,7 @@ char join_character(int i) THUMAN *s=postavy_2+i; int j; - SEND_LOG("(DIALOGS) Joining character '%s'",s->jmeno,0); + SEND_LOG("(DIALOGS) Joining character '%s'",s->jmeno); for(j=0,h=postavy;jused) { memcpy(h,s,sizeof(THUMAN)); @@ -966,7 +966,7 @@ char join_character(int i) bott_draw(1); return 0; } - SEND_LOG("(DIALOGS) Join failed - no room for new character",0,0); + SEND_LOG("(DIALOGS) Join failed - no room for new character"); return 1; } @@ -1335,7 +1335,7 @@ void call_dialog(int entr,int mob) curcolor=0; create_back_pic(); bar32(0,SCREEN_OFFLINE,639,SCREEN_OFFLINE+359); - SEND_LOG("(DIALOGS) Starting dialog...",0,0); + SEND_LOG("(DIALOGS) Starting dialog..."); for(i=0;ilives>0) return; - SEND_LOG("(GAME) Monster killed ... '%s'",p->name,0); + SEND_LOG("(GAME) Monster killed ... '%s'",p->name); sect=p->sector; p->vlajky&=~MOB_IN_BATTLE & ~MOB_LIVE; free_path(num); diff --git a/game/gamesave.c b/game/gamesave.c index 15d7c67..3403332 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -84,7 +84,7 @@ static int unable_open_temp(char *c) concat(e,d,c); closemode(); display_error(e); - SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c,0); + SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c); exit(1); } @@ -95,7 +95,7 @@ static void unable_write_temp(char *c) concat(e,d,c); closemode(); display_error(e); - SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c,0); + SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c); exit(1); } @@ -348,7 +348,7 @@ int save_map_state() //uklada stav mapy pro savegame (neuklada aktualni pozici); restore_sound_names(); strcpy(sta,level_fname); fsta=temp_storage_create(sta);if (fsta==NULL) unable_open_temp(sta); - SEND_LOG("(SAVELOAD) Saving map state for current map",0,0); + SEND_LOG("(SAVELOAD) Saving map state for current map"); if (load_org_map(level_fname,&org_sides,&org_sectors,NULL,NULL)) goto err; siz=(mapsize+7)/8; bf=(char *)getmem(siz); @@ -400,7 +400,7 @@ int save_map_state() //uklada stav mapy pro savegame (neuklada aktualni pozici); save_enemy_paths(fsta); res=0; err: - SEND_LOG("(SAVELOAD) State of current map saved (err:%d)",res,0); + SEND_LOG("(SAVELOAD) State of current map saved (err:%d)",res); temp_storage_close_wr(fsta); free(org_sectors); free(org_sides); @@ -430,7 +430,7 @@ int load_map_state() //obnovuje stav mapy; nutno volat po zavolani load_map; if (ver>STATE_CUR_VER) goto err; if (!temp_storage_read(&i,sizeof(mapsize)*1,fsta)) goto err; if (mapsize!=i) goto err; - SEND_LOG("(SAVELOAD) Loading map state for current map",0,0); + SEND_LOG("(SAVELOAD) Loading map state for current map"); temp_storage_read(&siz,1*sizeof(siz),fsta); bf=(char *)getmem(siz); if (!temp_storage_read(bf,siz*1,fsta)) goto err; @@ -483,7 +483,7 @@ int load_map_state() //obnovuje stav mapy; nutno volat po zavolani load_map; res|=load_all_fly(fsta); res|=load_enemy_paths(fsta); err: - SEND_LOG("(SAVELOAD) State of current map loaded (err:%d)",res,0); + SEND_LOG("(SAVELOAD) State of current map loaded (err:%d)",res); temp_storage_close_rd(fsta); free(bf); return res; @@ -493,7 +493,7 @@ void restore_current_map() //pouze obnovuje ulozeny stav aktualni mapy { int i; - SEND_LOG("(SAVELOAD) Restore map...",0,0); + SEND_LOG("(SAVELOAD) Restore map..."); kill_all_sounds(); for(i=0;idemon_save,sizeof(THUMAN)*1,f); //ulozeni polozek s demony res|=save_dialog_info(f); temp_storage_close_wr(f); - SEND_LOG("(SAVELOAD) Done... Result: %d",res,0); + SEND_LOG("(SAVELOAD) Done... Result: %d",res); return res; } @@ -659,7 +659,7 @@ int load_basic_info() TITEM *itg; THUMAN *h; - SEND_LOG("(SAVELOAD) Loading basic info for game (file:%s)",_GAME_ST,0); + SEND_LOG("(SAVELOAD) Loading basic info for game (file:%s)",_GAME_ST); f=temp_storage_open(_GAME_ST); if (f==NULL) return 1; res|=(temp_storage_read(&s,1*sizeof(s),f)!=sizeof(s)); @@ -726,7 +726,7 @@ int load_basic_info() } else load_another=0; for(i=0;i0) { - SEND_LOG("(ERROR) Error detected during unpacking game... Loading stopped (result:%d)",r,0); + SEND_LOG("(ERROR) Error detected during unpacking game... Loading stopped (result:%d)",r); return r; } load_book(); @@ -838,7 +838,7 @@ int load_game(int slotnum) norefresh=1; } for(t=0;tid; @@ -1393,7 +1397,7 @@ int load_string_list_ex(TSTR_LIST *list,char *filename) if (j==';') while ((j=temp_storage_getc(f))!='\n' && j!=EOF); if (j=='\n') lin++; } - while (j=='\n'); + while (j=='\n' || j == '\r'); temp_storage_ungetc(f); j=temp_storage_scanf(f,"%d",&i); if (j==EOF) @@ -1414,7 +1418,12 @@ int load_string_list_ex(TSTR_LIST *list,char *filename) enc_close(f); return lin; } - p=strchr(c,'\n');if (p!=NULL) *p=0; + + p=strchr(c,0); + while (p > c && isspace(p[-1])) { + --p; + *p = 0; + } for(p=c;*p;p++) *p=*p=='|'?'\n':*p; if (str_replace(list,i,c)==NULL) { diff --git a/game/inv.c b/game/inv.c index abe69c6..e9fcde8 100644 --- a/game/inv.c +++ b/game/inv.c @@ -1103,7 +1103,7 @@ void real_regeneration() if (sleep_ticks>MAX_SLEEP) sleep_ticks=MAX_SLEEP; tick_tack(1); TimerEvents(viewsector,viewdir,game_time); - SEND_LOG("(GAME) Tick Tack, Game time: %d",game_time,0); + SEND_LOG("(GAME) Tick Tack, Game time: %d",game_time); GlobEvent(MAGLOB_ONROUND,viewsector,viewdir); bott_draw(0); } @@ -2263,7 +2263,7 @@ void build_fly_map() if (!counter) SEND_LOG("(FLY) Fly_map was reduced - capacity: %d flies in game / was: %d",fly_count,fly_map_size); else - SEND_LOG("(FLY) Fly_map was expanded - capacity: %d flies in game ",fly_count,fly_map_size); + SEND_LOG("(FLY) Fly_map was expanded - capacity: %d flies in game / was: %d",fly_count,fly_map_size); counter=1000; fly_map_size=fly_count; } @@ -2416,26 +2416,70 @@ static void shop_mouse_event(EVENT_MSG *msg,void **unused) } } } + +static __inline void copy_data(char **src, void *target, int size) { + memcpy(target, *src, size); + (*src)+=size; +} + +static char * load_TSHOP(char *binary, TSHOP *target) { + copy_data(&binary, target->keeper, 16); + copy_data(&binary, target->picture, 13); + copy_data(&binary, &target->koef, 4); + copy_data(&binary, &target->products, 4); + copy_data(&binary, &target->shop_id, 4); + copy_data(&binary, &target->list_size, 4); + copy_data(&binary, &target->spec_max, 2); + copy_data(&binary, &target->list, 4); + return binary; +} + +static char * load_TPRODUCT(char *binary, TPRODUCT *target) { + copy_data(&binary, &target->item, 2); + copy_data(&binary, &target->cena, 4); + copy_data(&binary, &target->trade_flags, 2); + copy_data(&binary, &target->pocet, 4); + copy_data(&binary, &target->max_pocet, 4); + return binary; +} + static void rebuild_shops(void) { char *c=(char *)shop_hacek; int i; - SEND_LOG("(SHOP) Rebuilding shops....",0,0); + SEND_LOG("(SHOP) Rebuilding shops...."); if (shop_list!=NULL) free(shop_list); shop_list=NewArr(TSHOP *,max_shops); c+=4; - for(i=0;ilist=(TPRODUCT *)c; - c+=p->products*sizeof(TPRODUCT); - SEND_LOG("(SHOP) Shop found: '%s'",p->keeper,0); - } } void load_shops(void) @@ -2844,7 +2888,7 @@ void enter_shop(int shopid) { int i; - SEND_LOG("(SHOP) Entering shop...",0,0); + SEND_LOG("(SHOP) Entering shop..."); for(i=0;ikeeper,0); + SEND_LOG("(SHOP) Shops reroll: '%s' ",p->keeper); pr=p->list; for(i=0;ilist_size;i++,pr++) { @@ -2973,7 +3017,7 @@ char save_shops() TMPFILE_WR *f; int res=0; - SEND_LOG("(SHOP) Saving shops...",0,0); + SEND_LOG("(SHOP) Saving shops..."); if (max_shops==0 || shop_hacek==NULL) return 0; f = temp_storage_create(_SHOP_ST); if (f==NULL) return 1; @@ -2991,7 +3035,7 @@ char load_saved_shops() int res=0; int i=0,j=0; - SEND_LOG("(SHOP) Loading saved shops...",0,0); + SEND_LOG("(SHOP) Loading saved shops..."); f=temp_storage_open(_SHOP_ST); if (f==NULL) return 0; temp_storage_read(&i,1*sizeof(max_shops),f); diff --git a/game/kouzla.c b/game/kouzla.c index f5532c4..47298b7 100644 --- a/game/kouzla.c +++ b/game/kouzla.c @@ -190,10 +190,10 @@ static void play_anim(va_list args) //tasked animation if (running_anm) { - SEND_LOG("(ERROR)(ANIM) Animation's mutex is already in use!",0,0); + SEND_LOG("(ERROR)(ANIM) Animation's mutex is already in use!"); return; } - SEND_LOG("(ANIM) Running animation number %xh",block,0); + anim_render_buffer=getmem(ANIM_SIZE); mgif_install_proc(animace_kouzla); running_anm=1; @@ -202,7 +202,7 @@ static void play_anim(va_list args) //tasked animation alock(block); anm=open_mgif(ablock(block)); c=0; - SEND_LOG("(ANIM) Buffer is now ready...",0,0); + SEND_LOG("(ANIM) Buffer is now ready..."); while (anm!=NULL) { task_wait_event(E_KOUZLO_ANM); @@ -215,7 +215,7 @@ static void play_anim(va_list args) //tasked animation close_mgif(); running_anm=0; free(anim_render_buffer); - SEND_LOG("(ANIM) Closing animation %xh",block,0); + aunlock(block); } @@ -617,7 +617,7 @@ static void unaffect_after_demon(int cil) char a; TKOUZLO *spl; - SEND_LOG("(SPELLS) Unaffecting after demon...",0,0); + SEND_LOG("(SPELLS) Unaffecting after demon..."); do { a=0; @@ -657,7 +657,7 @@ void spell_end(int num,int ccil,int owner) unaffect_after_demon(ccil); zmena_demona(cil,owner,0); _flag_map[num]&=~SPL_DEMON; - SEND_LOG("(SPELLS) Spell 'Demon' has ended...",0,0); + SEND_LOG("(SPELLS) Spell 'Demon' has ended..."); } postavy[cil].stare_vls[VLS_KOUZLA]&=~_flag_map[num]; if (cil>=0 && cil0xffff) spell_end_global(); - SEND_LOG("(SPELLS) Spell ID %d ends.",num,0); + } static void spell_demon(int num,TKOUZLO *spl,int cil,int demon) @@ -1394,7 +1394,7 @@ void call_spell(int i) unsigned char ext=0; int cil; - SEND_LOG("(SPELLS) Calculating spell ID: %d",i,0); + p=spell_table[i]; if (p==NULL) return; cil=p->cil; @@ -1485,7 +1485,7 @@ int add_spell(int num,int cil,int owner,char noanim) int accnum; char time_acc=1; - SEND_LOG("(SPELLS) Casting spell number %d",num,0); + alock(H_KOUZLA); q=(TKOUZLO *)ablock(H_KOUZLA)+num; accnum=q->accnum; @@ -1500,7 +1500,7 @@ int add_spell(int num,int cil,int owner,char noanim) if (i==MAX_SPELLS) i=nl; if (i==-1) { - SEND_LOG("(ERROR) Too many spells in game!",0,0); + SEND_LOG("(ERROR) Too many spells in game!"); return -1; } if (spell_table[i]!=NULL) @@ -1636,7 +1636,7 @@ void cast(int num,THUMAN *p,int owner, char backfire) SEND_LOG("(SPELLS) Cast num %d cil %d",num2,cil); k=((TKOUZLO *)ablock(H_KOUZLA))+num2; - SEND_LOG("(SPELLS) Cast spell name %s",k->spellname,0); + if (cil>0 && k->cil!=C_postava_jinde) { @@ -1711,7 +1711,7 @@ void cast(int num,THUMAN *p,int owner, char backfire) if (p->mana>p->mana_battery) { if (p->mana_battery>=0)p->mana=p->mana_battery; - else SEND_LOG("(ERROR) Mana battery error on character %d",p-postavy,0); + else p->mana_battery=32767; } end: @@ -1821,7 +1821,7 @@ void area_cast(int num,int sector,int owner,char noanim) void kouzla_init() { - SEND_LOG("(SPELLS) Init...",0,0); + SEND_LOG("(SPELLS) Init..."); send_message(E_ADD,E_KOUZLO_ANM,kouzla_anm); send_message(E_ADD,E_KOUZLO_KOLO,kouzla_kola); memset(spell_table,0,sizeof(spell_table)); @@ -1837,7 +1837,7 @@ void reinit_kouzla_full() { int i; - SEND_LOG("(SPELLS) Reinit...",0,0); + SEND_LOG("(SPELLS) Reinit..."); for(i=0;icil==cil) { while (spell_table[i]!=NULL) diff --git a/game/menu.c b/game/menu.c index b17083a..1490791 100644 --- a/game/menu.c +++ b/game/menu.c @@ -365,9 +365,8 @@ int enter_menu(char open) char *get_next_title(signed char control,char *filename) { -/* - static TMPFILE_RD *titles=NULL; - static ENCFILE fl; + + static TMPFILE_RD *titles=NULL; static char buffer[81]; char *path,*c; @@ -389,13 +388,12 @@ char *get_next_title(signed char control,char *filename) } } return (char *)titles; - case 0:if (titles!=NULL)fgets(buffer,80,titles); + case 0:if (titles!=NULL)temp_storage_gets(buffer,80,titles); c=strchr(buffer,'\n');if (c!=NULL) *c=0; return buffer; - case -1:if (titles!=NULL)enc_close(&fl); + case -1:if (titles!=NULL)enc_close(titles); break; } - */ return NULL; } diff --git a/game/realgame.c b/game/realgame.c index de05b33..eb6200f 100644 --- a/game/realgame.c +++ b/game/realgame.c @@ -230,7 +230,7 @@ int load_map(char *filename) if (level_fname!=NULL) free(level_fname); level_fname=(char *)getmem(strlen(filename)+1); strcpy(level_fname,filename); - SEND_LOG("(GAME) Loading map: '%s'",level_fname,0); + SEND_LOG("(GAME) Loading map: '%s'",level_fname); strupr(level_fname); mob_template=NULL; mob_size=0; @@ -303,13 +303,13 @@ int load_map(char *filename) back_color=RGB888(mglob.fade_r,mglob.fade_g,mglob.fade_b); break; case A_MAPITEM: - SEND_LOG("(GAME) Loading items...",0,0); + SEND_LOG("(GAME) Loading items..."); load_item_map(temp,size); free(temp); break; case A_MAPMOBS: if (snd_load==0) create_sound_table_old(); - SEND_LOG("(GAME) Loading enemies...",0,0); + SEND_LOG("(GAME) Loading enemies..."); if (mob_template==NULL) { int32_t h;char *p; @@ -324,12 +324,12 @@ int load_map(char *filename) { load_enemies(temp,size,&ofsts,mob_template,mob_size); free(mob_template); - SEND_LOG("(GAME) Loading enemies from map template...",0,0); + SEND_LOG("(GAME) Loading enemies from map template..."); } free(temp); break; case A_MAPMACR: - SEND_LOG("(GAME) Loading multiactions...",0,0); + SEND_LOG("(GAME) Loading multiactions..."); load_macros(size,temp); break; case A_MAPVYK: @@ -413,7 +413,7 @@ void leave_current_map() { int i; TFLY *p; - SEND_LOG("(GAME) Leaving current map ... start",0,0); + SEND_LOG("(GAME) Leaving current map ... start"); add_leaving_place(viewsector); kill_all_sounds(); restore_sound_names(); @@ -1411,7 +1411,7 @@ void real_krok(EVENT_MSG *msg,void **data) if (msg->msg==E_INIT || msg->msg==E_DONE) return; check_all_mobs(); calc_game();msg;data; - SEND_LOG("(GAME) STEP",0,0); + SEND_LOG("(GAME) STEP"); } void do_halucinace() diff --git a/game/setup.c b/game/setup.c index 8c58249..4cc4361 100644 --- a/game/setup.c +++ b/game/setup.c @@ -97,7 +97,7 @@ static void wire_setup() mute_all_tracks(0); cur_mode=MD_SETUP; send_message(E_ADD,E_KEYBOARD,setup_keyboard); - SEND_LOG("(GAME) Starting setup",0,0); + SEND_LOG("(GAME) Starting setup"); } static void unwire_setup() @@ -113,7 +113,7 @@ static void unwire_setup() send_message(E_DONE,E_KEYBOARD,setup_keyboard); wire_proc(); cancel_render=1; - SEND_LOG("(GAME) Setup closed",0,0); + SEND_LOG("(GAME) Setup closed"); } char exit_setup(int id,int xa,int ya,int xr,int yr) diff --git a/game/skeldal.c b/game/skeldal.c index 083bdab..bcaadfa 100644 --- a/game/skeldal.c +++ b/game/skeldal.c @@ -92,7 +92,7 @@ TMA_LOADLEV loadlevel; typedef struct inis { - char heslo[25]; + char heslo[50]; char parmtype; }INIS; @@ -321,29 +321,29 @@ int set_video(int mode) { case 1:er=initmode256(cur_xlat); if (banking) report_mode(5); else report_mode(2); - SEND_LOG("(GAME) Video changed to 256 colors %s",banking?"Bank":"LFB",0); + break; case 2:er=initmode32(); if (banking) report_mode(4); else report_mode(1); - SEND_LOG("(GAME) Video changed to HIcolor %s",banking?"Bank":"LFB",0); + break; case 0:er=initmode_lo(cur_xlat); report_mode(3); - SEND_LOG("(GAME) Video changed to 256 VGA comp. ",0,0); + break; case 3: free(cur_xlat);cur_xlat=create_blw_palette16(); er=initmode16(cur_xlat); - SEND_LOG("(GAME) Video changed to 16 grayscale",0,0); + report_mode(3); break; case 4:er=init_empty_mode(); report_mode(3); - SEND_LOG("(GAME) Video changed to ",0,0); + break; case 5:free(cur_xlat);cur_xlat=create_hixlat(); er=initmode64(cur_xlat); if (banking) report_mode(7); else report_mode(6); - SEND_LOG("(GAME) Video changed to HIcolor64 %s",banking?"Bank":"LFB",0); + break; default:er=-1; @@ -542,18 +542,18 @@ void music_init(void) // char *path; /* if (sound_detection) { - SEND_LOG("(SOUND) SOUND_DETECT Detecting sound card",0,0); + if (sound_detect(&snd_devnum,&snd_parm1,&snd_parm2,&snd_parm3)) snd_devnum=DEV_NOSOUND; }*/ SEND_LOG("(SOUND) SOUND_SET Setting Sound: Device '%s' Port: %3X",device_name(snd_devnum),snd_parm1); SEND_LOG("(SOUND) SOUND_SET Setting Sound: IRQ: %X DMA: %X",snd_parm2,snd_parm3); set_mixing_device(snd_devnum,snd_mixing,snd_parm1,snd_parm2,snd_parm3); - SEND_LOG("(SOUND) SOUND_INIT Starting mixing",0,0); + start_mixing(); set_snd_effect(SND_GFX,init_gfx_vol); set_snd_effect(SND_MUSIC,init_music_vol); // path=plugins_path; - SEND_LOG("(SOUND) SOUND_DONE Sound Engine should work now",0,0); + } @@ -608,16 +608,17 @@ void *timming(EVENT_MSG *msg,void **data) p=q->next; q->zavora=1; q->counter=q->count_max; - if (q->calls!=-1) + if (q->calls!=-1) { if (--q->calls<1) { for(p=&timer_tree;p->next!=q;p=p->next); p->next=q->next; #ifdef LOGFILE - if (q->next==NULL) - SEND_LOG("(TIMER) Self remove for timer id: %d, next->",q->id,0); - else + if (q->next==NULL) { + + } else { SEND_LOG("(TIMER) Self remove for timer id: %d, next->%d",q->id,q->next->id); + } #endif free(q); q=p; @@ -625,6 +626,7 @@ void *timming(EVENT_MSG *msg,void **data) //else // q->counter=1; } + } else { q->counter=1; } @@ -632,7 +634,7 @@ void *timming(EVENT_MSG *msg,void **data) if (q->next!=p && q!=p) { THE_TIMER *z; - SEND_LOG("(TIMER) Timer integrity corrupted",0,0); + z=&timer_tree;while(z->next!=p && z->next!=NULL) z=z->next; if (z->next==NULL) return NULL; } @@ -655,10 +657,11 @@ void delete_from_timer(int id) if (q->zavora) { #ifdef LOGFILE - if (q->next==NULL) - SEND_LOG("(TIMER) Removing timer id: %d, next->",id,0); - else + if (q->next==NULL) { + + }else { SEND_LOG("(TIMER) Removing timer id: %d, next->%d",id,q->next->id); + } #endif p->next=q->next; free(q); @@ -666,7 +669,7 @@ void delete_from_timer(int id) } else { - SEND_LOG("(TIMER) Can't remove timer! id: %d. Currently in use.",id,0); + q->calls=-2; q->counter=1; } @@ -757,7 +760,7 @@ void do_timer(void) void done_skeldal(void) { - SEND_LOG("(GAME) Video returned to textmode",0,0); + close_manager(); close_story_file(); purge_temps(1); @@ -766,7 +769,7 @@ void done_skeldal(void) if (texty!=NULL) release_list(texty);texty=NULL; if (cur_config!=NULL) release_list(cur_config);cur_config=NULL; kill_timer(); - SEND_LOG("NORMAL TERMINATING--------------------------",0,0); + } @@ -878,11 +881,11 @@ void error_exception(EVENT_MSG *msg,void **unused) if (msg->msg==E_PRGERROR) { unused; - SEND_LOG("(ERROR) Runtime error detected ... Game terminator lunched.",0,0); - SEND_LOG("(ERROR) Log: Now dump of useful informations:",0,0); - SEND_LOG("(ERROR) Log: Map name '%s'",level_fname==NULL?"":level_fname,0); + + + SEND_LOG("(ERROR) Log: Sector %d Direction %d",viewsector,viewdir); - SEND_LOG("(ERROR) Log: Last 'memman' handle: %x",memman_handle,0); + SEND_LOG("(ERROR) Log: Battle: %d Select_player %d",battle,select_player); closemode(); printf("Program zp�sobil b�hovou chybu a bude ukon�en\n" @@ -899,7 +902,7 @@ void error_exception(EVENT_MSG *msg,void **unused) void swap_error_exception(void) { closemode(); - SEND_LOG("(ERROR) Disk is full ...",0,0); + puts("Program jiz nema kam odkladat, protoze disk s odkladacim souborem byl \n" "zaplnen. Uvolnete prosim nejake misto na odkladacim disku, nebo zmente \n" "adresar odkladani na jednotku, kde je vice mista"); @@ -970,78 +973,78 @@ void init_skeldal(void) int verr; boldcz=LoadDefaultFont(); -SEND_LOG("(INIT) Reading texts.",0,0); + cti_texty(); timer_tree.next=NULL; -SEND_LOG("(INIT) Setting random seed.",0,0); + srand(clock()); -SEND_LOG("(INIT) Creating 256 color palette.",0,0); + cur_xlat=create_special_palette(); -SEND_LOG("(INIT) Init message system - event handler",0,0); + init_events(); -SEND_LOG("(INIT) Setting videomode.",0,0); + verr=set_video(vmode); if (verr) { exit(ERR_GENERAL); } -SEND_LOG("(INIT) Initializing engine.",0,0); + general_engine_init(); atexit(done_skeldal); -/*SEND_LOG("(INIT) Loading DOS error handler.",0,0); +/* install_dos_error(device_error,(char *)getmem(4096)+4096);*/ swap_error=swap_error_exception; - snprintf(d,sizeof(d),"%s%s",pathtable[SR_DATA],"skeldal.ddl"); -SEND_LOG("(INIT) Initializing memory manager",0,0); + snprintf(d,sizeof(d),"%s%s",pathtable[SR_DATA],"SKELDAL.DDL"); + init_manager(d,c); SEND_LOG("(GAME) Memory manager initialized. Using DDL: '%s' Temp dir: '%s'",d,c); texty_knihy=find_map_path("kniha.txt"); -SEND_LOG("(INIT) Installing GUI",0,0); + install_gui(); -SEND_LOG("(INIT) Attaching patch.",0,0); + if (patch_file!=NULL) patch_error(add_patch_file(patch_file)); -SEND_LOG("(INIT) Registring basic data.",0,0); + register_basic_data(); -SEND_LOG("(INIT) Timer event handler.",0,0); + send_message(E_DONE,E_WATCH,timer); send_message(E_DONE,E_IDLE,redraw_desktop_call); send_message(E_ADD,E_TIMER,timming); -SEND_LOG("(INIT) User timer.",0,0); + send_message(E_ADD,E_WATCH,user_timer); -SEND_LOG("(INIT) Mouse clicking maps.",0,0); + send_message(E_ADD,E_MOUSE,ms_clicker); -SEND_LOG("(INIT) Global keyboard event handler.",0,0); + send_message(E_ADD,E_KEYBOARD,global_kbd); -SEND_LOG("(INIT) Error exception event handler.",0,0); + send_message(E_ADD,E_PRGERROR,error_exception); -SEND_LOG("(INIT) Wizard handler.",0,0); + if (debug_enabled) install_wizard(); -SEND_LOG("(INIT) Background music timer.",0,0); + add_to_timer(TM_BACK_MUSIC,5,-1,back_music); -SEND_LOG("(INIT) Creating game window.",0,0); + add_game_window(); -SEND_LOG("(INIT) Music.",0,0); + music_init(); -SEND_LOG("(INIT) Mouse interrupt handler.",0,0); + if ((verr=init_mysky())!=0) { closemode(); puts(texty[174-verr]); SEND_LOG("(ERROR) %s (%d)",texty[174-verr],verr); - SEND_LOG("(ERROR) Mouse not found, shutting down.",0,0); + exit(0); } -SEND_LOG("(INIT) Mouse initialized.",0,0); + // hranice_mysky(0,0,639,479); -SEND_LOG("(INIT) Loading mouse cursor.",0,0); + mouse_set_default(H_MS_DEFAULT); ukaz_mysku(); set_end_of_song_callback(end_of_song_callback, NULL); -SEND_LOG("(INIT) Loading spells.",0,0); + kouzla_init(); -SEND_LOG("(INIT) Loading items.",0,0); + load_items(); -SEND_LOG("(INIT) Loading shops.",0,0); + load_shops(); SetWheelMapping('H','P'); } @@ -1049,7 +1052,7 @@ SEND_LOG("(INIT) Loading shops.",0,0); void wire_main_functs(); void unwire_main_functs(void) { - SEND_LOG("(SYS) Wire main functions",0,0); + delete_from_timer(TM_FLY); delete_from_timer(TM_SCENE); delete_from_timer(TM_REGEN); @@ -1063,7 +1066,7 @@ void unwire_main_functs(void) void wire_main_functs(void) { - SEND_LOG("(SYS) unWire main functions",0,0); + add_to_timer(TM_SCENE,gamespeed,-1,refresh_scene); add_to_timer(TM_FLY,gamespeed,-1,calc_fly); add_to_timer(TM_REGEN,500,-1,real_regeneration); @@ -1080,9 +1083,9 @@ void wire_main_functs(void) void init_game(void) { - SEND_LOG("(INIT) Inventory.",0,0); + init_inventory(); - SEND_LOG("(INIT) Characters.",0,0); + reg_grafiku_postav(); build_all_players(); } @@ -1135,14 +1138,14 @@ void enter_game(void) cancel_pass=0; autosave(); set_game_click_map(); - SEND_LOG("(GAME) --------- Waiting for E_CLOSE_MAP ------------\n",0,0); + send_message(E_ADD,E_RELOADMAP,reload_map_handler); { EVENT_MSG *msg = task_wait_event(E_CLOSE_MAP); end = va_arg(msg->data, int); } send_message(E_DONE,E_RELOADMAP,reload_map_handler); - SEND_LOG("(GAME) --------- E_CLOSE_MAP triggered, leaving map------------\n",0,0); + unwire_main_functs(); delete_from_timer(TM_FAST_TIMER); cancel_pass=1; @@ -1174,7 +1177,7 @@ static int do_config_skeldal(int num,int numdata,char *txt) sound_detection=0; break; case 6:snd_mixing=numdata;break; - case 7:strncpy(default_map,txt,20);default_map[19]='\0';SEND_LOG("(GAME) Start map sets as '%s'",default_map,0);break; + case 7:strncpy(default_map,txt,20);default_map[19]='\0';break; case 8:gamespeed=numdata;break; case 9:level_preload=numdata;break; // case 10:system(txt);break; @@ -1262,9 +1265,9 @@ static void configure(char *filename) puts(s); exit(1); } - SEND_LOG("(GAME) Configuring game...",0,0); + process_ini(cur_config,config_skeldal); - SEND_LOG("(GAME) Done config.",0,0); + } static int update_config(void) @@ -1277,7 +1280,7 @@ static int update_config(void) add_field_num(&cur_config,sinit[9].heslo,level_preload); add_field_num(&cur_config,sinit[13].heslo,autosave_enabled); save_config(cur_config,CONFIG_NAME); - SEND_LOG("(GAME) Config. file was saved",0,0); + return 0; } @@ -1423,7 +1426,7 @@ static void game_big_circle(char enforced) int err; int r; char s[13]; - SEND_LOG("\n(GAME) --------- Entering big loop ------------",0,0); + purge_playlist(); s[12]=0;strncpy(s,loadlevel.name,12); err=load_map(s); @@ -1469,16 +1472,16 @@ static void game_big_circle(char enforced) for(r=0;r=3) rm=!strcmp(argv[1],"12345678");else rm=0; - //OPEN_LOG("syslog"); - OPEN_LOG("con"); - SEND_LOG("START --------------------------",0,0); + argv; c=getcwd(NULL,0); pathtable[SR_SAVES]=getmem(strlen(c)+2); strcpy(pathtable[SR_SAVES],c); strcat(pathtable[SR_SAVES],PATH_SEPARATOR); free(c); - SEND_LOG("(GAME) Save directory sets to '%s'",pathtable[SR_SAVES],0); + // set_verify(0); mman_pathlist=pathtable; zoom_speed(1); @@ -1672,7 +1673,7 @@ int main(int argc,char *argv[]) adventure=argv[1]; cur_config=NULL; - SEND_LOG("(GAME) Starting new adventure: %s",adventure,0); + configure(adventure); release_list(cur_config); cur_config=config; @@ -1680,25 +1681,25 @@ int main(int argc,char *argv[]) #ifdef LOGFILE { int i; - for(i=0;i<(sizeof(pathtable)/4);i++) SEND_LOG("(GAME) LOG: Using directory '%s' as '%s'",pathtable[i],sinit[i+CESTY_POS].heslo); + for(i=0;i<(int)(sizeof(pathtable)/sizeof(*pathtable));i++) SEND_LOG("(GAME) LOG: Using directory '%s' as '%s'",pathtable[i],sinit[i+CESTY_POS].heslo); } #endif start_check(); purge_temps(1); // textmode_effekt(); clrscr(); - SEND_LOG("\n(GAME) Init----------------",0,0); + init_skeldal(); //add_task(32768,check_number_1phase,argv[0]); - SEND_LOG("(INIT) Starting game thread.",0,0); + if (argc>=3 && rm) { add_task(65536,start_from_mapedit,argc,argv); } else add_task(65536,start); - SEND_LOG("(INIT) Main thread goes to sleep.",0,0); + /* position(200,200); set_font(H_FBIG,RGB(200,200,200)); outtext("Ahoj lidi"); diff --git a/game/sndandmus.c b/game/sndandmus.c index 6cb4ad2..ab661c2 100644 --- a/game/sndandmus.c +++ b/game/sndandmus.c @@ -340,7 +340,7 @@ void recalc_volumes(int sector,int side) if (sector>=mapsize) return; side; - SEND_LOG("(SOUND) %s","Recalculating volumes",0); + SEND_LOG("(SOUND) %s","Recalculating volumes"); newx=map_coord[sector].x; newy=map_coord[sector].y; // layer=map_coord[sector].layer; @@ -580,7 +580,7 @@ void mute_all_tracks(char all) void kill_all_sounds() { int i; - SEND_LOG("(SOUND) Killing sound tracks...",0,0); + SEND_LOG("(SOUND) Killing sound tracks..."); for (i=0;iused) @@ -1162,7 +1162,7 @@ void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje if(nxt==-255) { int i; - SEND_LOG("(BATTLE) Ending round...",nxt,mobs[nxt].name); + SEND_LOG("(BATTLE) Ending round...(nxt=%d,mob=%s)",nxt,mobs[nxt].name); delete_from_timer(TM_SCENE); add_to_timer(TM_SCENE,gamespeed,-1,refresh_scene); for(i=0;iname:"(NULL)",0); + SEND_LOG("(BATTLE) Battle started (monster: %s)",attack_mob!=NULL?attack_mob->name:"(NULL)"); poloz_vsechny_predmety(); zacatek_kola(); running_battle=1; @@ -2368,7 +2368,7 @@ char player_check_death(THUMAN *p, char afterround) if (p->level>1) p->exp=level_map[p->level-2]; p->kondice=0; p->mana=0; - SEND_LOG("(GAME) Character '%s' died. R.I.P.",p->jmeno,0); + SEND_LOG("(GAME) Character '%s' died. R.I.P.",p->jmeno); if (numplayers(p->sektor,0)==0) map_coord[p->sektor].flags &=~MC_PLAYER; mp=map_sectors[p->sektor].sector_type; if (mp==S_VODA || mp==S_LAVA || mp==S_VIR) p->sektor=0; diff --git a/game/temp_storage.cpp b/game/temp_storage.cpp index c5edbfe..e1e65d9 100644 --- a/game/temp_storage.cpp +++ b/game/temp_storage.cpp @@ -4,6 +4,7 @@ #include #include #include +#include extern "C" { #include "temp_storage.h" @@ -16,7 +17,6 @@ typedef struct _temp_storage_file_wr { typedef struct _temp_storage_file_rd { std::basic_string_view _data; int skp = 0; - int scan_ret = 0; } TMPFILE_RD; using FileSystem = std::map, std::less<> >; @@ -26,7 +26,11 @@ static FileSystem temp_fsystem; void temp_storage_store(const char *name, const void *data, int32_t size) { auto b = reinterpret_cast(data); auto e = b+size; - temp_fsystem[std::string(name)] = {b,e}; + auto &v =temp_fsystem[std::string(name)]; + v.clear(); + v.resize(size+1); + std::copy(b,e, v.begin()); + v[size] = 0; } int32_t temp_storage_find(const char *name) { @@ -89,7 +93,7 @@ uint32_t temp_storage_read(void *data, uint32_t size, TMPFILE_RD *f) { auto p = d.substr(0,size); d = d.substr(p.size()); auto b = reinterpret_cast(data); - std::copy(d.begin(), d.end(), b); + std::copy(p.begin(), p.end(), b); return p.size(); } @@ -106,7 +110,7 @@ void temp_storage_delete(const char *name) { int temp_storage_getc(TMPFILE_RD *f) { if (f->_data.empty()) return -1; - int r = f->_data[0]; + int r = static_cast(f->_data[0]); f->_data = f->_data.substr(1); return r; } @@ -114,7 +118,7 @@ int temp_storage_getc(TMPFILE_RD *f) { char *temp_storage_gets(char *buff, size_t sz, TMPFILE_RD *f) { auto &d =f->_data; auto pos = d.find('\n'); - if (pos > d.size()) pos = d.size(); + if (pos > d.size()) pos = d.size(); else ++pos; if (pos == 0) return NULL; if (pos > sz - 1) pos = sz - 1; temp_storage_read(buff, pos, f); @@ -123,23 +127,25 @@ char *temp_storage_gets(char *buff, size_t sz, TMPFILE_RD *f) { } -void temp_storage_internal_begin_scanf(TMPFILE_RD *f, const char *format, ...) { +int temp_storage_internal_begin_scanf(TMPFILE_RD *f, const char *format, ...) { if (f->_data.empty()) { - f->scan_ret = -1; + return -1; } va_list lst; va_start(lst, format); - f->scan_ret = vsscanf(reinterpret_cast(f->_data.data()), format, lst); + int scan_ret = vsscanf(reinterpret_cast(f->_data.data()), format, lst); va_end(lst); + return scan_ret; } int *temp_storage_internal_skip_ptr(TMPFILE_RD *f) { + f->skp = 0; return &f->skp; } -int temp_storage_internal_end_scanf(TMPFILE_RD *f) { +int temp_storage_internal_end_scanf(TMPFILE_RD *f, int r) { temp_storage_skip(f, f->skp); - return f->scan_ret; + return r; } void temp_storage_ungetc(TMPFILE_RD *f) { diff --git a/game/temp_storage.h b/game/temp_storage.h index 7688dd7..f9c2d11 100644 --- a/game/temp_storage.h +++ b/game/temp_storage.h @@ -28,11 +28,14 @@ uint32_t temp_storage_read(void *data, uint32_t size, TMPFILE_RD *f); void temp_storage_skip(TMPFILE_RD *f, int bytes); int *temp_storage_internal_skip_ptr(TMPFILE_RD *f); -void temp_storage_internal_begin_scanf(TMPFILE_RD *f, const char *format, ... ) __attribute__((format(scanf, 2, 3))); -int temp_storage_internal_end_scanf(TMPFILE_RD *f); +int temp_storage_internal_begin_scanf(TMPFILE_RD *f, const char *format, ... ) __attribute__((format(scanf, 2, 3))); +int temp_storage_internal_end_scanf(TMPFILE_RD *f, int r); -#define temp_storage_scanf(f, format, ...) (temp_storage_internal_begin_scanf(f, format "%n", __VA_ARGS__, temp_storage_internal_skip_ptr(f)),temp_storage_internal_end_scanf(f)) +#define temp_storage_scanf(f, format, ...) \ + temp_storage_internal_end_scanf(f,\ + temp_storage_internal_begin_scanf(f, format "%n", \ + __VA_ARGS__, temp_storage_internal_skip_ptr(f))) diff --git a/libs/bmouse.c b/libs/bmouse.c index 638085f..80d6396 100644 --- a/libs/bmouse.c +++ b/libs/bmouse.c @@ -4,6 +4,9 @@ #include "event.h" #include "devices.h" #include "bmouse.h" + +#include "memman.h" + #include char visible=0; @@ -74,6 +77,7 @@ void update_mysky(void) if (x.event) { ms_last_event=x; + x.event = 0; } if(!visible) move_ms_cursor(x.x-h_x,x.y-h_y,0); } diff --git a/libs/event.c b/libs/event.c index af6d058..1fe2a8e 100644 --- a/libs/event.c +++ b/libs/event.c @@ -232,15 +232,16 @@ void enter_event(T_EVENT_ROOT **tree,EVENT_MSG *msg) va_end(cpy.data); p->calls--; p->nezavora=1; - if (msg->msg==-2) + if (cpy.msg==-2) { p->proc=NULL; - msg->msg=ev; + cpy.msg=ev; } s=p->next; if (!p->calls && p->proc==NULL) force_delete_curr(tree,r,p); - if (msg->msg==-1) break; + if (cpy.msg==-1) + break; } /* if (p->next!=s) if (r->list!=p) diff --git a/libs/event.h b/libs/event.h index 8af02f4..65a5798 100644 --- a/libs/event.h +++ b/libs/event.h @@ -99,6 +99,18 @@ extern char *otevri_zavoru; //extern int curtask; //extern char *task_info; +///copies message +static inline EVENT_MSG clone_message(EVENT_MSG *msg) { + EVENT_MSG out; + out.msg = msg->msg; + va_copy(out.data, msg->data); + return out; +} +///destroys copied message +static inline void destroy_message(EVENT_MSG *msg) { + va_end(msg->data); +} + void init_events(void); // inicalizuje zakladni strom udalosto void send_message(int message,...); diff --git a/libs/gui.c b/libs/gui.c index db8ce09..663b6d9 100644 --- a/libs/gui.c +++ b/libs/gui.c @@ -610,42 +610,58 @@ void do_it_events(EVENT_MSG *msg,void **user_data) if (msg->msg==E_MOUSE) { *oz=1; + EVENT_MSG fwmsg = clone_message(msg); + fwmsg.msg = msg->msg; + va_copy(fwmsg.data, msg->data); msev=get_mouse(msg); aktivate_window(msev); - if (o_aktual==NULL) - if (o_start!=NULL && (msev->tl1 || msev->tl2 || msev->tl3)) - { - o_aktual=o_start; - while (o_aktual!=NULL && (!o_aktual->enabled || !mouse_in_object(msev,o_aktual,waktual) || o_aktual->call_event==empty3)) o_aktual=o_aktual->next; - if (o_aktual==NULL) return; - msg2.msg=E_GET_FOCUS; - o_aktual->call_event(&msg2,o_aktual); - o_aktual->on_enter(); - o_aktual->call_event(msg,o_aktual); - } - else return; - else - { - if (o_aktual->enabled) b=mouse_in_object(msev,o_aktual,waktual);else b=0; - if (b) - o_aktual->call_event(msg,o_aktual); - if ((msev->tl1 || msev->tl2 || msev->tl3)&& !b) - { - o_aktual->on_exit(); - if (f_cancel_event) return; - msg2.msg=E_LOST_FOCUS; - o_aktual->call_event(&msg2,o_aktual); - p=o_start; - while (p!=NULL && (!p->enabled || !mouse_in_object(msev,p,waktual) || p->call_event==empty3)) - p=p->next; - if (p!=NULL) o_aktual=p; - msg2.msg=E_GET_FOCUS; - o_aktual->call_event(&msg2,o_aktual); - o_aktual->on_enter(); - if (p!=NULL) o_aktual->call_event(msg,o_aktual); - } - } - } + if (o_aktual == NULL) { + if (o_start != NULL && (msev->tl1 || msev->tl2 || msev->tl3)) { + o_aktual = o_start; + while (o_aktual != NULL + && (!o_aktual->enabled + || !mouse_in_object(msev, o_aktual, waktual) + || o_aktual->call_event == empty3)) + o_aktual = o_aktual->next; + if (o_aktual != NULL) { + msg2.msg = E_GET_FOCUS; + o_aktual->call_event(&msg2, o_aktual); + o_aktual->on_enter(); + o_aktual->call_event(&fwmsg, o_aktual); + } + } + } else { + if (o_aktual->enabled) { + b = mouse_in_object(msev, o_aktual, waktual); + } else { + b = 0; + } + if (b) { + o_aktual->call_event(&fwmsg, o_aktual); + } + if ((msev->tl1 || msev->tl2 || msev->tl3) && !b) { + o_aktual->on_exit(); + if (f_cancel_event) + return; + msg2.msg = E_LOST_FOCUS; + o_aktual->call_event(&msg2, o_aktual); + p = o_start; + while (p != NULL + && (!p->enabled || !mouse_in_object(msev, p, waktual) + || p->call_event == empty3)) + p = p->next; + if (p != NULL) { + o_aktual = p; + } + msg2.msg = E_GET_FOCUS; + o_aktual->call_event(&msg2, o_aktual); + o_aktual->on_enter(); + if (p != NULL) + o_aktual->call_event(msg, o_aktual); + } + } + destroy_message(&fwmsg); + } if (msg->msg==E_KEYBOARD) { *oz=1; @@ -689,20 +705,23 @@ void do_it_events(EVENT_MSG *msg,void **user_data) if (msg->msg==E_GUI) { OBJREC *o; + + EVENT_MSG msg2 = clone_message(msg); + int control = va_arg(msg->data, int); msg->msg = va_arg(msg->data, int); o=find_object(waktual,control); - EVENT_MSG msg2; + if (o!=NULL) { - msg2.msg=msg->msg; - va_copy(msg2.data,msg->data); - o->call_event(&msg2,o); - o->on_event(msg,o_aktual); - va_end(msg2.data); + EVENT_MSG msg3 = clone_message(msg); + o->call_event(&msg2,o); + o->on_event(&msg3,o_aktual); + destroy_message(&msg3); } + destroy_message(&msg2); } if (msg->msg==E_CHANGE) diff --git a/libs/memman.c b/libs/memman.c index 5c53dba..97e6c5a 100644 --- a/libs/memman.c +++ b/libs/memman.c @@ -38,7 +38,7 @@ int32_t last_load_size; void standard_mem_error(size_t size) { char buff[256]; - SEND_LOG("(ERROR) Memory allocation error detected, %u bytes missing",size,0); + SEND_LOG("(ERROR) Memory allocation error detected, %lu bytes missing",size); DXCloseMode(); sprintf(buff,"Memory allocation error\n Application can't allocate %lu bytes of memory (%xh)\n",size,memman_handle); display_error(buff); @@ -48,7 +48,7 @@ void standard_mem_error(size_t size) void load_error(char *filename) { char buff[256]; - SEND_LOG("(ERROR) Load error detected, system can't load file: %s",filename,0); + SEND_LOG("(ERROR) Load error detected, system can't load file: %s",filename); #ifdef LOGFILE // bonz_table(); #endif @@ -100,7 +100,7 @@ void *load_file(char *filename) size_t size; if (mman_action!=NULL) mman_action(MMA_READ); - SEND_LOG("(LOAD) Loading file '%s'",filename,0); + SEND_LOG("(LOAD) Loading file '%s'",filename); f=fopen(filename, "rb"); if (f==NULL) { load_error(filename); @@ -139,10 +139,10 @@ uint32_t bk_global_counter=0; char *swap_path; #ifdef LOGFILE -static void bonz_table() +void bonz_table() { int i; - if (bmf==-1) return; + if (bmf==NULL) return; for(i=0;i>3);i++) grptable[i*2+1]=(grptable[i*2+1]-grptabsiz)>>4; - SEND_LOG("(LOAD) Group Table Loaded",0,0); + SEND_LOG("(LOAD) Group Table Loaded"); } void load_file_table() @@ -182,16 +182,17 @@ void load_file_table() int strsize; void *p; - SEND_LOG("(LOAD) Loading File Table",0,0); + SEND_LOG("(LOAD) Loading File Table"); fseek(bmf,grptabsiz,SEEK_SET); fseek(bmf,12,SEEK_CUR); fread(&strsize,4,1,bmf); strsize-=grptabsiz; fseek(bmf,grptabsiz,SEEK_SET); - p=getmem(strsize);memcpy(&nametable,&p,4); + p=getmem(strsize); + nametable = p; fread(nametable,1,strsize,bmf); nmtab_size=strsize/sizeof(*nametable); - SEND_LOG("(LOAD) File Table Loaded",0,0); + SEND_LOG("(LOAD) File Table Loaded"); } @@ -232,7 +233,7 @@ int swap_block(THANDLE_DATA *h) fseek(swap,0,SEEK_END); wsize=ftell(swap); fseek(swap,pos,SEEK_SET); - SEND_LOG("(SWAP) Swaping block '%-.12hs'",h->src_file,0); + SEND_LOG("(SWAP) Swaping block '%-.12s'",h->src_file); wsize=fwrite(h->blockdata,1,h->size,swap); swap_status=1; if ((unsigned)wsize==h->size) @@ -244,7 +245,7 @@ int swap_block(THANDLE_DATA *h) } else { - SEND_LOG("(SWAP) Swap failed!",0,0); + SEND_LOG("(SWAP) Swap failed!"); swap_error(); } swap_free_block(pos,h->size); @@ -350,10 +351,10 @@ THANDLE_DATA *kill_block(int handle) h=get_handle(handle);if (h->status==BK_NOT_USED) return h; if (h->flags & BK_LOCKED) { - SEND_LOG("(ERROR) Unable to kill block! It is LOCKED! '%-.12hs' (%04X)",h->src_file,handle); + SEND_LOG("(ERROR) Unable to kill block! It is LOCKED! '%-.12s' (%04X)",h->src_file,handle); return NULL; } - SEND_LOG("(KILL) Killing block '%-.12hs' (%04X)",h->src_file,handle); + SEND_LOG("(KILL) Killing block '%-.12s' (%04X)",h->src_file,handle); if (h->status==BK_SAME_AS) return h; if (h->status==BK_PRESENT) free(h->blockdata); if (h->flags & BK_HSWAP) swap_free_block(h->seekpos,h->size); @@ -405,7 +406,7 @@ void *load_swaped_block(THANDLE_DATA *h) if (mman_action!=NULL) mman_action(MMA_SWAP_READ); i=getmem(h->size); - SEND_LOG("(LOAD)(SWAP) Loading block from swap named '%-.12hs'",h->src_file,0); + SEND_LOG("(LOAD)(SWAP) Loading block from swap named '%-.12s'",h->src_file); fseek(swap,h->seekpos,SEEK_SET); fread(i,1,h->size,swap); h->status=BK_PRESENT; @@ -451,7 +452,7 @@ THANDLE_DATA *def_handle(int handle,char *filename,void *decompress,char path) if (i==handle) return h; if (kill_block(handle)==NULL) { - SEND_LOG("(ERROR) File/Block can't be registred, handle is already in use '%-.12hs' handle %04X",filename,handle); + SEND_LOG("(ERROR) File/Block can't be registred, handle is already in use '%-.12s' handle %04X",filename,handle); return NULL; } if (i!=-1 && i!=handle) @@ -466,8 +467,8 @@ THANDLE_DATA *def_handle(int handle,char *filename,void *decompress,char path) h->loadproc=decompress; if (filename[0]) h->seekpos=get_file_entry(path,h->src_file); - SEND_LOG("(REGISTER) File/Block registred '%-.12hs' handle %04X",h->src_file,handle); - SEND_LOG("(REGISTER) Seekpos=%d",h->seekpos,0); + SEND_LOG("(REGISTER) File/Block registred '%-.12s' handle %04X",h->src_file,handle); + SEND_LOG("(REGISTER) Seekpos=%d",h->seekpos); h->flags=0; h->path=path; if (h->status!=BK_DIRLIST) h->status=BK_NOT_LOADED; @@ -498,7 +499,7 @@ void *afile(char *filename,int group,int32_t *blocksize) } else if (mman_pathlist!=NULL) { - SEND_LOG("(LOAD) Afile is loading file '%s' from disk",d,group); + SEND_LOG("(LOAD) Afile is loading file '%s' from disk (group %d)",d,group); c=alloca(strlen(filename)+strlen(mman_pathlist[group])+2); c=strcat(strcpy(c,mman_pathlist[group]),filename); p=load_file(c); @@ -531,7 +532,7 @@ void *ablock(int handle) void *p;int32_t s; char c[200]; - SEND_LOG("(LOAD) Loading file as block '%-.12hs' %04X",h->src_file,handle); + SEND_LOG("(LOAD) Loading file as block '%-.12s' %04X",h->src_file,handle); if (h->seekpos==0) { if (h->src_file[0]!=0) @@ -704,7 +705,7 @@ void undef_handle(int handle) if (h->status!=BK_NOT_USED) { if (kill_block(handle)==NULL) return; - SEND_LOG("(REGISTER) File/Block unregistred %04X (%-.12hs)",handle,h->src_file); + SEND_LOG("(REGISTER) File/Block unregistred %04X (%-.12s)",handle,h->src_file); } h->src_file[0]=0; h->seekpos=0; @@ -840,7 +841,7 @@ char add_patch_file(char *filename) int32_t poc; int i,cc=0; TNAMETABLE p; - SEND_LOG("Adding patch: %s",filename,0); + SEND_LOG("Adding patch: %s",filename); if (!patch) return 2; if (!bmf) return 3; patch=fopen(filename,"rb"); diff --git a/libs/memman.h b/libs/memman.h index e9bc0e6..3886ee3 100644 --- a/libs/memman.h +++ b/libs/memman.h @@ -3,8 +3,15 @@ #include + #ifndef _MEMMAN_H_ #define _MEMMAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + #define freemem(size) free(size); //#define malloc(size) getmem(size) #define New(typ) (typ *)getmem(sizeof(typ)) @@ -110,12 +117,19 @@ void display_status(void); //zobrazi na display status memmanageru #ifdef LOGFILE char *get_time_str(void); int q_current_task(void); +void send_log_impl(int task, const char *format, ...) __attribute__((format(printf, 2, 3))); #define OPEN_LOG(log) memcpy(stderr,fopen(log,"w"),sizeof(FILE)); -#define SEND_LOG(format,parm1,parm2) fprintf(stderr,"%-2d %s "format"\n",q_current_task(void),get_time_str(void),parm1,parm2),fflush(stderr) +#define SEND_LOG(...) send_log_impl(q_current_task(), __VA_ARGS__) #define CLOSE_LOG(void) fclose(logfile); #else #define OPEN_LOG(log) -#define SEND_LOG(format,parm1,parm2) +#define SEND_LOG(...) #define CLOSE_LOG(void) #endif + +#ifdef __cplusplus +} +#endif + + #endif diff --git a/libs/zvuk.h b/libs/zvuk.h index bf7599b..d5b5f83 100644 --- a/libs/zvuk.h +++ b/libs/zvuk.h @@ -34,7 +34,7 @@ int mix_back_sound(int synchro); int open_backsound(char *filename); void change_music(const char *filename); int get_timer_value(void); -char *device_name(int device); +const char *device_name(int device); void force_music_volume(int volume); void set_backsnd_freq(int freq); diff --git a/platform/error.cpp b/platform/error.cpp index 75469d5..b14aafb 100644 --- a/platform/error.cpp +++ b/platform/error.cpp @@ -1,9 +1,28 @@ +#include +#include #include extern "C" { #include "error.h" } +#include "platform.h" void display_error(const char *text) { std::cerr << "ERROR:" << text << std::endl; } + + +static std::uint32_t gtick = get_game_tick_count(); +void send_log_impl(int task, const char *format, ...) { + va_list args; + char buff2[1000]; + va_start(args, format); + auto reltik = get_game_tick_count() - gtick; + double sec = reltik * 0.001; + std::cerr << sec << "[" << task << "]"; + vsnprintf(buff2,1000,format, args); + std::cerr << buff2 << std::endl; + va_end(args); + + +} diff --git a/platform/error.h b/platform/error.h index 223eab4..307c36f 100644 --- a/platform/error.h +++ b/platform/error.h @@ -1,3 +1,4 @@ #pragma once void display_error(const char *text); +void send_log_impl(int task, const char *format, ...); diff --git a/platform/legacy_coroutines.cpp b/platform/legacy_coroutines.cpp index 0f079cc..96f50b3 100644 --- a/platform/legacy_coroutines.cpp +++ b/platform/legacy_coroutines.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include struct TaskInfo { @@ -13,6 +14,7 @@ struct TaskInfo { std::chrono::system_clock::time_point _wake_up_after = {}; int wake_up_msg = -1; bool request_exit = false; + bool exited = false; TaskInfo(int id):id(id) {} }; @@ -32,41 +34,83 @@ static std::atomic resume_master_flag = {false}; static TaskInfo *current_task_inst = NULL; static EVENT_MSG *cur_message = NULL; +struct MsgQueue { + EVENT_MSG *msg; + TaskInfo *sender; +}; + +static std::queue msg_queue; + +void flush_message_queue(); + static void switch_to_task(TaskInfo *task) { if (task == current_task_inst) return; if (task == NULL) { TaskInfo *me = current_task_inst; current_task_inst = NULL; - me->resume_flag = false; resume_master_flag = true; resume_master_flag.notify_all(); me->resume_flag.wait(false); + me->resume_flag = false; } else if (current_task_inst == NULL) { + if (task->exited) return ; current_task_inst = task; - resume_master_flag = false; task->resume_flag = true; task->resume_flag.notify_all(); resume_master_flag.wait(false); + resume_master_flag = false; + flush_message_queue(); } else { + if (task->exited) return ; TaskInfo *me = current_task_inst; - me->resume_flag = false; + current_task_inst = task; task->resume_flag = true; task->resume_flag.notify_all(); me->resume_flag.wait(false); + me->resume_flag = false; + } +} + +static void clean_task_table() { + for (auto iter = task_list.begin(); iter != task_list.end();) { + if (iter->second->exited) { + iter = task_list.erase(iter); + } else { + ++iter; + } } } static void clean_up_current_task() { TaskInfo *me = current_task_inst; if (!me) return; - int id = me->id; me->thr.detach(); - task_list.erase(id); + me->exited = true; current_task_inst = NULL; resume_master_flag = true; resume_master_flag.notify_all(); } +void flush_message_queue() { + while (!msg_queue.empty()) { + auto m = msg_queue.front(); + msg_queue.pop(); + for (auto &[id, task]: task_list) { + if (task->wake_up_msg == m.msg->msg && task.get() != m.sender) { + EVENT_MSG cpy; + cpy.msg = m.msg->msg; + va_copy(cpy.data, m.msg->data); + cur_message = &cpy; + switch_to_task(task.get()); + va_end(cpy.data); + cur_message = NULL; + } + } + clean_task_table(); + } + +} + int add_task(int stack,TaskerFunctionName fcname,...) { int id = get_new_task_id(); auto st = task_list.emplace(id, std::make_unique(id)); @@ -75,6 +119,7 @@ int add_task(int stack,TaskerFunctionName fcname,...) { va_start(args, fcname); new_task->thr = std::thread([&]{ new_task->resume_flag.wait(false); + new_task->resume_flag = false; fcname(args); clean_up_current_task(); }); @@ -93,17 +138,13 @@ char is_running(int id_num) { return id_num < 0 || task_list.find(id_num) != task_list.end(); } void unsuspend_task(EVENT_MSG *msg) { - for (auto &[id, task]: task_list) { - if (task->wake_up_msg == msg->msg) { - EVENT_MSG cpy; - cpy.msg = msg->msg; - va_copy(cpy.data, msg->data); - cur_message = &cpy; - switch_to_task(task.get()); - va_end(cpy.data); - cur_message = NULL; - } + msg_queue.push({msg, current_task_inst}); + if (current_task_inst) { + switch_to_task(NULL); + } else { + flush_message_queue(); } + } void task_sleep(void) { if (current_task_inst) { @@ -115,13 +156,14 @@ void task_sleep(void) { switch_to_task(task.get()); } } + clean_task_table(); } } EVENT_MSG *task_wait_event(int32_t event_number) { if (current_task_inst == NULL) return NULL; current_task_inst->wake_up_msg = event_number; switch_to_task(NULL); - return NULL; + return cur_message; } int q_any_task() { return task_list.size(); diff --git a/platform/sdl/BGraph2.cpp b/platform/sdl/BGraph2.cpp index a2e6b70..372e8d6 100644 --- a/platform/sdl/BGraph2.cpp +++ b/platform/sdl/BGraph2.cpp @@ -26,9 +26,10 @@ char DXInit64(char inwindow,int zoom,int monitor, int refresh) { get_sdl_global_context().init_screen(mode, "Skeldal"); //todo allow change screen_buffer = std::make_unique(screen_pitch*480); buffer2nd = std::make_unique(screen_pitch*480); + std::fill(screen_buffer.get(), screen_buffer.get()+screen_pitch*480,0); render_target = screen_buffer.get(); - return 0; + return 1; } void DXCloseMode() { @@ -77,7 +78,7 @@ void StripBlt(void *data, unsigned int startline, uint32_t width) { while (width--) { memcpy(start,data,640*2); - data=(void *)(reinterpret_cast(data)+get_sdl_global_context().get_surface_pitch()); + data=(void *)(reinterpret_cast(data)+GetScreenPitch()); start=start+GetScreenPitch(); } diff --git a/platform/sdl/CMakeLists.txt b/platform/sdl/CMakeLists.txt index b4e0582..82b28fd 100644 --- a/platform/sdl/CMakeLists.txt +++ b/platform/sdl/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(tests) -add_library(skeldal_sdl sdl_context.cpp BGraph2.cpp input.cpp sound.cpp) \ No newline at end of file +add_library(skeldal_sdl sdl_context.cpp BGraph2.cpp input.cpp sound.cpp) +set_property(TARGET skeldal_sdl PROPERTY CXX_STANDARD 20) diff --git a/platform/sdl/input.cpp b/platform/sdl/input.cpp index 332734c..c853e9e 100644 --- a/platform/sdl/input.cpp +++ b/platform/sdl/input.cpp @@ -15,14 +15,15 @@ void SetWheelMapping(char up, char down) { //todo } -static MS_EVENT ms_event = {}; - void get_ms_event(MS_EVENT *event) { - *event = ms_event; + *event = get_sdl_global_context().getMsEvent(); } void ShareCPU() { + if (q_is_mastertask()) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } } diff --git a/platform/sdl/sdl_context.cpp b/platform/sdl/sdl_context.cpp index a9e1831..ff7f13b 100644 --- a/platform/sdl/sdl_context.cpp +++ b/platform/sdl/sdl_context.cpp @@ -1,4 +1,7 @@ #include "sdl_context.h" + +#include +#include #include "../platform.h" #include @@ -44,6 +47,11 @@ SDLContext::SDLContext() { void SDLContext::init_screen(DisplayMode mode, const char *title) { char buff[256]; + static Uint32 update_request_event = SDL_RegisterEvents(1); + _update_request_event = update_request_event; + + assert(!_render_thread.joinable()); + int width = 640; int height = 480; @@ -51,90 +59,137 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) { width*=2; height*=2; } - SDL_Window *window = SDL_CreateWindow(title, - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - width, height, SDL_WINDOW_RESIZABLE|(mode==fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0)); - if (!window) { - snprintf(buff, sizeof(buff), "SDL Error create window: %s\n", SDL_GetError()); - throw std::runtime_error(buff); - } - - _window.reset(window); - SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, 0); - if (!renderer) { - snprintf(buff,sizeof(buff), "Chyba při vytváření rendereru: %s\n", SDL_GetError()); - throw std::runtime_error(buff); - } - _renderer.reset(renderer); - // Vytvoření softwarového backbufferu (surface) - SDL_Surface *backbuffer = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 16, SDL_PIXELFORMAT_RGB565); - if (!backbuffer) { - snprintf(buff,sizeof(buff), "Chyba při vytváření surface: %s\n", SDL_GetError()); - throw std::runtime_error(buff); - } - _surface.reset(backbuffer); - // Vytvoření textury pro zobrazení backbufferu - SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480); - if (!texture) { - snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError()); - throw std::runtime_error(buff); - } - _texture.reset(texture); - - SDL_LockSurface(_surface.get()); - - if (!_timer_event) _timer_event = SDL_RegisterEvents(1); _fullscreen_mode = mode == fullscreen; + + std::atomic done = false; + std::exception_ptr e; + _render_thread = std::jthread([&](std::stop_token stp){ + bool err = false; + try { + SDL_Window *window = SDL_CreateWindow(title, + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + width, height, SDL_WINDOW_RESIZABLE|(mode==fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0)); + + if (!window) { + snprintf(buff, sizeof(buff), "SDL Error create window: %s\n", SDL_GetError()); + throw std::runtime_error(buff); + } + + _window.reset(window); + SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, 0); + if (!renderer) { + snprintf(buff,sizeof(buff), "Chyba při vytváření rendereru: %s\n", SDL_GetError()); + throw std::runtime_error(buff); + } + _renderer.reset(renderer); + // Vytvoření textury pro zobrazení backbufferu + SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480); + if (!texture) { + snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError()); + throw std::runtime_error(buff); + } + _texture.reset(texture); + } catch (...) { + e = std::current_exception(); + err = true; + } + done = true; + done.notify_all(); + if (!err) event_loop(stp); + _texture.reset(); + _renderer.reset(); + _window.reset(); + }); + + done.wait(false); + if (e) { + _render_thread.join(); + std::rethrow_exception(e); + } + + } void SDLContext::close_screen() { - SDL_UnlockSurface(_surface.get()); - _texture.reset(); - _surface.reset(); - _renderer.reset(); - _window.reset(); - + _render_thread.request_stop(); + _render_thread.join(); } -uint16_t* SDLContext::get_surface_addr() { - return reinterpret_cast(_surface->pixels); +void SDLContext::event_loop(std::stop_token stp) { + + static Uint32 exit_loop_event = SDL_RegisterEvents(1); + std::stop_callback stopcb(stp,[&]{ + SDL_Event event; + event.type = exit_loop_event; + SDL_PushEvent(&event); + }); + + SDL_Event e; + while (SDL_WaitEvent(&e)) { + if (e.type == SDL_QUIT) { + return; + } + if (e.type == exit_loop_event) { + return; + } + if (e.type == _update_request_event) { + update_screen(); + } + + if (e.type == SDL_KEYDOWN) { + if (e.key.keysym.sym == SDLK_RETURN && (e.key.keysym.mod & KMOD_ALT)) { + _fullscreen_mode = !_fullscreen_mode; + SDL_SetWindowFullscreen(_window.get(), _fullscreen_mode ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + } + } else if (e.type == SDL_MOUSEMOTION) { + int mouseX = e.motion.x; + int mouseY = e.motion.y; + int windowWidth; + int windowHeight; + SDL_GetWindowSize(_window.get(), &windowWidth, &windowHeight); + float normalizedX = (float)mouseX / windowWidth; + float normalizedY = (float)mouseY / windowHeight; + ms_event.event = 1; + ms_event.event_type = 1; + ms_event.x = (int16_t)(640*normalizedX); + ms_event.y = (int16_t)(480*normalizedY); + } else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) { + int button = e.button.button; + int up = e.type == SDL_MOUSEBUTTONUP?1:0; + ms_event.event = 1; + ms_event.event_type = (1<<(2*button-1+up)); + switch (button) { + default: break; + case 1: ms_event.tl1 = !up; break; + case 2: ms_event.tl2 = !up; break; + case 3: ms_event.tl3 = !up; break; + } + } + + } } -int32_t SDLContext::get_surface_pitch() { - return _surface->pitch; -} - - -void SDLContext::charge_timer() { - _active_timer = SDL_AddTimer(1000/TIMERSPEED, [](Uint32 interval, void *param) -> Uint32 { - SDLContext *me = reinterpret_cast(param); - SDL_Event* event = (SDL_Event*)param; - event->type = me->_timer_event; - SDL_PushEvent(event); - return 0; - }, this); - -} +/* void SDLContext::pool_events() { - if (!_active_timer.has_value()) charge_timer(); + SDL_RenderClear(_renderer.get()); + SDL_RenderCopy(_renderer.get(), _texture.get(), NULL, NULL); + SDL_RenderPresent(_renderer.get()); + ms_event.event = 0; SDL_Event e; while (true) { if (SDL_WaitEvent(&e)) { if (e.type == SDL_QUIT) { _quit_requested = true; return; - } - if (e.type == _timer_event) { - break; - } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_RETURN && (e.key.keysym.mod & KMOD_ALT)) { _fullscreen_mode = !_fullscreen_mode; SDL_SetWindowFullscreen(_window.get(), _fullscreen_mode ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); } } else if (e.type == SDL_MOUSEMOTION) { + std::lock_guard _(_mx); int mouseX = e.motion.x; int mouseY = e.motion.y; int windowWidth; @@ -147,6 +202,7 @@ void SDLContext::pool_events() { ms_event.x = (int16_t)(640*normalizedX); ms_event.y = (int16_t)(480*normalizedY); } else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) { + std::lock_guard _(_mx); int button = e.button.button; int up = e.type == SDL_MOUSEBUTTONUP?1:0; ms_event.event = 1; @@ -164,21 +220,46 @@ void SDLContext::pool_events() { } } charge_timer(); +}*/ -} void SDLContext::present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs, unsigned ys) { - auto beg = pixels + y * pitch + y; + + auto beg = pixels + y * pitch + x; SDL_Rect r = {static_cast(x), static_cast(y), static_cast(xs), static_cast(ys)}; - SDL_UpdateTexture(_texture.get(), &r, beg, pitch*2); - SDL_RenderClear(_renderer.get()); - SDL_RenderCopy(_renderer.get(), _texture.get(), NULL, NULL); - SDL_RenderPresent(_renderer.get()); + std::vector data; + data.resize(xs*ys); + auto iter = data.begin(); + for (unsigned int yp = 0; yp #include #include +#include +#include #include class SDLContext { @@ -22,14 +24,15 @@ public: void close_screen(); - uint16_t *get_surface_addr(); - int32_t get_surface_pitch(); - - - void pool_events(); - void present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs,unsigned ys); + MS_EVENT getMsEvent() { + std::lock_guard _(_mx); + MS_EVENT out = ms_event; + ms_event.event = 0; + return out; + } + protected: struct SDL_Deleter { @@ -43,13 +46,26 @@ protected: std::unique_ptr _window; std::unique_ptr _renderer; - std::unique_ptr _surface; std::unique_ptr _texture; - std::optional _active_timer; - Uint32 _timer_event = 0; + std::jthread _render_thread; bool _quit_requested = false; bool _fullscreen_mode = false; + bool _present = false; void charge_timer(); + + void event_loop(std::stop_token stp); + std::mutex _mx; + + struct UpdateMsg { + SDL_Rect rc; + std::vector data; + }; + + std::vector _display_update_queue; + Uint32 _update_request_event; + + void update_screen(); + }; diff --git a/platform/sdl/sound.cpp b/platform/sdl/sound.cpp index 968e44d..ae81de7 100644 --- a/platform/sdl/sound.cpp +++ b/platform/sdl/sound.cpp @@ -74,5 +74,10 @@ void DoneVideoSound(void *buffer) { } +const char *device_name(int ) + { + return "SDL sound device"; + } +