From 5d4dc0630c54bb6c2219ef40a07e7f88aa7c7c29 Mon Sep 17 00:00:00 2001 From: goyuken Date: Sun, 17 Nov 2013 02:10:38 +0000 Subject: [PATCH] saturn: support input callback stuffs --- .../Consoles/Sega/Saturn/LibYabause.cs | 12 + .../Consoles/Sega/Saturn/Yabause.cs | 5 + output/dll/libyabause.dll | Bin 625152 -> 625152 bytes yabause/src/libyabause/yui.cpp | 985 +++++++++--------- yabause/src/smpc.c | 6 + yabause/src/yui.h | 8 + 6 files changed, 527 insertions(+), 489 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs index 88b8691a5c..e586dea834 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs @@ -73,6 +73,18 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void libyabause_hardreset(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void InputCallback(); + + /// + /// set a fcn to call every time input is read + /// + /// execxutes right before the input read. null to clear + [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void libyabause_setinputcallback(InputCallback cb); + + /// /// /// diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs index 3e705d5657..a9d278fa5a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs @@ -39,6 +39,8 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn LibYabause.CDInterface.ReadSectorFAD ReadSectorFADH; LibYabause.CDInterface.ReadAheadFAD ReadAheadFADH; + LibYabause.InputCallback InputCallbackH; + public Yabause(CoreComm CoreComm, DiscSystem.Disc CD, byte[] bios, bool GL = false) { CoreComm.RomStatusDetails = "Yeh"; @@ -46,6 +48,9 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn this.CD = CD; ResetCounters(); Init(bios, GL); + + InputCallbackH = new LibYabause.InputCallback(() => CoreComm.InputCallback.Call()); + LibYabause.libyabause_setinputcallback(InputCallbackH); } void Init(byte[] bios, bool GL = false) diff --git a/output/dll/libyabause.dll b/output/dll/libyabause.dll index fda79c723e3e5a954394fd15c51e4217c2fd5668..ae60f7529210664b5c773526b49116bbf1ed1b8f 100644 GIT binary patch delta 44515 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�u$ym+O?6Wps+a1c)=+ieUc5R|9it|w z6M=Oz)g*N*(CwV+e4u)1K7g?Rt&A3^1p&xZfL9l7Dv&BkTc9o0mIJHSY6rCp?GDh$ zp?m2*dU4=U89h*Mpm)><=+pExJzYPhp91n^=vVX`z#b&!Fn61IwU!hjl{ikEBd!v+ zh!SKKvL88`oCDgILLMg1I?2oA3(_B3x+chyPW7c0W3O(bj$?oRMb)Hvx)U7(mNbZ- zjUBd<-b3G^bHI*ljLNiT1~5~ZmDmOkn751equckvE{h> z$m(6VK8Vgy++>8}K`_U=;Epc5vk2dckK+6Dk$y+LlR9r!-CpD4UNL{2p z2*P2~TyWSGQlQ*I?u<-1T;7D7m?ozqE1r_iAunE$3n;&WmXuLLR7q{FPEc2<>yW?B zs2A1i>MPZ*g&`01)+TDxu$+dr0%>Q9wo}`$9np&FvhM7vPtfP;$@*G-qrOE?K?ZrD z=jgTwciTfOp@Z-ue2C&i08xerMEVFOc%+UFL^omphR#&Ff}C~cK1>zs0`{M^_KcV6{ahJ^fm@?PNHXEIhWGOPWlw!@iScW6(~Ux8VJe4R_xzn!X+ zJ+Zt*WBYCc6DcNBvVz%5P-ZAAlrm~n%+e}tt9C}i*~PfqN}WT53PfWh!yY)J1mY5L z7s>4l;UJBaQl7GL@0r6rbQ`sgI!|4twgA`9AOd$VhnT_aJnkX)iu=NO@I?Vx3||L8 z6~!CLv5r#Cb3%r21;=|ENBmI87Cs1tMSro3SV62Mwi4T0%x#)DTihm%_uTE2Et2@-aU^G|MXKIdWG8a*+r?uB& zEON41+kkC;RePg-M0AwUtLT(2>HR=567@Oy3VnnAyPm4w(jV&CR+zlkbM* z5SC=yBB%9XXR_y6f36Iwm}*=*?Dfsq-&L_D65pF2z#rgW@w`w^Xp9UoRyYfe?I%Ww z{lvi_%*(~I;#YB?G#d1Fy|hKTB^7c4p=Zc*F|ld#X~1v|C0SXo>{RxlHhHPY>OfGz z*XjqgDoEdGZJSn6ucfnkZy@0TbMGX$+e|^j9TmwW%)=fc4dm$w(U$B?b_WYuL@p

CZ&Y-9 z*lhL-TbGOA+5*pJa!a^WE`o2%cSnLWQ{r!^hhv0ZsLDnO>xC`CKH<7hRGcKv5EqLp z#FHop{6X^fA+pXPd3~1}$iw8P@<;IMs!9!IxD%Dwex(MsN|@ST9iom<*Qi_6n`#!$ zxto@t{i?0ewrhWASqPJFnv32PY_z*RSRbR$)(x=G-N*)K!9XAB&-D*xcqF;o!c19* zC`6P1js$~*a)d(Ehfoj$BpF7G#!Mv<%TQ^jpw@OCB2HKdBa?Ve{2)9?FVY{}vL-2! zb-^hk$qpctLjgSFQG723`20@pCDX|hWCjB1iA5M)s6r_7s)8OipdzSFR4~AY6Z2PN&^c#MP0zIzJ;mJrd}c9zEUooV!b^h>b1=FD!U324uJW|a~?jHAud(OS* zK65`fH@+b6!~64P_=VfQYj~Ew$X`V*`335Rhu{lD zq(*c-SqR-A@a-YceyCx9$J6U{^M8Opwo;y2M1 z2ty*nbdY*TLxC_eqk~knAJ-S&SwK#am68mIYar z>sqB-l-xs}kYBK^k~hdZQ6Jxsv*lMP%^WDq$}5}_tvHoSN)c4@i72OzTCn4-mDZYR zvDz?1(Pl7;TyTmSNJInlDf&V%hv#OzB)i*EoYod9Oq3-m6Ez5d&;imdi7u#D`T?dV z6Dx^z#39rrnZz?9hX_V=2xJ||GkqY;Od^xW)sSNjqnNl%-X$N91t@Q-1WJd>R4u9= z1ev7}WHurOn$sP?FNV@nz~DE4v;Tp7bdA1EKck&FVCiL;8Vn6)9tKw4)dHSGW*M^z z@bi;_-({XNg(19D2Fb3^b_5U&gxE5koy;x(son}QeT}`vK4x=4pNn%8CvhD>LuMdC zHgjp*S?)HX;u}{CoRGg`2#8CD^dz2wU-8iMl8VsACS&~w`NHW zl;nim21WOLkk4(vxXbbb5Q*YSP1Mhc$_C|~>JCoW0%>8Ob`#a;7mWqiYpwrb;#69o~4W;bv)aYsz}Gt6X~-I{fBCz>v(_5)JM3PbR z0Z_fWat>A~K&b}$-%ROhs6{>NJ1?oFwTfCT@VfcP&TB#5Ug__3TZX&s6b`%+V3vU* zn@CK9`uZod*8*f=RO+oj+Ij;ux09(@Fc->>G!zLrY(BLLY3M1C@Eheyo7}r0Jq$$6 zo5cUEoDlb+8Z`Q@8Vh6FOIK=S%;;3oddE^MFBzwyN z(2Z&UcIu*VN`N}FT24W@W}rsOf)eyYHfp|il;MXezbFaHEM0O}u4%H`HOn9e$NIz|&P^P;r z2Gi&QS$hm*kza`;#C^h@tV}in$c(d6&pL7klnPg>I@Q;B6X#jGvZ>crU`S-`NC3uU zfJGHRLwh!k9mCFHSF^j>lk62!axL4%!FwSO6i3Zlh7aU}_~xi`JE6Y4#((2!tLhjG z>S#xtm}&ch_!gQSi#oNFG)PL67D0VGBIQbj!ypx9>9!mQLO8YJq!Z$GGPxFdNTw0#4%8>dVD2F)=~ZjWKV}sQJ{rz$eo)} zbYF+KX(p&gGHun+hObG1@q7J%qED+Gj}j74>KR=}c}{W0G4T*-W{X^H_uV2Jzz9+FFi4Gw zNXxr*TOd9GbNHV^&?Nc{(Fa>&36Tq8ZzJ7E2bh`<5T-6fzoB4bS3vD=lbI+DvoWbb zlt8tmlA*+H#B`=myP(CTQ8~aGAE;`bok+wzQ0n(b)`*9Mb{f$a!~`>;Fh3YZU=(EG ziP%s(nfFXC^Nq2wZmfg#Vtv@=5Vgi&nvcQJI0sMT3Z$#stS48N&0L?i?-u15vy8tRG0oFvavKEwhi;|-3QuZn@lpjj@ z|I$(xsEgGTAjqH9_F88|We*UX{#u+C4|(^b_DK8pe1?NACtw$@`F90Hc-VH~hiYKR zZiIsfBU%yti7nv5yTFFih;-1LQ-mw&2a*#<#zR9LLngp^nhF*5FzTo0WGK8Q2Ggs6 z@YbWk5wWvCakHrxnBMnPE&$y|yU{$`2om68$Rj5VmwKKhjFjh&g2Db!Ir<>bT%qbz z)Q9Mkpa%Sp@-EE7mgZ`_%5wNuYzXq*8+BVcc???Zx%@@$O^w1HIRz^HkuqjKL@+%> z!te)ws)%)~168v*!*BbDFupJY#a0k62Attfk4Mg4r4@{a=!07q&Zi z)gX45#jF;xOD(Z-3%i5e%O1j-pTUY>!+JkJQS<}s+mt7DCp4cXTraLaHw1fbJ}RW0 z+&&18e<3@6h3;d|C*O_u7J%J2emFmdH~3%qH6R+t_%r+?{yG1K|HOaiy@jICBFYIt zm?pyF-*o_P&4t!NNAU1oLVqN6SHw9`@xY%55jVsPLqKpIap1(Rf|6_KWL0BsB6E;Fzh2Pp7s+ zT+5_hT5`7?;&vF_8A*Nx6za{)VdkroDS}1lYSoz|KxJpcF+7gx{Qxa(xao{>C%8)% zas3S0wji{R(x9(3LDhEf6@{uu{EBY7z$g4921&t42Sh$OGhX#_6m*V6U9uV}?su3=XW%ONK>G-g%gBKcQ+vw;;TTPn z_sJ)~0-k{wxhtjM|NP@7DjCQZH-KxIN(VK{Dq&Y3KC;TijYt!V?DHf z+9++hwiKnvVeNvJ3FV_KES9EDy&FW2xu|AW>$VsViw8_c*?0n_;!9{*zH|WSkxqxh z2pC9D1H(;)uJ6GVWQs!7uK-OygrPu@`XVW$Gbf?XJCF=UL)yBBS|ET6M-8xrdyQJq z3)2@0ojU^R_E0_%LAa6M#@9cNy6-+zi*Kj^0uXz&5QdoRggRiJUK_rO3tF(ugw`B-6^ z-3{4h5PzdkeNBg*VVW7+fDY&LO^ny9JLd~=s3Iybg=+xAq8-;2;1I`+KtNCArdt59 ziQ5bM{*2>4p(Lxyv(S#hU_Ug4K-`J%1&MeRMB=$WEeC!Bzm?D8v-x+()};hlXehKY zd<#Ol`b{vm{|Rv1r!aH9Ao*1jC2-p)sKMjK`Otv(z>&QPANIRg81^_N)rH*KTN)`% zmzGOgrNh!i=>g1B516La;2<=WqvSaF&-3MV(4$Vtf631w^%a2`Kq27UzyKJfOh<~^ zrW{r-Dp^jb{~l^-wH7S%4$%B2z|-8UrmI)grvQs$T2(ldky=mf7i|u*{a$dV`w(#o z>E)5}8-WH7K^eXbGVpQzrfDB0c-XSBk_8~!gc7xhHt-6a#C)vjLE<6`zpq3Q6h$K0 zjO<2^03l8$>D}aM@(z4W>R?<6D z=MMHP?Go0((&2~jD=@jK{3-qp|DONKdkJMB1B(`{bOG3of|0(!+5m@8@x2pbA^ygJ zTSiGn;o+WvLPymF_Uk0wmgHeeK`h4NaCZ@vNtG;0iBugrknuxRz6FldF06MNO14Zc zlwZmlKEpf%oetR_?oDfWHL>t&;s7%fV9*>v<4AiX{s6TlOye=?WOcrpoWBWn!63e& z(wYnzwFQLKD1b^lrgs`V-ZgM_|J441M%E23?O&F%;bBY0QRzfS!UvUvPR4+M-y+|l zFTsy`?1T@Q3lGu@{$nsIFcGd}GdLjK>128xe8pE#%4ww0ZOl!kC0l?iiGXef*KIf) zjVrLzM)C<(gn9|>ffJhrcj)0Qu+0-uH|;>(^bow-UkO6TMT{~6`+JRY3<8Z=8!gbz zfiF67Xel1HdbqhkI3SLcWPSn5$JG<^Yn4l=ze|8Xjz%r=SPEB$Bkr=5`jD0*wP=vd zC6I{m=5!BRIKsw-C`H5~OcXMVtcN~~rcgkC0bi*O8W?3U>v7aXYBq3nEwu@RaF5ec zV3)q;!pp1hnN%SD!RnnKrfB+G1$l# zFiQuRi0Pn)vMl=-Ki#TY-=Mk02a-!wF;ryCoQ*wg67n@jWP8QasL-y8x5QkaZFQ*@ zs+(}BE4n7eqK@}N;|nj>LtJ%*&^iS*+X?R zRQ7DkzPDv~*v4Q+$3yW-hWGxG=u6J0HdEywQQn3Rc9Ol!I=I3xS%2e>8eP3TEA(o{ zcR@U7^DCi=bU~`s(VE(e5Y7+(Qa7f=xDm6nnbRT7)*lJXc1rKj3YeXBk+sSANVSlm;1*E> z=HNHdM!8WAwCj|j{$d}2&hO^tq0C&1toR*D~;f)Oau-*Lx+-!T1d^(o@zzlgxVtPw&nPqB1CDTDw172 zbcZcPKUg;HUJtJ5Jq32CKfmiiFi0z`WfycYT`z) z_NStcDv4jfZ-roBN||R-@!F*tQl!*T>IH#pHk_J$NR-~_E7Ij?Y^pIZY)qP*Cf}2v z$dysGY3TKfRJ^oeT8Kt#jr2Ysbo*dRd~2lJ;_No_(q*IJV3sCBNDlZkk(`AtzO}Ft zPJ=UFCm(?~yCe9@U{*|@rZ+VZ{Uoy>9It{Im=5FMHf1Ega`-!GTBciqL-&DvLAeuYYWoVm={P;OM?Q{fzE3lXS37f6{nNMB{CvJ+YRyfQ_bjZ|Dw4+i5j zg^Q!;Zo97EhZYVoFTtLVrFNnTns(Zut#THz0&O`>(CN~F9_fTLZfbKh3azGS6j=a2 z{2mjIZjU)A^{%khIU1dP3%KoEeY8x>hm?9B_Vz|F$g2<|z2KoX1C(_XV<5iuLn@sh zPK7VI8Z&YLwzlMmF!jz zL`C48X}g92^TH9v5kS87pzR|p?Aw4v`a?d6UG*8ny{Hlj9uupq#-_cde1~8ctWs)S zwK2rH>FQjxW98;aPimg(srhN;L1JoZf>s|JqO;b^2`j+~SNo)P13J)K%@;*1 zj~d%Fwv&;L_F^Br(BGIikYu+7z=kS?PN*)hu%{8TQC=T}$CQJ{gfdVq!cka{CpVH? zvHb7RcH|BhiGrOy2&K~mEdD|i)my0@)CVdLB|r(fEIL-56kQuaX{+_YeE%P87Z9rE~8uJHp5qst_8als1 zJSxKav6axysj#it7`87vlAVZBY&&~_y~^H4IaYxqIgtx@LO1Wk^|ZQfrlRL&Ew>f5 z?ji08%%(i9Amqgm?5LUiV$iBB{C+-%|IFv{1;JTsLuBkEbVu<&)9RDigYMZ}t4u9| zTCEd04Ew@ON<=gqvswu6h=EcFob@oNIa1pYX%ymMqSP=6-7$xyyHbwy8SCFi9*b3; zhc&*2)eV3l9jdfe`YK5fQFbWli1wSxeI*CdtOL?)5ZV@KwZ0mmMjQ77J!R)xRA=t! zs|(RcbkjA~TA~%DH%!*W+HUOt@a_bfc77;9Y@%yl4Cs`dI#Y#dv%-4+4z zQ4=ysb95l@K-b!1K%NHQa5=dLF5xvamc2!jt`{7kDrh4Mqnc11sh(6kUzWF znWLg{dbnqK=L4+_>=wIi3(lu3QJo+FRUrUrUo;T!M`HejFe%86MOvB9E1t){8Y z6WI6{P_t)(6Fo)0!WYyq1<-eCwkwrIvrLC7C!*}#hT+7HcDx1+t%Y-Xwe_@#6XR%9KZM+7oyXD8(3 zzUVg|4#93BWaT7%DQuRXeU>Jy9Mk{QF9E6VT6) zQ9N;k1Pil))f(Rcj#6J@ATgBq1)UOR%jE(f`f9k}+bq5B2ukKl#5KZs3%1h>pwkEF zs~%RLr9T;nimMt)zzf%aSdGcnWP7p;+A9Z=Lr{Z_vqZtUaK%@X>*0!LAle_GiSi@( zR3Oy{rPu^?JAVELziOf1z7AxJj^NZLmtIM4f|PL(O^dhb`%d~3okyF^=V8nWW`r(-p;Vw0x?qon3l=VS*0yHKumRSUcR()7~R>I zL62Vn1-)TdwT6Z_5PrG=fAu{2v2Ws3J_!zldNU_Fx#o)-VVXN6KdCgjq&Go1J_)jU zAKqLkbohmVTSuTm?+(nH38l`IqI}Sf90CGT7xqOIB;!3OvM#^{udK>yEIKLD)FTjz zi)-xwZR?Tu4{FcQ>-$ynMiE{eeI#`NXLIxgh&87z6TcQi#tMf2t)Z>PiL`%+xQRxZ z0_e9b4+<9wH?Kc_NwEcP-hPO(r=hvu1iIzI!tg-$@&%m_0)dGH!o^_y;~~_}Lyw)= z0kIiU;6CaYbsc>V1?WP6xeDlZtxrclf**s98@rP!1}&>9il>%L7icjFaQl)`9~EI4 z=*XkldF%#u9~9WL03DN}zhXbb=l0_KP$@LvIzxMRLM~hj;-1Ex&#?8Oj) zgbpi15o-u%JW}X@4*PhRjArNOOiLeIjcd7dxe2(dB*~%~xL}FK`+WJf^4I54ykzw5acp&x34! zk-f0eEwR?|s125*1v3r8;|t{-N;v{~tsPpg63}>+q^5$$oC2KP2BCkUzEi&e%1nA% z22EI@ps0#g7ckZl^nS874~=@8HRn#`yd&Cau>9-VJvcfqfLWi>aN}XMgqPPV>!g+a zqV*nV1)qRM@D=)RaBB|eN6?CCHsAn|a(=QNlRgedqs?U4_6yP9oeDeigyjm~vhc-~ z^d^gu0YH};_}PSn{_Sulgq_yVk>}%QI_t=t`C;XUf-De;GZc!y0XDo9+43rsomVK= z3(`eUf?o#X`DArD+Zk`fP)VjdY~yOkoUGN*)Br@aCDhTLs29ee?Qa2c=~{>yyP=hu zRl{xOJ~+@@#+l3fKzl_=(4b(p7D{oMt&38k1=|L#7JWg77Q;_H1ex!VmGO!q`HGwl z-9M7+$i+h3TaEUcYiPd7=H9@McemP$gRG_-iWksc?1bXK7Tr?6Bjir=7ofR5u#mys zQv549g&NSFG+>nxuDOtC;&zRmFlDpRmWPtUC2}) zsTLTK`=ivF5*M0a%83UGBWHt``g*KbFL}79T*^wGV$EQXQ@LX8t{{f>CzH0yg delta 44331 zcmag{30%$T|NoDl>vdksiJD$%QB+DNLMRoX$WpSOitNN-vJB0PeJiq*BjVs!dBM zlU>eB>lVi?e(OoLnLJ2i?rJYnCsLdAF?~tu+WB}8O_`HU0&y?r@YCKl(k(*Tm^|$~IemRo z3%mBDn<>?9B>Belhh0t5%OqCmKvGTJs!S(~P3NnuCI6U4Ro%()`KB87lgL?<$-b04 zGL3VXp*tHcY90%gcBa=3C&|&h`Jc@t-1Wmt++0lqsObzrC$rRH@ z{ZP`=r1Q@t=S)ldhm)bESN;phHB&~NL1etiQfDl8a+8v1Y~8LTXYbLvuee5TqM&g+ zP+}~y*ekxWf`_`Q&$2r3kd{}1Vyya0RtK@*zRvQ<^q~GR^wy>Z!%6(!s(}v)X<+)N z;bxL;TG?m^xnYWFJcR5sZEHM=#F|`##*me!*+HMPvV(?`i>B_uL&$d155a>-XH&H% zUomSF#oA;h*=rgZGLmGNu7#u#vneq&iY(bnL&tKBPQBvQ3La5>A60Oh%~)B%m8Q^U zg~Z=f-fSQ_wYOLJG(s{>KQ)gcE+*F&dhW>{Q_B`!4*W_%Gq9hr>)VhEmJ_C7EoQMA zwus}N<$`7qau^tL zp`T^^-hB~^30HlYsY9!2Xw`{UOF4e2sc&mD>AbgER0<*An$p|kk$a|ywjEfj+m0ZO zO@G5ZY3kiBkZdx|X?H!9JmE1>c`_ry7!wg^usr=6dZNyz#~Up7nBL94(ta5_l;l{g zMzp#nrOUE0F~SgUIjF>wE8}fb@^PumXQg6yue4_>cF%^kfbfSHMeD(|w~tlLlWBifXzolatO{>s&rj1cGktu^KOud6a1h;DZhG5kDJ|8CZt0sl&)eLY01jx) zn>+K{T9JBY!+hSTC0*(5EdD9!M=vhqgGha9UC19MW9Z>Ud<&9JUo7IAbFcc*;B0<0 zG19f!{25X}lNa;;WEEYwnE!@MG;>S%zloSU zpJ@CF{%eO}&=!JI;G+5R3f|G4Jg4_I@v+>quW5ttc;8e5(iTO@*@|$9Ld2pdclkRe zJd+gRQ>+Mm@j4b5P^O5$Qbhz|tPmJ#6X7-yVT&1Mi`m{5GnU!<6-9Mna!^r}fyt13 zdhR&U#Xm+w>fkBE0N>M~;wj#pwY48?4IQCG=|Je*25NVaUX?7{i@KHpdK@maO ziU`eBM0hFvehXhOHDxo4Dd#J~C1?xN+;bG+S*8dd!&Vk(8<`l}$iyfk({B)3sEkI8 zZERv}V-sT=8!Q)W_+o5h6QhhxQH(M)MKKj46Tg-B(U&PD$UfUxbe9xGxECwJQ=^Q5 zPZV9gm2a5ZXDsV5HhQ{#gVIl12M#D)&qlN;%HC%;Qb);Aif~C$gnO(EcPvxTGk;-PR^goA9v-eHv_4F*mZ6IDt8|>o(pa)z(DY zME$=zLuqMcyVYJ$`$X*_wZGJo)N<8YxUiYs4^?C(p~LNqAw%-f@T`uS=XzA;mp#1P z>jz#g1|9eE@^LV1AK1^!yC7>&yYKm%WD33iJs(Q;QTOe4Cx#J$*M2Jl9{J=LQc4n8oyd5E( zsrNpj-yJmj6!>HrD%$Nz5(-C?6x7@2BDjeh| zlWsKiAU~M=N$(xxm)e~^!^?^2FAJSK00Q{+-+5ud!HUU#D_U|t;&>_ zio3_2`D;?{Fke?PIWVOm4LZy>lcHs&ETUr$^UZ6yIx*##;-0C-{3d7SI=C|T20e9{ z50L&=lu7j8!+a~3Gj7b1P@TC)-I?3Wi*`7|*H5kK!L;#;YxQLQSBm>gad#@=6Kk;W zHZ_@BRSCbQxR(_7jN%q5?oq{+yjV=)&D@r7F=H2>;$;fffQ?`q*bP$m!#NBJKoPhA z-T`e9FWUh};0l_7NYD<92UEdJupb--1)vCA09V0H@D^~Vd07YAfDWK5NC166>S;bk zo&%2&ECv*;0UNo-iN0#K#aaefed+0g0o5 zm-$hc#w#u(a4o%inXga2p;fN%ZAdWfa)qzWefBd=xq_*ApMHx_Zv8FV^$PDxW|*y4 z_}*Icmg{_LEls@68_W-H@;gORmo6>kuM-0ub&tQoJ+`B*f8{%qwPxe5JV&_4PUc1T z`7kXRYCidpudQ`%!`Y4!+rBy^zn`Tsef^04mMo>q{@`zrBlOG1*za^V-+Ii~bR_BK z7q9tE+ICBpXf%n&63cwZf>OC^NkZ}@y-x0Bbv+{MaPoEOSC~$?M9WCn4Ii6io5euy zyyv%*O*GTW`(S(Zy%j50H+t8~dsPWqtkLvB?g5LJiGp`c9aLK;i52-Pne?*!y}z|^ zj#R0=$X1&gi>M1H_>*Vm7M#HA$lvDHRfJ$CQ+8)JI-#a;i{?JzeW<}x;770({~$I7 znqz6(W%=3my#E4{8hjFvkF6(SuwAAtNzy1K#(x1h4U`y3$znyOk1O(^M?HmjwiTt- zylfux7hVD()eU_``54RMN9G*z>4&r|TB^4i|0i!@pOVm6OX#O(kut-MpkyU}rmN>@ zC;3ns3w1bx8nd+KDn5d{HdSd#8cu%4(stXb@eDOr0+Je6)JqM>ANyb1Y%#|E*ES^} zr}2MnQv%YSe3D1n9woq_meNXdEGhVtDEVJ~TFh6U789%%L+|9_pvs1IxQr;BDdRe0nSi?{v`1Z`yO_Tg{vf)ouFyjaviY?E zLZ84=B@Uddwofh2&#czN`9m?HrEq?fhl%nb1Dt~?aPqRv836)EniWIIj6BlTNj_G_ zykXO3VK{w;!|Qr`7KSs4c^#&;#c-yvPD-Zd>kADU8d6wR zw^>#xn01+9t65gcByoMqvSP6_9agifG*sUJZ4WX}ZXmR0r_vt-p%zo;h7dV4nTa%d z6rx5pvOSgy=f`3=hsxj_l)pj~f@p(Ag0&f&;hB-s+M(FoiLBTNTm!4cu1>EkHliJh zO__ui^e;pUG<0xdVNSx=PEb~%eKbEFtrb%#XtWMSD#kjMDXPxo zLYCT-M9^KqLeG{R*Q!bG!Nh3RN|0Ye%8*QFvJN88s9zxpW4?+})tTG?SaSCFQ5K=C>CE4Rn)Fr^!Qb!BCXFWhDWWo}w6;+dlIcwP zw5GK~1U+^%9YTcBbw+H#6$o~V*;8O+{0>$EEVzo!P+8=2oFX1ermnh6-5& zmrk%+Nqc>`#dyeSH9Cy`wW_SB(|$mX4k;Dtmr#}P_UxiwiH}uY@%&Je*gTUPs-B!^ z)nhgf4-@JUGJ<9|6_SXKK5Z&2#R+q6Ga(EY<42kab;!5$elx*8l^=rD;hoiL9faFX zUGxDV=Ph^ka!R9&?e#K(TnurRZbz)vtR8yz_^kGNA478Q0G(`Uao1|a8Ej7e_#DKN z<7|yEzPAMLQMQqYFSGdWhU6p`zlsvyeonsQoY5%HmPV&E)nd)1i^2uhh9$qSJe4>t zD&koDhJTu03d?T?y&Nt?1&>ma1hQ-|yhpY@^e)E!DB1F>J7JfysDW(A>Y{g#OHO0S zTGF=7g|-dL@34}TWPMpO7R#b-YfHkKqck_!lO;J%_cRxZaWi993&D>hm^Zf&9&2^F zE&{tbU@@<3CDbBb=Q{~BF>8>OxrkmRcdON*A(L4?G zY8zn>38!<~3UTCXdZVonM8;EHJ7I;#&8~v%*-encz!)HaWk5p<+6k_-xSb%Zu^I$&)PJs*HC-5`)6+8lEv|f9mTa%Of*`Q-9W4qh<^%mQxC$m#ULZan| zTu!6-vlc2Lah4pqt-bJ+45X`~1rP4}E_xtZ=)k@Cj#{III^5OoXx$jh?`3pojL-+2 z^<#|igmgCV>L9G-Xb09K&6qP0{X}UeA%}j^NvKBN&?%h+FWQUwUz+=N7OE4wQIVYH zWl7EaLi7AC!ZO0i{its@p&zc)rgsy9m2>@`ZbB3254s7BNhx*dF0>?3Wk?L2)~gs^Sc4UA}+PX z2ths#Zh(J)$4KM?nt<-$ORyE30`Gz6C_!!jT7X#43k(P2z+O-WgwcZR2J|2Zv;-Z% zATSxs2dlv5(E_bHSm;ruM~ba(dgSSTd<=7vKAGwEtXo$HSgn#E?t|yRN`r?A3A)~2vBNG)PZtaoYKU`vHJV3X(H%pD-od+3 ziDTd-I14U;67U?n16riC2h~7LkVnIY30*>Ze9bak765U`5jRtY`^ItUW!!KhuPd}H z^wHoMfx~>NlN}G_7u?fTEhw~%p!O4qzQT^P%gziF)up$6GVTVx2aUR5qytuxLc79*d zvP@x0)qieTt&Zk0W1+=D$Ill6$rid{zOb8nIf5n_g?8KzBj^gF5K^^t4UP&Sc83mY z&2^&?X8&pgr@8IWI}(fOTv~mB5GWTQ7}f1DbUgHTWFmGw$UY!VA8W05W!U6r7= zLs?J`9k^7ON6hr$QeiBiG;x`*lGLMR%Y@pb6LnrLbRa*{e#^0=ZcTSB7gmu%+KCF` zu%%OBzGuGyoF-wUrk5oi9;53xv?l$8yYZ6ol%+kbw?fz--2Z-61j)FQSI-!h1SQMm zs0M%WSy`T&tk$?Jm)v;EmVO-0X7<{bnPExPaitLB>)fBytoIC%>5Sq>_C_wt4ZEyM1lhzRy%lG$mbVRRt#m-2WM9DUUPP z{#IB>TCr{Ccs|n*RXFoiZeKwjuPcg*!p>Clp^hh*OfRjlW9l&-i}&BFaPk{R^HvK{ zWHx=ZT8JF9bQ@+!R20j&5Rzs3p=6mbUB+^at>n3_Sf0Rr@C4W+wL8#*AkYcKgT7!0 z7-?R%Mi{3hgJ_lY!U~^n7qMxZpBb&g%*|4il7jnk)d9N4b_jVxkFOVkiJsotAarmo z2-9e^<8iKAQt6D1f{&Xw%cEqDbzDsMf+t)D+z!GicO~7oQK+N)HOp!>Bw9w% zUpESEtGYu&<&76DYiZ+6LTL3q2>9RPH`$7B8S=lypZK8oyVUzT!MEx=V@0Ovw9|J& zUGji_{hg3x|80GZ<}nwNkK)JDU%nHXrb@d6nbBRPwyHDP0(`Er9g;C!)tOuh{!$6s zjZF;D0T#xj59p|}7?Sb1sxvudw=hu7%EhH4xTdmI)tSr(k5q#92r@$pSQwKvz#J6| zK%$%v2y$J}5_AWjgIQob$Ol!-f_xY9Prx#AJa8ucm80Xlw@M~iU1-#H z;cbru#2N!K!6tAFoCl@gFA$q&<2C#`_+3G5&=^F3%AD;T=lx>Kc^b{$A>3}i5!N5U zP4FBz9>fj+1c68}MWvG}dqXM>)jG~gw>7jq&D|-?b|{49S3nM7D$+K)a1t${{dWnY zoyH<06Kn)W!F76bmvDsBoHWzj!c8rSqF?RBR^31g_X_Epm`Y>!33G8GzO+y1rpr0W zwgXuyX8--zm6FkP@ByK{T{y1G(Z}|u%)1TX9mER% zIVZ@?!RH_YoB}1_5qJZtofl+35C&pE@AHBve+kc2^Q(M;a_qjTOtTAxrsM!EDik_m z@SRQw(WDOTbwcPyZqUsqgid4ueaZr3XtR?-JooG^HJ*fVBfWJ}=uQ%7{ZkNHI)#b7 z=Ch}S2#&;?r89!0)dk#A8lPi!J1>kRsm)8!AkY;gf+R2!d;_L~c_15n3wDBha28wz zcfjwU47>*XO+j`5)qyXl4?;mJ&;i7OfnX$<2xi|zbVy07J)V3dyofCfveyicw&ycg3B>G z{eAQ)j^j<{-dBY{ZR*s!f;<;22AjZ!Uj=zL>wMqp!0elO#fy3Y~umZn( zs1x`C%mb^zHgEtGf@1I*_#p3CFb2#3D9fz9f$Lbih=;6GviOJ8t3;SV0?eyRuqkfZ z`T-VeFbIqVsbCT4_8acCfp5W1kPohc`#}4U*0?47?R^aK&Vd`?K6nD&010uNf1`DN z76No-e=5bMnK51$30LlJu5(9dp-r9qJ1$f~oCS>n)4(E-@CS}CFd1Zl^}rjs{U*$-@*Ru@qhzoIQm2PPrz&w3 zdI=r&P%t$Ne~JzT(m$vu*a$!4caUBVz&EJaMbbvyeL!0zl7@MkS9WCQZ)@aMmm`V zlQO}>yrE3E#p_nvg0t!De}&V!BZ`JA`W`QYak>XK+j(02LYSS}?4=+(m1C3q24|DE zII!V&c#oBhh;jo?lzW0a@H^tg!FC<~1k{zW2zqxlJo=c_`V%$i`W;nVHs%z+&0A}i&o$@T8`IjQ41@D#I8U?2!YG4X*3#E=tT6! z3ZSIbXtBO&wVXz){A2cKu(=~&7RM1XfEJVs6Y<=#`72=*=b4Gcu|N1hm2*_N3z80Q zE4tH?H$p?*R-H1)tEt0VVXR$SXvrXm&Uq_5rfKg4Kkij5{qCJ`qS^gW%;|2u(_wb^5!#*qCgl)g8pvWH{~RAU+`zXot_l#!`%*)tVV&pj|%`>v3*= zbn9p0m};AAqcvs5Xk9u#k2mt`EX&LRj$%EcJ>n(Wo-d4)#rk;pYnd$SwYNVE4?sFs6{UByP)QY0(&txgBHim}`m2j~SC zF~B>!m#-)@&Z*2)btbpczg)#;TyAY@@DOXzC^xZF$Z_1}x7wT2JM`wP^Vm#MWn8%GK`L|E=EeBdZdlknGE*T zX>oP2O;F3jwrOaa!I*?b>nTKM_#-akiK;VMjka+Y+ey6t$JsO*fu|{KHdkh|0tp!} zRSHy{$p_TQLyW`|zV064fZ!aA^+!o@Q9cCuGxAmDt2&cA=^YO-kjtpUIVc>Z4`;TY6(Rv#38G(&$JX3WhJ!n@yO#8QVrk~iBG^Z#0!~n0Q zh{(9DvPadKJVovFVl%uZ(nc@#X*^`_CvzpcN02BpcBxEJbtYHQGkUQ(mln(_-8(qv zhffk?T-<_1nUSIrq3TQypjrN66Fh6hB<>S*f6phWjn=D(#Aw*W#w%54vIgx~M+_$A zO5)&vPZOi)g-FG)sO(d9Ca;-=x?&Sf>)F(H`Z3Wd^>F@)XlgtEEPEzK$Mx7|tI&t% zpUz>T%vhu{Ox2m326m{}Hx*^ZPpZ!3D|5&C;&OsZ0hVtB&rXJTzxpD5(m*^zbq&R2 znja{}nv)xfa|s@1J!ymq;my;a#$qe-3mw~7v~s_2>;S7p7X^v6xV5Tsi75kZirFz( zd`7h8t!?c(O`}7^hFbS1^}L!DB1R`nS%(T>B~4dWQl2fPY@}Laq(EPlAXR6w1DLDw z5R$P=)tS6X{X@luey`uZw;B^Gw*tpGycPeDg(+KsEI!W?OUH+bSG4Eb*s7OK=ZA?+ zy!y2fWyU&{@v6=w4*W22p|(pqTZ+%=_f0WSquYHjQ2N#XJ5W>G;GFMZRxlt@zR^xKqBx{8Hu=OuRoAa{$nAu0EXMTW^pf+=}vA!T&3CVS4 z{+uYqYR}v<3|3)YYJMmaQHnWRsYOl*3rS*bMQH`NC6Cg4I-#^OrP)E%lw?kdtF$!9 zjrmKJkZi>@D9ue%+)~BOufpQwxH8wLDs!u+F<~1vcJr^dQc_kDwKf+$KJ#hL;*=>l z`!u)pq$^_N(%du_UgNWz8Z1(Z;zrf572brU#_1b|Qg`NJWoJ{xxhgXh zEA7Zp+!VDP4{(`~m!{MwNpYjpb{u7fVkLK3aZA;#mNP?Hb(VWsE9M&9l`?2)OHoM8 zRSM5l3Qtq~LD-98#_h@UBJ~4o3E_!AnbWC3vg0E6R`8d z;e)exVP2Zj$r{^X<-kIs6o0AW*C>@WD95J{J3cFOSDKaT)0s_9CF>-dF);m=!!Syj z@3!Eyqt(z+n!;7C%!4NABV&IlM=Y`Kt+;%3{ykA=7# zM~z=}D%PQBQC<$-0sB~NEx}AM4_pN|!Cmkh=!FA!0Fc{@ax>5i3;>^l5nwD>4vvBc zpepio0@Z;RhyZOtEchJxbW4S&2j~luz;G}cd<`an8DKV;53<2Fz!L6;+z$?e0#F1l zfUAJnZ$jP$zk$c#DR>F0#o!7JB!PJ#br+nA;9ua`L6qBpkzg^%11vMfUHC=xfG?;E z8iEke9JB_}pfiXAy}$tQIT!)Pg7IJ~SOYc!HQ!Wu8cXzj*JMK!2^zh*djTU(LHU%aDFeYU)cSD zrqr*kSl4bAu1Ox-^|E|xPG~Fk(~?6J17DL=qvs&F7vE7!v{=u%*KVRo)?t}Rn0d+v zBGD2}^)X^#-7dB8)@R+mR;wkxJ!%`qUMsV_oQbzU5leGQ`0_zjeDl+kPK*)z=+EP| zbjy}Lh$na@uc}V{No(vcOdx|-abF0L(pTV^(<_DEXjYwr=3a5hz$z4a;jYwO=i!x%@aJw zk8W<#qgvyK((9eXda0kK`H!q8%Z|e{T}MHtMRvqv?fc^q+zB2Q+?hS+R?5jtaL+Wc zmS?)|sE@#Qo^$eN#2P!hHz-Ii!ch85_cmnp@bHQ6W%+U&(ZG&J=?&Vs7q!DvIXv;K zmi3L#K^=T~K5(9WN7}ik+Hy7)XGXs@rn8D6%OUBneWnjE?qx+CWKkQOYH+q?!SuR@ ztl8cH2*itK)p0Y_4uznEK?94Fl!&NNo(RTerGF6X{#K$nq~y}`En*X;1?scI^9?E< z(lNQ7b!?(BjP>6k6r;&V3{IP*(~Rq68H|_LC^;#Fjf}+`g~(=Rx0E!*7+C0d;4{Co z8L@Wbf-($M=66G{YimQ-S&qHN@Vc@r=eN}v9ayIMrGkC;j5a|7AI+L%wZ4cUx^e4} zD#M^V6%!O?xquf0PsKEr2R`~7=JWKIE@EqaXkT_@EaM?8SKAYfGP)VPgZm9AL{*ik z)`hm|Dt2+Ygrn^PtEDwv+f|&~NY@9q&_GkrAB+amzyh!u6aWkO7rg638|Jb#g$=`v@xs7lEf4wtA9hZW5MJk0N1Of=(_TEMiJ=E+_YKB)9g7BGL@C^Q$c8f1Iwnk0Uu%lJ|m?MZZDk{E@r9xf$`S)4qK z4je4jua`R-r%aFqz6F?n${(Hy5>F&NjKypPS95)#P7KG^J&gV@iOk8e?3Z!s$HeG?d4QFQAY=(TXEmW--@FE&#os3&GlS zT)0C14z!bTashQfIOqiWfiFQS$Oaq0K5!D;0FS_HU_V8ay+LEp1|)!?U;@YhE5UYf z6kMDlrpl%8`~$R8Q7EVj!a*m{AAAW?!D6rh>;tF34e$uO0rt~SC

=Kmr&BCV&j^ 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 qQdARodJ~XrSOBK9+MXc0(N;Q-kibY -#include -#include "../windows/glext.h" - -extern "C" { -#include "../cs0.h" -#include "../m68kcore.h" -#include "../peripheral.h" -#include "../vidsoft.h" -#include "../vdp2.h" -#include "../yui.h" -#include "../movie.h" -#include "../vidogl.h" -} - -CDInterface FECD = -{ - 2, - "FECD", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; - -SoundInterface_struct FESND; - - -extern "C" SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -NULL -}; - -extern "C" PerInterface_struct *PERCoreList[] = { -&PERDummy, -NULL -}; - -extern "C" CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -&FECD, -NULL -}; - -extern "C" SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -&FESND, -NULL -}; - -extern "C" VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -&VIDOGL, -&VIDSoft, -NULL -}; - -extern "C" M68K_struct *M68KCoreList[] = { -&M68KDummy, -&M68KC68K, -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -/* If Yabause encounters any fatal errors, it sends the error text to this function */ -void YuiErrorMsg(const char *string) -{ - MessageBoxA(NULL, string, "Yabooze dun goofed", 0); -} - - -int red_size; -int green_size; -int blue_size; -int depth_size; - -PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; +#define WIN32_LEAN_AND_MEAN +#include +#include +#include "../windows/glext.h" + +extern "C" { +#include "../cs0.h" +#include "../m68kcore.h" +#include "../peripheral.h" +#include "../vidsoft.h" +#include "../vdp2.h" +#include "../yui.h" +#include "../movie.h" +#include "../vidogl.h" +} + +void (*inputcallback)(void) = NULL; + +extern "C" __declspec(dllexport) void libyabause_setinputcallback(void (*cb)(void)) +{ + inputcallback = cb; +} + +CDInterface FECD = +{ + 2, + "FECD", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +SoundInterface_struct FESND; + + +extern "C" SH2Interface_struct *SH2CoreList[] = { +&SH2Interpreter, +&SH2DebugInterpreter, +NULL +}; + +extern "C" PerInterface_struct *PERCoreList[] = { +&PERDummy, +NULL +}; + +extern "C" CDInterface *CDCoreList[] = { +&DummyCD, +&ISOCD, +&FECD, +NULL +}; + +extern "C" SoundInterface_struct *SNDCoreList[] = { +&SNDDummy, +&FESND, +NULL +}; + +extern "C" VideoInterface_struct *VIDCoreList[] = { +&VIDDummy, +&VIDOGL, +&VIDSoft, +NULL +}; + +extern "C" M68K_struct *M68KCoreList[] = { +&M68KDummy, +&M68KC68K, +#ifdef HAVE_Q68 +&M68KQ68, +#endif +NULL +}; + +/* If Yabause encounters any fatal errors, it sends the error text to this function */ +void YuiErrorMsg(const char *string) +{ + MessageBoxA(NULL, string, "Yabooze dun goofed", 0); +} + + +int red_size; +int green_size; +int blue_size; +int depth_size; + +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; + +int LoadExtensions() +{ + glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbufferEXT"); + if( glBindRenderbuffer == NULL ) return 0; + glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffersEXT"); + if(glDeleteRenderbuffers==NULL) return 0; + glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffersEXT"); + if( glGenRenderbuffers == NULL ) return 0; + glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorageEXT"); + if( glRenderbufferStorage == NULL ) return 0; + glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebufferEXT"); + if( glBindFramebuffer==NULL) return 0; + glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffersEXT"); + if( glDeleteFramebuffers==NULL) return 0; + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffersEXT"); + if( glGenFramebuffers == NULL ) return 0; + glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatusEXT"); + if( glCheckFramebufferStatus == NULL ) return 0; + glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); + if( glFramebufferRenderbuffer == NULL ) return 0; + + return 1; +} + +/* Sets attribute for the Video display. The values passed to this function + depends on what Video core is being used at the time. This may end up + being moved to the Video Core. */ +void YuiSetVideoAttribute(int type, int val) +{ + // only called in GL mode + switch (type) + { + case RED_SIZE: + red_size = val; + break; + case GREEN_SIZE: + green_size = val; + break; + case BLUE_SIZE: + blue_size = val; + break; + case DEPTH_SIZE: + depth_size = val; + break; + case DOUBLEBUFFER: + break; + } +} + -int LoadExtensions() -{ - glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbufferEXT"); - if( glBindRenderbuffer == NULL ) return 0; - glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffersEXT"); - if(glDeleteRenderbuffers==NULL) return 0; - glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffersEXT"); - if( glGenRenderbuffers == NULL ) return 0; - glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorageEXT"); - if( glRenderbufferStorage == NULL ) return 0; - glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebufferEXT"); - if( glBindFramebuffer==NULL) return 0; - glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffersEXT"); - if( glDeleteFramebuffers==NULL) return 0; - glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffersEXT"); - if( glGenFramebuffers == NULL ) return 0; - glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatusEXT"); - if( glCheckFramebufferStatus == NULL ) return 0; - glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); - if( glFramebufferRenderbuffer == NULL ) return 0; - - return 1; -} - -/* Sets attribute for the Video display. The values passed to this function - depends on what Video core is being used at the time. This may end up - being moved to the Video Core. */ -void YuiSetVideoAttribute(int type, int val) -{ - // only called in GL mode - switch (type) - { - case RED_SIZE: - red_size = val; - break; - case GREEN_SIZE: - green_size = val; - break; - case BLUE_SIZE: - blue_size = val; - break; - case DEPTH_SIZE: - depth_size = val; - break; - case DOUBLEBUFFER: - break; - } -} - - GLuint fbuff = 0; GLuint color = 0; GLuint depth = 0; int glwidth, glheight; - -u8 *glbuff = NULL; - -/* Tells the yui it wants to setup the display to display the specified video - format. It's up to the yui to setup the actual display. This may end - up being moved to the Video Core. */ -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) -{ - // only called in GL mode - if (bpp != 32 || red_size != 8 || green_size != 8 || blue_size != 8 || depth_size != 24) - return -1; // failure - - if (fbuff) - glDeleteFramebuffers(1, &fbuff); - if (color) - glDeleteRenderbuffers(1, &color); - if (depth) - glDeleteRenderbuffers(1, &depth); + +u8 *glbuff = NULL; + +/* Tells the yui it wants to setup the display to display the specified video + format. It's up to the yui to setup the actual display. This may end + up being moved to the Video Core. */ +int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) +{ + // only called in GL mode + if (bpp != 32 || red_size != 8 || green_size != 8 || blue_size != 8 || depth_size != 24) + return -1; // failure + + if (fbuff) + glDeleteFramebuffers(1, &fbuff); + if (color) + glDeleteRenderbuffers(1, &color); + if (depth) + glDeleteRenderbuffers(1, &depth); glGenFramebuffers(1, &fbuff); glGenRenderbuffers(1, &color); glGenRenderbuffers(1, &depth); @@ -182,32 +189,32 @@ int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return -1; - - glwidth = width; - glheight = height; - - if (glbuff) - free(glbuff); - glbuff = (u8*) malloc(glwidth * glheight * 4); - - return 0; // success -} - -int usinggl = 0; -HWND glWND; -HDC glDC; -HGLRC glRC; - -void KillGLContext() -{ - wglMakeCurrent(NULL, NULL); - wglDeleteContext(glRC); + + glwidth = width; + glheight = height; + + if (glbuff) + free(glbuff); + glbuff = (u8*) malloc(glwidth * glheight * 4); + + return 0; // success +} + +int usinggl = 0; +HWND glWND; +HDC glDC; +HGLRC glRC; + +void KillGLContext() +{ + wglMakeCurrent(NULL, NULL); + wglDeleteContext(glRC); ReleaseDC(glWND, glDC); - DestroyWindow(glWND); -} - -int StartGLContext() -{ + DestroyWindow(glWND); +} + +int StartGLContext() +{ PIXELFORMATDESCRIPTOR pfd; memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); @@ -249,316 +256,316 @@ int StartGLContext() DestroyWindow(glWND); return 0; } - if (!wglMakeCurrent(glDC, glRC)) - { - wglDeleteContext(glRC); + if (!wglMakeCurrent(glDC, glRC)) + { + wglDeleteContext(glRC); ReleaseDC(glWND, glDC); DestroyWindow(glWND); return 0; - } - return 1; -} - - - -s16 *sndbuff = NULL; -int sndbuffpos = 0; -u32 *vidbuff = NULL; - -PerPad_struct *ctrl1; -PerPad_struct *ctrl2; - -extern "C" int vdp2height; -extern "C" int vdp2width; - -/* Tells the yui to exchange front and back video buffers. This may end - up being moved to the Video Core. */ -void YuiSwapBuffers(void) -{ - if (vidbuff) - { - if (!usinggl) - { - u8 *src = (u8*)dispbuffer; - u8 *dst = (u8*)vidbuff; - - for (int j = 0; j < vdp2height; j++) - for (int i = 0; i < vdp2width; i++) - { - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - dst[3] = 0xff; - src += 4; - dst += 4; - } - } - else - { - glReadPixels(0, 0, glwidth, glheight, GL_BGRA, GL_UNSIGNED_BYTE, glbuff); - - u32 *src = (u32*)glbuff; - u32 *dst = (u32*)vidbuff; - - dst += glwidth * (glheight - 1); - - for (int j = 0; j < glheight; j++) - { - memcpy(dst, src, glwidth * 4); - src += glwidth; - dst -= glwidth; - } - } - } -} - -static void FESNDUpdateAudio(UNUSED u32 *leftchanbuffer, UNUSED u32 *rightchanbuffer, UNUSED u32 num_samples) -{ - /* - static s16 stereodata16[44100 / 50]; - ScspConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)stereodata16, num_samples); - */ -} - -static u32 FESNDGetAudioSpace(void) -{ - return 44100; -} -// some garbage from the sound system, we'll have to fix this all up -extern "C" void DRV_AviSoundUpdate(void* soundData, int soundLen) -{ - // soundLen should be number of sample pairs (4 byte units) - if (sndbuff) - { - s16 *src = (s16*)soundData; - s16 *dst = sndbuff; - dst += sndbuffpos * 2; - memcpy (dst, src, soundLen * 4); - sndbuffpos += soundLen; - } -} - -// must hold at least 704x512 pixels -extern "C" __declspec(dllexport) void libyabause_setvidbuff(u32 *buff) -{ - vidbuff = buff; -} - -extern "C" __declspec(dllexport) void libyabause_setsndbuff(s16 *buff) -{ - sndbuff = buff; -} - -extern "C" __declspec(dllexport) void libyabause_softreset() -{ - YabauseResetButton(); -} - -extern "C" __declspec(dllexport) void libyabause_hardreset() -{ - YabauseReset(); -} - -extern "C" __declspec(dllexport) int libyabause_loadstate(const char *fn) -{ - return !YabLoadState(fn); -} - -extern "C" __declspec(dllexport) int libyabause_savestate(const char *fn) -{ - return !YabSaveState(fn); -} - -extern "C" __declspec(dllexport) int libyabause_savesaveram(const char *fn) -{ - return !T123Save(BupRam, 0x10000, 1, fn); -} - -extern "C" __declspec(dllexport) int libyabause_loadsaveram(const char *fn) -{ - return !T123Load(BupRam, 0x10000, 1, fn); -} - -extern "C" __declspec(dllexport) int libyabause_saveramodified() -{ - return BupRamWritten; -} - -extern "C" __declspec(dllexport) void libyabause_clearsaveram() -{ - FormatBackupRam(BupRam, 0x10000); -} - -typedef struct -{ - void *data; - const char *name; - int length; -} memoryarea; - -memoryarea normmemareas[] = -{ - {NULL, "Boot Rom", 512 * 1024}, - {NULL, "Backup Ram", 64 * 1024}, - {NULL, "Work Ram Low", 1024 * 1024}, - {NULL, "Sound Ram", 512 * 1024}, - {NULL, "VDP1 Ram", 512 * 1024}, - {NULL, "VDP1 Framebuffer", 512 * 1024}, - {NULL, "VDP2 Ram", 512 * 1024}, - {NULL, "VDP2 CRam", 4 * 1024}, - {NULL, "Work Ram High", 1024 * 1024}, - {NULL, NULL, 0} -}; - -extern "C" __declspec(dllexport) memoryarea *libyabause_getmemoryareas() -{ - normmemareas[0].data = BiosRom; - normmemareas[1].data = BupRam; - normmemareas[2].data = LowWram; - normmemareas[3].data = SoundRam; - normmemareas[4].data = Vdp1Ram; - normmemareas[5].data = Vdp1FrameBuffer; - normmemareas[6].data = Vdp2Ram; - normmemareas[7].data = Vdp2ColorRam; - normmemareas[8].data = HighWram; - return &normmemareas[0]; -} - -extern "C" __declspec(dllexport) int libyabause_frameadvance(int *w, int *h, int *nsamp) -{ - LagFrameFlag = 1; - sndbuffpos = 0; - YabauseEmulate(); - if (usinggl) - { - *w = glwidth; - *h = glheight; - } - else - { - *w = vdp2width; - *h = vdp2height; - } - *nsamp = sndbuffpos; - return LagFrameFlag; -} - -extern "C" __declspec(dllexport) void libyabause_deinit() -{ - PerPortReset(); - YabauseDeInit(); - if (usinggl) - { - KillGLContext(); - usinggl = 0; - } - if (glbuff) - { - free(glbuff); - glbuff = NULL; - } -} - -extern "C" __declspec(dllexport) void libyabause_setpads(u8 p11, u8 p12, u8 p21, u8 p22) -{ - ctrl1->padbits[0] = p11; - ctrl1->padbits[1] = p12; - ctrl2->padbits[0] = p21; - ctrl2->padbits[1] = p22; -} - -int glnativefactor = 0; - -extern "C" __declspec(dllexport) void libyabause_glresize(int w, int h) -{ - if (usinggl && !glnativefactor) - VIDCore->Resize(w, h, 0); -} - -extern "C" __declspec(dllexport) void libyabause_glsetnativefactor(int n) -{ - if (!usinggl) - return; - if (n > 4) - n = 4; - if (n < 0) - n = 0; - glnativefactor = n; - if (n) - VIDCore->Resize(vdp2width_gl * n, vdp2height_gl * n, 0); -} - -void (*vdp2hookfcn)(u16 v) = NULL; - -void vdp2newhook(u16 v) -{ - vdp2hookfcn(v); - if (glnativefactor) - { - if (glwidth != vdp2width_gl * glnativefactor || glheight != vdp2height_gl * glnativefactor) - VIDCore->Resize(vdp2width_gl * glnativefactor, vdp2height_gl * glnativefactor, 0); - } -} - -extern "C" __declspec(dllexport) int libyabause_init(CDInterface *_CD, const char *biosfn, int usegl) -{ - usinggl = usegl; - if (usegl && (!StartGLContext() || !LoadExtensions())) - return 0; - - FECD.DeInit = _CD->DeInit; - FECD.GetStatus = _CD->GetStatus; - FECD.Init = _CD->Init; - FECD.ReadAheadFAD = _CD->ReadAheadFAD; - FECD.ReadSectorFAD = _CD->ReadSectorFAD; - FECD.ReadTOC = _CD->ReadTOC; - - // only overwrite a few SNDDummy functions - memcpy(&FESND, &SNDDummy, sizeof(FESND)); - FESND.id = 2; - FESND.Name = "FESND"; - FESND.GetAudioSpace = FESNDGetAudioSpace; - FESND.UpdateAudio = FESNDUpdateAudio; - - yabauseinit_struct yinit; - memset(&yinit, 0, sizeof(yabauseinit_struct)); - yinit.percoretype = PERCORE_DUMMY; - yinit.sh2coretype = SH2CORE_INTERPRETER; - if (usegl) - yinit.vidcoretype = VIDCORE_OGL; - else - yinit.vidcoretype = VIDCORE_SOFT; - yinit.sndcoretype = 2; //SNDCORE_DUMMY; - yinit.cdcoretype = 2; // CDCORE_ISO; //CDCORE_DUMMY; - yinit.m68kcoretype = M68KCORE_C68K; - yinit.cartpath = CART_NONE; - yinit.regionid = REGION_AUTODETECT; - yinit.biospath = biosfn; - yinit.cdpath = "Saturnus"; //NULL; - yinit.buppath = NULL; - yinit.mpegpath = NULL; - yinit.cartpath = NULL; - yinit.netlinksetting = NULL; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - - if (usegl && !vdp2hookfcn) - { - // hook vdp2setresolution - vdp2hookfcn = VIDOGL.Vdp2SetResolution; - VIDOGL.Vdp2SetResolution = vdp2newhook; - } - - if (YabauseInit(&yinit) != 0) - return 0; - - SpeedThrottleDisable(); - DisableAutoFrameSkip(); - ScspSetFrameAccurate(1); - - OSDChangeCore(OSDCORE_DUMMY); - - ctrl1 = PerPadAdd(&PORTDATA1); - ctrl2 = PerPadAdd(&PORTDATA2); - - return 1; -} + } + return 1; +} + + + +s16 *sndbuff = NULL; +int sndbuffpos = 0; +u32 *vidbuff = NULL; + +PerPad_struct *ctrl1; +PerPad_struct *ctrl2; + +extern "C" int vdp2height; +extern "C" int vdp2width; + +/* Tells the yui to exchange front and back video buffers. This may end + up being moved to the Video Core. */ +void YuiSwapBuffers(void) +{ + if (vidbuff) + { + if (!usinggl) + { + u8 *src = (u8*)dispbuffer; + u8 *dst = (u8*)vidbuff; + + for (int j = 0; j < vdp2height; j++) + for (int i = 0; i < vdp2width; i++) + { + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + dst[3] = 0xff; + src += 4; + dst += 4; + } + } + else + { + glReadPixels(0, 0, glwidth, glheight, GL_BGRA, GL_UNSIGNED_BYTE, glbuff); + + u32 *src = (u32*)glbuff; + u32 *dst = (u32*)vidbuff; + + dst += glwidth * (glheight - 1); + + for (int j = 0; j < glheight; j++) + { + memcpy(dst, src, glwidth * 4); + src += glwidth; + dst -= glwidth; + } + } + } +} + +static void FESNDUpdateAudio(UNUSED u32 *leftchanbuffer, UNUSED u32 *rightchanbuffer, UNUSED u32 num_samples) +{ + /* + static s16 stereodata16[44100 / 50]; + ScspConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)stereodata16, num_samples); + */ +} + +static u32 FESNDGetAudioSpace(void) +{ + return 44100; +} +// some garbage from the sound system, we'll have to fix this all up +extern "C" void DRV_AviSoundUpdate(void* soundData, int soundLen) +{ + // soundLen should be number of sample pairs (4 byte units) + if (sndbuff) + { + s16 *src = (s16*)soundData; + s16 *dst = sndbuff; + dst += sndbuffpos * 2; + memcpy (dst, src, soundLen * 4); + sndbuffpos += soundLen; + } +} + +// must hold at least 704x512 pixels +extern "C" __declspec(dllexport) void libyabause_setvidbuff(u32 *buff) +{ + vidbuff = buff; +} + +extern "C" __declspec(dllexport) void libyabause_setsndbuff(s16 *buff) +{ + sndbuff = buff; +} + +extern "C" __declspec(dllexport) void libyabause_softreset() +{ + YabauseResetButton(); +} + +extern "C" __declspec(dllexport) void libyabause_hardreset() +{ + YabauseReset(); +} + +extern "C" __declspec(dllexport) int libyabause_loadstate(const char *fn) +{ + return !YabLoadState(fn); +} + +extern "C" __declspec(dllexport) int libyabause_savestate(const char *fn) +{ + return !YabSaveState(fn); +} + +extern "C" __declspec(dllexport) int libyabause_savesaveram(const char *fn) +{ + return !T123Save(BupRam, 0x10000, 1, fn); +} + +extern "C" __declspec(dllexport) int libyabause_loadsaveram(const char *fn) +{ + return !T123Load(BupRam, 0x10000, 1, fn); +} + +extern "C" __declspec(dllexport) int libyabause_saveramodified() +{ + return BupRamWritten; +} + +extern "C" __declspec(dllexport) void libyabause_clearsaveram() +{ + FormatBackupRam(BupRam, 0x10000); +} + +typedef struct +{ + void *data; + const char *name; + int length; +} memoryarea; + +memoryarea normmemareas[] = +{ + {NULL, "Boot Rom", 512 * 1024}, + {NULL, "Backup Ram", 64 * 1024}, + {NULL, "Work Ram Low", 1024 * 1024}, + {NULL, "Sound Ram", 512 * 1024}, + {NULL, "VDP1 Ram", 512 * 1024}, + {NULL, "VDP1 Framebuffer", 512 * 1024}, + {NULL, "VDP2 Ram", 512 * 1024}, + {NULL, "VDP2 CRam", 4 * 1024}, + {NULL, "Work Ram High", 1024 * 1024}, + {NULL, NULL, 0} +}; + +extern "C" __declspec(dllexport) memoryarea *libyabause_getmemoryareas() +{ + normmemareas[0].data = BiosRom; + normmemareas[1].data = BupRam; + normmemareas[2].data = LowWram; + normmemareas[3].data = SoundRam; + normmemareas[4].data = Vdp1Ram; + normmemareas[5].data = Vdp1FrameBuffer; + normmemareas[6].data = Vdp2Ram; + normmemareas[7].data = Vdp2ColorRam; + normmemareas[8].data = HighWram; + return &normmemareas[0]; +} + +extern "C" __declspec(dllexport) int libyabause_frameadvance(int *w, int *h, int *nsamp) +{ + LagFrameFlag = 1; + sndbuffpos = 0; + YabauseEmulate(); + if (usinggl) + { + *w = glwidth; + *h = glheight; + } + else + { + *w = vdp2width; + *h = vdp2height; + } + *nsamp = sndbuffpos; + return LagFrameFlag; +} + +extern "C" __declspec(dllexport) void libyabause_deinit() +{ + PerPortReset(); + YabauseDeInit(); + if (usinggl) + { + KillGLContext(); + usinggl = 0; + } + if (glbuff) + { + free(glbuff); + glbuff = NULL; + } +} + +extern "C" __declspec(dllexport) void libyabause_setpads(u8 p11, u8 p12, u8 p21, u8 p22) +{ + ctrl1->padbits[0] = p11; + ctrl1->padbits[1] = p12; + ctrl2->padbits[0] = p21; + ctrl2->padbits[1] = p22; +} + +int glnativefactor = 0; + +extern "C" __declspec(dllexport) void libyabause_glresize(int w, int h) +{ + if (usinggl && !glnativefactor) + VIDCore->Resize(w, h, 0); +} + +extern "C" __declspec(dllexport) void libyabause_glsetnativefactor(int n) +{ + if (!usinggl) + return; + if (n > 4) + n = 4; + if (n < 0) + n = 0; + glnativefactor = n; + if (n) + VIDCore->Resize(vdp2width_gl * n, vdp2height_gl * n, 0); +} + +void (*vdp2hookfcn)(u16 v) = NULL; + +void vdp2newhook(u16 v) +{ + vdp2hookfcn(v); + if (glnativefactor) + { + if (glwidth != vdp2width_gl * glnativefactor || glheight != vdp2height_gl * glnativefactor) + VIDCore->Resize(vdp2width_gl * glnativefactor, vdp2height_gl * glnativefactor, 0); + } +} + +extern "C" __declspec(dllexport) int libyabause_init(CDInterface *_CD, const char *biosfn, int usegl) +{ + usinggl = usegl; + if (usegl && (!StartGLContext() || !LoadExtensions())) + return 0; + + FECD.DeInit = _CD->DeInit; + FECD.GetStatus = _CD->GetStatus; + FECD.Init = _CD->Init; + FECD.ReadAheadFAD = _CD->ReadAheadFAD; + FECD.ReadSectorFAD = _CD->ReadSectorFAD; + FECD.ReadTOC = _CD->ReadTOC; + + // only overwrite a few SNDDummy functions + memcpy(&FESND, &SNDDummy, sizeof(FESND)); + FESND.id = 2; + FESND.Name = "FESND"; + FESND.GetAudioSpace = FESNDGetAudioSpace; + FESND.UpdateAudio = FESNDUpdateAudio; + + yabauseinit_struct yinit; + memset(&yinit, 0, sizeof(yabauseinit_struct)); + yinit.percoretype = PERCORE_DUMMY; + yinit.sh2coretype = SH2CORE_INTERPRETER; + if (usegl) + yinit.vidcoretype = VIDCORE_OGL; + else + yinit.vidcoretype = VIDCORE_SOFT; + yinit.sndcoretype = 2; //SNDCORE_DUMMY; + yinit.cdcoretype = 2; // CDCORE_ISO; //CDCORE_DUMMY; + yinit.m68kcoretype = M68KCORE_C68K; + yinit.cartpath = CART_NONE; + yinit.regionid = REGION_AUTODETECT; + yinit.biospath = biosfn; + yinit.cdpath = "Saturnus"; //NULL; + yinit.buppath = NULL; + yinit.mpegpath = NULL; + yinit.cartpath = NULL; + yinit.netlinksetting = NULL; + yinit.videoformattype = VIDEOFORMATTYPE_NTSC; + + if (usegl && !vdp2hookfcn) + { + // hook vdp2setresolution + vdp2hookfcn = VIDOGL.Vdp2SetResolution; + VIDOGL.Vdp2SetResolution = vdp2newhook; + } + + if (YabauseInit(&yinit) != 0) + return 0; + + SpeedThrottleDisable(); + DisableAutoFrameSkip(); + ScspSetFrameAccurate(1); + + OSDChangeCore(OSDCORE_DUMMY); + + ctrl1 = PerPadAdd(&PORTDATA1); + ctrl2 = PerPadAdd(&PORTDATA2); + + return 1; +} diff --git a/yabause/src/smpc.c b/yabause/src/smpc.c index 30fd64b7c4..7972a1a421 100644 --- a/yabause/src/smpc.c +++ b/yabause/src/smpc.c @@ -32,6 +32,8 @@ #include "yabause.h" #include "movie.h" +#include "yui.h" + #ifdef _arch_dreamcast # include "dreamcast/localtime.h" #endif @@ -362,6 +364,10 @@ static void SmpcINTBACKPeripheral(void) { if (SmpcInternalVars->port1.size == 0 && SmpcInternalVars->port2.size == 0) { + ///// + if (inputcallback) + inputcallback(); + // Request data from the Peripheral Interface port1 = &PORTDATA1; port2 = &PORTDATA2; diff --git a/yabause/src/yui.h b/yabause/src/yui.h index 54299e3de7..897da7f262 100644 --- a/yabause/src/yui.h +++ b/yabause/src/yui.h @@ -52,6 +52,14 @@ int YuiSetVideoMode(int width, int height, int bpp, int fullscreen); up being moved to the Video Core. */ void YuiSwapBuffers(void); + + +extern void (*inputcallback)(void); + + + + + ////////////////////////////////////////////////////////////////////////////// // Helper functions(you can use these in your own port) //////////////////////////////////////////////////////////////////////////////