From 192e53bb8780c43b6c1bf0a3d01801b3e3922823 Mon Sep 17 00:00:00 2001 From: byuu Date: Mon, 21 Aug 2006 00:43:46 +0000 Subject: [PATCH] Update to bsnes v016r52 release. bsnes now builds with no warnings on Linux: http://byuu.cinnamonpirate.com/images/desktop082106.png However, input is not working unless you build the non- GTK+ port (see below for more info). I'm planning on releasing next weekend. This will likely be the last public WIP, unless something major is found before the weekend: byuu.cinnamonpirate.com/files/bsnes_v016_wip52.zip <- copy/paste link > If you can actually get it going fast in an all-in-one window like > that it'd be cool. I normally just punt and have the GUI separate > from the emulator output (GTK or Qt for the UI, SDL for the output) > but it'd be nice for my NEStopia port if I could make it "one piece" > like the Win32 original I can. Please take a look at my above sourcecode, and check your private messages for another note. Specifically, src/ui/video/sdl.cpp and src/ui/gtk/gtk_mainwindow.cpp. I am able to merge the SDL output into the GTK+ window by setting the environment variable "SDL_WINDOWID=%ld", GDK_WINDOW_XWINDOW(mydrawingbox->window). One important thing to note is that you must not initialize SDL video until the render window has been realized. Simply showing the window is not enough. You need to also clear all pending events in GTK+ after showing the window before calling SDL video init, or it will die. You can do that with this code: gtk_widget_show(mainwindow); while(gtk_events_pending() == true) { gtk_main_iteration_do(false); } However, one problem I am having is that by calling gtk_main_iteration_do(), it steals all SDL input, and I'm not able to poll any keypresses. This happens whether I embed the SDL video output into the GTK+ window or not. The only way to get SDL input is to ignore all GTK+ events, effectively freezing the window completely. I don't suppose you'd mind sharing how you got SDL input working with GTK+ with me? --- bsnes.exe | Bin 929792 -> 929792 bytes src/apu/sapu/memory/memory.h | 4 +- src/apu/sapu/timing/timing.h | 2 +- src/base.h | 4 +- src/cart/cart.cpp | 52 +---- src/cart/cart.h | 3 - src/cart/db/dbcreate.exe | Bin 77824 -> 0 bytes src/chip/c4/c4oam.cpp | 119 +++++----- src/interface.h | 4 +- src/lib/libbase.h | 1 - src/lib/libco_x86.asm | 26 ++- src/lib/libwin32_control.cpp | 4 +- src/memory/bmemory/bmemory.cpp | 27 ++- src/memory/bmemory/bmemory.h | 9 + src/memory/bmemory/bmemory_mapper_generic.cpp | 42 +--- src/memory/bmemory/mapper/mapper.cpp | 15 +- src/memory/bmemory/mapper/mapper.h | 1 + src/ppu/bppu/bppu.cpp | 75 ++---- src/ppu/bppu/bppu.h | 14 +- src/ppu/bppu/bppu_mmio.cpp | 1 - src/ppu/bppu/bppu_render.cpp | 18 +- src/ppu/bppu/bppu_render.h | 6 +- src/ppu/bppu/bppu_render_bg.cpp | 35 +-- src/ppu/bppu/bppu_render_cache.cpp | 4 +- src/ppu/bppu/bppu_render_line.cpp | 31 +-- src/snes/snes.h | 2 +- src/ui/Makefile | 216 +++++++++++------- src/ui/audio/audio.h | 10 +- src/ui/audio/dsound.cpp | 4 +- src/ui/audio/dsound.h | 4 +- src/ui/cc.sh | 2 + src/ui/clean.sh | 2 + src/ui/config.cpp | 34 +-- src/ui/gtk/bsnes.cpp | 48 ++++ src/ui/gtk/bsnes.h | 22 ++ src/ui/gtk/gtk_mainwindow.cpp | 192 ++++++++++++++++ src/ui/gtk/main.cpp | 92 ++++++++ src/ui/gtk/main.h | 4 + src/ui/input/input.h | 2 +- src/ui/input/sdl.cpp | 37 +++ src/ui/input/sdl.h | 13 ++ src/ui/input/sdl_keymap.cpp | 37 +++ src/ui/main.cpp | 6 +- src/ui/sdl/bsnes.cpp | 53 +---- src/ui/sdl/bsnes.h | 9 - src/ui/sdl/main.cpp | 31 ++- src/ui/sdl/main.h | 2 +- src/ui/video/d3d.cpp | 65 +++++- src/ui/video/d3d.h | 9 +- src/ui/video/ddraw.cpp | 22 +- src/ui/video/ddraw.h | 3 +- src/ui/video/gtk.cpp | 38 +++ src/ui/video/gtk.h | 23 ++ src/ui/video/sdl.cpp | 45 ++++ src/ui/video/sdl.h | 21 ++ src/ui/video/video.cpp | 14 +- src/ui/video/video.h | 11 +- src/ui/win/debugger/debugger.cpp | 4 +- src/ui/win/debugger/ui_memory.cpp | 8 +- src/ui/win/debugger/ui_memory.h | 2 +- src/ui/win/event.cpp | 21 +- src/ui/win/main.cpp | 4 + src/ui/win/settings/ui_coloradjust.cpp | 4 +- src/ui/win/settings/ui_videosettings.cpp | 39 +++- src/ui/win/settings/ui_videosettings.h | 4 +- src/ui/win/ui.cpp | 26 ++- src/ui/win/ui_main.cpp | 5 +- 67 files changed, 1152 insertions(+), 535 deletions(-) delete mode 100644 src/cart/db/dbcreate.exe create mode 100644 src/ui/cc.sh create mode 100644 src/ui/clean.sh create mode 100644 src/ui/gtk/bsnes.cpp create mode 100644 src/ui/gtk/bsnes.h create mode 100644 src/ui/gtk/gtk_mainwindow.cpp create mode 100644 src/ui/gtk/main.cpp create mode 100644 src/ui/gtk/main.h create mode 100644 src/ui/input/sdl.cpp create mode 100644 src/ui/input/sdl.h create mode 100644 src/ui/input/sdl_keymap.cpp create mode 100644 src/ui/video/gtk.cpp create mode 100644 src/ui/video/gtk.h create mode 100644 src/ui/video/sdl.cpp create mode 100644 src/ui/video/sdl.h diff --git a/bsnes.exe b/bsnes.exe index 6338284d6c7ddea0d5086ce979fe3361c35985d0..45c3797238b20a45933177e21e712477395e10a4 100644 GIT binary patch delta 139470 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 z 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
b~PMUS=ts%H=K%KFm(xFpE-s zYk_?)V}V!7%U)rHbi~zFvI)3#n_h{vfXGi)vQheSGjCtTHt7=h_A1tM*d;3HbeXrX z?L(rW7H=LC1^iCICC>G^N7Uo6?wD^1S$PQ;x}@X%GS0SO6OQC#x3FIAzi7DGV(Q9k zxXCTUSx3HU3+vFX!cTiQ|IaPBe%67KdWTn~aB`@A?<{rxExx1^|v12dc55CU2|yh{GY0c7CxU}#*5>UX;M8<)JI(YOUqV-xoTg>X$Ag+Ch<*{ z*bQ~yzk2#fB?PTJf9*_E%$3mCz?h@B#!mHDy~#ENU?t55?_eX1((1Z!ApR$V#qw8o z;H;wpgL((MTmPbo8{T5s5;gZNf9e-+$<#J)%hZIoS+=jRxl&=li5I%!N>usEkyO{` zZ{t8kiC*vcm-PHQQc12)-eLFYBo5o@$8iGO`b# z+>k62zh@WgsTWK&I`>N><#5ryV#;WcF6KV+vBtxFJ}x~dC+u#YPZVF zQz!|T($!{ijeZXuqc1n{CtR#4buS2CAN~5zGhcu0{`%Yct~-!_>73`~YTP^$3J%wY z)If0Y!!vA`A90&Pq-Vs6U#<^1XyVn?tZJ6Ib8~0(kAeLpMG(XJbMrBC0QbQ$sX3Dty8i&eKRj~-e7lU{?;BgTVL6kN9<*n z!|l;h8{O~Y4zh4@GkTgWjONiFu)eLVP#rkKY|(t;2kb7rCEB(41NL-4>UPMr9bJJu zb#y^|eMmLZ7h?~vUVt5yy7LUH^kbL%*u{qW5N9+`+t2=-Qwv#M=)K|Bx{VV;pLt4; zHz}=r7{4SFAuE_mDKBYPG+>%UBQXl6&`3msqj{>7{{{p53k>Wt*xkAw>Bf&AV4btv;9d!Rq!zo`3D^W4GRfqaLlH>) z&$=NYts12lG1|$nhus@4nBijAGb{)(-oT3Am6w7rwc(ws_>aYUqG^?q08V`bbahAb z{RdfiE6FzSkSCg-JIFFyS7woyVd2g!KJpN|x1$M#A|Jb&68P_s&_402%`tq%AvV-; z4O~nj=kh`ezUrM9dgw5inZ2llUO4FD-xPGcZerV`i=tM?#Y&?#R!UGgS@Ekaaa8uC zUQVf;EHA8UP~J(Dcd{GGI{!;X0s?Z9A-m0+S4WGw^u^@(d>2^?FlKxS4|GHXrOVncnEkB0JDzo_8 z$JlhT3HgMLYGp;hCSX#jS&orCzj5;io>qIui5;YFHHSSi=VSGIRB&DSS^2 zT7xows$nAyw5{Kd;yd@UEC^|VVH>bG#20dLX^{Mko5DZ;3=2G~!S#AAniYPj0*85gWJ@}9_o4Md zC61U~PO`g0x8a~JT2ErBfq#XLxWXSg$@28UQ~92gtb2!?L$o--1v23RzUPNW2pje|!*j#EbucKtSS*@yvA3nSe9X#WRKr^u>s^X{UUu3p6Dn-3b3KekIE(eF0ab zNsgLqb*yLitE7Jsf=iUxAZet6qc5(KX*=pzjN?3+p2vD<`TmGToJRZ+EWh#*H_aBG z!M`&2Dta9Wa_nLy5|XPNiFzvfStRNxu^NdQDsGYN$w5j#A*bC$FoCd_5=JDdkvL=I z4}QUVrPLgtUg=Kre6sgUv~+i-tm#}m9&`mR1J{87_!A6pq$3b7N4yY-LAoE1aK^Rw z3%0JEZm;Y9f3YrleU^deU0`oI?tMq;^aEl~DNR+;zd1@TG7_iN+`y90mL51(*i!w+ zB4O)Zyt8Smn||muNn+A7*qF_)ZoF{u(v2p~E3CveM{YFPtgsd%TQX&mW0LLX8a&PF zr61FA`ftyD+wu8X@#=rV&PjIPuccLGpzqcBKE4@LTMmAzOYu3}eb>ljKbd&R#Mx}( z1;utf*yw-*&lp$ z4R7tQrX~=*do#TT?_-!F*iwma`*f_sXF%T&6R)_a0c3D_O>>)NgHkf6R4brwe&HSG z;Kv!j-+v2#FY!;QeEQs%xRLmF;%`v+^clQK_{s#f02wr@2J{s=aTXak$zY~ppz8os_-sPYc7-67mVL)AKC4+;if%6=;z=_?| z0^)!Ew0{rP6F;z4afrUpAZ{VPllWDBe4Wh%s?8CDUyQk>Q^77GwwKt28n)D8awwh* zGG%`KdGM2o9~T6E((U*;#9u1&>08cXxa2+YJ1BhLX9#H<u+#wJ$KQ^hLVT;trw?B{L?*SM4GaQX8i-{VQ8j%G<1nMQ zESmK=17|C5!hf*0(x);$W_9=##ABS5;#9oxJbr%v_ ztLcZnnBowhgRMM)+dSljqd9L1Mt+`}7hjt3XOqoL!l|l|YVrl&R9i?*EXR*LF{IE` zI6!J7S(;(#o6U(&+rN?w_NoSMGSHEMoeaEavBm(@8sdv8KbE@v^LJ@85#O!hOMBHd zqQ{(6{HY=O#(#qD1>GTTXy(&QXe%9sXS_y$Zp&6}wmkxy8DtX|f+`+SOo;EE4t^o= z*QoqH*s|ii#J3Z_zm_kQfWMjeyYS=rM z)Y86wS@J&=e9v;tn8;E26)HcIHu8R{1;lr1`P)@~{g>+TcLYri8_2*(2BlhqOR9nS zE2RZBG$Lja-%I>-Ek6z{xdAyUKLtCmI6!KE34F7{$NWFZR;U_mR}D&kM+G{m1!UkY zZEmqNs;kMSUZs0!#C`M*`A_uy&2;JT9&Pgy-*QUvf19)yymP~W29Uu9KZAj`Y;bK$ zRRbGM=d-ASxOU*r^y5EZt04Z>ZPP$aN02cW5q}gs-vt_!TmL9qli#5VGoma7TmlvOy{J z=MQgD3)+K!e%YN`d{ySx(}M3k;@gS8>kfPemQ3|hm!A3_E0on_;3R`pcQ6oa9c2C* z+J_$|zL)r!cjU*&e1S%2FR1|?z>ksn4&{qjnl6o(4Jv8L^xF<<0U2B^xl@Z%Wqt+i zVuy(DB>q7^zRe1n&2|Pqd+{R=I?+J~n<}XlWK`a4Brm&biElou@adD-;w-8oE*$ik z&2;UcO9CH*w31ppSZV-~<27V;kUFGMoh2K@(KcpM3&zAmaq@>Zs0E$CKfmNoEv}RK6|{NZBfg#ZyKdn-l!@ZJ zY!FBltR@2|8LYa+K;d7N`8Jxh9wxq*_?dU)2cMJ1gqM1>m(+j=@M9c)1~xNzHnRsm zh4_(2sX#_LX)})3)4Qh-Xu*)@(-QL<=EE!K!Y4VvUw~m_5b-gwTaAkHk;Q> za@gvKe2RV|epD>%v@30pT16J6%@&hvv0&NK>1UzJHxqxR)T++lr)&7q!D=1RH>>o8 zv}5!jhwKjGcW>s?(Mo#RwarO3vHwzBx=IJ!U$#>t$mHimzCM`z;WauIyjpg>X`tKY zh3+sTN&O96uxN*tZ!uBx_sRSj2PS{$p+kKU_*fg89Fb%|qH8eN+Bg#HVgZY#Eq&UtrdK76a{#R@XT!s7(NdL2wk9`b6fqJE1)-#e*Eq9r6cJ=lCFqd z$T&LlM$>_s>KfWa37c*-Raa9gmQvd&)q_&yl!`#AimvtG_IUeraafVG{SPw|QP7_I zR2{)YD)YjMc$&cw*}I|8$9F@eu?8@8|h5UFUi|oBy;hLao!L?#aebm?K2b(i6~UnD7w4E1Vu?Q z3Tgo(u=4RWwt%k>gtH9`d<~0-ss-1COl-r19s?6P}a7aX<>Z+F@`5>cp%Rdu@+9f>HYeif?w?M8(|A_`UcitaA4SW%LU zf?9x6-Pjp+e!ML;OyO?#-{?bBZkU~?5w~HUuVHci++FI1JTZ?Szezj4!rkG&As4DU z^hR()&|$?2*X}>5)Ty14p>Rk4v8pK1uD9`#D=-PhLMbd zT0jgAfxb~Um#5JP-K}t=plZPtaX9vky19J4)G&qXfvN?Ut~#xDH(!vVxj02(lahk0 zPH)0v{hGB2CCftSqSNZ5&DW#wz9%EQ-XsgMae)dZ{Ko)8MEmprJSfS;uL4O+A2*E( z;Oznp;f_^M$OTW@Cw)yeH|#wUDTLm~=QR#jK5=tx9CakI*!axxSS zi6~T^^6C1diwTO7WE9i_Qq_JBdxEDi8hrUaN0R*e{gTQ(kP&g!_P*tPqb}Kp(QBeKL#=6SaE`>uP3RRhk4l{$IBpC&@fIzF#F&U5Z5NXO& zxQ+gM@Q~&y?{U5!$H~?Wc-jePK!;fz--*My{=^)9oDS=|6}i`c>i0I!0&{p8)mN-= zMgLi#P~E^8bDmE_KPD*DeE;p6t?bldn8G0ug{n+d*D%}XE{Q0p-Ec`A11A&?i6~T^ zS9EuYyA>tLD5wS4)Me1d**xS=7MWM9aIOB!ph_%n<&Bo1a7aXqwSz@SNYdfsrK#0Jf5bfBc;Nv@bBA3Wz8sNC>#<|sJg1^5)>VYD5!p2!(}U9 zyA%$IC{%eBU2m}=S813}sTQyud$?S{2_775=z{0O`ve<$;J=#T`3TJ68qs#bTduw0JsE@MW`@%iKQ-?@Tvl#_uI3Wr2eg9KH#ThWn-g4&){ zxI`tlXQRR)5rwLyiVicXq9hpwwE%bXp(2MLr$bnR!mal2gLHLEhvo3~SVZ=2c+}Uh z6#p$Ps{M81Q67S|R^D!f>+$a}5m%~wjZiowqEO{gb;XK~L=@CERH$`jJj&P89-E+W z%l+%JsgFYe!XXibDyOPTP;?}spf)W=tt(97kcdK6l%m7ZaHg*fB%`1futuHDPR!(KH1q9N zxTXHHndt{*@7g$%uSZ`viWP1UR4vLiH}|>1ArXbD2vwJ$=tx9C^($355fH-^4v8pK zB`G@W$yQ&(NJc>|pj_R{PVm%rw80eW8vmWlqEa_nc?f3C*2M~U2%nGHjm`m4gd;%_ zm-}z?4(fy$rf^6^p(T2&FbtDh8R;Qw$&;34$GjC2&LcRx65bf%_iY`M*OLxS6 z<&jD%uMvl8F^ozPDHY_PWF3+hZkDuot_LMwD0{udwZ{vOzuhvw$JsK!WM|9#o?R{T zOR`&3apA^$*IhB~4VMC6FdKp#-gS5n6++~CImUxurIdeUgHf0Oj0WO?7@#B28n|9= z6n+Bg05?FP`URu#8t?+}6krFeKq@c-=nq5zCcpq(f8HpZf8OX2>X4`eEA;Bf z4x{isDropSDgbJMYTzlzZo=qOw6-3&1Y83GHyVX#AQl(_j0dIyc3=gt5!eRo295z| zf$Km7%8Uh)fNWqc@D#AgfuBm?ZGgh0=imT5I|6(Oh`@Gq@e9B+z+%7#Oa&$Yqk#mV z4-f?e12<8|72rFd4yXaDfj59nz%#&7U=HB8h6+-V7zV@wkw6g8@T^hz5%>l;0_*~| z0h@rQfTh43AR9;l;(%zNHSikBq_6@#wg8~;vM;XljW?2+uOvH!^ecEh22ct(0S{pM z6)))k>_8<@3kX;7!VbU+lml+S3z&aP7Se%IzzKK&Qv>V)J5UMK0>baG2dqFjPzwmx z?gIH53IQyD9jF9q0pSlA09K%!f6>#>&0)F$8ej)1fm%Rl1P!nP<$xRT0_H#A7f=c~ z0S{oh346c}R06et&;)zH3X}tGzzdiK{D&Y=3OE6efV=7@-B`f_*nvvG33vdL9&*4A zR06etIRJT}9B=})fEO^~QNB1p3DHaOBG?y`gpIxNyyN6#A#X9>uktV)^M#Gbk9sKy zxgc5c$HT4(F^2Yf{gfm=ueYJAtF*V_f)4-IJg1N0W?037al*}INrDIQ8>LCYzVoid zcN?~}>gfDFNqEo)Yr#0-lk<{t;2^^*K|N~VX96Z;zzSG^7$9~yVnFs@s{p-68dgkpZLcs` z`f%}}p_6{_K$q^2p&;BbX?9NTJhN@)f}AI3F32^{o?Do^AaCZQxzzfCMFoYqPxLP) z3gr`va%TSVE=XuzA!sRi2GrTklxcGm`_@S^sk`DcSiSPXSyA% z|AHOh=>QwV&JQg@K9#%FA_3)Kc12-?7%1Fna@sxJBG~6xg!;wf1j{oP!Mzq0B2EXa zK-{wyVH0#zspmP1PzjLUi91ez;pbSE-if>EeG6y2Qb4>*(>5vq4k}= zR-qX@zxtZ@e{GjmzKzNN4I^W3kVf$OKEls=RZY_s_ z6R@KK_q*8c?^%S+sL+DhPCF9{$eU;e#BQsd3GI;8*1)vG2qfigbk44cLUr*tq1>FP+PRUYS~8tD>YTPjVHqc z>jlUG#oqfPILOQMz8cFDO6f(p08&<7LK>?-^M672vqdNc(tiOiTZBT$orpbv=6dwfFvj@EcRPId_79wx@ zfYSUJGwz#qumsNEfIY_LLZp==tMeRs-2?fzz;}tNob(p6Ma`Fk*DGh%>_XJlE9Y@3 z(JSW(id~-=jPrEu3WUDqjKnnaL$ep>nunQt6}TP>GU{{=%Q6g}R-*+k;9r|XKUzqK zJRLPrZRNqE1vlUUD3rri@mlftug28t;5yVMXbr7UmWPZM>ZyX~M+=sU(L&`m#IM3h z#BQJ#@Bm&wfZPnYVdDWT<=~kie*<`Zv|xP=jrd=q1rze=fD@d!H}O$XhoiZ#6$i?p z@Ojt5IdZBJx>(qluYvOiD!YyfZj2Vlrql^%{)7{akllnsfE#i*;^5L->!JF}9atv0 zQJ_^f2B$)pFpOAk1p%$F1cNRUhT1N6LZ&$S?_w`4!QgahILbzvCL*CDfKZ8Y)4Pum z#=Cor5iAf=!PZHr6mSE=WXOS1zzRJTWX%{Om?n-9DiJ#Y0X(H(`xMuUZH%LI8Rivo zQ{(W3>$>F_<}=V5q}L#AUx^A zK4-Bpa%u`>N}zJHBu=wT(WRhFEtlk_yT%D?H1gli5lT8I|>ilfZ zBku(&mhiqyjM0O&da`lC#*ArB2~dB@NHi0-wD1kiffV>$9@_E`Qd#a@oJ>ord znxCl^`FxFO1m94CMrvtfIs~Sh{Y-ZtU#&46BANEr(#SLmrlOzeHRJb|_5haj| zBalx4l-8}2Tc@QFeH%;{`kAglev@R%KP`o)T0Pn9h0Q@fn>yq@l8x-fUfEMEjZEuc zYV!3r<;hbs^09#8X`O7Ur4jWKOtbw=^O0YuF})<2_SMqJRB(+GwrfmjBCeLq`1R$+ z=mAER<^65TVoNT705G@I2rG94R z$XEDeNs?Jdf676qYj6};fd=f-m{XDYD6&x_BTs^{hbVhVzEosiErra?AEXFLz8#73 zWR{71_EJ7~r7@Z>Txv8$4*_YNhD4iiGxFPkJ|+Bp5C?1ZR8S^tPWjo0$X^Aru`ZQ3 zeE&*gr;b`0)o+Fx#SU9#jP7XiQHd`3hJ1Djp9|gKB#n;rmE@*ICb^0Hb|41pKZzq% zIY3JzaW#3XF{P?RQ@6)6j}N}#?;M?M?a=HPRm!jRJHiD!Y$I*ko=%4Uf#mt)}*pEh=CuceS#=DrmE znFF2=!Fo&*@Xyy6JMo}WqbbscGR;0Y>8Q*&b^T7E#(}tVESS4(~v|8UXPa5oNQp9KC=4WArYhkOO#E#Ys#X0TRIHd(Ma;%9RT z`SX&E+$g;56h7&Xtl%A=G2X+!ea6^L|Jp)6bsg5dcP*CVSLIl@l5Z%3`r#5;>{=$p z(Kj7*i$xG#!95cSQLFIgTEu-2C#~Y6%8Xs`UbU%Z#>jy5^GSThI&|{kRdN~PQyll* zqV;iWhw zSMka4y?Z6kbsk=|-q_9f)@jL>|FYf~sXHgB0{-@`#P1sV(|2;gRLJh{d|r(BUT*q? z|B~ZQzsPaFKjf}BcU_Lp+~9AZivpIkP3BA18M_Aj5thuSQDRv8WZvdkV^{q*U3uT< zKq=}bYxIYE$bu=oWr6XHyQSM=vU@{i<#>yaT{@1pE;mMpj=jJ6-dRaXG7o*$*g2s0 zc!|~7cydv)@XI2}ht7_h&SW8SCtmEYxheW1(uF+?xCCURhDsq2H&lbn2Ene8wS_DK zGMh#g2bl@7?HXAHWa*GyDr+upS2=Fvb~mI83pGUB2BTmGv0CHICdjOC=AcIQPss8i z%hK4oArs7o4c){4|3d};|Dl5aXAc#$7LsN!$bFRORv5$imI`C)3!98X+Ggle=grJX zojq&8%ms@QdBP@RUg$v~dG5?v`MHy4&&`?lq`+U=Wc(nkt!`XyVN!0v*osNEWOM6l5u8)_oxF$I*15i~G#(AqdwzAj{i?CA zuJ^IHWZ~a~-+axuI{>da|NDOZQC_;;m>+Qd&#|swwj2M^HUN+6KfS?a{ClmwGvDS4 ziV3I;829de{Y1SZ3Aez@`zA>T2s-B32jB~?vL}KiF-f3Zo$~JCNz&qq4)el2GM^4A zTE1y~GbbHoQh9_*@X3z&&Y{hm+OfEnNCc{&cBHJJyt&`)4boGZE7n#}>uUg25Ep;@ z2G~b5S6n_SNicvLAjG#c(6+$pYXN!ZK?}%9a?U!8PuLUG$$>JcQ6#eTSIQ%Gb3Iyr zwZ%Do{*tXX;r9NTef{Cz;R>JL5h`f?E!Fh6J+|37({SE)Z%co*{cF-}SgpU>;TJV0*oSKA?G_^b4SEpUEnxy z0=NPgJg@@>0vW($U_MX`ya2obeB{BiNnaw-0Nen=zs0c{7zRuL@_@y_i@+?TQ7zK<0rUSEp6~GI?+rUS_cfh{@-S=<|=nV`5GQQ_K_6Nl|=*?$cF=&Dj zMV3+yx5YHq38}hS9H2?qr delta 137272 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 0; i--) { - if(size & (1 << i)) { - if(!(size & ~(1 << i))) { return 1 << i; } - data = (uint8*)realloc(data, 2 << i); - return 2 << i; - } - } - return 0; -} - -uint Cartridge::mirror(uint8 *&data, uint size) { -uint r = mirror_realloc(data, size); - - while(size < r) { - uint i = 0; - for(; i < 32; i++) { if(size & (1 << i))break; } - uint masklo = 1 << i++; - for(; i < 32; i++) { if(size & (1 << i))break; } - uint maskhi = 1 << i; - if(i > 31)break; //no mirroring necessary - - while(masklo < maskhi) { - uint start = size - masklo; - memcpy(data + size, data + start, masklo); - size += masklo; - masklo <<= 1; - } - } - - return r; -} - void Cartridge::load_rom(Reader &rf) { -uint8 *data = rf.read(); -uint size = rf.size(); -bool header = ((size & 0x7fff) == 0x0200); +uint size = rf.size(); +bool header = ((size & 0x7fff) == 512); info.rom_size = size - (header ? 512 : 0); - - base_rom = (uint8*)malloc(info.rom_size); - memcpy(base_rom, data + (header ? 512 : 0), info.rom_size); - SafeFree(data); + if(info.rom_size & 0x7fff) { + info.rom_size += 0x8000 - (info.rom_size & 0x7fff); + } + base_rom = rf.read(info.rom_size + (header ? 512 : 0)); + rom = base_rom + (header ? 512 : 0); info.crc32 = 0xffffffff; for(int32 i = 0; i < info.rom_size; i++) { - info.crc32 = crc32_adjust(info.crc32, base_rom[i]); + info.crc32 = crc32_adjust(info.crc32, rom[i]); } info.crc32 = ~info.crc32; - - info.rom_size = mirror(base_rom, info.rom_size); - rom = base_rom; } bool Cartridge::load(const char *fn) { diff --git a/src/cart/cart.h b/src/cart/cart.h index 7157bc83..ed4e6586 100644 --- a/src/cart/cart.h +++ b/src/cart/cart.h @@ -78,9 +78,6 @@ struct { uint header_index; } info; - uint mirror_realloc(uint8 *&data, uint size); - uint mirror(uint8 *&data, uint size); - void load_rom(Reader &rf); void load_sram(); void save_sram(); diff --git a/src/cart/db/dbcreate.exe b/src/cart/db/dbcreate.exe deleted file mode 100644 index c6687d71cba024205fc87ddfa07e18f97eae6c6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77824 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 && i>=0;i-=4) { + for(int32 i = 0x1fd; i > oamptr && i >= 0; i -= 4) { //clear oam-to-be if(i >= 0)ram[i] = 0xe0; } @@ -19,58 +19,55 @@ uint8 sprcount; sprcount = 128 - ram[0x626]; uint8 offset = (ram[0x626] & 3) * 2; - for(int pri=0x30;pri>=0;pri-=0x10) { - uint32 srcptr = 0x220; - for(int i=ram[0x620];i>0 && sprcount>0;i--, srcptr+=16) { - if((ram[srcptr + 4] & 0x30) != pri)continue; - sprx = readw(srcptr) - globalx; - spry = readw(srcptr + 2) - globaly; - sprname = ram[srcptr + 5]; - sprattr = ram[srcptr + 4] | ram[srcptr + 6]; +uint32 srcptr = 0x220; + for(int i = ram[0x620]; i > 0 && sprcount > 0; i--, srcptr += 16) { + sprx = readw(srcptr) - globalx; + spry = readw(srcptr + 2) - globaly; + sprname = ram[srcptr + 5]; + sprattr = ram[srcptr + 4] | ram[srcptr + 6]; - uint32 spraddr = readl(srcptr + 7); - if(r_mem->read(spraddr)) { - int16 x, y; - for(int sprcnt=r_mem->read(spraddr++);sprcnt>0 && sprcount>0;sprcnt--, spraddr+=4) { - x = (int8)r_mem->read(spraddr + 1); - if(sprattr & 0x40) { - x = -x - ((r_mem->read(spraddr) & 0x20) ? 16 : 8); + uint32 spraddr = readl(srcptr + 7); + if(r_mem->read(spraddr)) { + int16 x, y; + for(int sprcnt = r_mem->read(spraddr++); sprcnt > 0 && sprcount > 0; sprcnt--, spraddr += 4) { + x = (int8)r_mem->read(spraddr + 1); + if(sprattr & 0x40) { + x = -x - ((r_mem->read(spraddr) & 0x20) ? 16 : 8); + } + x += sprx; + if(x >= -16 && x <= 272) { + y = (int8)r_mem->read(spraddr + 2); + if(sprattr & 0x80) { + y = -y - ((r_mem->read(spraddr) & 0x20) ? 16 : 8); } - x += sprx; - if(x >= -16 && x <= 272) { - y = (int8)r_mem->read(spraddr + 2); - if(sprattr & 0x80) { - y = -y - ((r_mem->read(spraddr) & 0x20) ? 16 : 8); - } - y += spry; - if(y >= -16 && y <= 224) { - ram[oamptr ] = (uint8)x; - ram[oamptr + 1] = (uint8)y; - ram[oamptr + 2] = sprname + r_mem->read(spraddr + 3); - ram[oamptr + 3] = sprattr ^ (r_mem->read(spraddr) & 0xc0); - ram[oamptr2] &= ~(3 << offset); - if(x & 0x100)ram[oamptr2] |= 1 << offset; - if(r_mem->read(spraddr) & 0x20)ram[oamptr2] |= 2 << offset; - oamptr += 4; - sprcount--; - offset = (offset + 2) & 6; - if(!offset)oamptr2++; - } + y += spry; + if(y >= -16 && y <= 224) { + ram[oamptr ] = (uint8)x; + ram[oamptr + 1] = (uint8)y; + ram[oamptr + 2] = sprname + r_mem->read(spraddr + 3); + ram[oamptr + 3] = sprattr ^ (r_mem->read(spraddr) & 0xc0); + ram[oamptr2] &= ~(3 << offset); + if(x & 0x100)ram[oamptr2] |= 1 << offset; + if(r_mem->read(spraddr) & 0x20)ram[oamptr2] |= 2 << offset; + oamptr += 4; + sprcount--; + offset = (offset + 2) & 6; + if(!offset)oamptr2++; } } - } else if(sprcount > 0) { - ram[oamptr ] = (uint8)sprx; - ram[oamptr + 1] = (uint8)spry; - ram[oamptr + 2] = sprname; - ram[oamptr + 3] = sprattr; - ram[oamptr2] &= ~(3 << offset); - if(sprx & 0x100)ram[oamptr2] |= 3 << offset; - else ram[oamptr2] |= 2 << offset; - oamptr += 4; - sprcount--; - offset = (offset + 2) & 6; - if(!offset)oamptr2++; } + } else if(sprcount > 0) { + ram[oamptr ] = (uint8)sprx; + ram[oamptr + 1] = (uint8)spry; + ram[oamptr + 2] = sprname; + ram[oamptr + 3] = sprattr; + ram[oamptr2] &= ~(3 << offset); + if(sprx & 0x100)ram[oamptr2] |= 3 << offset; + else ram[oamptr2] |= 2 << offset; + oamptr += 4; + sprcount--; + offset = (offset + 2) & 6; + if(!offset)oamptr2++; } } } @@ -178,13 +175,11 @@ uint32 waveptr = read(0x1f83); uint16 mask1 = 0xc0c0; uint16 mask2 = 0x3f3f; -int32 i, j; -int16 height, temp; - for(j = 0; j < 0x10; j++) { + for(int j = 0; j < 0x10; j++) { do { - height = -((int8)ram[waveptr + 0xb00]) - 16; - for(i = 0; i < 40; i++) { - temp = readw(destptr + wave_data[i]) & mask2; + int16 height = -((int8)read(waveptr + 0xb00)) - 16; + for(int i = 0; i < 40; i++) { + uint16 temp = readw(destptr + wave_data[i]) & mask2; if(height >= 0) { if(height < 8) { temp |= mask1 & readw(0xa00 + height * 2); @@ -202,22 +197,22 @@ int16 height, temp; destptr += 16; do { - height = -((int8)ram[waveptr + 0xb00]) - 16; - for(i = 0; i < 40; i++) { - temp = readw(destptr + wave_data[i]) & mask2; + int16 height = -((int8)read(waveptr + 0xb00)) - 16; + for(int i = 0; i < 40; i++) { + uint16 temp = readw(destptr + wave_data[i]) & mask2; if(height >= 0) { if(height < 8) { temp |= mask1 & readw(0xa10 + height * 2); } else { temp |= mask1 & 0xff00; } - writew(destptr + wave_data[i], temp); - height++; } - waveptr = (waveptr + 1) & 0x7f; - mask1 = (mask1 >> 2) | (mask1 << 6); - mask2 = (mask2 >> 2) | (mask2 << 6); + writew(destptr + wave_data[i], temp); + height++; } + waveptr = (waveptr + 1) & 0x7f; + mask1 = (mask1 >> 2) | (mask1 << 6); + mask2 = (mask2 >> 2) | (mask2 << 6); } while(mask1 != 0xc0c0); destptr += 16; } diff --git a/src/interface.h b/src/interface.h index d91e9bbc..01112989 100644 --- a/src/interface.h +++ b/src/interface.h @@ -20,11 +20,11 @@ #include "cpu/cpu.h" #include "cpu/scpu/scpu.h" -#include "cpu/bcpu/bcpu.h" +//#include "cpu/bcpu/bcpu.h" #include "apu/apu.h" #include "apu/sapu/sapu.h" -#include "apu/bapu/bapu.h" +//#include "apu/bapu/bapu.h" #include "dsp/dsp.h" #include "dsp/bdsp/bdsp.h" diff --git a/src/lib/libbase.h b/src/lib/libbase.h index 16b0b3aa..3c79a69d 100644 --- a/src/lib/libbase.h +++ b/src/lib/libbase.h @@ -70,7 +70,6 @@ typedef signed short int16; typedef signed long int32; typedef signed long long int64; - /***** * templates *****/ diff --git a/src/lib/libco_x86.asm b/src/lib/libco_x86.asm index dfb9a2a8..0db03ed3 100644 --- a/src/lib/libco_x86.asm +++ b/src/lib/libco_x86.asm @@ -1,9 +1,9 @@ ;***** -;libco_x86 : version 0.06 ~byuu (05/21/06) +;libco_x86 : version 0.07 ~byuu (08/15/06) ;cross-platform x86 implementation of libco ; ;context save/restore adheres to c/c++ ABI -;for x86 win32, linux and freebsd +;for x86 windows, linux and freebsd ; ;context saves esp+ebp+esi+edi+ebx ;context ignores eax+ecx+edx @@ -22,6 +22,7 @@ section .code ;***** ;linker-specific name decorations ;***** +%ifdef WIN32 %define malloc _malloc %define free _free @@ -33,6 +34,7 @@ section .code %define co_jump @co_jump@4 %define co_call @co_call@4 %define co_return @co_return@0 +%endif extern malloc extern free @@ -47,7 +49,7 @@ global co_call global co_return ;***** -;extern "C" void __fastcall co_init(); +;extern "C" void fastcall co_init(); ;***** align 16 @@ -65,7 +67,7 @@ co_init: ret ;***** -;extern "C" void __fastcall co_term(); +;extern "C" void fastcall co_term(); ;***** align 16 @@ -73,7 +75,7 @@ co_term: ret ;***** -;extern "C" thread_t __fastcall co_active(); +;extern "C" thread_t fastcall co_active(); ;return = eax ;***** @@ -87,7 +89,7 @@ co_active: ret ;***** -;extern "C" thread_t __fastcall co_create(thread_p coentry, unsigned int heapsize); +;extern "C" thread_t fastcall co_create(thread_p coentry, unsigned int heapsize); ;ecx = coentry ;edx = heapsize ;return = eax @@ -107,8 +109,12 @@ co_create: ;create heap space (stack + register storage) add edx,28 ;+8(esp+prev_call_context)+4(coentry)+16(stack_align) push ecx + push edx + push edx call malloc + add esp,4 + pop edx pop ecx @@ -130,7 +136,7 @@ co_create: ret ;return allocated memory block as thread handle ;***** -;extern "C" void __fastcall co_delete(thread_t cothread); +;extern "C" void fastcall co_delete(thread_t cothread); ;ecx = cothread ;***** @@ -142,7 +148,7 @@ co_delete: ret ;***** -;extern "C" void __fastcall co_jump(thread_t cothread); +;extern "C" void fastcall co_jump(thread_t cothread); ;ecx = cothread ;***** @@ -166,7 +172,7 @@ co_jump: ret ;***** -;extern "C" void __fastcall co_call(thread_t cothread); +;extern "C" void fastcall co_call(thread_t cothread); ;ecx = cothread ;***** @@ -191,7 +197,7 @@ co_call: ret ;***** -;extern "C" void __fastcall co_return(); +;extern "C" void fastcall co_return(); ;***** align 16 diff --git a/src/lib/libwin32_control.cpp b/src/lib/libwin32_control.cpp index b49d83a1..301d280e 100644 --- a/src/lib/libwin32_control.cpp +++ b/src/lib/libwin32_control.cpp @@ -34,10 +34,10 @@ void Control::Focus() { SetFocus(hwnd); } void Control::Enable(bool do_enable) { if(do_enable == true) { - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_DISABLED); + EnableWindow(hwnd, TRUE); state.ws &= ~WS_DISABLED; } else { - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_DISABLED); + EnableWindow(hwnd, FALSE); state.ws |= WS_DISABLED; } } diff --git a/src/memory/bmemory/bmemory.cpp b/src/memory/bmemory/bmemory.cpp index c6e47db6..4dcf07a4 100644 --- a/src/memory/bmemory/bmemory.cpp +++ b/src/memory/bmemory/bmemory.cpp @@ -66,14 +66,16 @@ uint region = read(0xffd9) & 0x7f; rom_loaded = true; //print cartridge info to debug console - +char t[256]; dprintf("* CRC32 : %0.8x", cartridge.info.crc32); dprintf("* Name : \"%s\"", cartridge.info.name); dprintf("* PCB : %s", cartridge.info.pcb); - dprintf("* ROM Size : %dmbit", cartridge.info.rom_size / 1024 / 1024 * 8); - dprintf("* RAM Size : %dkbit", cartridge.info.ram_size / 1024 * 8); + calc_size(t, cartridge.info.rom_size); + dprintf("* ROM Size : %s", t); + calc_size(t, cartridge.info.ram_size); + dprintf("* RAM Size : %s", t); dprintf("* Region : %s", (cartridge.info.region == Cartridge::NTSC) ? "NTSC" : "PAL"); -char t[256]; + strcpy(t, ""); if(cartridge.info.srtc)strcat(t, "S-RTC, "); if(cartridge.info.sdd1)strcat(t, "S-DD1, "); @@ -124,22 +126,23 @@ void bMemBus::unload_cart() { *****************************************/ uint8 bMemBus::memory_type(uint32 addr) { -uint8 bank; - bank = addr >> 16; +uint8 bank = addr >> 16; addr &= 0xffff; - if((bank >= 0x00 && bank <= 0x3f) || (bank >= 0x80 && bank <= 0xbf)) { + if((bank & 0x40) == 0x00) { + //$[00-3f|80-bf]:[0000-ffff] if(addr >= 0x0000 && addr <= 0x1fff)return TYPE_WRAM; if(addr >= 0x2000 && addr <= 0x5fff)return TYPE_MMIO; return TYPE_CART; } - if((bank >= 0x40 && bank <= 0x7d) || (bank >= 0xc0 && bank <= 0xff)) { - return TYPE_CART; + if((bank & 0xfe) == 0x7e) { + //$[7e-7f]:[0000-ffff] + return TYPE_WRAM; } -//(bank >= 0x7e && bank <= 0x7f) - return TYPE_WRAM; +//$[40-7d|c0-ff]:[0000-ffff] + return TYPE_CART; } uint8 bMemBus::read(uint32 addr) { @@ -209,7 +212,7 @@ void bMemBus::cart_map_system() { void bMemBus::power() { cart_write_protect(true); - memset(wram, 0xff, 0x020000); + memset(wram, 0x55, 0x020000); reset(); } diff --git a/src/memory/bmemory/bmemory.h b/src/memory/bmemory/bmemory.h index 20a985cd..33fda945 100644 --- a/src/memory/bmemory/bmemory.h +++ b/src/memory/bmemory/bmemory.h @@ -55,6 +55,15 @@ enum { TYPE_WRAM, TYPE_MMIO, TYPE_CART }; void power(); void reset(); +//load_cart() helper + void calc_size(char *t, uint size) { + if(size < 1024) { sprintf(t, "%dbit", size); return; } + size /= 1024; + if(size < 1024) { sprintf(t, "%dkbit", size); return; } + size /= 1024; + sprintf(t, "%dmbit", size); + } + bMemBus(); ~bMemBus(); }; diff --git a/src/memory/bmemory/bmemory_mapper_generic.cpp b/src/memory/bmemory/bmemory_mapper_generic.cpp index 13a597dd..824f06bb 100644 --- a/src/memory/bmemory/bmemory_mapper_generic.cpp +++ b/src/memory/bmemory/bmemory_mapper_generic.cpp @@ -15,22 +15,8 @@ * $[80-bf]:[2000-5fff] MMIO *****/ void bMemBus::cart_map_generic(uint type) { -uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size; - ROM_size = cartridge.info.rom_size; - SRAM_size = cartridge.info.ram_size; - -//calculate highest power of 2, which is the size of the first ROM chip - P0_size = 0x800000; - while(!(ROM_size & P0_size))P0_size >>= 1; - P1_size = ROM_size - P0_size; - - if(ROM_size == P0_size) { - //cart only contains one ROM chip - ROM_mask = (P0_size - 1); - } else { - //cart contains two ROM chips - ROM_mask = (P0_size + P0_size - 1); - } +uint rom_size = cartridge.info.rom_size; +uint ram_size = cartridge.info.ram_size; for(uint page = 0x0000; page <= 0xffff; page++) { if(memory_type(page << 8) != TYPE_CART)continue; @@ -51,10 +37,10 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size; //HiROM SRAM region //$[20-3f|a0-bf]:[6000-7fff] if((bank & 0x7f) >= 0x20 && (bank & 0x7f) <= 0x3f && (addr & 0xe000) == 0x6000) { - if(SRAM_size == 0)continue; + if(ram_size == 0)continue; addr = ((bank & 0x7f) - 0x20) * 0x2000 + ((addr & 0xffff) - 0x6000); - addr %= SRAM_size; + addr %= ram_size; page_handle[page] = cartridge.sram + addr; page_read [page] = &bMemBus::read_ram; page_write [page] = &bMemBus::write_ram; @@ -65,12 +51,12 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size; //$[70-7f|f0-ff]:[0000-7fff] //Note: WRAM is remapped over $[7e-7f]:[0000-ffff] if(bank >= 0x70 && bank <= 0x7f && (addr & 0x8000) == 0x0000) { - if(SRAM_size == 0)continue; + if(ram_size == 0)continue; if(type == Cartridge::LOROM || !(bank & 0x80)) { //HiROM maps $[f0-ff]:[0000-7fff] to ROM addr = ((bank & 0x7f) - 0x70) * 0x8000 + (addr & 0x7fff); - addr %= SRAM_size; + addr %= ram_size; page_handle[page] = cartridge.sram + addr; page_read [page] = &bMemBus::read_ram; page_write [page] = &bMemBus::write_ram; @@ -82,18 +68,12 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size; switch(type) { case Cartridge::LOROM: { - addr = (bank & 0x7f) * 0x8000 + (addr & 0x7fff); - addr &= ROM_mask; - if(addr >= P0_size) { - addr = P0_size + (addr & (P1_size - 1)); - } + addr = (bank & 0x7f) * 0x8000 + (addr & 0x7fff); + addr = mirror(rom_size, addr); } break; case Cartridge::HIROM: { - addr &= ROM_mask; - if(addr >= P0_size) { - addr = P0_size + (addr & (P1_size - 1)); - } + addr = mirror(rom_size, addr); } break; case Cartridge::EXLOROM: { @@ -103,13 +83,13 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size; } else { addr &= 0x3fffff; } - addr %= ROM_size; + addr = mirror(rom_size, addr); } break; case Cartridge::EXHIROM: { addr &= 0x3fffff; addr += (bank < 0x80) ? 0x400000 : 0x000000; - addr %= ROM_size; + addr = mirror(rom_size, addr); } break; } diff --git a/src/memory/bmemory/mapper/mapper.cpp b/src/memory/bmemory/mapper/mapper.cpp index d426c67d..03e6f837 100644 --- a/src/memory/bmemory/mapper/mapper.cpp +++ b/src/memory/bmemory/mapper/mapper.cpp @@ -1,3 +1,16 @@ +uint bMemBus::mirror(uint size, uint pos) { + if(size == 0)return 0; + if(pos < size)return pos; + +uint mask = 1 << 31; + while(!(pos & mask))mask >>= 1; + if(size <= (pos & mask)) { + return mirror(size, pos - mask); + } else { + return mask + mirror(size - mask, pos - mask); + } +} + void bMemBus::cart_map_range( uint mode, uint8 bank_lo, uint8 bank_hi, @@ -33,7 +46,7 @@ uint8 page_hi = (addr_hi >> 8) & 255; for(uint page = page_lo; page <= page_hi; page++) { uint16 n = (bank << 8) + page; - page_handle[n] = data + index; + page_handle[n] = data + mirror(size, index); if(size) { index = (index + 256) % size; } switch(type) { diff --git a/src/memory/bmemory/mapper/mapper.h b/src/memory/bmemory/mapper/mapper.h index 1c28f830..b7e28bbd 100644 --- a/src/memory/bmemory/mapper/mapper.h +++ b/src/memory/bmemory/mapper/mapper.h @@ -14,6 +14,7 @@ enum { MAP_OBC1, }; + uint mirror(uint size, uint pos); void cart_map_range(uint mode, uint8 bank_lo, uint8 bank_hi, uint16 addr_lo, uint16 addr_hi, uint type, uint offset = 0); #define mapper(name) void cart_map_##name() diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index 09db2b96..2fa6f27b 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -6,7 +6,6 @@ void bPPU::run() {} void bPPU::scanline() { line.y = r_cpu->vcounter(); - line.width = (regs.hires) ? 512 : 256; line.interlace = r_cpu->interlace(); line.interlace_field = r_cpu->interlace_field(); @@ -89,8 +88,8 @@ void bPPU::power() { region = snes->region(); //$2100 - regs.display_disabled = 0; - regs.display_brightness = 0; + regs.display_disabled = 1; + regs.display_brightness = 15; //$2101 regs.oam_basesize = 0; @@ -99,12 +98,12 @@ void bPPU::power() { //$2102-$2103 regs.oam_baseaddr = 0x0000; - regs.oam_addr = 0x0000; + regs.oam_addr = regs.oam_baseaddr << 1; regs.oam_priority = false; - regs.oam_firstsprite = 0x00; + regs.oam_firstsprite = 0; //$2104 - regs.oam_latchdata = 0x00; + regs.oam_latchdata = 0x00; //$2105 regs.bg_tilesize[BG1] = 0; @@ -113,7 +112,6 @@ void bPPU::power() { regs.bg_tilesize[BG4] = 0; regs.bg3_priority = 0; regs.bg_mode = 0; - regs.hires = false; //$2106 regs.mosaic_size = 0; @@ -205,10 +203,10 @@ void bPPU::power() { regs.window2_invert [COL] = false; //$2126-$2129 - regs.window1_left = 0; - regs.window1_right = 0; - regs.window2_left = 0; - regs.window2_right = 0; + regs.window1_left = 0x00; + regs.window1_right = 0x00; + regs.window2_left = 0x00; + regs.window2_right = 0x00; //$212a-$212b regs.window_mask[BG1] = 0; @@ -245,7 +243,8 @@ void bPPU::power() { //$2130 regs.color_mask = 0; regs.colorsub_mask = 0; - regs.addsub_mode = 0; + regs.addsub_mode = false; + regs.direct_color = false; //$2131 regs.color_mode = 0; @@ -304,7 +303,6 @@ void bPPU::reset() { regs.bg_y[2] = 0; regs.bg_y[3] = 0; - line.width = 256; clear_tiledata_cache(); } @@ -377,62 +375,25 @@ bPPU::bPPU() { init_tiledata_cache(); for(int l = 0; l < 16; l++) { - mosaic_table[l] = (uint16*)malloc(4096 * 2); for(int i = 0; i < 4096; i++) { mosaic_table[l][i] = (i / (l + 1)) * (l + 1); } } - light_table = (uint16*)malloc(16 * 32768 * 2); -uint16 *ptr = (uint16*)light_table; for(int l = 0; l < 16; l++) { int r, g, b; - #if 0 - double y, cb, cr; - double kr = 0.2126, kb = 0.0722, kg = (1.0 - kr - kb); - for(int i = 0; i < 32768; i++) { - if(l == 0) { *ptr++ = 0; continue; } - if(l == 15) { *ptr++ = i; continue; } - - r = (i ) & 31; - g = (i >> 5) & 31; - b = (i >> 10) & 31; - - y = (double)r * kr + (double)g * kg + (double)b * kb; - cb = ((double)b - y) / (2.0 - 2.0 * kb); - cr = ((double)r - y) / (2.0 - 2.0 * kr); - - y *= (double)l / 15.0; - cb *= (double)l / 15.0; - cr *= (double)l / 15.0; - - r = y + cr * (2.0 - 2.0 * kr); - b = y + cb * (2.0 - 2.0 * kb); - g = (y - b * kb - r * kr) / kg; - - r = minmax<0, 31>(r); - g = minmax<0, 31>(g); - b = minmax<0, 31>(b); - - *ptr++ = (r) | (g << 5) | (b << 10); - } - #else double m = (double)l / 15.0; for(int i = 0; i < 32768; i++) { - if(l == 0) { *ptr++ = 0; continue; } - if(l == 15) { *ptr++ = i; continue; } - r = (i ) & 31; g = (i >> 5) & 31; b = (i >> 10) & 31; - r = minmax<0, 31>((int)((double)r * m)); - g = minmax<0, 31>((int)((double)g * m)); - b = minmax<0, 31>((int)((double)b * m)); + r = minmax<0, 31>( (int)((double)r * m + 0.5) ); + g = minmax<0, 31>( (int)((double)g * m + 0.5) ); + b = minmax<0, 31>( (int)((double)b * m + 0.5) ); - *ptr++ = (r) | (g << 5) | (b << 10); + light_table[l][i] = (b << 10) | (g << 5) | (r); } - #endif } } @@ -440,10 +401,4 @@ bPPU::~bPPU() { SafeFree(vram); SafeFree(oam); SafeFree(cgram); - - for(int i = 0; i < 16; i++) { - SafeFree(mosaic_table[i]); - } - - SafeFree(light_table); } diff --git a/src/ppu/bppu/bppu.h b/src/ppu/bppu/bppu.h index 8a070b48..dc0faaf2 100644 --- a/src/ppu/bppu/bppu.h +++ b/src/ppu/bppu/bppu.h @@ -8,10 +8,9 @@ enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5, COL = 5 }; enum { SC_32x32 = 0, SC_64x32 = 1, SC_32x64 = 2, SC_64x64 = 3 }; struct { - uint32 y; - uint32 width; - bool interlace; - bool interlace_field; + uint y; + bool interlace; + bool interlace_field; } line; struct { @@ -43,7 +42,6 @@ struct { bool bg_tilesize[4]; bool bg3_priority; uint8 bg_mode; - bool hires; //$2106 uint8 mosaic_size; @@ -227,8 +225,8 @@ struct { #include "bppu_render.h" -uint16 *light_table; -uint16 *mosaic_table[16]; +uint16 light_table[16][32768]; +uint16 mosaic_table[16][4096]; void render_line(); void update_oam_status(); @@ -240,7 +238,7 @@ uint16 *mosaic_table[16]; void power(); void reset(); - bool scanline_is_hires() { return (regs.pseudo_hires || regs.hires); } + bool scanline_is_hires() { return (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6); } bPPU(); ~bPPU(); diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index 71d00d29..d2f54e0f 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -147,7 +147,6 @@ void bPPU::mmio_w2105(uint8 value) { regs.bg_tilesize[BG1] = bool(value & 0x10); regs.bg3_priority = bool(value & 0x08); regs.bg_mode = (value & 7); - regs.hires = (regs.bg_mode == 5 || regs.bg_mode == 6); } //MOSAIC diff --git a/src/ppu/bppu/bppu_render.cpp b/src/ppu/bppu/bppu_render.cpp index 9a85fd07..9e1ac8c0 100644 --- a/src/ppu/bppu/bppu_render.cpp +++ b/src/ppu/bppu/bppu_render.cpp @@ -45,7 +45,7 @@ Mode 0: -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 BG4B, BG3B, OAM0, BG4A, BG3A, OAM1, BG2B, BG1B, OAM2, BG2A, BG1A, OAM3 */ -inline void bPPU::render_line_mode0() { +void bPPU::render_line_mode0() { render_line_bg(BG1, COLORDEPTH_4, 8, 11); render_line_bg(BG2, COLORDEPTH_4, 7, 10); render_line_bg(BG3, COLORDEPTH_4, 2, 5); @@ -62,7 +62,7 @@ Mode 1 (pri=0): -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 BG3B, OAM0, BG3A, OAM1, BG2B, BG1B, OAM2, BG2A, BG1A, OAM3 */ -inline void bPPU::render_line_mode1() { +void bPPU::render_line_mode1() { if(regs.bg3_priority) { render_line_bg(BG1, COLORDEPTH_16, 5, 8); render_line_bg(BG2, COLORDEPTH_16, 4, 7); @@ -81,7 +81,7 @@ Mode 2: -> 1, 2, 3, 4, 5, 6, 7, 8 BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 */ -inline void bPPU::render_line_mode2() { +void bPPU::render_line_mode2() { render_line_bg(BG1, COLORDEPTH_16, 3, 7); render_line_bg(BG2, COLORDEPTH_16, 1, 5); render_line_oam(2, 4, 6, 8); @@ -92,7 +92,7 @@ Mode 3: -> 1, 2, 3, 4, 5, 6, 7, 8 BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 */ -inline void bPPU::render_line_mode3() { +void bPPU::render_line_mode3() { render_line_bg(BG1, COLORDEPTH_256, 3, 7); render_line_bg(BG2, COLORDEPTH_16, 1, 5); render_line_oam(2, 4, 6, 8); @@ -103,7 +103,7 @@ Mode 4: -> 1, 2, 3, 4, 5, 6, 7, 8 BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 */ -inline void bPPU::render_line_mode4() { +void bPPU::render_line_mode4() { render_line_bg(BG1, COLORDEPTH_256, 3, 7); render_line_bg(BG2, COLORDEPTH_4, 1, 5); render_line_oam(2, 4, 6, 8); @@ -114,7 +114,7 @@ Mode 5: -> 1, 2, 3, 4, 5, 6, 7, 8 BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3 */ -inline void bPPU::render_line_mode5() { +void bPPU::render_line_mode5() { render_line_bg(BG1, COLORDEPTH_16, 3, 7); render_line_bg(BG2, COLORDEPTH_4, 1, 5); render_line_oam(2, 4, 6, 8); @@ -125,7 +125,7 @@ Mode 6: -> 1, 2, 3, 4, 5, 6 OAM0, BG1B, OAM1, OAM2, BG1A, OAM3 */ -inline void bPPU::render_line_mode6() { +void bPPU::render_line_mode6() { render_line_bg(BG1, COLORDEPTH_16, 2, 5); render_line_oam(1, 3, 4, 6); } @@ -139,7 +139,7 @@ Mode 7 EXTBG: -> 1, 2, 3, 4, 5, 6, 7 BG2B, OAM0, BG1n, OAM1, BG2A, OAM2, OAM3 */ -inline void bPPU::render_line_mode7() { +void bPPU::render_line_mode7() { if(regs.mode7_extbg == false) { render_line_mode7(BG1, 2, 2); render_line_oam(1, 3, 4, 5); @@ -151,7 +151,7 @@ inline void bPPU::render_line_mode7() { } void bPPU::render_line() { - if(regs.display_disabled == true || regs.display_brightness == 0) { + if(regs.display_disabled == true) { memset(output + (line.y * 1024), 0, 1024); return; } diff --git a/src/ppu/bppu/bppu_render.h b/src/ppu/bppu/bppu_render.h index ac6bbeba..ff2f33af 100644 --- a/src/ppu/bppu/bppu_render.h +++ b/src/ppu/bppu/bppu_render.h @@ -88,12 +88,8 @@ void render_line_mode7(uint8 bg, uint8 pri0_pos, uint8 pri1_pos); inline uint16 addsub(uint32 x, uint32 y, bool halve); //bppu_render_line.cpp -enum { BLENDTYPE_BACK = 0, BLENDTYPE_MAIN = 1, BLENDTYPE_SUB = 2, BLENDTYPE_COMBINE = 3 }; - inline uint16 get_palette(uint8 index); inline uint16 get_direct_color(uint8 p, uint8 t); inline uint16 get_pixel_normal(uint32 x); inline uint16 get_pixel_swap(uint32 x); -inline uint16 get_pixel_lores(uint32 x); -inline uint16 get_pixel_hires(uint32 x); -inline void render_line_output(); +inline void render_line_output(); diff --git a/src/ppu/bppu/bppu_render_bg.cpp b/src/ppu/bppu/bppu_render_bg.cpp index 6e22a0e0..b2d0fb98 100644 --- a/src/ppu/bppu/bppu_render_bg.cpp +++ b/src/ppu/bppu/bppu_render_bg.cpp @@ -1,10 +1,13 @@ //called once at the start of every rendered scanline void bPPU::update_bg_info() { +uint hires = (regs.bg_mode == 5 || regs.bg_mode == 6); +uint width = (!hires) ? 256 : 512; + for(int bg = 0; bg < 4; bg++) { bg_info[bg].th = (regs.bg_tilesize[bg]) ? 4 : 3; - bg_info[bg].tw = (regs.hires) ? 4 : bg_info[bg].th; + bg_info[bg].tw = (hires) ? 4 : bg_info[bg].th; - bg_info[bg].mx = (bg_info[bg].th == 4) ? (line.width << 1) : line.width; + bg_info[bg].mx = (bg_info[bg].th == 4) ? (width << 1) : width; bg_info[bg].my = bg_info[bg].mx; if(regs.bg_scsize[bg] & 0x01)bg_info[bg].mx <<= 1; if(regs.bg_scsize[bg] & 0x02)bg_info[bg].my <<= 1; @@ -66,20 +69,22 @@ uint16 tile_mask = 0x0fff >> color_depth; //0x0fff, 0x07ff, 0x03ff //index is a tile number count to add to base tile number uint tiledata_index = regs.bg_tdaddr[bg] >> (4 + color_depth); -uint8 *bg_td = (uint8*)bg_tiledata[color_depth]; -uint8 *bg_td_state = (uint8*)bg_tiledata_state[color_depth]; +uint8 *bg_td = bg_tiledata[color_depth]; +uint8 *bg_td_state = bg_tiledata_state[color_depth]; uint8 tile_width = bg_info[bg].tw; uint8 tile_height = bg_info[bg].th; uint16 mask_x = bg_info[bg].mx; //screen width mask uint16 mask_y = bg_info[bg].my; //screen height mask -uint16 x = 0; uint16 y = regs.bg_y[bg]; uint16 hscroll = regs.bg_hofs[bg]; uint16 vscroll = regs.bg_vofs[bg]; - if(regs.hires) { +uint hires = (regs.bg_mode == 5 || regs.bg_mode == 6); +uint width = (!hires) ? 256 : 512; + + if(hires) { hscroll <<= 1; if(regs.interlace) { vscroll <<= 1; @@ -87,7 +92,7 @@ uint16 vscroll = regs.bg_vofs[bg]; } } -uint16 *mtable = (uint16*)mosaic_table[(regs.mosaic_enabled[bg]) ? regs.mosaic_size : 0]; +uint16 *mtable = mosaic_table[(regs.mosaic_enabled[bg]) ? regs.mosaic_size : 0]; uint16 hval, vval; uint16 t, tile_pri, tile_num; @@ -102,8 +107,8 @@ bool is_opt_mode = (config::ppu.opt_enable == true) && (regs.bg_mode == 2 || r uint8 *wt_main = window[bg].main; uint8 *wt_sub = window[bg].sub; -int32 prev_x = -1, prev_y = -1; - for(x = 0; x < line.width; x++) { +uint16 prev_x = 0xffff, prev_y = 0xffff; + for(uint16 x = 0; x < width; x++) { hoffset = mtable[x] + hscroll; voffset = y + vscroll; @@ -148,18 +153,18 @@ int32 prev_x = -1, prev_y = -1; t = bg_get_tile(bg, hoffset, voffset); - mirror_y = bool(t & 0x8000); - mirror_x = bool(t & 0x4000); + mirror_y = !!(t & 0x8000); + mirror_x = !!(t & 0x4000); tile_pri = (t & 0x2000) ? pri1_pos : pri0_pos; tile_num = t; if(tile_width == 4) { //16x16 horizontal tile mirroring - if(bool(hoffset & 8) != mirror_x)tile_num++; + if(!!(hoffset & 8) != mirror_x)tile_num++; } if(tile_height == 4) { //16x16 vertical tile mirroring - if(bool(voffset & 8) != mirror_y)tile_num += 16; + if(!!(voffset & 8) != mirror_y)tile_num += 16; } tile_num &= 0x03ff; @@ -176,7 +181,7 @@ int32 prev_x = -1, prev_y = -1; ypos = voffset & 7; if(mirror_y)ypos ^= 7; //invert y tile pos - tile_ptr = (uint8*)bg_td + (tile_num * 64) + (ypos * 8); + tile_ptr = bg_td + (tile_num * 64) + (ypos * 8); } xpos = hoffset & 7; @@ -189,7 +194,7 @@ int32 prev_x = -1, prev_y = -1; col = get_palette(col + pal_index); } - if(!regs.hires) { + if(!hires) { if(bg_enabled == true && !wt_main[x]) { setpixel_main(x); } if(bgsub_enabled == true && !wt_sub[x]) { setpixel_sub(x); } } else { diff --git a/src/ppu/bppu/bppu_render_cache.cpp b/src/ppu/bppu/bppu_render_cache.cpp index dbdacec4..40b07695 100644 --- a/src/ppu/bppu/bppu_render_cache.cpp +++ b/src/ppu/bppu/bppu_render_cache.cpp @@ -99,9 +99,9 @@ uint8 *dest; #undef render_bg_tile_line_4bpp #undef render_bg_tile_line_8bpp -inline void bPPU::clear_pixel_cache() { +void bPPU::clear_pixel_cache() { uint16 main = get_palette(0); -uint16 sub = (regs.pseudo_hires || regs.hires) ? main : regs.color_rgb; +uint16 sub = (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6) ? main : regs.color_rgb; uint32 i = 255; do { pixel_cache[i].src_main = main; diff --git a/src/ppu/bppu/bppu_render_line.cpp b/src/ppu/bppu/bppu_render_line.cpp index 860c8f3a..7aa902d5 100644 --- a/src/ppu/bppu/bppu_render_line.cpp +++ b/src/ppu/bppu/bppu_render_line.cpp @@ -81,33 +81,24 @@ uint8 bg_sub; return src_main; } -inline uint16 bPPU::get_pixel_lores(uint32 x) { - return get_pixel_normal(x); -} - -inline uint16 bPPU::get_pixel_hires(uint32 x) { - if(x & 1) { - return get_pixel_normal(x >> 1); - } else { - return get_pixel_swap(x >> 1); - } -} - inline void bPPU::render_line_output() { -uint16 *ptr = (uint16*)output + (line.y * 1024) + - ((line.interlace && line.interlace_field) ? 512 : 0); -uint16 *ltable = (uint16*)light_table + (regs.display_brightness << 15); - if(!regs.pseudo_hires && !regs.hires) { +uint16 *ptr = (uint16*)output + (line.y * 1024) + + ((line.interlace && line.interlace_field) ? 512 : 0); +uint16 *luma = light_table[regs.display_brightness]; + if(!regs.pseudo_hires && regs.bg_mode != 5 && regs.bg_mode != 6) { for(int x = 0; x < 256; x++) { - *ptr++ = *(ltable + get_pixel_lores(x)); + *ptr++ = luma[get_pixel_normal(x)]; } } else { uint32 curr, prev = 0; - for(int x = 0; x < 512; x++) { - curr = *(ltable + get_pixel_hires(x)); + for(int x = 0; x < 256; x++) { + curr = luma[get_pixel_swap(x)]; + *ptr++ = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1; + prev = curr; + + curr = luma[get_pixel_normal(x)]; *ptr++ = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1; prev = curr; - //*ptr++ = *(ltable + get_pixel_hires(x)); } } } diff --git a/src/snes/snes.h b/src/snes/snes.h index 9124e003..9363f6fb 100644 --- a/src/snes/snes.h +++ b/src/snes/snes.h @@ -19,7 +19,7 @@ enum { NTSC = 0, PAL = 1 }; //system functions virtual inline void run(); - virtual inline void runtoframe(); + virtual void runtoframe(); virtual void init(); virtual void term(); diff --git a/src/ui/Makefile b/src/ui/Makefile index 042de997..c2c8508a 100644 --- a/src/ui/Makefile +++ b/src/ui/Makefile @@ -1,90 +1,127 @@ -ifeq ($(PLATFORM),win-visualc) -CC = cl -CXX = cl +# bsnes makefile + +################################## +### platform-specific settings ### +################################## + +ifeq ($(PLATFORM),x-gcc-gtk) +OS = unix +CC = gcc +CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_GTK `pkg-config --cflags gtk+-2.0` `sdl-config --cflags` AS = nasm -RM = del -OBJ = obj -CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 -COMPILE = $(CC) $(CFLAGS) /c -ASSEMBLE = $(AS) -f win32 -LINK = -LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \ - d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib +ASFLAGS = -f elf +LIBS = `pkg-config --libs gtk+-2.0` `sdl-config --libs` +endif + +ifeq ($(PLATFORM),win-visualc) +OS = win +CC = cl +CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN +AS = nasm +ASFLAGS = -f win32 -DWIN32 +LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib endif ifeq ($(PLATFORM),win-visualc-wip) +OS = win CC = cl -CXX = cl +CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN AS = nasm -RM = del -OBJ = obj -CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 -COMPILE = $(CC) $(CFLAGS) /c -ASSEMBLE = $(AS) -f win32 +ASFLAGS = -f win32 -DWIN32 +LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib LINK = /link /LTCG -LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \ - d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib endif ifeq ($(PLATFORM),win-visualc-pgi) +OS = win CC = cl -CXX = cl +CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN AS = nasm -RM = del -OBJ = obj -CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 -COMPILE = $(CC) $(CFLAGS) /c -ASSEMBLE = $(AS) -f win32 +ASFLAGS = -f win32 -DWIN32 +LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT -LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \ - d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib endif ifeq ($(PLATFORM),win-visualc-pgo) +OS = win CC = cl -CXX = cl +CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN AS = nasm -RM = del -OBJ = obj -CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 -COMPILE = $(CC) $(CFLAGS) /c -ASSEMBLE = $(AS) -f win32 +ASFLAGS = -f win32 -DWIN32 +LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE -LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \ - d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib endif ifeq ($(PLATFORM),win-visualc-sdl) +OS = win CC = cl -CXX = cl +CFLAGS = /nologo /O2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_SDL AS = nasm -RM = del -OBJ = obj -CFLAGS = /nologo /O2 /DPLATFORM_SDL /DCOMPILER_VISUALC /DPROCESSOR_X86 -COMPILE = $(CC) $(CFLAGS) /c -ASSEMBLE = $(AS) -f win32 -LINK = -LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \ - sdlmain.lib sdl.lib +ASFLAGS = -f win32 -DWIN32 +LIBS = sdlmain.lib sdl.lib dsound.lib endif -OBJS = main.$(OBJ) \ - libco.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \ - reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) \ - memory.$(OBJ) bmemory.$(OBJ) \ - cpu.$(OBJ) scpu.$(OBJ) bcpu.$(OBJ) \ - apu.$(OBJ) sapu.$(OBJ) bapu.$(OBJ) \ - bdsp.$(OBJ) \ - ppu.$(OBJ) bppu.$(OBJ) \ - snes.$(OBJ) \ - srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ) -# adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \ -# inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \ -# jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ) +##################################### +### compiler / assembler switches ### +##################################### + +ifeq ($(CC),gcc) +OUT = -obsnes +CXX = g++ +OBJ = o +COBJFLAG = -c +endif + +ifeq ($(CC),cl) +OUT = /Febsnes.exe +CXX = cl +OBJ = obj +COBJFLAG = /c +endif + +ifeq ($(AS),nasm) +ASOBJFLAG = -o +endif + +################### +### OS switches ### +################### + +ifeq ($(OS),unix) +RM = rm -f +endif + +ifeq ($(OS),win) +RM = del +LIBS += kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib +endif + +######################### +### begin compilation ### +######################### + +OBJS = main.$(OBJ) \ + libco.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \ + reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) \ + memory.$(OBJ) bmemory.$(OBJ) \ + cpu.$(OBJ) scpu.$(OBJ) \ + apu.$(OBJ) sapu.$(OBJ) \ + bdsp.$(OBJ) \ + ppu.$(OBJ) bppu.$(OBJ) \ + snes.$(OBJ) \ + srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ) + #adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \ + #inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \ + #jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ) + +ifeq ($(OS),win) + ifeq ($(CC),cl) + OBJS += bsnes.res + endif +endif all: $(OBJS) - rc /r /fobsnes.res bsnes.rc - $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) $(LINK) + $(CXX) $(OUT) $(CFLAGS) $(OBJS) $(LIBS) $(LINK) # mt -nologo -manifest bsnes.exe.manifest -outputresource:bsnes.exe;1 clean: @@ -99,117 +136,120 @@ clean: ######################### ### platform-specific ### ######################### -main.$(OBJ): *.cpp *.h video/* audio/* input/* ../config/* win/* win/settings/* win/debugger/* - $(COMPILE) main.cpp +main.$(OBJ): *.cpp *.h video/* audio/* input/* ../config/* win/* win/settings/* win/debugger/* sdl/* + $(CXX) $(CFLAGS) $(COBJFLAG) main.cpp + +bsnes.res: bsnes.rc + rc /r /fobsnes.res bsnes.rc ################# ### libraries ### ################# libco.$(OBJ): ../lib/* - $(ASSEMBLE) -o libco.$(OBJ) ../lib/libco_x86.asm -# $(COMPILE) /Folibco.obj ../lib/libco_win32.cpp + $(AS) $(ASFLAGS) $(ASOBJFLAG) libco.$(OBJ) ../lib/libco_x86.asm +# $(CXX) $(CFLAGS) $(COBJFLAG) /Folibco.$(OBJ) ../lib/libco_win32.cpp libstring.$(OBJ): ../lib/*.cpp ../lib/*.h - $(COMPILE) ../lib/libstring.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../lib/libstring.cpp libconfig.$(OBJ): ../lib/*.cpp ../lib/*.h - $(COMPILE) ../lib/libconfig.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../lib/libconfig.cpp ############## ### memory ### ############## memory.$(OBJ): ../memory/memory.cpp ../memory/memory.h - $(COMPILE) ../memory/memory.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../memory/memory.cpp bmemory.$(OBJ): ../memory/bmemory/* ../memory/bmemory/mapper/* - $(COMPILE) ../memory/bmemory/bmemory.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../memory/bmemory/bmemory.cpp ########### ### cpu ### ########### cpu.$(OBJ): ../cpu/* - $(COMPILE) ../cpu/cpu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/cpu.cpp scpu.$(OBJ): ../cpu/scpu/* ../cpu/scpu/core/* ../cpu/scpu/dma/* ../cpu/scpu/memory/* ../cpu/scpu/mmio/* ../cpu/scpu/timing/* - $(COMPILE) ../cpu/scpu/scpu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/scpu/scpu.cpp bcpu.$(OBJ): ../cpu/bcpu/* - $(COMPILE) ../cpu/bcpu/bcpu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/bcpu/bcpu.cpp ########### ### apu ### ########### apu.$(OBJ): ../apu/* - $(COMPILE) ../apu/apu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../apu/apu.cpp sapu.$(OBJ): ../apu/sapu/* ../apu/sapu/core/* ../apu/sapu/memory/* ../apu/sapu/timing/* - $(COMPILE) ../apu/sapu/sapu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../apu/sapu/sapu.cpp bapu.$(OBJ): ../apu/bapu/* - $(COMPILE) ../apu/bapu/bapu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../apu/bapu/bapu.cpp ########### ### dsp ### ########### bdsp.$(OBJ): ../dsp/bdsp/* - $(COMPILE) ../dsp/bdsp/bdsp.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../dsp/bdsp/bdsp.cpp ########### ### ppu ### ########### ppu.$(OBJ): ../ppu/*.cpp ../ppu/*.h - $(COMPILE) ../ppu/ppu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../ppu/ppu.cpp bppu.$(OBJ): ../ppu/bppu/* - $(COMPILE) ../ppu/bppu/bppu.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../ppu/bppu/bppu.cpp ################# ### utilities ### ################# reader.$(OBJ): ../reader/*.cpp ../reader/*.h - $(COMPILE) ../reader/reader.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../reader/reader.cpp cart.$(OBJ): ../cart/*.cpp ../cart/*.h - $(COMPILE) ../cart/cart.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../cart/cart.cpp cheat.$(OBJ): ../cheat/*.cpp ../cheat/*.h - $(COMPILE) ../cheat/cheat.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../cheat/cheat.cpp ############ ### snes ### ############ snes.$(OBJ): ../snes/* ../snes/video/* ../snes/audio/* ../snes/input/* - $(COMPILE) ../snes/snes.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../snes/snes.cpp ##################### ### special chips ### ##################### srtc.$(OBJ): ../chip/srtc/* - $(COMPILE) ../chip/srtc/srtc.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../chip/srtc/srtc.cpp sdd1.$(OBJ): ../chip/sdd1/* - $(COMPILE) ../chip/sdd1/sdd1.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../chip/sdd1/sdd1.cpp c4.$(OBJ): ../chip/c4/* - $(COMPILE) ../chip/c4/c4.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../chip/c4/c4.cpp dsp1.$(OBJ): ../chip/dsp1/* - $(COMPILE) ../chip/dsp1/dsp1.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../chip/dsp1/dsp1.cpp dsp2.$(OBJ): ../chip/dsp2/* - $(COMPILE) ../chip/dsp2/dsp2.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../chip/dsp2/dsp2.cpp obc1.$(OBJ): ../chip/obc1/* - $(COMPILE) ../chip/obc1/obc1.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../chip/obc1/obc1.cpp ############ ### zlib ### ############ adler32.$(OBJ): ../reader/zlib/*.c ../reader/zlib/*.h - $(COMPILE) ../reader/zlib/*.c + $(CC) $(CFLAGS) $(COBJFLAG) ../reader/zlib/*.c ########### ### jma ### ########### jma.$(OBJ): ../reader/jma/*.cpp ../reader/jma/*.h - $(COMPILE) ../reader/jma/*.cpp + $(CXX) $(CFLAGS) $(COBJFLAG) ../reader/jma/*.cpp diff --git a/src/ui/audio/audio.h b/src/ui/audio/audio.h index 98033921..013a62fe 100644 --- a/src/ui/audio/audio.h +++ b/src/ui/audio/audio.h @@ -1,11 +1,11 @@ class Audio { public: uint frequency; - virtual void run(uint32 sample) = 0; - virtual void set_frequency(uint new_freq) = 0; - virtual void clear_audio() = 0; - virtual void init() = 0; - virtual void term() = 0; + virtual void run(uint32 sample) {} + virtual void set_frequency(uint new_freq) {} + virtual void clear_audio() {} + virtual void init() {} + virtual void term() {} Audio() : frequency(32000) {} } *uiAudio; diff --git a/src/ui/audio/dsound.cpp b/src/ui/audio/dsound.cpp index 9f4759ef..26649171 100644 --- a/src/ui/audio/dsound.cpp +++ b/src/ui/audio/dsound.cpp @@ -4,7 +4,7 @@ void AudioDS::run(uint32 sample) { if(data.buffer_pos >= data.samples_per_frame) { uint32 pos, size; void *buffer; - if(bool(config::system.regulate_speed) == true) { + if(config::system.regulate_speed == true) { for(;;) { dsb_b->GetCurrentPosition(&pos, 0); data.read_buffer = pos / data.buffer_size; @@ -62,7 +62,7 @@ void AudioDS::init() { data.buffer_size = data.samples_per_frame * 4; DirectSoundCreate(0, &ds, 0); - ds->SetCooperativeLevel(wMain.hwnd, DSSCL_PRIORITY); + ds->SetCooperativeLevel(hwnd, DSSCL_PRIORITY); memset(&dsbd, 0, sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); diff --git a/src/ui/audio/dsound.h b/src/ui/audio/dsound.h index 4618e395..60319723 100644 --- a/src/ui/audio/dsound.h +++ b/src/ui/audio/dsound.h @@ -2,6 +2,7 @@ class AudioDS : public Audio { public: +HWND hwnd; LPDIRECTSOUND ds; LPDIRECTSOUNDBUFFER dsb_p, dsb_b; DSBUFFERDESC dsbd; @@ -21,7 +22,8 @@ struct { void init(); void term(); - AudioDS() { + AudioDS(HWND handle = 0) { + hwnd = (handle) ? handle : GetDesktopWindow(); ds = 0; dsb_p = 0; dsb_b = 0; diff --git a/src/ui/cc.sh b/src/ui/cc.sh new file mode 100644 index 00000000..497e7718 --- /dev/null +++ b/src/ui/cc.sh @@ -0,0 +1,2 @@ +#!/bin/sh +gmake PLATFORM=x-gcc-gtk diff --git a/src/ui/clean.sh b/src/ui/clean.sh new file mode 100644 index 00000000..964e3d2e --- /dev/null +++ b/src/ui/clean.sh @@ -0,0 +1,2 @@ +#!/bin/sh +gmake PLATFORM=x-gcc-gtk clean diff --git a/src/ui/config.cpp b/src/ui/config.cpp index ae2372cc..91c2892c 100644 --- a/src/ui/config.cpp +++ b/src/ui/config.cpp @@ -1,9 +1,15 @@ namespace config { struct System { + static Setting video, audio, input; + static Setting regulate_speed; static Setting speed_slowest, speed_slow, speed_normal, speed_fast, speed_fastest; } system; +Setting System::video(&config_file, "system.video", "Video hardware interface", ""); +Setting System::audio(&config_file, "system.audio", "Audio hardware interface", ""); +Setting System::input(&config_file, "system.input", "Input hardware interface", ""); + Setting System::regulate_speed(&config_file, "system.regulate_speed", "Regulate speed to 60hz (NTSC) / 50hz (PAL)", true, Setting::TRUE_FALSE); Setting System::speed_slowest (&config_file, "system.speed_slowest", "Slowest speed setting (in hz)", 16000, Setting::DEC); Setting System::speed_slow (&config_file, "system.speed_slow", "Slow speed setting", 24000, Setting::DEC); @@ -12,19 +18,14 @@ Setting System::speed_fast (&config_file, "system.speed_fast", "Fast spee Setting System::speed_fastest (&config_file, "system.speed_fastest", "Fastest speed setting", 64000, Setting::DEC); struct Video { - static Setting renderer; - static Setting profile, fullscreen; + static Setting profile; static Setting profile_0, profile_1, profile_2, profile_3; static Setting profile_4, profile_5, profile_6, profile_7; - static Setting use_vram, triple_buffering; + static Setting use_vram; static Setting pscanline_intensity, iscanline_intensity; } video; -Setting Video::renderer(&config_file, "video.renderer", "Video renderer\n" - "\"dd\" (DirectDraw7 -- faster, less features)\n" - "\"d3d\" (Direct3D9 -- slower, more features)", "d3d"); Setting Video::profile(&config_file, "video.profile", "", 2, Setting::DEC); -Setting Video::fullscreen(0, "video.fullscreen", "", false, Setting::TRUE_FALSE); /* software_filter * hardware_filter @@ -45,18 +46,17 @@ Setting Video::profile_0(&config_file, "video.profile_0", "Video profile 0-7 con "Please use bsnes GUI configuration editor to modify video profile settings\n" "Format: software_filter;hardware_filter;video_standard;multiplier-1;correct_aspect_ratio;\n" " enable_scanlines;manual_render_size;render_width;render_height;\n" - " resolution_width;resolution_height;refresh_rate;triple_buffering" - "", "0;0;0;0;false;false;false;256;224;0;0;0;false"); -Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;1;false;false;false;512;448;0;0;0;false"); -Setting Video::profile_2(&config_file, "video.profile_2", "", "0;1;0;1;true;false;false;597;448;0;0;0;false"); -Setting Video::profile_3(&config_file, "video.profile_3", "", "0;1;0;2;true;false;false;896;672;0;0;0;false"); -Setting Video::profile_4(&config_file, "video.profile_4", "", "0;1;0;3;true;false;false;1195;896;0;0;0;false"); -Setting Video::profile_5(&config_file, "video.profile_5", "", "0;0;0;0;false;false;false;256;224;0;0;0;false"); -Setting Video::profile_6(&config_file, "video.profile_6", "", "0;0;0;0;false;false;false;256;224;0;0;0;false"); -Setting Video::profile_7(&config_file, "video.profile_7", "", "0;0;0;0;false;false;false;256;224;0;0;0;false"); + " fullscreen;triple_buffering;resolution_width;resolution_height;refresh_rate" + "", "0;0;0;0;false;false;false;256;224;false;false;0;0;0"); +Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;1;false;false;false;512;448;false;false;0;0;0"); +Setting Video::profile_2(&config_file, "video.profile_2", "", "0;1;0;1;true;false;false;597;448;false;false;0;0;0"); +Setting Video::profile_3(&config_file, "video.profile_3", "", "0;1;0;2;true;false;false;896;672;false;false;0;0;0"); +Setting Video::profile_4(&config_file, "video.profile_4", "", "0;1;0;3;true;false;false;1195;896;false;false;0;0;0"); +Setting Video::profile_5(&config_file, "video.profile_5", "", "0;1;0;1;true;false;false;597;448;true;false;0;0;0"); +Setting Video::profile_6(&config_file, "video.profile_6", "", "0;1;0;2;true;false;false;896;672;true;false;0;0;0"); +Setting Video::profile_7(&config_file, "video.profile_7", "", "0;1;0;3;true;false;false;1195;896;true;false;0;0;0"); Setting Video::use_vram(&config_file, "video.use_vram", "Use Video RAM instead of System RAM", true, Setting::TRUE_FALSE); -Setting Video::triple_buffering(&config_file, "video.triple_buffering", "Use triple buffering", false, Setting::TRUE_FALSE); Setting Video::pscanline_intensity(&config_file, "video.pscanline_intensity", "Progressive scanline intensity\n" "Value is percentage of intensity from 0 to 100", 30, Setting::DEC); diff --git a/src/ui/gtk/bsnes.cpp b/src/ui/gtk/bsnes.cpp new file mode 100644 index 00000000..0b7b801e --- /dev/null +++ b/src/ui/gtk/bsnes.cpp @@ -0,0 +1,48 @@ +void bSNES::set_status(uint32 new_status) { run_status = new_status; } +uint32 bSNES::get_status() { return run_status; } + +void bSNES::run() { + if(cartridge.loaded() == false)return; + + switch(run_status) { + case RUN: + SNES::runtoframe(); + return; + case STOP: + return; + } +} + +void bSNES::video_run() { + if(r_ppu->status.frames_updated == true) { + char t[256]; + r_ppu->status.frames_updated = false; + sprintf(t, "%s : %d fps", BSNES_TITLE, r_ppu->status.frames_executed); + gtk_window_set_title(GTK_WINDOW(main_window.window), t); + } + + uiVideo->redraw(); +} + +void bSNES::sound_run(uint32 data) { + uiAudio->run(data); +} + +uint16 *bSNES::video_lock(uint &pitch) { + return uiVideo->lock(pitch); +} + +void bSNES::video_unlock() { + uiVideo->unlock(); +} + +void bSNES::poll_input(uint8 type) { + uiInput->poll(type); +} + +bool bSNES::get_input_status(uint8 device, uint8 button) { + return uiInput->get_status(device, button); +} + +void bSNES::notify(uint32 message, uint32 param1, uint32 param2) {} +bSNES::bSNES() { run_status = STOP; } diff --git a/src/ui/gtk/bsnes.h b/src/ui/gtk/bsnes.h new file mode 100644 index 00000000..d54fe599 --- /dev/null +++ b/src/ui/gtk/bsnes.h @@ -0,0 +1,22 @@ +class bSNES : public SNES { +private: +uint32 run_status; + +public: +enum { STOP = 0, RUN }; + void run(); + void video_run(); + void sound_run(uint32 data); + + uint16 *video_lock(uint &pitch); + void video_unlock(); + + void set_status(uint32 status); + uint32 get_status(); + + void poll_input(uint8 type); + bool get_input_status(uint8 device, uint8 button); + + void notify(uint32 message, uint32 param1, uint32 param2); + bSNES(); +} *bsnes; diff --git a/src/ui/gtk/gtk_mainwindow.cpp b/src/ui/gtk/gtk_mainwindow.cpp new file mode 100644 index 00000000..0904a384 --- /dev/null +++ b/src/ui/gtk/gtk_mainwindow.cpp @@ -0,0 +1,192 @@ +const char about_text[4096] = "" + "bsnes -- version " BSNES_VERSION "\r\n" + "Author: byuu\r\n" + "Project began: October 14th, 2004\r\n" + "\r\n\r\n" + "Contributors:\r\n" + " anomie, blargg, DMV27, GIGO, kode54, Nach,\r\n" + " Overload, Richard Bannister, TRAC, zones"; + +struct MainWindow { + GtkWidget *window; + GtkWidget *box; + + GtkWidget *menu; + GtkWidget *menu_file, *menu_file_item; + GtkWidget *menu_file_loadrom; + GtkWidget *menu_file_unloadrom; + GtkWidget *menu_file_separator1; + GtkWidget *menu_file_reset; + GtkWidget *menu_file_power; + GtkWidget *menu_file_separator2; + GtkWidget *menu_file_quit; + GtkWidget *menu_help, *menu_help_item; + GtkWidget *menu_help_about; + + GdkColor render_bg; + GtkWidget *render; + + GtkWidget *fileopen; + GtkWidget *aboutbox; +} main_window; + +void init_main_window(); +void menu_main_window(const char *item); +void term_main_window(); +void load_rom(); +void cancel_load_rom(); +void unload_rom(); +void snes_reset(); +void snes_power(); +void close_aboutbox(); + +void init_main_window() { +MainWindow *w = &main_window; + +// +//create window +// + w->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(w->window), BSNES_TITLE); + gtk_window_set_resizable(GTK_WINDOW(w->window), false); + g_signal_connect(G_OBJECT(w->window), "destroy", G_CALLBACK(term_main_window), 0); + +// +//create widget container +// + w->box = gtk_vbox_new(false, 0); + gtk_container_add(GTK_CONTAINER(w->window), w->box); + gtk_widget_show(w->box); + +// +//create menu +// + w->menu = gtk_menu_bar_new(); + gtk_widget_show(w->menu); + + w->menu_file = gtk_menu_new(); + w->menu_file_item = gtk_menu_item_new_with_label("File"); + gtk_widget_show(w->menu_file_item); + +#define add_item(menu, item, label, id) \ + item = gtk_menu_item_new_with_label(label); \ + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); \ + g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(menu_main_window), (gpointer)id); \ + gtk_widget_show(item) +#define add_separator(menu, item) \ + item = gtk_separator_menu_item_new(); \ + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); \ + gtk_widget_show(item) + + add_item (w->menu_file, w->menu_file_loadrom, "Load ROM", "file.loadrom"); + add_item (w->menu_file, w->menu_file_unloadrom, "Unload ROM", "file.unloadrom"); + add_separator(w->menu_file, w->menu_file_separator1); + add_item (w->menu_file, w->menu_file_reset, "Reset", "file.reset"); + add_item (w->menu_file, w->menu_file_power, "Power (Hard Reset)", "file.power"); + add_separator(w->menu_file, w->menu_file_separator2); + add_item (w->menu_file, w->menu_file_quit, "Quit", "file.quit"); + + w->menu_help = gtk_menu_new(); + w->menu_help_item = gtk_menu_item_new_with_label("Help"); + gtk_widget_show(w->menu_help_item); + + add_item (w->menu_help, w->menu_help_about, "About", "help.about"); + + gtk_menu_item_set_submenu(GTK_MENU_ITEM(w->menu_file_item), w->menu_file); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(w->menu_help_item), w->menu_help); + + gtk_menu_bar_append(GTK_MENU_BAR(w->menu), w->menu_file_item); + gtk_menu_bar_append(GTK_MENU_BAR(w->menu), w->menu_help_item); + +#undef add_item +#undef add_separator + +// +//create render widget +// + w->render_bg.pixel = 0; + w->render_bg.red = 0; + w->render_bg.green = 0; + w->render_bg.blue = 0; + + w->render = gtk_drawing_area_new(); + gtk_widget_set_size_request(w->render, 256, 224); + gtk_widget_modify_bg(w->render, GTK_STATE_NORMAL, &w->render_bg); + gtk_widget_show(w->render); + +// +//pack widgets +// + gtk_box_pack_start(GTK_BOX(w->box), w->menu, false, false, 0); + gtk_box_pack_end(GTK_BOX(w->box), w->render, true, true, 0); + +// +//display window +// + gtk_widget_show(w->window); + + while(gtk_events_pending() == true) { + gtk_main_iteration_do(false); + } + +// +//initializations +// + w->fileopen = 0; +} + +void menu_main_window(const char *item) { +MainWindow *w = &main_window; + + if(!strcmp(item, "file.loadrom")) { + if(!w->fileopen) { + w->fileopen = gtk_file_selection_new("Load ROM"); + g_signal_connect_swapped(G_OBJECT(w->fileopen), "destroy", G_CALLBACK(cancel_load_rom), 0); + g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(w->fileopen)->ok_button), "clicked", G_CALLBACK(load_rom), 0); + g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(w->fileopen)->cancel_button), "clicked", G_CALLBACK(gtk_widget_destroy), (gpointer)w->fileopen); + } + gtk_widget_show(w->fileopen); + } else if(!strcmp(item, "file.unloadrom")) { + if(cartridge.loaded() == true) { cartridge.unload(); } + gtk_window_set_title(GTK_WINDOW(w->window), BSNES_TITLE); + gdk_window_invalidate_rect(GDK_WINDOW(w->render->window), 0, true); + } else if(!strcmp(item, "file.reset")) { + bsnes->reset(); + } else if(!strcmp(item, "file.power")) { + bsnes->power(); + } else if(!strcmp(item, "file.quit")) { + term_main_window(); + } else if(!strcmp(item, "help.about")) { + if(!w->aboutbox) { + w->aboutbox = gtk_message_dialog_new(0, (GtkDialogFlags)0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, about_text); + gtk_window_set_title(GTK_WINDOW(w->aboutbox), "About bsnes..."); + g_signal_connect_swapped(G_OBJECT(w->aboutbox), "destroy", G_CALLBACK(close_aboutbox), 0); + g_signal_connect_swapped(G_OBJECT(w->aboutbox), "response", G_CALLBACK(gtk_widget_destroy), (gpointer)w->aboutbox); + } + gtk_widget_show(w->aboutbox); + } +} + +void term_main_window() { + running = false; +} + +void load_rom() { + if(!main_window.fileopen)return; + +const char *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(main_window.fileopen)); + gtk_widget_hide(main_window.fileopen); + + if(cartridge.loaded() == true) { cartridge.unload(); } + if(cartridge.load(fn) == false) { return; } + + bsnes->power(); +} + +void cancel_load_rom() { + main_window.fileopen = 0; +} + +void close_aboutbox() { + main_window.aboutbox = 0; +} diff --git a/src/ui/gtk/main.cpp b/src/ui/gtk/main.cpp new file mode 100644 index 00000000..8efb73d6 --- /dev/null +++ b/src/ui/gtk/main.cpp @@ -0,0 +1,92 @@ +#include "main.h" + +#include "bsnes.h" +#include "gtk_mainwindow.cpp" +#include "bsnes.cpp" + +#include "../video/gtk.h" +#include "../video/gtk.cpp" +#include "../video/sdl.h" +#include "../video/sdl.cpp" + +#ifdef PLATFORM_WIN +#include "../audio/dsound.h" +#include "../audio/dsound.cpp" +#endif + +#include "../input/sdl.h" +#include "../input/sdl.cpp" + +void alert(char *s, ...) { +char str[4096]; +va_list args; + va_start(args, s); + vsprintf(str, s, args); + va_end(args); +#ifdef PLATFORM_WIN + MessageBox(0, str, "bsnes", MB_OK); +#else + fprintf(stdout, "%s\r\n", str); +#endif +} + +void dprintf(char *s, ...) { +char str[4096]; +va_list args; + va_start(args, s); + vsprintf(str, s, args); + va_end(args); + fprintf(stdout, "%s\r\n", str); +} + +#ifdef PLATFORM_WIN +int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { +int argc = __argc; +char **argv = __argv; +#else +int main(int argc, char *argv[]) { +#endif + gtk_init(&argc, &argv); + init_main_window(); + + config_file.load("bsnes.cfg"); + init_snes(); + uiVideo = new VideoSDL((void*)GDK_WINDOW_XWINDOW(main_window.render->window)); + uiAudio = new Audio(); + uiInput = new InputSDL((void*)GDK_WINDOW_XWINDOW(main_window.render->window)); + uiVideo->init(); + uiAudio->init(); + uiInput->init(); + +//will not run if cartridge not loaded + bsnes->set_status(bSNES::RUN); + + if(argc >= 2 && cartridge.load(argv[1]) == true) { + snes->power(); + } + + while(running == true) { + bsnes->run(); + + while(gtk_events_pending() == true) { + gtk_main_iteration_do(false); + } + + SDL_Event event; + while(SDL_PollEvent(&event)) { + } + } + +end: + config_file.save("bsnes.cfg"); + cartridge.unload(); + uiVideo->term(); + uiAudio->term(); + uiInput->term(); + SafeDelete(uiVideo); + SafeDelete(uiAudio); + SafeDelete(uiInput); + term_snes(); + + return 0; +} diff --git a/src/ui/gtk/main.h b/src/ui/gtk/main.h new file mode 100644 index 00000000..0cbb1e9e --- /dev/null +++ b/src/ui/gtk/main.h @@ -0,0 +1,4 @@ +#include +#include + +bool running = true; //set to false to terminate main program loop diff --git a/src/ui/input/input.h b/src/ui/input/input.h index 035932e9..44cff559 100644 --- a/src/ui/input/input.h +++ b/src/ui/input/input.h @@ -16,7 +16,7 @@ struct joypad { keymap key; //this must be initialized by init() bool8 keystate[4096]; - virtual void poll() = 0; + virtual void poll() {} virtual void poll(uint8 device); virtual void init(); virtual void term(); diff --git a/src/ui/input/sdl.cpp b/src/ui/input/sdl.cpp new file mode 100644 index 00000000..e5b9d361 --- /dev/null +++ b/src/ui/input/sdl.cpp @@ -0,0 +1,37 @@ +void InputSDL::poll(uint8 device) { + Input::poll(device); +} + +void InputSDL::poll() { + memcpy(keystate, SDL_GetKeyState(0), SDLK_LAST); +} + +void InputSDL::init() { + #include "sdl_keymap.cpp" + Input::init(); +} + +void InputSDL::term() { + Input::term(); +} + +InputSDL::InputSDL(void *handle) { + window = handle; + +// +//SDL hack +//Put SDL output into main GTK+ window, rather than +//creating a new window for SDL output. +// + if(window) { + char t[64]; + sprintf(t, "SDL_WINDOWID=%ld", window); + #if defined(COMPILER_GCC) + putenv(t); + #elif defined(COMPILER_VISUALC) + _putenv(t); + #endif + } +} + +InputSDL::~InputSDL() {} diff --git a/src/ui/input/sdl.h b/src/ui/input/sdl.h new file mode 100644 index 00000000..4c3aed8c --- /dev/null +++ b/src/ui/input/sdl.h @@ -0,0 +1,13 @@ +class InputSDL : public Input { +private: +void *window; + +public: + void poll(); + void poll(uint8 device); + void init(); + void term(); + + InputSDL(void *handle = 0); + ~InputSDL(); +}; diff --git a/src/ui/input/sdl_keymap.cpp b/src/ui/input/sdl_keymap.cpp new file mode 100644 index 00000000..d043abdf --- /dev/null +++ b/src/ui/input/sdl_keymap.cpp @@ -0,0 +1,37 @@ +key.esc = SDLK_ESCAPE; + +key.up = SDLK_UP; +key.down = SDLK_DOWN; +key.left = SDLK_LEFT; +key.right = SDLK_RIGHT; + +key.a = SDLK_a; +key.b = SDLK_b; +key.c = SDLK_c; +key.d = SDLK_d; +key.e = SDLK_e; +key.f = SDLK_f; +key.g = SDLK_g; +key.h = SDLK_h; +key.i = SDLK_i; +key.j = SDLK_j; +key.k = SDLK_k; +key.l = SDLK_l; +key.m = SDLK_m; +key.n = SDLK_n; +key.o = SDLK_o; +key.p = SDLK_p; +key.q = SDLK_q; +key.r = SDLK_r; +key.s = SDLK_s; +key.t = SDLK_t; +key.u = SDLK_u; +key.v = SDLK_v; +key.w = SDLK_w; +key.x = SDLK_x; +key.y = SDLK_y; +key.z = SDLK_z; + +key.lshift = SDLK_LSHIFT; +key.rshift = SDLK_RSHIFT; +key.enter = SDLK_RETURN; diff --git a/src/ui/main.cpp b/src/ui/main.cpp index a425c554..a8482157 100644 --- a/src/ui/main.cpp +++ b/src/ui/main.cpp @@ -22,9 +22,11 @@ void term_snes(); * platform abstraction layer *****/ -#if defined(PLATFORM_WIN) +#if defined(UI_WIN) #include "win/main.cpp" -#elif defined(PLATFORM_SDL) +#elif defined(UI_GTK) + #include "gtk/main.cpp" +#elif defined(UI_SDL) #include "sdl/main.cpp" #else #error "unsupported platform" diff --git a/src/ui/sdl/bsnes.cpp b/src/ui/sdl/bsnes.cpp index a532e33c..d5846f86 100644 --- a/src/ui/sdl/bsnes.cpp +++ b/src/ui/sdl/bsnes.cpp @@ -22,7 +22,9 @@ void bSNES::video_run() { render(); } -void bSNES::sound_run(uint32 data) {} +void bSNES::sound_run(uint32 data) { + uiAudio->run(data); +} uint16 *bSNES::video_lock(uint &pitch) { if(SDL_MUSTLOCK(screen)) { @@ -49,57 +51,12 @@ void bSNES::video_unlock() { *** Input functions *** ***********************/ -//It would appear that keystate does not need to be released -//after calling SDL_GetKeyState... doing so causes libSDL -//to throw error messages about a bad free call to stdout... void bSNES::poll_input(uint8 type) { -uint8 *keystate = SDL_GetKeyState(0); - joypad1.up = keystate[(int)config::input.joypad1.up]; - joypad1.down = keystate[(int)config::input.joypad1.down]; - joypad1.left = keystate[(int)config::input.joypad1.left]; - joypad1.right = keystate[(int)config::input.joypad1.right]; - joypad1.select = keystate[(int)config::input.joypad1.select]; - joypad1.start = keystate[(int)config::input.joypad1.start]; - joypad1.y = keystate[(int)config::input.joypad1.y]; - joypad1.b = keystate[(int)config::input.joypad1.b]; - joypad1.x = keystate[(int)config::input.joypad1.x]; - joypad1.a = keystate[(int)config::input.joypad1.a]; - joypad1.l = keystate[(int)config::input.joypad1.l]; - joypad1.r = keystate[(int)config::input.joypad1.r]; - -//It's impossible to hold both up+down, or left+right down -//at the same time on a directional pad; and besides, allowing -//this to happen causes glitches in many SNES games. - if(joypad1.up) joypad1.down = 0; - if(joypad1.left)joypad1.right = 0; + uiInput->poll(type); } bool bSNES::get_input_status(uint8 device, uint8 button) { - switch(device) { - case DEV_JOYPAD1: - switch(button) { - case JOYPAD_UP: return joypad1.up; - case JOYPAD_DOWN: return joypad1.down; - case JOYPAD_LEFT: return joypad1.left; - case JOYPAD_RIGHT: return joypad1.right; - case JOYPAD_A: return joypad1.a; - case JOYPAD_B: return joypad1.b; - case JOYPAD_X: return joypad1.x; - case JOYPAD_Y: return joypad1.y; - case JOYPAD_L: return joypad1.l; - case JOYPAD_R: return joypad1.r; - case JOYPAD_SELECT:return joypad1.select; - case JOYPAD_START: return joypad1.start; - } - break; - } - return 0; -} - -bJoypad::bJoypad() { - up = down = left = right = false; - a = b = x = y = false; - l = r = select = start = false; + return uiInput->get_status(device, button); } void bSNES::notify(uint32 message, uint32 param1, uint32 param2) {} diff --git a/src/ui/sdl/bsnes.h b/src/ui/sdl/bsnes.h index f2cf2863..e2c7b6c3 100644 --- a/src/ui/sdl/bsnes.h +++ b/src/ui/sdl/bsnes.h @@ -1,15 +1,6 @@ -class bJoypad { -public: -bool up, down, left, right; -bool a, b, x, y; -bool l, r, select, start; - bJoypad(); -}; - class bSNES : public SNES { private: uint32 run_status; -bJoypad joypad1, joypad2; public: enum { STOP = 0, RUN }; diff --git a/src/ui/sdl/main.cpp b/src/ui/sdl/main.cpp index 5a6ee7ad..b9414497 100644 --- a/src/ui/sdl/main.cpp +++ b/src/ui/sdl/main.cpp @@ -4,13 +4,21 @@ #include "render.cpp" #include "bsnes.cpp" +#ifdef PLATFORM_WIN +#include "../audio/dsound.h" +#include "../audio/dsound.cpp" +#endif + +#include "../input/sdl.h" +#include "../input/sdl.cpp" + void alert(char *s, ...) { char str[4096]; va_list args; va_start(args, s); vsprintf(str, s, args); va_end(args); -#ifdef _WIN32 +#ifdef PLATFORM_WIN MessageBox(0, str, "bsnes", MB_OK); #else fprintf(stdout, "%s\r\n", str); @@ -27,7 +35,7 @@ va_list args; } void center_window() { -#ifdef _WIN32 +#ifdef PLATFORM_WIN HWND hwnd; RECT rc; int x, y; @@ -39,13 +47,13 @@ int x, y; #endif } -#ifdef _WIN32 +#ifdef PLATFORM_WIN int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { int argc = __argc; char **argv = __argv; SDL_SetModuleHandle(GetModuleHandle(0)); #else -int SDL_main(int argc, char *argv[]) { +int main(int argc, char *argv[]) { #endif SDL_Event event; @@ -59,6 +67,15 @@ SDL_Event event; init_snes(); +#ifdef PLATFORM_WIN + uiAudio = new AudioDS(); +#else + uiAudio = new Audio(); +#endif + uiInput = new InputSDL(); + uiAudio->init(); + uiInput->init(); + if(cartridge.load(argv[1]) == false) { alert("Failed to load image. Usage: bsnes_sdl "); goto _end; @@ -73,7 +90,7 @@ SDL_Event event; screen_rect.h = 224; screen = SDL_SetVideoMode(screen_rect.w, screen_rect.h, 16, - SDL_HWSURFACE | ((config::video.fullscreen) ? SDL_FULLSCREEN : 0)); + SDL_HWSURFACE | (0 ? SDL_FULLSCREEN : 0)); if(!screen) { alert("Failed to initialize SDL"); goto _end; } backbuffer = SDL_CreateRGBSurface(SDL_HWSURFACE, 512, 448, 16, 0xf800, 0x07e0, 0x001f, 0x0000); @@ -115,6 +132,10 @@ int cursor_status; _end: config_file.save("bsnes_sdl.cfg"); cartridge.unload(); + uiAudio->term(); + uiInput->term(); + SafeDelete(uiAudio); + SafeDelete(uiInput); term_snes(); return 0; diff --git a/src/ui/sdl/main.h b/src/ui/sdl/main.h index e49a3bf2..ff22ab8a 100644 --- a/src/ui/sdl/main.h +++ b/src/ui/sdl/main.h @@ -1,4 +1,4 @@ -#ifdef _WIN32 +#ifdef PLATFORM_WIN #include #endif diff --git a/src/ui/video/d3d.cpp b/src/ui/video/d3d.cpp index 0f2d2f26..44fd8819 100644 --- a/src/ui/video/d3d.cpp +++ b/src/ui/video/d3d.cpp @@ -16,7 +16,7 @@ HRESULT hr; presentation.Flags = D3DPRESENTFLAG_VIDEO; presentation.SwapEffect = (settings.triple_buffering == true) ? D3DSWAPEFFECT_FLIP : D3DSWAPEFFECT_DISCARD; - presentation.hDeviceWindow = wMain.hwnd; + presentation.hDeviceWindow = hwnd; presentation.BackBufferCount = (settings.triple_buffering == true) ? 2 : 1; presentation.MultiSampleType = D3DMULTISAMPLE_NONE; presentation.MultiSampleQuality = 0; @@ -26,7 +26,7 @@ HRESULT hr; D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; presentation.FullScreen_RefreshRateInHz = settings.refresh_rate; - if(bool(config::video.fullscreen) == false) { + if(settings.fullscreen == false) { presentation.Windowed = true; presentation.BackBufferFormat = D3DFMT_UNKNOWN; presentation.BackBufferWidth = 0; @@ -38,7 +38,7 @@ HRESULT hr; presentation.BackBufferHeight = settings.resolution_height; } - hr = lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wMain.hwnd, + hr = lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentation, &device); if(hr != D3D_OK) { alert("Failed to create Direct3D9 device"); @@ -328,6 +328,8 @@ void VideoD3D::update() { } bool VideoD3D::capture_screenshot() { + if(!d3dx || !pD3DXSaveSurfaceToFileA) { return false; } + //fill both backbuffers with currently rendered image redraw(); redraw(); @@ -358,8 +360,7 @@ uint32 format; format = D3DXIFF_PNG; } - D3DXSaveSurfaceToFile(fn, static_cast(format), - temp_surface, NULL, NULL); + pD3DXSaveSurfaceToFileA(fn, format, temp_surface, NULL, NULL); temp_surface->Release(); return true; } @@ -379,7 +380,9 @@ void VideoD3D::term() { SafeRelease(lpd3d); } -VideoD3D::VideoD3D() { +VideoD3D::VideoD3D(HWND handle) { + hwnd = handle; + vertex_buffer = 0; surface = 0; texture = 0; @@ -388,6 +391,56 @@ VideoD3D::VideoD3D() { scanline[2] = 0; device = 0; lpd3d = 0; + +//Below code dynamically loads d3dx9 DLL at runtime +//to map D3DXSaveSurfaceToFileA function, used to +//capture screenshots. +// +//We are forced to link against this DLL dynamically +//because Microsoft decided that releasing 10+ versions +//of this DLL, all with different filenames, rather than +//making one DLL that was backwards-compatible. +// +//As a result of this blatant stupidity, if the application +//statically links against d3dx9.lib, then the application +//will then *require* the version of the d3dx9 DLL included +//with the DX9 SDK used to build said application. +// +//And since most end users generally have not downloaded +//every single bimonthly DX9 update, the application will +//completely fail to load when it cannot find said dx9 DLL. +// +//Hillariously enough, most (if not all) of the d3dx9 +//functionality appears to be backwards-compatible anyway, +//including this function. +// +//Therefore, as a workaround, we search through all possible +//DLL filenames. If a d3dx9 DLL is found, we dynamically map +//the D3DXSaveSurfaceToFileA function. Otherwise, screenshot +//support will fail silently. +// +//The benefit to this approach is that it allows all users +//to run this application, without explicitly requiring said +//d3dx9 DLL to run the application at all. + + d3dx = 0; + pD3DXSaveSurfaceToFileA = 0; + + for(int i = 0; i < 256; i++) { + char t[256]; + sprintf(t, "d3dx9_%d.dll", i); + d3dx = LoadLibrary(t); + if(d3dx) { break; } + } + if(!d3dx) { d3dx = LoadLibrary("d3dx9.dll"); } + if(!d3dx) { return; } + + pD3DXSaveSurfaceToFileA = (HRESULT(WINAPI*)(LPCSTR, DWORD, LPDIRECT3DSURFACE9, CONST PALETTEENTRY*, CONST RECT*)) + GetProcAddress(d3dx, "D3DXSaveSurfaceToFileA"); +} + +VideoD3D::~VideoD3D() { + if(d3dx)FreeLibrary(d3dx); } #undef D3DVERTEX diff --git a/src/ui/video/d3d.h b/src/ui/video/d3d.h index ec4bedb5..b353ac7a 100644 --- a/src/ui/video/d3d.h +++ b/src/ui/video/d3d.h @@ -1,8 +1,8 @@ #include -#include class VideoD3D : public Video { public: +HWND hwnd; LPDIRECT3D9 lpd3d; LPDIRECT3DDEVICE9 device; LPDIRECT3DVERTEXBUFFER9 vertex_buffer, *vertex_ptr; @@ -14,6 +14,10 @@ D3DCAPS9 d3dcaps; LPDIRECT3DTEXTURE9 texture, scanline[3]; LPDIRECT3DSURFACE9 surface, temp_surface; +HINSTANCE d3dx; +HRESULT (WINAPI *pD3DXSaveSurfaceToFileA)(LPCSTR, DWORD, LPDIRECT3DSURFACE9, CONST PALETTEENTRY*, CONST RECT*); +enum { D3DXIFF_BMP = 0, D3DXIFF_JPG = 1, D3DXIFF_PNG = 3 }; + struct d3dvertex { float x, y, z, rhw; //screen coords uint32 color; //diffuse color @@ -58,5 +62,6 @@ struct { void redraw(); void update(); - VideoD3D(); + VideoD3D(HWND handle = 0); + ~VideoD3D(); }; diff --git a/src/ui/video/ddraw.cpp b/src/ui/video/ddraw.cpp index 118c9782..f06e7b0d 100644 --- a/src/ui/video/ddraw.cpp +++ b/src/ui/video/ddraw.cpp @@ -7,17 +7,17 @@ bool VideoDD::update_video_profile() { lpdd->QueryInterface(IID_IDirectDraw7, (void**)&lpdd7); SafeRelease(lpdd); - if(bool(config::video.fullscreen) == true) { - lpdd7->SetCooperativeLevel(wMain.hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE); + if(settings.fullscreen == true) { + lpdd7->SetCooperativeLevel(hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE); lpdd7->SetDisplayMode(settings.resolution_width, settings.resolution_height, 16, settings.refresh_rate, 0); } else { - lpdd7->SetCooperativeLevel(wMain.hwnd, DDSCL_NORMAL); + lpdd7->SetCooperativeLevel(hwnd, DDSCL_NORMAL); } create_presentation(); lpdd7->CreateClipper(0, &clipper, 0); - clipper->SetHWnd(0, wMain.hwnd); + clipper->SetHWnd(0, hwnd); screen->SetClipper(clipper); create_render_target(); @@ -101,7 +101,7 @@ DDBLTFX fx; backbuffer->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx); surface->Blt (0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx); - if(bool(config::video.fullscreen) == true) { + if(settings.fullscreen == true) { screen->Flip(0, DDFLIP_WAIT); backbuffer->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx); screen->Flip(0, DDFLIP_WAIT); @@ -113,7 +113,7 @@ void VideoDD::create_presentation() { memset(&ddsd, 0, sizeof(DDSURFACEDESC2)); ddsd.dwSize = sizeof(DDSURFACEDESC2); - if(bool(config::video.fullscreen) == true) { + if(settings.fullscreen == true) { ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = (settings.triple_buffering == true) ? 2 : 1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; @@ -149,14 +149,14 @@ RECT rd, rs; snes->get_video_info(&vi); SetRect(&rs, 0, 0, vi.width, vi.height); - if(bool(config::video.fullscreen) == true) { + if(settings.fullscreen == true) { SetRect(&rd, settings.rx, settings.ry, settings.rx + settings.rw, settings.ry + settings.rh); backbuffer->Blt(&rd, surface, &rs, DDBLT_WAIT, 0); hr = screen->Flip(0, DDFLIP_WAIT); } else { POINT p = { 0, 0 }; - ClientToScreen(wMain.hwnd, &p); - GetClientRect(wMain.hwnd, &rd); + ClientToScreen(hwnd, &p); + GetClientRect(hwnd, &rd); OffsetRect(&rd, p.x, p.y); hr = screen->Blt(&rd, surface, &rs, DDBLT_WAIT, 0); @@ -184,7 +184,9 @@ void VideoDD::term() { SafeRelease(lpdd); } -VideoDD::VideoDD() { +VideoDD::VideoDD(HWND handle) { + hwnd = handle; + lpdd = 0; lpdd7 = 0; screen = 0; diff --git a/src/ui/video/ddraw.h b/src/ui/video/ddraw.h index 6e3a79c2..7b95154c 100644 --- a/src/ui/video/ddraw.h +++ b/src/ui/video/ddraw.h @@ -2,6 +2,7 @@ class VideoDD : public Video { private: +HWND hwnd; LPDIRECTDRAW lpdd; LPDIRECTDRAW7 lpdd7; LPDIRECTDRAWSURFACE7 screen, backbuffer; @@ -29,5 +30,5 @@ public: void redraw(); void update(); - VideoDD(); + VideoDD(HWND handle); }; diff --git a/src/ui/video/gtk.cpp b/src/ui/video/gtk.cpp new file mode 100644 index 00000000..9b22c72e --- /dev/null +++ b/src/ui/video/gtk.cpp @@ -0,0 +1,38 @@ +//WARNING: GTK video renderer is currently broken +//Renderer is displaying incorrect colors + +uint16 *VideoGTK::lock(uint &pitch) { + pitch = 512; + return (uint16*)buffer; +} + +void VideoGTK::unlock() {} + +void VideoGTK::redraw() { +uint8 *dest = gdkbuffer; +uint16 *src = buffer; +uint z = 256 * 224; + while(z--) { + uint32 p = *src++; + *(uint32*)dest = ((p & 0xf800) << 8) | ((p & 0x07e0) << 5) | ((p & 0x001f) << 3); + dest += 3; + } + gdk_draw_rgb_image(GDK_DRAWABLE(widget->window), gc, 0, 0, 256, 224, GDK_RGB_DITHER_NONE, gdkbuffer, 768); +} + +void VideoGTK::update() { redraw(); } + +void VideoGTK::init() { + buffer = (uint16*)malloc(256 * 224 * 2); + gdkbuffer = (uint8*) malloc(256 * 224 * 3); +} + +void VideoGTK::term() { + SafeFree(buffer); + SafeFree(gdkbuffer); +} + +VideoGTK::VideoGTK(GtkWidget *output_widget) { + widget = output_widget; + gc = gdk_gc_new(GDK_DRAWABLE(output_widget->window)); +} diff --git a/src/ui/video/gtk.h b/src/ui/video/gtk.h new file mode 100644 index 00000000..531369e2 --- /dev/null +++ b/src/ui/video/gtk.h @@ -0,0 +1,23 @@ +#include + +class VideoGTK : public Video { +private: +GtkWidget *widget; +GdkGC *gc; +uint16 *buffer; +uint8 *gdkbuffer; + +public: + uint16 *lock(uint &pitch); + void unlock(); + + uint screen_width() { return 1152; } + uint screen_height() { return 864; } + + void redraw(); + void update(); + void init(); + void term(); + + VideoGTK(GtkWidget *output_widget); +}; diff --git a/src/ui/video/sdl.cpp b/src/ui/video/sdl.cpp new file mode 100644 index 00000000..a8262e72 --- /dev/null +++ b/src/ui/video/sdl.cpp @@ -0,0 +1,45 @@ +uint16 *VideoSDL::lock(uint &pitch) { + if(SDL_MUSTLOCK(backbuffer)) { SDL_LockSurface(backbuffer); } + pitch = backbuffer->pitch; + return (uint16*)backbuffer->pixels; +} + +void VideoSDL::unlock() { + if(SDL_MUSTLOCK(backbuffer)) { SDL_UnlockSurface(backbuffer); } +} + +void VideoSDL::redraw() { + SDL_BlitSurface(backbuffer, 0, screen, 0); + SDL_UpdateRect(screen, 0, 0, 256, 224); +} + +void VideoSDL::update() { redraw(); } + +void VideoSDL::init() { + SDL_Init(SDL_INIT_VIDEO); + atexit(SDL_Quit); + + screen = SDL_SetVideoMode(256, 224, 16, SDL_HWSURFACE); + backbuffer = SDL_CreateRGBSurface(SDL_HWSURFACE, 512, 448, 16, 0xf800, 0x07e0, 0x001f, 0x0000); +} + +void VideoSDL::term() {} + +VideoSDL::VideoSDL(void *handle) { + window = handle; + +// +//SDL hack +//Put SDL output into main GTK+ window, rather than +//creating a new window for SDL output. +// + if(window) { + char t[64]; + sprintf(t, "SDL_WINDOWID=%ld", window); + #if defined(COMPILER_GCC) + putenv(t); + #elif defined(COMPILER_VISUALC) + _putenv(t); + #endif + } +} diff --git a/src/ui/video/sdl.h b/src/ui/video/sdl.h new file mode 100644 index 00000000..13461016 --- /dev/null +++ b/src/ui/video/sdl.h @@ -0,0 +1,21 @@ +#include + +class VideoSDL : public Video { +private: +void *window; +SDL_Surface *screen, *backbuffer; + +public: + uint16 *lock(uint &pitch); + void unlock(); + + uint screen_width() { return 1152; } + uint screen_height() { return 864; } + + void redraw(); + void update(); + void init(); + void term(); + + VideoSDL(void *handle = 0); +}; diff --git a/src/ui/video/video.cpp b/src/ui/video/video.cpp index b2e46775..ed0ec8d5 100644 --- a/src/ui/video/video.cpp +++ b/src/ui/video/video.cpp @@ -25,10 +25,11 @@ int i = 0; v->manual_render_size = strmatch(part[i++], "true"); v->render_width = strdec(part[i++]); v->render_height = strdec(part[i++]); + v->fullscreen = strmatch(part[i++], "true"); + v->triple_buffering = strmatch(part[i++], "true"); v->resolution_width = strdec(part[i++]); v->resolution_height = strdec(part[i++]); v->refresh_rate = strdec(part[i++]); - v->triple_buffering = strmatch(part[i++], "true"); if(v->render_width < 256)v->render_width = 256; if(v->render_height < 224)v->render_height = 224; @@ -50,10 +51,11 @@ VideoSettings *v = &video_settings[profile]; sprintf(part, "%s", v->manual_render_size ? "true" : "false"); strcat(line, part); strcat(line, ";"); sprintf(part, "%d", v->render_width); strcat(line, part); strcat(line, ";"); sprintf(part, "%d", v->render_height); strcat(line, part); strcat(line, ";"); + sprintf(part, "%s", v->fullscreen ? "true" : "false"); strcat(line, part); strcat(line, ";"); + sprintf(part, "%s", v->triple_buffering ? "true" : "false"); strcat(line, part); strcat(line, ";"); sprintf(part, "%d", v->resolution_width); strcat(line, part); strcat(line, ";"); sprintf(part, "%d", v->resolution_height); strcat(line, part); strcat(line, ";"); - sprintf(part, "%d", v->refresh_rate); strcat(line, part); strcat(line, ";"); - sprintf(part, "%s", v->triple_buffering ? "true" : "false"); strcat(line, part); + sprintf(part, "%d", v->refresh_rate); strcat(line, part); switch(profile) { case 0: config::video.profile_0.sset(strptr(line)); break; @@ -90,11 +92,13 @@ VideoSettings *v = &video_settings[profile]; } } - settings.hardware_filter = v->hardware_filter; + settings.fullscreen = v->fullscreen; settings.triple_buffering = v->triple_buffering; + + settings.hardware_filter = v->hardware_filter; settings.enable_scanlines = v->enable_scanlines; - if((bool)config::video.fullscreen == true) { + if(v->fullscreen == true) { settings.resolution_width = (v->resolution_width) ? v->resolution_width : screen_width(); settings.resolution_height = (v->resolution_height) ? v->resolution_height : screen_height(); settings.refresh_rate = v->refresh_rate; diff --git a/src/ui/video/video.h b/src/ui/video/video.h index 0369e6ed..f73c36d0 100644 --- a/src/ui/video/video.h +++ b/src/ui/video/video.h @@ -13,10 +13,11 @@ struct VideoSettings { bool manual_render_size; uint render_width; uint render_height; + bool fullscreen; + bool triple_buffering; uint resolution_width; uint resolution_height; uint refresh_rate; - bool triple_buffering; } video_settings[8]; void load_video_settings(uint profile); @@ -30,8 +31,10 @@ struct { uint render_width; uint render_height; - uint hardware_filter; + bool fullscreen; bool triple_buffering; + + uint hardware_filter; bool enable_scanlines; uint resolution_width; @@ -48,8 +51,8 @@ struct { virtual uint screen_width() = 0; virtual uint screen_height() = 0; - virtual bool update_video_profile() = 0; - virtual void clear_video() = 0; + virtual bool update_video_profile() { return true; } + virtual void clear_video() {} virtual void pause_enable() {} virtual void pause_disable() {} diff --git a/src/ui/win/debugger/debugger.cpp b/src/ui/win/debugger/debugger.cpp index be108aa2..646600ce 100644 --- a/src/ui/win/debugger/debugger.cpp +++ b/src/ui/win/debugger/debugger.cpp @@ -55,7 +55,7 @@ uint8 r = 0x00; r = r_mem->read(addr); } break; case SPCRAM: - r = r_apu->spcram_read(addr & 0xffff); + r = r_apu->spcram[addr & 0xffff]; break; case VRAM: r = r_ppu->vram_read(addr & 0xffff); @@ -80,7 +80,7 @@ void Debugger::write(uint8 mode, uint32 addr, uint8 data) { r_mem->cart_write_protect(true); break; case SPCRAM: - r_apu->spcram_write(addr & 0xffff, data); + r_apu->spcram[addr & 0xffff] = data; break; case VRAM: r_ppu->vram_write(addr & 0xffff, data); diff --git a/src/ui/win/debugger/ui_memory.cpp b/src/ui/win/debugger/ui_memory.cpp index d98155d6..fb1b8508 100644 --- a/src/ui/win/debugger/ui_memory.cpp +++ b/src/ui/win/debugger/ui_memory.cpp @@ -107,7 +107,7 @@ bool MemoryEditor::Event(EventInfo &info) { case EVENT_CHANGED: case EVENT_CLICKED: { - if(info.control == &Mode) { + if(info.control == &Mode && info.event_id == EVENT_CHANGED) { switch(Mode.GetSelection()) { case 0: status.mode = Debugger::DRAM; @@ -147,7 +147,7 @@ bool MemoryEditor::Event(EventInfo &info) { } Refresh(); - } else if(info.control == &Goto) { + } else if(info.control == &GotoAddr) { char t[16 + 1]; GotoAddr.GetText(t, 16); status.addr = strhex(t) & status.mask; @@ -247,9 +247,9 @@ void MemoryEditor::Setup() { SetWindowLong(View.hwnd, GWL_WNDPROC, (long)NSMemoryEditor::wndproc_new_memory_view); Mode.Create(this, "visible", 405, 5, 90, 200, "DRAM|ROM|SRAM|SPCRAM|VRAM|OAM|CGRAM"); - GotoAddr.Create(this, "visible|edge", 405, 26, 55, 20, "000000"); + GotoLabel.Create(this, "visible", 405, 26 + 4, 35, 15, "Goto:"); + GotoAddr.Create(this, "visible|edge", 440, 26, 55, 20, "000000"); GotoAddr.SetFont(global::fwf); - Goto.Create(this, "visible", 460, 26, 35, 20, "Go"); OffsetLabel.Create(this, "visible", 405, 50, 90, 15, "Offset: Data:"); Offset.Create(this, "visible|edge", 405, 65, 55, 20, "000000"); diff --git a/src/ui/win/debugger/ui_memory.h b/src/ui/win/debugger/ui_memory.h index 08595f24..6a15f387 100644 --- a/src/ui/win/debugger/ui_memory.h +++ b/src/ui/win/debugger/ui_memory.h @@ -12,8 +12,8 @@ class MemoryEditor : public Window { public: Editbox View; Combobox Mode; +Label GotoLabel; Editbox GotoAddr; -Button Goto; Label OffsetLabel; Editbox Offset; Editbox Data; diff --git a/src/ui/win/event.cpp b/src/ui/win/event.cpp index b9d57506..9d4848a6 100644 --- a/src/ui/win/event.cpp +++ b/src/ui/win/event.cpp @@ -30,7 +30,7 @@ void set_video_profile(uint profile) { uiVideo->update_video_settings(); string t; - if(bool(config::video.fullscreen) == true) { + if(uiVideo->settings.fullscreen == true) { strcpy(t, "topmost|popup"); if(wMain.Visible())strcat(t, "|visible"); wMain.HideMenu(); @@ -57,12 +57,21 @@ string t; } void toggle_fullscreen() { - config::video.fullscreen.toggle(); - if(bool(config::video.fullscreen) == true) { - wSettings.Hide(); - wAbout.Hide(); - debugger.deactivate(); +bool fullscreen = !uiVideo->settings.fullscreen; +uint i; + for(i = 0; i < 8; i++) { + if(video_settings[i].fullscreen == fullscreen)break; } + + if(i <= 7) { + if(fullscreen == true) { + wSettings.Hide(); + wAbout.Hide(); + debugger.deactivate(); + } + config::video.profile = i; + } + event::set_video_profile(config::video.profile); } diff --git a/src/ui/win/main.cpp b/src/ui/win/main.cpp index 4f396669..70610564 100644 --- a/src/ui/win/main.cpp +++ b/src/ui/win/main.cpp @@ -12,13 +12,17 @@ #include "../video/d3d.h" #include "../video/ddraw.h" +//#include "../video/sdl.h" #include "../audio/dsound.h" #include "../input/dinput.h" +//#include "../input/sdl.h" #include "../video/d3d.cpp" #include "../video/ddraw.cpp" +//#include "../video/sdl.cpp" #include "../audio/dsound.cpp" #include "../input/dinput.cpp" +//#include "../input/sdl.cpp" #include "event.cpp" #include "ui.cpp" diff --git a/src/ui/win/settings/ui_coloradjust.cpp b/src/ui/win/settings/ui_coloradjust.cpp index 2d406b92..d8f779d4 100644 --- a/src/ui/win/settings/ui_coloradjust.cpp +++ b/src/ui/win/settings/ui_coloradjust.cpp @@ -85,7 +85,7 @@ int x = 15, y = 30; GammaSlider.SetPos(int32(config::snes.gamma)); y += 75; - GammaRamp.Create(this, "visible", x, y, 475, 15, "Half Gamma Adjust (darkens image, helps prevent washed out colors)"); + GammaRamp.Create(this, "visible", x, y, 475, 15, "Half gamma adjust (darkens image, helps prevent washed out colors)"); GammaRamp.Check(config::snes.gamma_ramp); y += 15; Sepia.Create(this, "visible", x, y, 475, 15, "Sepia"); @@ -94,7 +94,7 @@ int x = 15, y = 30; Grayscale.Create(this, "visible", x, y, 475, 15, "Grayscale"); Grayscale.Check(config::snes.grayscale); y += 15; - Invert.Create(this, "visible", x, y, 475, 15, "Invert Colors"); + Invert.Create(this, "visible", x, y, 475, 15, "Invert colors"); Invert.Check(config::snes.invert); y += 20; diff --git a/src/ui/win/settings/ui_videosettings.cpp b/src/ui/win/settings/ui_videosettings.cpp index a387a4c0..edfcd809 100644 --- a/src/ui/win/settings/ui_videosettings.cpp +++ b/src/ui/win/settings/ui_videosettings.cpp @@ -9,6 +9,8 @@ bool VideoSettingsWindow::Event(EventInfo &info) { SaveSettings(VideoProfile.GetSelection()); } else if(info.control == &SelectProfile) { event::set_video_profile(VideoProfile.GetSelection()); + } else if(info.control == &ManualRenderSize || info.control == &Fullscreen) { + UpdateControls(); } } break; @@ -17,6 +19,19 @@ bool VideoSettingsWindow::Event(EventInfo &info) { return false; } +void VideoSettingsWindow::UpdateControls() { +bool r = ManualRenderSize.Checked(); + Multiplier.Enable(!r); + FixAspectRatio.Enable(!r); + RenderWidth.Enable(r); + RenderHeight.Enable(r); + + r = Fullscreen.Checked(); + FullResWidth.Enable(r); + FullResHeight.Enable(r); + FullResHz.Enable(r); +} + void VideoSettingsWindow::LoadSettings(uint profile) { load_video_settings(profile); @@ -30,10 +45,13 @@ VideoSettings *v = &video_settings[profile]; ManualRenderSize.Check(v->manual_render_size); RenderWidth.SetText("%d", v->render_width); RenderHeight.SetText("%d", v->render_height); + Fullscreen.Check(v->fullscreen); + TripleBuffering.Check(v->triple_buffering); FullResWidth.SetText("%d", v->resolution_width); FullResHeight.SetText("%d", v->resolution_height); FullResHz.SetText("%d", v->refresh_rate); - TripleBuffering.Check(v->triple_buffering); + + UpdateControls(); } void VideoSettingsWindow::SaveSettings(uint profile) { @@ -50,13 +68,14 @@ char t[64 + 1]; v->render_width = strdec(t); RenderHeight.GetText(t, 64); v->render_height = strdec(t); + v->fullscreen = Fullscreen.Checked(); + v->triple_buffering = TripleBuffering.Checked(); FullResWidth.GetText(t, 64); v->resolution_width = strdec(t); FullResHeight.GetText(t, 64); v->resolution_height = strdec(t); FullResHz.GetText(t, 64); v->refresh_rate = strdec(t); - v->triple_buffering = TripleBuffering.Checked(); //update config file line entry save_video_settings(profile); @@ -107,9 +126,8 @@ int x = 15, y = 30; FixAspectRatio.Create(this, "visible|auto", x, y, 460, 16, "Correct aspect ratio"); Scanlines.Create(this, "visible|auto", x, y + 15, 460, 15, "Enable hardware scanlines"); - ManualRenderSize.Create(this, "visible|auto", x, y + 30, 460, 15, - "Manual render screen size (ignores correct aspect ratio and multiplier settings)"); - y += 45; + ManualRenderSize.Create(this, "visible|auto", x, y + 30, 460, 15, "Manual render screen size"); + y += 47; RenderWidthLabel.Create(this, "visible", x, y + 3, 90, 15, "Render width:"); RenderWidth.Create(this, "visible|edge", x + 90, y, 50, 20); @@ -117,19 +135,20 @@ int x = 15, y = 30; RenderHeight.Create(this, "visible|edge", x + 240, y, 50, 20); y += 25; - Separator1.Create(this, "visible|sunken", x, y, 460, 3); + Separator2.Create(this, "visible|sunken", x, y, 460, 3); y += 8; + Fullscreen.Create(this, "visible|auto", x, y, 460, 16, "Fullscreen"); + TripleBuffering.Create(this, "visible|auto", x, y + 15, 460, 15, "Triple buffering (buggy, causes sound desync)"); + y += 35; + FullResWidthLabel.Create(this, "visible", x, y + 3, 90, 15, "Resolution width:"); FullResWidth.Create(this, "visible|edge", x + 90, y, 50, 20); FullResHeightLabel.Create(this, "visible", x + 150, y + 3, 90, 15, "Resolution height:"); FullResHeight.Create(this, "visible|edge", x + 240, y, 50, 20); FullResHzLabel.Create(this, "visible", x + 300, y + 3, 70, 15, "Refresh rate:"); FullResHz.Create(this, "visible|edge", x + 370, y, 50, 20); - y += 22; - - TripleBuffering.Create(this, "visible|auto", x, y, 460, 15, "Triple buffering (buggy, causes sound desync)"); - y += 20; + y += 27; ApplySettings.Create(this, "visible", x, y, 120, 25, "Apply settings"); SelectProfile.Create(this, "visible", x + 125, y, 120, 25, "Set as active profile"); diff --git a/src/ui/win/settings/ui_videosettings.h b/src/ui/win/settings/ui_videosettings.h index bb47a951..5c502971 100644 --- a/src/ui/win/settings/ui_videosettings.h +++ b/src/ui/win/settings/ui_videosettings.h @@ -20,17 +20,19 @@ Editbox RenderWidth; Label RenderHeightLabel; Editbox RenderHeight; Label Separator2; +Checkbox Fullscreen; +Checkbox TripleBuffering; Label FullResWidthLabel; Editbox FullResWidth; Label FullResHeightLabel; Editbox FullResHeight; Label FullResHzLabel; Editbox FullResHz; -Checkbox TripleBuffering; Button ApplySettings; Button SelectProfile; bool Event(EventInfo &info); + void UpdateControls(); void LoadSettings(uint profile); void SaveSettings(uint profile); diff --git a/src/ui/win/ui.cpp b/src/ui/win/ui.cpp index 0e963a72..d6d53709 100644 --- a/src/ui/win/ui.cpp +++ b/src/ui/win/ui.cpp @@ -31,13 +31,28 @@ long height; init_settings(); init_debugger(); - if(strmatch(config::video.renderer.sget(), "dd")) { - uiVideo = new VideoDD(); + if(!stricmp(config::system.video.sget(), "dd")) { + uiVideo = new VideoDD(wMain.hwnd); +//} else if(!stricmp(config::system.video.sget(), "sdl")) { +// uiVideo = new VideoSDL((void*)wMain.hwnd); } else { - uiVideo = new VideoD3D(); + uiVideo = new VideoD3D(wMain.hwnd); } - uiAudio = new AudioDS(); - uiInput = new InputDI(); + + if(!stricmp(config::system.audio.sget(), "none")) { + uiAudio = new Audio(); + } else { + uiAudio = new AudioDS(wMain.hwnd); + } + + if(!stricmp(config::system.input.sget(), "none")) { + uiInput = new Input(); +//} else if(!stricmp(config::system.input.sget(), "sdl")) { +// uiInput = new InputSDL((void*)wMain.hwnd); + } else { + uiInput = new InputDI(); + } + uiVideo->init(); uiAudio->init(); uiInput->init(); @@ -56,6 +71,7 @@ void term_ui() { uiVideo->term(); uiAudio->term(); uiInput->term(); + SafeDelete(uiVideo); SafeDelete(uiAudio); SafeDelete(uiInput); diff --git a/src/ui/win/ui_main.cpp b/src/ui/win/ui_main.cpp index f86f2891..5d59486d 100644 --- a/src/ui/win/ui_main.cpp +++ b/src/ui/win/ui_main.cpp @@ -45,12 +45,11 @@ bool MainWindow::Event(EventInfo &info) { uint id = info.control_id; bool ctrl = uiInput->keydown(key->lctrl) || uiInput->keydown(key->rctrl); if(id == key->esc) { - if(bool(config::video.fullscreen) == false) { + if(uiVideo->settings.fullscreen == false) { ShowMenu(!MenuVisible()); Center(); } else { - config::video.fullscreen = false; - event::set_video_profile(config::video.profile); + event::toggle_fullscreen(); } } else if(id == key->f11) { event::toggle_fullscreen();