From d75d26bcc9c0f0cea7085800a7b4c1927df5bb91 Mon Sep 17 00:00:00 2001 From: nia Date: Mon, 20 Nov 2023 11:23:26 +0100 Subject: [PATCH 001/336] Scripting: Check for ENOTRECOVERABLE It's part of "robust mutexes" and may not necessarily be available (e.g. on NetBSD 9) --- src/script/socket.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/script/socket.c b/src/script/socket.c index 5b2e95b60..4684c243e 100644 --- a/src/script/socket.c +++ b/src/script/socket.c @@ -28,7 +28,9 @@ static const struct _mScriptSocketErrorMapping { { ECONNREFUSED, mSCRIPT_SOCKERR_CONNECTION_REFUSED }, { EACCES, mSCRIPT_SOCKERR_DENIED }, { EPERM, mSCRIPT_SOCKERR_DENIED }, +#ifdef ENOTRECOVERABLE { ENOTRECOVERABLE, mSCRIPT_SOCKERR_FAILED }, +#endif { ENETUNREACH, mSCRIPT_SOCKERR_NETWORK_UNREACHABLE }, { ETIMEDOUT, mSCRIPT_SOCKERR_TIMEOUT }, { EINVAL, mSCRIPT_SOCKERR_UNSUPPORTED }, From 978e7c94b292fe148b360cda3c7e5fbd44636892 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 16 Nov 2023 03:24:02 -0800 Subject: [PATCH 002/336] Tools: Add SDF-generation tool and 4x font SDF --- CMakeLists.txt | 7 ++ include/mgba-util/gui/font-metrics.h | 5 +- res/font-mask.png | Bin 0 -> 8744 bytes res/font-sdf.png | Bin 0 -> 59791 bytes src/tools/font-sdf.c | 136 +++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 res/font-mask.png create mode 100644 res/font-sdf.png create mode 100644 src/tools/font-sdf.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 81fdeec3f..b3a07530c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ if(NOT LIBMGBA_ONLY) set(BUILD_GLES2 ON CACHE BOOL "Build with OpenGL|ES 2") set(BUILD_GLES3 ON CACHE BOOL "Build with OpenGL|ES 3") set(BUILD_DOCGEN OFF CACHE BOOL "Build the scripting API documentation generator") + set(BUILD_MAINTAINER_TOOLS OFF CACHE BOOL "Build tools only useful for maintainers") set(USE_EPOXY ON CACHE STRING "Build with libepoxy") set(DISABLE_DEPS OFF CACHE BOOL "Build without dependencies") set(DISTBUILD OFF CACHE BOOL "Build distribution packages") @@ -93,6 +94,7 @@ if(NOT LIBMGBA_ONLY) mark_as_advanced(WIN32_UNIX_PATHS) endif() mark_as_advanced(BUILD_DOCGEN) + mark_as_advanced(BUILD_MAINTAINER_TOOLS) else() set(DISABLE_FRONTENDS ON) set(DISABLE_DEPS ON) @@ -1045,6 +1047,11 @@ if(ENABLE_SCRIPTING AND BUILD_DOCGEN) target_link_libraries(docgen ${OS_LIB} ${PLATFORM_LIBRARY} ${BINARY_NAME}) endif() +if(BUILD_MAINTAINER_TOOLS) + add_executable(font-sdf-tool ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/font-sdf.c ${CMAKE_CURRENT_SOURCE_DIR}/src/util/gui/font-metrics.c) + target_link_libraries(font-sdf-tool ${OS_LIB} ${PLATFORM_LIBRARY} ${BINARY_NAME}) +endif() + if(BUILD_SDL) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/sdl ${CMAKE_CURRENT_BINARY_DIR}/sdl) endif() diff --git a/include/mgba-util/gui/font-metrics.h b/include/mgba-util/gui/font-metrics.h index c60d6dfc8..c2e6668d4 100644 --- a/include/mgba-util/gui/font-metrics.h +++ b/include/mgba-util/gui/font-metrics.h @@ -6,9 +6,10 @@ #ifndef DEFAULT_FONT_METRICS_H #define DEFAULT_FONT_METRICS_H +#include #include -extern struct GUIFontGlyphMetric defaultFontMetrics[]; -extern struct GUIIconMetric defaultIconMetrics[]; +extern const struct GUIFontGlyphMetric defaultFontMetrics[128]; +extern const struct GUIIconMetric defaultIconMetrics[GUI_ICON_MAX]; #endif diff --git a/res/font-mask.png b/res/font-mask.png new file mode 100644 index 0000000000000000000000000000000000000000..2e223597b52671f0fd9c11b6804889bf3a03dd3d GIT binary patch literal 8744 zcmd^lcT`i^`sh9>1f&E3DN=%>BBK;Xr9(0{tY8}}kT{Bn2t-8)5XeF71?&wZQS2y1 zP*F+(C_x1RHV}}68mdWX36SKxgZI8QcfH@-|K1;Ot(Wz!v&-4-EBk9Fr`P-X=uVkF z1puJCYUQ$x0N~In4rpT0Vr6+#E?Pi`H~K6ASv3|tXhUQD+Re++5fl&O#t9K7bgnK8bN)z&vZOlQuyKuB>0zkh-VL(7N{NP zf#q6$o<@-d^l}+Hr>6x8dI3CDra8navKDR{s4_zH8{5C5WnnYOyw0{EuP?`X}nHBodWp)`~z-hS0EGSQ>+qZ)HZ*8!@JK5 z6UVSE;GlG6<<3jIYD$C)kBef{`5Y>u#dd#n46aHR*hVFm~L$S~Hx2S>Z=@%;=&8mURuqBtfH){o!kXyZAt zRJ|6h0G6V-38IKXOR3Ms1=!j^JgsmkTrCNH)N;LC_#kR8hz$Z(NOV2ciH~G5Bg-xuQr_xJL~%VrWD#RHf%DQ2dPzbui*782On>aLqpmdbMC8$z>P(UUKE+ z@&u}9*pN@c_Sxf27OS`e3r57wm-ia)K+MSN*b9^^f=N_mBk1rxL|eS9o?52<+(s6p zE0>zN@eD(5rx~ubMO2Z)0*diXwT74t1CSjr)JSEg0;x&0qL$y2UNip!;P(BS33ABqN+^U`MB^l}FK*pb5hk)sK*vkvp z7hs*C0%O?N9~oGKS-(h)U05<(lq)Ya^YaWL{In^jqx`NJv?T$iH`39Wtv1a$piB|C zn~LfkIrZ0UM;4S?=4eswvA5PE0k$32NXKI8cXd?Q_SlQ;AO_Pos0sL!@pD1aQl|yr zG5!>uLo$Y`hTpva_92X;(ZOB~>pXA=43}f1ann-?w2r0Lkf}w&V`$}k$}AAS7yR5Y z?V{k1Et(YOXSp5pMr={xYuozG{}gW(519x)2%dWfgqDX|yB~dmablQIA_5n z%G;i~d76GTHs;8XNl>@%1!_Cj3FHnD&o-|$^g6w0;cfX3o&0s++Kz@IkEASOWA52q zzhf^jmd45kiVm-!R+Lu8zq%Z50KdDoxG!`uI-vCIu0f0wGH>0_i6totWpFXOQsq1Y zdbB-Fw6#<@9hnWSRQul99sw=EfACE3^#&_rY+CJkX~(rBuecSgKY&5>t@ONE3%ii< z)m3I6<3Gx$x@v86Q}dm_DBd}lnR|^b&KR#^4u=<2d1U%nEs`DHhOe|lGR%KFv|ueG zLrnU83v1E!NROZSU=LB#1aq|rA(ljkFNO-*Eq7PcRh}CQ4qTl&c4Nfhp!Z#HXQ~lX zZ28)BPJZ2lebSMQz@SimvOu^QpSJQA$T>D=SnIG9(#gbo!h0|b5u2Fs` zlXysA{_(I-J}cf{AsyP*5n7#Bk0f)oorc<*f+~=8*PpJ{=A98{vi0Fhq;CylC$~TG zZF{y67Ks(_gP}QrXWq2=g;uLVUi7lR?Fb&rIGOiYxFYwfLhuIb!dSYY?gyji)!o@% zs(=Ll!#6wq%$6Td%Kht_UFLY!M5!&_TD2noo>;io%e!b{bDnbc$+{QixwI4SsbyDV zT@+7&XWHuVkc%E-_C&n3od@r&%J!heS7PP&yfuhb%iGL5U3kv%1div(o*f_b(+Zl2 zCbXaG%PtqLnO@2Ze%U0+E?sBy{QqIkQ#Q2>e{QiOC%X@gvBu?o zY@bLIiR{wgy3e`u>C)_~lUOH-_;G|{*Wgj`_Bs`u@Tuk@3N`tx z`U9yuG|W(>viC=W&914QdvPbc@HkCI;A!>vp${#x0PX zO;U_d9kQ9ID3$WhrSo*~9Im?WMTn6GO}T8aL6!tGDTB<<4kz9?GbYZG1JhRQ0u|&{ zv4{&gLklwHp4-pZPGV|A#i)o@?`EOeCFAW@+Zm{{GKXMI*Zrt??yX{t^A=6PN?+{> zf*x7Hg#_BSA*wxCczuGLGBNbTEeFxDL#B1}iK&KEpqR`{u`AT?PPd^!bh{jIuIT*0P6FpobZq2@Fl=Qt z1>-b$<5Ftkb8PJsOzo$dG8DxtI8IxXNC}?Gj$5w-I9eg7LY7>}o9V5#Wo&f;m~ zTaU)?1TPyQJOw=A8b$VjWv_OO@Zl0;tX~NbfeI%(&4=1j(+;=@Ym)M->NACYZ5FLwf?zq zWbczY!w@@{WiM`lb1juy%;94sdB7qN)-|}5T=HW*{4xaG0&7(<(ubGl>QWe*YZ+ty zvw)d^bsKaPop-kbveXakwHXeeb%B2T$XZu*x*4n(qRs*#;te%ZC`*<@|NZ*H3qsYd z!6V9cvc6lpY@X7!b0#_Bwygc$vM?jf zY}SX>11V&0(E4h9OhhS;b_e9QLCrYYMxfTKue+SHs+~I%gy2mBlGFM$QHj$?|Cn9; zbI{i`o>@UtUIKg4ll5UsOf5!Cd5)1DuGBjx>~23>BW&IPmv(k@v9&0pAK*pYBJ}Hl~b;~KMCqmTEq2t=j=iOZ zS`?}5dc^)GB?bqNgM2>q(ZL>nz983Qe7kS|-gK#riR*A+$I3lI883&y`0!iyxQ*z!ybqM%@Haq`R_U>zZ{KluBhzQX|HG#yTeFvEp3-D|hfuQ>Uy*I@oZud)>oBLLRIK2n61=5>+BZ_~N_xC#Zy z9!BN4Q{@9HYHoWz8|c=8pNzcnN0r>Hm`vblI9BOkCKP>V~A#9hh5mw%$N8 zS?HZ;W>)@Q0v?kxrZH!%>{9M5t;+x%Mj|QjbU!`v{n+Oy-twP&&$5?>qgrI>zc};% zy21SsFG#;X-I4x;bfoH5aF<{8*6MoV{wb8|K_m5(On?RjUmW~;1n%gjnv|ZwN#|uy zRowrcM1tGmBjlE>`*0W)c+hqMi$pEnX}qf!8u#F6H!%&+$6u`WosZ6h!Te2N(%8Wm zw64j!h}Q>@KKS*7ZM0GCZ4IXUdioes0D9L<-4mU1FnQs}-p4YBWBNyxTel+_pB1Vb zH=87_`wLxfUj4@UXy%z~N$+;+@K%p6`())_02zu&0ms^aj^hd^fOtv=cliH>2y`j5 z*?Sky@>Dvmn>kWyZ$mv?k1T;srQB&KC@e8BX+Vas`YlkoR*2zsYk8gBNyqrEaq3)f z89N$$U-#+TaTRjSV6Eq|vn9A?Cf2Tqbk4^#7LB-L2Dlhh8P{W~&6AD`+;OXYDZ{gB zI^E`wO9Z!ATfn6*ZW#EjX4mjB%${PPCqZ1MS))?c+n(VOPFH^>tc)0@MR3F9`xcUM%R8ZrP<6gegzh0S*x+89xU_O1}`rhi{ z&}Kc)2(?z~TJU=yc%{q3yuuQ=7ih(fxSOuXm9ROWc(ySu4}4+GSjq4S?44KIRYRWe z7|w4o z`@wvVe=;#nn-s4SgKG@8{iS%QeDh+2*jdgR6cpN4O`mIp)RF$&3>roiWGf)S(As4r zWP1=E?gja8z#<3^AcE%@4v3RboJDsCz^qBAwgH*|!wZ*yPZ%1(0L^Mavjs!|Lc7v_=~&js7so^**hpqAgB$HQLK{Ki@(!;`seAnJ5ps;d1-l7}1YI zUht;9imA*%qUdTzwUc;^Fq(9w?$V-e2j7m?yewT_Ez?kA{T}s2tu!lml%Wn|gASc* zPydJx`HjeyH_L=~$IknDZH^RnR^z^~3{jgulSGZI&qSGV3a|FW06re=G01BbXqF z>ibrToN}h&X-u(jcsDP&FT9t(;p)j8H;>wA9Ea#xgt#+EEGwCzlPuAQtm|(HcaL4> zo!pMe8Q2N)RuvS1x8xPN#Cyk5?u-&CrMmb`ymi9#p-P|}XSE4-M}ec}wbc~VyxnIe zY_x(e)=Px!neS3~J2!y4kO`cGy|583+sc!rw5o4^7b3ygU{=7CHx$$%sUlJ;n&5FT zTtuuh)EN8%_5_@901q{+6ISF5&f4}PXl*EJIu+87*N;x299XzH9q(9pVXQ9lLo&RY z%1Tk~kbZT*HQIx^)R4cReMHGjt@B7}5Q%zzl?hj|>%tY=z<4|Q_nq*)rSP%TOMKyL z9I>7MEijU>x=>N=mvlePJM)d%T)A0QGyWQbX!V}jy_XXguA!aw?y(jH$pUNB-dff} zMgiKJ6$|!s9GRPTVL3)5F3rO@9hn*JPjFJ{E(=Vku#)#v7mJ;qVD#PfvWs;>?trRv z-`@C!RS~n+_|AMGb0Z`5l%Y#{NvkpI>3RhN>Np@zJ1+0M_3*h0&(ou^&;m}9+s<18 zay(`Li#*~qCR-Q7I|Svd#_?`>IfE^yK!digF8tzucwvQok4ICHG&dl@M zNCO`8VET+)G9t1(%@BRZYbOwk$_&29M zi@N{$q-#Kvqfs;Z4+R{dMHv|){O|X!Zb0_gSj%r^7D|R>UD(DLwc>}dBCoT*FqlLl z5vnXW^w&geni0hW^X#=(nN7ibK&68jzbJ_klfDC7Q^3(m>a-220G}MVNoY7VV&daRm8zC69_!De6zKr^DUj zsoalKQ1{3bP6%-gYR1XrtJdmJBH8mAg3)u$!EvaJ1CdI^Ejis7?)Kf9`+0J(8Jyq+ zmL67*RjTD|LyZ29zSW~UPzsqritc-~vQTlx?$fJ$fZ0PUvE(I+sT?N~tSXRywn(24 z^1aTM#-rh8^zw;kC@Ho8^-wH{$dfjV$s>qDi)M72jrCYcX( zX3Pm7=>Hh{FzS!)6oi$2|GkJ=drv#@Zeie$ta$))!2nh}fcRN}H2>X4{@OPNPH!aB zeiowJ--NoqLj_SSqWYzC0;X8}82c?c5M9F#QtWwBsA0{}vl*DoWm8RHdo%`~WDs*{ ze;n%2qRjtwS6R=}^hk_X?pc z7%+D(dks~_wcMnho&(JBocPi?u2BzHHSV}>8?0n)04>brDd50*xTigWE#oS^iz#5o zJ4v%P?=HS!w;FT7h0YQl7u)knwHkue7`oUEb^zk#G%gy3`a#KhKxinFhN1~QeGmar zz)anSgO-h#T^E3Xs!UsyhQOCdS*UImfo0rO!@s>3&a$5Swc!;<+hkNXC63n;9YbWu zC;AQ>yAGI750$IiWVS#i(NLv}<693dMcOYxt`pM~!ys+qFr{43-pPuYNZI``;=UV=QOZYHr>H%d;k&;Ldt~b))L=AnFP<#lYW+6_Q*WiXXwM4E{bA(0sG3L=1sS$~m z-5uysnH-{tTOfRA@rLPeWA&>ty+}H!Q3Z&iv5Xv$C}T%gCWOT1R@Z-y=5^yxfmqVy zxf#y=y50XEAfm(TtwO<#v_ezYxdSFYnqB(;ut_n2+cDDj z+m(HI(*!enZOXt`Y;^yUrIOvgy1Y4LqPHA~%EStR_j1#1*Vb$$-p502?wZ>=bZz}=vto&7I(DqsuA2Ur+*%SgT^A~B(oDQ zcPB+q=3(@kPQ(xV%Bq?{`$F1L-+m+7ck2H2nPTCT7&J>y&Ij57D>oU#4J-Qle$B4Z zq?}Db5@gCh%Le%`{}Rsl6|<}WOI$uHi<4;|2Kmmrg*LxBWx(^zg?(j%gjX4p%JNfSXI+|7}zv_({6(NO=xZb=Zh&ONLJ4o+Gfod~1`hfDUPs{(UQZWA3Q5{d)Xbt+j zWuYvt_iTOmDqC@%OHJ3;QWzXCgw z_!i$rLR6Pedou0`mQ9_U{g8#wrW37to@nA|1Gef`A^GN8w$F4#lh^B~%;R!*gg6Qf zOwr~iKV=4&WdyUAwkUi+6r+u;ROL+yr#br4%1@cZWtqZ=Zd^MFYUn)8MJ66X`%<3~ zP&KGd=f{nC29mc=zWRBZk2uFdlZ3YFE{O@I7OhWe4@hc^>fsSv^{9kR;H{$I zXnD43wS+|A@nKC^JJDbB7&tKaHrt9K`mI z(7}n?xvbx(Qm32&2d2RSL|wO;Y43{3*#I2SGrw2t(#O$Kf&bXV*B;($d_#K(b$p^z zD-k?Z=4Y!^<5xtrm;|E4u>J3ePcYcpmWn;s55UFYfyeVb)59SYU|TfzN*UK4pE Z#Cs|ij7wY6SJJHNUkD7v=0sug5ps#HX0F3Y_ z43H5%fzACOdjQt0474>YLuNM4jAmXgdx@L1+6G@k-NC|PM{v6tF{aVe z*GGW^b2p>8F}mH7hlxU-4Dw;zyx&fu1d5ROU5W!oLlP zQ8t7x=f4;?hZH>}d;w;L|9AWxQZ%UXe}|_3A5s3l%n$#st^5C#Wk1!4P)o1a@V&ZM z#a=LJe){v#d-mgmjpy5%86{+$!jSx{^jB4imVZ3!CTw`s>nHAd)`eYcur<-(Z?ua?Qmqfln`#rj4OqxfsQ)hpz zolCq^6nG5WAToi<1G#%W6b}dOl=uTK@HJ!A@3sD(aWCZwFi_~zB^mAZ-e4GwZuw}B ze5PJ?dP$tz)hbZow%JnZ15$ef{ zU!#`xzZz{=!oW<+pX<+bqalceGe=P?TW8aUk+gSaY!XzKgD}R)fBb-7!>3c3nFxJ} z2&cjF3sN($*HGz24a2rN`jU8S%Jnc>z=$(Q_b3xkd#r0)3Qr?D5rUw9<9=EDm)HPs z|0msWK9R?r&ZlYAK;+4zV0$XC^Y?c@rJdX9tHByb=V}M*{4-WXrLIvR6}0BvIx6=F zfbG47XBLhNBG5=U-)7oaw4&L^Og>;;nDkO>Un^j7UHSRc0x?RTgl>eB|25hAPg)pi z8>@K2$5YFYLRA(icWQQ(>WmJcrG{rN^nv!Sd`@8P`PO?<0F+q~*=j0)Jo7IPQ9g%@ z0Q2tD+D_YwChq|HW6zOlE4ke{e7yY4xrqE{A_i;^K~65>*AfgGg`g0^nA%cEI?9Mwu(bxrFBt*u;k3+TbqPO0DIQ zP*rwgJoRigtE1u-l=c|Bs2O&w2H{o5hXX$Y^OXHEZ`2*0RL`f^wRu-tKPXxWob`|) zh|m@7)t(HX;v4$hSudaL@}ZkG8iQWmJN#nU`z5;8?jLm`^+KpjYN$XESC|R|rzM<% z2Yghe&$E)ElEnE>%*j|kp87@c7t+3sRH{rXwHTO&Opq+l5L8n?VgHr_1!&E~)S8*K zsG$(jX*NIL4k7xJIj>M9T^M*8`#N} zVzSz8-LO&mXSbg+WJBKnN_tmpdW2mlB11q?9k@H!$>;*%AOCYC{R>U99G_vv?~dO~ zcLRo}{m1@B5)+7Z2`PAcaRlCFeopc~)_!Rz=C9Hz07C09Ro>?C&=k+BGIsQ+$D=%6 zg4RDikEUsHC#JWDH9NUn0}1Ygo{q~Jl~GQY$OLpr3!XOUAY44 zwMp@}a0;M5nWA7*m|*IYC^wq^ zamOIay9s)SiN5W7Fs9?s3LXBADvcN%VkdQH(*TE;^~XBGS)i#O$P~ zqS~`^t`iDEqOihshMuOF)Oe73q;1AMyRz>Sv7hLpBEf{3kKQcw>95<-xZe$L)dQ^c zP4qIq&hrM*$zw7M6kN6SEM3qA)~+k!0A(F5WeijIkOQ&(a57*$nKEHhsBPlICQneX z*C5LI)>$5Zd*kWjahUDte@0N0I6q7kWSJ(|ly+ZJU`Km`V(Ra8__${?RFZAX< z6D773e&0$=d=YmZz_MlV>hDvw)lZAO>qdMXL0)bx8Q>>wm!n@RdjZh)I6Hu7e5V2s z1U=7zoHB?q3?oBaX5 zSUAIN`00WtC+@~I()mYgv|fsXyau!GDFCQtPswmvQkNrggf(B>pdan8V!S#=^Db=%J$K@kIhSMflg;eYfNzp57xqL^sbONoJHCaA$h|$BGoNEHzI` z%m<-_Aeh?4kGD}!YLyOk$dA3^TL<#Jqsq7w^);?x<}w=;6sY-W+pAM;eih)kG~H_# z@0;?C=0^D8x}NHTQdo6qPqtPz{`B0}EX4~o`IjJ=IuD>fbdwB7!;~1Mzb>kh7x7&B zey~}{*va^yHvTiUwtLN6H@vABe^X=CD$90ho&mBu0q@sM3z5N*P3G(;!BGASZy|uY z^l!nh8$+|3{>KrY0-3Kq$iE2LIW~Jo?AtoZ^)YMW7Z)`_LD4jagF!(?&$l0NqD_jl z5#k)=Y5*mF|Hoat`dPy6%1s-PcHbeO)cE%<@;p6m3GAzU%=~U+$m{VE@XEVM18q7f z<4&b`*?Zv3z49Hcaeh$&-FS6;-Te9y&o`&~mY=fk61G2Y&g$ZMom$Z)ldG)>#Hn|% zbi7Nceh&>=^?{kWc`_lqd-|GRGNGicL}+=>E){Q7xDefz@Qry`Nc%JF=>{4FU634CG0|QuMyV~T`?_% zp!FJ4=WRE$84pmjN=1aCgLWsSM6a70k_ zPK5^ZVD;(JgtPkZ=A`xhk>=3i&$p|}HlCm+e)&iW#DsRL_`aQopf=%WA3e!%TPoZ1 znyo7L97zFSMvQLS(=!0nP_8X^g0JtqHhS1qrJn{tBS2F2+lNtPO$0^?7;H9%aXc2< z?pgShZ@R7QwS~ST99(F1O6JZE{S$$RfiinxAScn4-~~c5%pn!JH~(O0AP{@aG%W_; zkUq9?zf9w4=G<6{jcDre8#lH<`Ig3gu5CLA=PnMx?H}&b*n9pbU@?yTG2Q*|Fdd8gCBb>RpVwVM*9c3BMjB46`Q<)|GuMlwW3!N z^W+~XTY0&4WkkD$gwKwl=ttDi1^m~+D{>fMg0{rY*{U=>0!1vkXS(;DsNYM1wU4Le zt+1QkYM$>odcVI|dIkW=EsC{5|LM1xRxj~)-$t(>U#BSCkUG%~4!!`^bUd;MNAA{i z5)d>v7XTyOZV_+?tM7fQ@NMOZdzchI;Z03O9ZYv;_e#-S!JJEJx}l8PGhtSzoMAEh7xv zOKt6+M{uPh*wy@7_EKefJ;JUK0Wn;??(^UK&CMSq5(-kxW^6pq!q~yEa$vu-j`~us zZptP1ly9<4kSAWt)yHwVQhz5;`05taZpfKOf7F`d4#HA);uhHOMOv&!@LkFy<{u+k zGQ2-}EdEoBNcb$$kQ`hJA_>*V1YV3`G}OJxu;(h;3_0N$?M(gNz5HvHFKZG(WEtFU(VFq6c zP$$G#%9Rl5;~Q^wV+=m6Bn<_gBm0H9X~Bt#fZ6Pl?eEwo&Ks<4B=lTMQd zqnCQcg)n?`I35U?lf*pF?_>?xS7L6Sg3OuTv1R^8nA^fP zmNI_Iece~Y+5n{EjGk}8Sc9L}hK3dM91BnBXB*xFonrfbyKH7FN64mjx*MRVpq3;K z=RpAy2o9<2q|`(=kfcM>D$prj>j2f7gQV2{T`|t(dDs9*}Xp}s@5*5 z61D(K-Y1W{Ee+hih^#DT@zI%KeY@#ydfSjsLGKRB)a<2N0K@ zcmboB_~1suI=kYnxuVIRHtlq4tQX?>0l28tH3`vn`TCo)jgALBru|W8M=C=@dj8HR zyqggmfo%Kpngwnitmst|NF1fz2`CXWRqE6hZ3 ztKh@;()-vd@IZOUBw4ne6GX(SA-m!bnPhC@%N^uyys`M0km!kUVpeGmT`gYE_)ld- ze=y3p@G@CCH8&sp&@u!a-b(2T5(e>W;`&fD-}oc1xzYEq%` zSLfHYKx;)kPPj8juz88S}ynL4kwGC3)&BaV4uSEoyH&4!QJmk0MnPK23yE{8I2KUR@S-T`6jZArV*K5dzn z`qgQ8ND@oM*Pa}fcjhVHZ@HWyXqQtiJB^l<_sFopTVzU#gxl$M#hDe%ZFbP-C9T1P zAZIS$;2!W{JPn%VA zzXij|25WnU!&#_7{vB_plGF+m?^%~48Up{)Q`QwhMoYoIj^7E1p1H*jaaemB*Ct8U zXc$H5j33BrKn^Yt0o0eYWl%065%Kb@;p{#c@^uI z1PC0b1%;{ilp-&t@IydB!Vq2#z`~D-nSj15%3pv+WYPHUq9qe8s4n6>JzFkv$MP6- zQI5|Lq0n?>4hbd{f9PD{PG!Ea8>zo# zooduySBQr8n@*|){CY^Vv!%m0Tkqp9WYZPp-`uUMeMPYs#N^$&{Y4t99o>pZLeW9q z8hmvg+Qzxr!6YXN1Z4foWrur=PF6#pfCscBcYO%nm>?VmR2d5J&BWslfOwI#E%dMQ z)rk6uP~y5zdThUv$Ludq5IqnNz*cd{*cFA7cFskgGCAHY&NA2K5SLn0BvZ*4&!cv$ zG#0wwV7Q5vi9+vtY4E-G*w0;)8{;~PcDEO1v_jqgf?W!d! z!9Hbbtgh*dWe2IQ$1sDND{lFUmauo46hQKOAJg@0UxQ|2BfI9 z-st%v$0tdHfWbK4!k~c3MivI6xNk(ZW(Y6#6gP?iO7g#v1PeO`(i{kPxuMg5j$7xX zZMDivrMUnwA%xTpMSn_dU0!I6&1P^(AX9Z8N^hKcz{a$1#`y((h_?uYpi@YBU3f+< zgxO8`)!bHAq5_1Iat8?TAn98=#0}i~)Ic|ND_B~El@2m_g;(056emA8inL6IGmWDWv ztwDi^{1nH)+#_mP`5eblc&Z)OmotAw8gMGaOjbz--qg(Cc%pQ#`k8Oruuz{so^N0N zSeVPX?~*f$PQ{b=lv_%G^qQ zMl@f(z7@^s)36l=s*f)DB@qR9VJYa!v_%1ctF>>PC|5R;nGc6%G`dSA&yWPy5Dn~O zXyXl1-mu^;1TEtA26_F%w$)WWWiXghZy#hBP^}Dnl{(vw8;h}B#sBDdw9QpS+-pFZ{P9JF;r_S0d%B) z843Hzl8g8Qnc%#}BdWD6j$RiXV}jZOKU2+Q?Y!TH6Yrbw{{G&@z5P}4Wv^Yc9Bs4N z)|K7HJGpKGyLRF}2A!0gje9;u_WSB!$sKX&qJ#!1XfP0z={M<4FEFX`*Bf{pzLi(Gh=UKk{U+YK`Fi2l9hRm{O6L=oxG&p@Ev?&NVG-p ze9BtzXCqT+b;ec0qSk9NiEVieKeY#NIPHo$EtRtGi}KRm0 zERpEBW^c*!Ke%i;-_#yc@JY&F!ydlP;q@4E-``2x(GSN?(IA~V&#A-pi(G*SXeB-J zpuob^j&&wJT?!_-=eSnw{{YYl`2e_o*Yb>(&A^3#TYD$zQPh(?HBy;7$&!`1SE zIsc=-?Ofs@9t!-xPmNT(e|SVE4btn^MZ&&C(B~;YNwqCJSf|=QS7=k|(mm44_Z)++ zgF!U}6A?ni;C*ZS!m$m#9ppP>uaU~S)L#mDSJt&mC{1+dkB*IzgeF6pw2+Rr} zz1Gz$?BGGin!Ta0bdGGj7vD|=K@*j8O`?+B5_5Lgz3W=I3h>bv7+t*BQ>i~N{5{Iy z!VQla6Tq1zu!b3YW1x)5f{*(!dC&>`gbcsaLW^&Tp{}c`QTz4qT$z%PXh)~C;L<%L9mv}hc~^_K`j0o(oar*ClK*%! zs{un;WU_kuJX}Sxf#itLpk?F?H_wNTt>>RR2Hu7wg*_k?mXYZPPW+b{>6XdEc4x_y z=z{aU#loJmb?e)f)Mx^~*H{|=RjqfZP5#G8esb!6*;j>KHBN3Gx0hemUcMbb*GU;G zDnHeTJKiD#f*>S*q&3^fNy^PfnW3wUrdagPFpWoWh{#LgXU{t4s0Q)FkH}>dQuM;o zC0tWeXBQ8f3CEZwW3@JBLLqWu(>V?n{-6Ns(B+4`6=gOo1ZDfBFjCYSTtnNmJKLF0 z+X(%fr1YkvrkCPdqrpMqarbXam((ym{;dq6E$`VUdZck7imG@$2zov0$CcB!?+pa| zi=_$>FddKh`}&O?^_gU-c%fFdJbV`zR=oeIXCq5Z-7$W_Lx*tu-!e0;76eCAB+T}~fBqknzzWe8TsQmm15Zkz zla&~*Uz*zULZrB+kX`p4x-G?Gng}`|3bqwHkTR>jaDQB?nc(QZbmn`T9ypiIvdQZ9 zPRVWR4Ivjev)^|pPS|t}ysfAdv1SKNEYoqhtmiBkxj;z}J{BXHKG^$?4z%db9Vc9J z5G2au9mKN&KQ_$&2sMIpudWa+kPOm;3?Stbw=nyL{|(RGTU7 z9Gh(H98*9ze#gq7qX?;7ORa4M6lH%El$D=a+Fxe8v_iVkV)q3r#OV^?38wn~r zp~O^#6U5PRDijD4-AdbUvL(VbDZ#l{R)~g31}^{^FdV#cI&jQ5e!O+~tVv&MAsHPg3owse0v!AFU(7!k^yHipD;Te=r9} z?W!Qb1rf306VCpmo%j0u8o8{5z1= zps%%aprWuu?Hkht5C~S+$A;63&zYNok6Z&TWtdh=1ExyHmEBQ+{pFXIJge5_?G*sdP6OQcMJ*1cXKI7HilH;NA zm#26V3-a#kB?tAif~^+0Hh*lo$;o6)G~y}mh4g0sp>>#hQsRf}${hJ^8bGAGrJTK# zXb2Eq`u@cUQQA?Q5UJnxRt>@8`Yo|sUt?p+*{VI4E(YRK-z2D?QQcI)ub%|rk=+p_ zOX{UBj#`%;|Bx^OZqe{A0eXz|g{?vu(B6|Q=$@+)`V5f}*0Z-#@{0o~A)R5H-$^?A z=|rMIpKia$ef)CsJz|u3#a);W_7O6t@J?nG-}`DUGfw~EUf~TN?VIZP9RmZB$3+6Zxng=or$C_QXHW*O>cE=r_koei?HqNd1W1rCEusTW34X^W!O zrG6tz0zSS;tBX^6Wfq2XHH8 zUuON24$gkThuR9L$^S%fMYgk5hTs?pBJf%3R73+OSH9wJ9zIjabtr;?WTnql=xmXP zV5nj$pNSMi;JPRiSVS8j^sR&aui9KuWMCUbVahZ@OIwt9Zbn%E?oHZ$!uKy_54+j? z?*8YBH1*BLx76`Lk)QE!$Il(m+Lpd;5DXFfS;0SWM?Yzob^AF5C)f{}w>Y?A4c z~Tm8Y>2HorxZ)<{Xyvgjf6GpBN9GPN;qSg-zK$})0D!<$L~%|4@{;%QoPQiIO8fFfeJn|cKcueLeSHygdV zXL=qWT6fHh941&oae5tIpDWvx?z8eUj>#S#)U~%?r4-Fa?u4p}D}02E91UhW2aifK z;4E`Z-fSDuM;?ORb)s6FkkIp>Tb}y5-SY&zsMhNJGnMhAH;mvkhU&h!o$~-eQzcOk zoCslgNM~r?bI5K;@p64rIX#GNXD}=RsKM4FXgaI25!uKE&%{pF8)+y8=gWD;0sJ3E zWp(yRci&Qs4RqttL&fU_6WedRN zz9IF+Cp>{k6?#v&1Z!Y!xWlS~sI)veHKdtk;U@ktr%yWiCK4|ES=XL2fJn|rg(|c6 zPp%&Dz8rTkR+`#13in~c2757=TSYZ`TXkr5k#R=OW2r3{idvmp&Jv9LvzmKvt$yHS zc8SD2jj6vVSWZ+%QIQ0!3n<-Pq6x$uzKvGb<|k&dtiqw@GLPjPX3>#Tf^R1@ddZzA6 zWe4?i`7o4e=z68t$wa^0)~Ijpfn*~G+LZeHAy*zg8=!t|-EyV+)RBkRVFPKN(IfHi zh;;TybqG;~lzfuoTr6mvwe=pD+2DEKwNM<{U%hC01S#k0me3}}FdF6KXH*|uCnW~v zG}jn~rrdGy`x`$dOTsg4D&Flbzg3HnGHHvgnB8HVk&4r$0K*<2q@`+|nx~ldK4-LE ztLsGT4{ubrtIM|of-)=+6x8|6Wu`XyK-~4|3y8k*wn=C)eDFpaR>Lv!6@J0+<*E;Q zY8eN)b4HpVB3_8+(E3S^L=iyIa?}e!WT@g#m+R7j^lpUW>Di%r>^*#fed?w$rO*p0 ztB%2`-^8NRb@zcqFwMsc%22TvARmHa>3&Az<-Fg+wLC^Zriz5a!99T(M7Ad|2<5pB zwu)OoFK3xk*iyy}lZtt-V>LV?OYjTdr2uDnLA5B3b_3AJ{*ih&vg$?xxdN2pQ*0=t zth8F8lt73hX9ej*Al{AA@XU-9Ih(BzvKF&fHQ#TY(0zI<%0`0F7YYE|B^H6VOV0q{urEykf~I9TrB-APmUAw?Il|R`jo^|CCnWj0C~m;50T2-D*TJ0R4$^{GW_PCTJ$E>E%BT(H=bc~V zeRNgIoqaU!gz_qrVFO1&P0@5GMa);_S_@N~*9fT{-{2^O@t;Y4ct@KQ`sqIJY#ohSA|L{Jy1-%BF8C6! zYcP--UTlT4{2=sY$JcybY|zzxcP1mCzRvy1rF4c0G{t)HUKnMmQ<{|dZLc>k^*zwq zHjxO?N)qo5hK2ZxoCaG59~G7GJbuqgL}BCQW4Jeh3*>nMH@ip?0dqsoNdbF(FZCU_sr~s z+0cFLi}~Wm)JiXL#+`IMD)ApQ0Xo^!PYMD)BgpG|zam-WMjJBBY$9%v3w1Aoiw_KA zae(Q5<#FoomnZnQ)ErQ?Hw@)(S`$USN#GsC%b)hXZ#8kPJc9PPctq zFaCk;c~s|W*$+XTE-Mh56q@|qAj!MVBj4#iDDCMC{3accVYv50h|}GJbpNicqa)d@ z#)z|Keusx7#c)h&jp0|MH4odQB`&g~9PO6nRD&@fxIA9`C{Zvi{q#-EXK!0d^Ij(4 z2GC1L%i=@&b^X$(FyLE)_~HR`6-l#&w?<#n;*7_qBy>w>M~AocP;2~UAp$MYK4WpB z=1$ncaNVYUuOZC3xmc}pS zG?qqVplIgCG$MEecfQ&bAmp$sb(Bp_3Tr50`pvgVU(T@2H6c*u8;`jgJu~t58k_bI zywsax@KJ}f9q1w_5 zYz=L;n!wdBLdRED9<%4V*aR`Mc|(EqkgUV6D@R|c<6+@OVo${eZ?4EKu$KHxlfAfi zLU-GlBi|63(^F8+N_FR}DtQjkTz?$q8?(fG+j(#fxnlnIttlI1?{xVpOMX+e;~4=L zuTar&7E2*qlmi}$iiqrRY%4U+67wv;zjaP(eIvI0TiD5Q0pQ;{C{xSe%jbNE-{;TkH)oSgFM?v6Uxiah5c5py}wq} zIP^4NC3k5Ep0fd=r{%2{_{0Evkwq_CiiH=%k?M0LYz=6A<;hAZl%trH1FFW;blKaj zTunPq2`wAfMA_XbwkzBkifg>0`aDlGqP=Xsu!%xIz%ud+yNT!7{Vc23*Fu5RQrIno zkCeH7^4T?H0Pg|qJhctg{R(26?cV$w3WUj(?#sUiRr(93Qu6 zo${Vgl(5fUu}I4~2f~B7W&IL*EQ{sZ>w5u zr!i5CefbKJ?n}G(w9=3w2}*ZOD7yR!%JfeFNLva?FXGJ?*ruZfv}Bq@AQ_v=+L8Q| znkR_k2`P{?U0OeaJat0u)4a8cBu3}2_gzA`KT3+*f3`G~dKtQNlExlJ5P()HK_2fR+U|3jB?yxU4w~zl7V!pZC(rVsi(>CV%S_A z->`GzE%Fd_dgwE$^Tj(M&j?Mcqt@%M8=u49#bW>ED0AvY=5xz z{zg1#5f3FX8YlEjK!u=6^O}3<2zA7RV=8MoT&FCi+&EftW7iF>^=`h@KjuNmoGEva z95BLGJ%@n-3+OYc<`c{S3ihO9YGLRpv(0D?b@VW?5eJl9IP#hUS=K9jAe*6GCzd0{ zYcW1I4&mK)WD$pWPDqfg{nXKqD==*66mltlxEZM^1<>SpErRp4plH51gi^R#^)9vX zT4ZTa0N-i&vDk+ZU3j&og@a{me-2d9=p;>%*kl4P-G|HKsBKN;aeM}?Ki&~Bj#m6b z6LCNLIn?)I7_Fi(y7TOslgM)@O4rs|4_D7m3<9a5)AoOzd}8^gNOh5=8p+Xf9sWti zjrUd}V~W5km0YI!a(;Bi0TN}1ucHy3>Rz?_L&cN|UuSv0j^cH@-yl1zRWtAWh@dkv zZ)Sur5c**zQq@F#{i_tQ?$~Rd!_pHHjh~!<C*C`f&e7hWsK5#lPb3S z1`iRt+?r6G8$J{w|CEeOQ|LaLO^lH)mSfn388nrwKv5I#E@O7S^$?Nu6mIk*eUwDk z`fhX6Ej!-Yk`668nA=JKb}H`rQk8n|y)Tzp)Tl@m*nLlQALY$9`yDcVnaBJR3q!Ke zpR6XsOdPg$jc_qB2bd;u^$&3&AW-vJ^ZUhW4DFxYGzT~RW<5&oLlu71ERBk&y9a`f zzxgxEXvGdc{*#U19kZ`4W@c9!oL4RzAMFj5(hi&$LeUkp5qGF}z{*D90Tj(jkuBa6 z9BMXPTQ}cPmqmuD>!6{;`QOx+y4W118l73u&|W>WFFPTBr8)5LWx~*MeC|G>9-`6@ zMO4vZ$FKZ=3{1hRq;x{k3FCy2w70jpnXw~f^DzvN^7|8+tT5>!zR}mD08_ww$>fcO z;Kxtwr(^NhLPGB@)}U|}e}j$C?s2(k?3AW_x_Y6U!L+#3rD>$7KKCDnjgxcEO#|$y88T-)} zO+v7DbK#0?X+LzKAYdSg2;CGs&X2?n^NgB$UxsM;w!2UrE|ndJxF*@)v`>l zwOHGcemZ-3ICRO#tst^*N5sqhw%fBNEgyL5Q<}bqGwBWh!}0#R#=SxT<>#4@0*R65 z)|RlfAYk7uv($;3bJ2hOJn<63DxwECtf>6@Q-X`frCH$N&#>zvK!4@pcE83yI2<2A z7|yuA1ZF9IoP_w`*U#<94@L%H$vI{q=-O4J$e0=9blHZ!KJcpxS$_W{R$yeMfxkIX zM+bPmVYb%}SmGl{GwZh{7jiI(W+6gjgU4-k&Qh^_Jvb!Ob}ON{^W-(}e$Smz(mQ87 zFA7G^#nsZEsdF2OLaI+pw+gqUh{8DaA&4(=_rW&ySh6QqTi9H9L!VHv$(t5$@FK?g zemJ(wo$oB+M}4!3;8W1@`VQ0-SD|Cz09;tweLUvD4M-cl4`>#DLNC@MDO)3pq56QOsQ>Ll96kd-S

t`@D!=nY&VV^=NWY`{i*`N zn?h24s5_q7OP$wEOt1YNIt)*K#F3A;{*Rr9{C^J@Tt#xHNwBjiD+JNf+!VY;%Y^Do zj8U1;hCZR0aC6D{Y4XVX5AT|^qna(>DN5&%@v3tz1s7V0+aU%Dt(P{@I=)3jz;FIq z)rA9|!}xLC=k-v+4P>e9q$=k;DCCpRC{NU~M9%gW=s_pN={aZOH{f5!xIt{OV2^hs z0bo(uV>(`nL1d~(OrqQ;E(3Z%wfJ}2l_TLrt6f2{qI3couN~QTILwc}+3wT(DWz-@ zYBKY`Bv)ePel(TZN&JE@(t6Z|GX6w1nOfsH{vpiPjuSfL?r@46AU;g=&DAm1CPsC!JBEl%d^_zJMvHjAx=(| z=Aj90k=O!otFwxwKzw4zm4lSn7=jpoT{;jv{#xhER}87Y7uJd252?mc{xepm6X$xy zz4U{06+Zu;vCf1Rkw(d1HsK!&XJVi%#QiQ>lLXR42+myvCq2T`EU+(qkUG zXD=0NEQ>rYlQUktpryu@ssvA&~1nP;aUluZosMJ zKi3|lol%~uA<#P6;c5`Xn`-<%?%0FHUtEdM`E!7Rp7^ex3z1?#Fx1_vDDb910iMkC zit(Ha6s-|3J+t;5wulVzFQ0dLu&DlHBU5G$a&|(#e9)fV<&`ZbIQ-oO@NWDs`Ld~a z`rDRheMda;IohrC)ku$4QnF8&K*^E+td<4)SRSEYC`T`JYZ4O}RUKCx)?|k~I5%5& zKlv63=sE0U(b3H zuLzdW_#E*^vZLepr{`&D!TfGz6fK?K;G&&9pu4mIZ${3qIgy;4_r8<>=A_yP``R4j zVE9T?xSa?4I*(KLmZv)9g#o8<_E!UDuDOFc|hL+ev#I?xF>{^yqh*+_gCQuRwVR&VQ;??P}03@t55Y48FH7r zIgu2&5d;=*u}Rz~arb<)e@~GZU=DwY?s45~tiVe|#olyYc+N28{8=P;$ z_C?V)F4iG88MrWi3+Lfm8be)naL&ZfI@%x`X#sLp__jo|j*hozNpgGtpz!^WBF{TX zw>~DYcH_4@8NwK8fr)O$jXMycn?_w%5;VbD*uB`}$0r8Y@U}n5YEMRwRLUeM+Vq<} zSu@qEPg`%b#((!~R|&49@jFjahH5M-tF4zn2*6n8A1M-}TvcNQ5CtNH!J3Ex7;4E_ zS^CWu3jxd!fW8j3>$>A@uBSAUT=7cYYBo^kD*8aI`0*1lzJ`MvC9vCem*dlKGTSb8_Wd@u};NnOtafAA8*LUz)y0!Q1LLxn7d~^UCKGndlRdm2s z!YL-J{bRyDk#BrAPJi!|=MSQU)|b%2<#kT3yY0}M^$IEO35fe}_BTgScj;cVGJgy7 z)YyG#p)bE%&pY|@^}vDKbErLy^TjZJ)TG<8&V9m@QnBq5qid;Ix%`2@t2&v&LM@h$ z&xRoA;duKy18IEDkDG2ge93#&`b0iD&IMm3?xCrs%7?vUIV2B<HgXelC?(f zN6T8g!dXp_Q)HaAHkC1cD}o)pttj}70_j@Uri6>?dKMnsDtsq1SxC74C=b5IBmkd6 z!U$F&;Qd3>q#isj;JVp6cXG);-fo^NGzw2@ljbiGrMC2liYWki^6c#!4mrWo z*5)#f1H$5e2#Y@;OE>iYUyF0mEz4xw^k9H=_mW6N;W#2cit_fJK+QQXQ|hATs{{pScKP~N4v|H~ zx!X=vZtdwB!s65SHS}u<>U)XG>HkHB_nF;|VZgNN9?VH;(>=UEISb4BJ4JY5Gj?y~ zq&DV(oo?+VT7EQP97%|<{ty!}@ojsvFQi`{WCRe_7yY%XVX%7GNHl7RO12&|7*3b7q}%51DDtEf|j**k2b8Jey9`z`8NDrb{ck8|LG6;kU9_T_O|3 zXr2lQFHUT+I|}RGRG03<;%Mu5GhLPsjLb7E7d$}1Y|$@YSH=>=d;F}Suq9g-K+=5+ zRJ@|yr_-(gdGV)d%01x33AntF`zozryeRVko*aX=#26+!~q62Iu^iY+(>)@j8E&nI_d>c(odY zb-qYE`_Q65N9&3r7ENOYW%pi@96w4{=QbvEg~Z>zE$ImPn`&O20 zL$XBK%B~qp_ChL>HA416WSg;MDMDn4vScknQnZ*UvXtzhA|qwbkbN-s@Ai7V-=FX2 z_jr82fBDCKu5)c?&bgN7mAfx{m%Rg|NhKwNMOsoK94U2febkp zpe4<=8Y{4LLZJyM^YvJZZPwepzXD@yKt0m8#Oqa$oi!Ucd{PAg9yhd2I0kHz()IWe z_}+N)jie^}&*9kBE|K%huE!UW+2!H%(x0oHmkHH1uO$*udZv2gt;o!{D|k`3r#$(7 zM98!P{?x&x0sR)9-H>^;(p8N$Uei*h+_luF-a9wJ((O28kI1KIret9icSNCxYKfO- zvz-Ds_U*T0z?M_49>9DvUhh;Kc8WNz7&k-ndj4aXOEQO489g6$eV98=a-^A=ft3jn zu^yrppuY8k`Hg@Pmw-EYfxf+VSvKHrwG93qwWzsy-CMM|zkUyz#sU z`%p|KoaWhDQmN$T7|5U+cq1DuA1i4(;yc#G@TTREZlsk#fer3**I%xB`tn)|2?L@G z4=iuGUg+jBu0xOwcBrVnd!>j%v+Df_VlBr;Obhhv2qUOrmpc>b)ie(^RG^++3EIfx z)7%&DxNpE1rIvXMyH}%Jbjn+oWh0ij%XEnE#FqZZvm$1^fx7V;>Cb$~O0l_BWZa3G zsQ&!5){pZwemiiP`GL!ALW37R?z3G+;9Ga7h`uj}5Y8P>6HGw0fag2>+x;qsh?OaK z+AB|7-GJkvk7w`gXVhG|$q@8WpfsJ)FG!AWRBzv^t&1*WLFmG`j%#`bPLV?NDf2|O z(>FLSN|d5wkhCtENkUe}lN!>iWqv@mxN0OS_@%D?L3GJa6!G2WI76|w8G4??BQOatd}HWm*A(D(;~0-;qfY8szxo=>#eZu+BgX7aY2Zo9T{%28`%Zk0=G$(X-FK@@NB5mr9t|bB*vW}E z_t6J)W!?<2%a-2%(k2XQ_d%)npg>h1pz!jYf3Za)YU34@+e9Gig1TeCZNr}hNI5QM z64~850*pRTxenG?2z8ufpz<{O|2D-F3N<`f>I?xUGlY><`G$MSTEoy8)ibx;o0ctl zj8``a0*tF&N@uv7SFRrn$K>=GDgn?5p}58#vI5<(`kJD(_*gMUDaT8Y`G&i<8WYe_ zh<)VHYR(-Sl6d;tOS;y50+YbOZ;AzoKsFzh#msAwfD1RCtKPNxb?pmPB0jkJ*R`bO z*YRAxHVIsk>m4d*(wtorJ#kM`&H&>j0;hqN3WD6zRQjhzn%Hg|@Dv%i!KseHsv*G8 zgk9R8h;ZGZKRsa&UOcYc@=6wo+F0+*EqJH zO+IKLc~a=wJ(YlL%><6ejkYKdw>z%uV;p}%`$atM4j*pb#;KoREE7%AS0qe?zdAvY zK7Q{Bk~krIwAn%8k!#c4`+N#J1rIB{ zSJSLeC>2-`U>&`%8~p++6(AE^0Tg~)Wx zy_NtoDOW~)V?TmZH%NWQ=ADcWU=h=T{>Lua!AKx}2;hD@A5BDZKS$!rnpGzmBOb$b zq9ocW6qy@W*Thxa1ize(NB&4(fb9Fxg0}J6?{$e9@dnHdI>@F_o+Z%X9m& z7YIb)+R)dt&k?cry%XZiXrcq3_6-Y11l%#_vU?&UNH6BH`3-KPvKwWs-qy%l%8ZK( z3|xo$IW9vhR2cxuVqF$-zlBO2|FzHxA$54U8VDW7^cL@g~5QkI|SihZTr zb4|+by9%}|EI}dM@bC@8Cq2Xpg|`iDbJL$5B5tgZ+C0dQqWpfGXxP=+V8g&DGxHk~ z=W6bmvUmnAzA<6+`+a7y)msJawIx2hoHGbs~B2QobWVd*0wH-ILUHIXs2K2a&?^ z#+HPO3}!lAQc1tJwn3;~Bwy4W+oO4v38uNDq@4kr#0z~7dC(j3xhRXTQQ-((JnBBb z^Ege7BFcd&?o3h3RCw9|&2wU&?f)WD;A4XTav02AM^d@@fsfh4>h!y7lZ*^w@8|fs!o@*tY|PXU zwR3eo`X`bcLC+Q3_gr3nGtF7On`4LU5Ni1Sk;^+B-od4<&O%VT{XWLOD0l@9{l*G1 zy2ms0JRRp1Vg%Q1mx^1l?}T1meflV2F-H9J4|6si^`a3=Mn!J0(AJ8*7&_)ds@yWO z9XOIMAW4c!^%npmNxHYr#D4IfnLMf;!Eb(L!_7-knHF1KzzLeZUHgvOt@`2QbQBXlwxJqg`^s<+j*1Txljf-k|9knR z(&H(lpxrYz#L%^tqWVT zt}ickG)^Md(7&u-^xAp*dffVL_d)Lhl)$Lx#MP6QRQ8XgZl=d+3z9)Z)Tv1Y2h#AY z2YF$nzK56;W!=2*s?**>BBr^#EkLR1dYXfcb2oHqigvq4O+3n2yp-$FalP31ApOqDm{@Vuup_Xho3aY3!U)rZhLXMNwv+G(b#^PPjEwKd+!epkG&c$Ogl( z_1|xEdKFbO*^Tehwp3z&(H{)Q$G8GCtw^aYdv74!ackGc9DA*Q4NMa@uyWU(84w4E zy&~6GLw*Yr_|Iy}t8uMy(}hj~{+7Zj$Qp%U6g~Q{echCw>;Qa#^5Gu?b2J)@z6x?? zIr0}adV6yXcJE02kNPG5tNu1v{dz>PgTz9>wO#68^iH^J90u5uRTFl^l`SL!j(FV* z&|5}(HtjP81rCJSt=qyx>636bls2hsIs57OyfL23N3>$ur*wWVx|nbBzm?MWUt5NQ zKME)IPZ)7x;iizN+4kCi)7@0$aud50wkmabToP$6z<7Dr-vJY(v}F9RUKH*ioQ2n! zLjC?RFty?|XJrICNl+zLq*}sZC+7sZUMP>gLn79&1Zg^X+2DIz{;YOjQu&`Cz za`LO`@S$xuK$}-F-WLbQwDzs)9FGs|Y=~WWg$$(EC=WYni~MW{SY{AlL-7>uZ}J3n z51#`d%N=c*p?CJ=bq7H_ zfP#a3rT?&D_P^OM;lv38ae!Sl!yPyjytK#0L7gj0;R2T}&@=7e@^0z@0mc8yit{#t z5>}~G_YV&j{mv8jc+j~2)NEY~&UmuHmUZtRZ#?>6Z#)Nk<84G#GPsK-USYTsf91g~ zCaxKi+km_u@k$AQ0s78`Oo$AE>*8P2`&SY^0L9aJ{Qvrg+zChpP*SHoUmgAGF9btZ zF&eK!rhA5~p7&qFRfY}s(b1?zpa=hMXGaZMEX;%i@sNvqd<&)7=O1OlIC1ysS?78Q zCDDFjBL6viU6g>m+LsmY1B6-H+x-uq&HwTcP9fJP(Ht)S-|76L?@mCjMH=b+nS6t2 z4C~heO9sG*DQ%u0r0@JP^~HajFo%uuVyojH5A;7d4ToHfMU0W)eH5o~sHzo?3GQhS z1s{jFgjxg{LCHE{cE?|3*eU<&QVWWU2SkuoAMw(#A|ed6Gb=^x*ty9}6gM2haNAB* zEv&A)_l;C1E4I*UUnwji>*Avo9SyX!_>b- zR+m~3Y4Uq@ldWG)bc>QJq~XW06MBj3*cXT|7VljZRr^1x2>6ur@A@1)kOUwHV@&{t z2ComFA~;SkWPjwJC|-Pj^0&udjK}`vT!&@0m&+dbzp|L2RW>_2XePd(sBx{S zC%|TCgUzJ5_0_ErUUQlbICjdj|27~#p&yGxY1xC#(Wi>7UmL}_uCO7!mE#Uq6M|ae zWkzZC`uU&cRSYB^Z%U9&q;}<8&vjMWppUn#IOTnZzk2^v@xxf7tl||87H{R7NB6!e ztAM|<9{sbHEAi-@9yeuQ2K`H&mm~@eh;Z@n=r1IhKjfxLciV$#;{-0-43)E2b{`2{ zH=G!n)|~XI=@DeE#|MUuWzBoivHp@g8fMs3EnN@ zm9P}Wn_dj_-|c#$mjqH3XU7AA6N}gsksz4v{q{2h(dqksT@5wSeS=p#8+1jQ)?TU# zXWqS7Ae0#x9;s{c;P7)yK$ZzKwQpD~9nosbs{=Lki3K7k!yzYa7gG`#LJrvZ+Isly zR>Qd(uv ze(CF!q4944mstEF{Vv`4vvx@8s>&vn}W<}UT-9*chKIxvDC*^sUC<-5B=^j&7+ki z3@Yf|3;V7hR$F!buC>hyc6>O(fOYZG(;Eh72v>XhLOM(_+h@pt1sr=%rcXbCvl7C2IYi6MEB9jg;coS)$Oi?nAaFSsdn&aWdGJ(ow7zmENk%a4@`5Av*YdKK8 z%%7y@Fr^Ue9*BqQni<+`6&8|_%-4Tm6?E#i*^W(QWe&w$pEvUsk2sipDhQU=xjzt%(mk{r zET3HoPRFFZMwZZ?HVkoHC4{7{y-jmIm1?kgyH)7uN;Zm&L8=4KY8|x}hKi)v=TZgH zhNC=fUL(tMYJcJ`pWbzES-q@xBX;f3*{Q^B4&e4^_4%yxx8#;~xoXHH8ksT|&Ij@v z9%Tj?xvosahFL8G|33$LYCWo0o1yB@rOYzbTsx=AzHEk_l1P7nKp@HWHM;Tmy{z0hF zwPATt{&#DZ%IV(MdgFH)g+rb6V(++TqlhOF&kM*(Kku%%aD(h&NYdNjQ4T1~h*vk_ zUN1O^%s+hqSt$?VN_5!nzF?U6d~qpzsOA$uxC0`L&QLplbDsmD&=T!K({e5#o30uW zl~1lwk4B!#4fq+EWUl!Iu8N9vC=%vi6pT6>z>sGJW#kL`j)#~NEHOay@~!Y=?$8AZ za%ZM&?MDnoIc?wbZeeGIkyH&kKZF+W=Hp0eKEb>lM?CYy%d{6p4 z*gnqzV$rMNH_GW1lMpyu~&>W-eN%+4sNKEI|&LqiNZ!#MC{Ws z0dZ`Y;#+{??8M)v7gHC;#Fv9ntcA(JYPy9We+za%oDX4gyhRU<;jjV5xy3(P^)#$p zb@jAF-0p~3y)Q*zont1Mzf}{@yUmQZnOBOGF~kw-%SKe@2zoaMt_jUwP#P5TtX}&9 zH>RF7etPh+OA_F;6n}SC5SXvEgmn15WSXNA;e5yQ)4=vL^Gi)2Q)E$4_=tzAu;_u6 zANHNFwX~PO=rUK}&QqSFlprJ+{k=ggM6k=DpI4g?kdoA`n}pc}Aou*bsljnWl-I37 zS$jfZ!_Y7bj3}!uGwt$$7qLF6t6O>)P1K*DZTo-K0dbr%18foUD6|X%$YUZFdo&(D z@P1#Pe>(562u8H0Nyy;*RrTq?2bwI@h&YX?1;Kasf&dgMFYWp5494?fUKv5>dilD# zfF=FZE7zXKq?EY9I|n3InIfT2055b*eq$nD8Y$mfOG!D*Ky3LzPZ@uPxbg1#2KDzE z0-r11O=EMBpv~yirdafjaCIn6bB@Q>oMaX`lV@ziEPAI}6wo61H3!(Htz-fGb9d$P zU<0EDNt)x~kD^HWDYRRz4a5sA_|&?~?COf0dBO#rxA6oDdxc66TX|yLXcJin-^uB1 zX0i9NUJqbkQNDc-N&Jk&7s)PuV{_4?=|Bmq7tuNgt(|*&VW7Q78UN&H|@WJAvt9WWpE3&6}0^#hx$Em>{aZoG+R2FVD4zmfFn5eAIkN zKL;TnOcTbX9mnsZfSr*tSsYgGB8*;Sg?siRu_c$Y+4tgEXe#;Fa}JQa6>JGSpC2z> zY`lG38`ZX2nwD{+$%wQzC=G*i8PA&mzm4(@$|py?^fKq=0MatnxyBcC4~c7k=G*?WZb!-?W;8Z9u$!SDJ)1y`8-HdC&Ja5f{{3a zmn5%Jdl%7sM;~fMbE+UHS*CIbY&EjCocUW>9>zE2%jW|K@|kJEWZ$t&w%W;?Er)*+ z6psGjfcs}XLnX*-4S?)ff2pv@*Y=fMNjMSKb%yAh8J09m=e=Wbbp!R9(=3HR?U34} zT&r7*Mm##uHKu79Aj5BQN^?JsSkB*fGgT2mDJ#AQLtqyk29fcFV;cCNoZ+X-ECEaj zoNis}akjq`S`JST6l}y+SZZq~lE5%reQsc^JTf~>NKd@tyd$?D4|<1Yln*&e$awT~ z877~$l0QU2DtahS>gb<7El|wLGG_`S4iPPH@BHY1PHo95Ys+5n?omQe;wA2Zr$y|g z$lg@S^HVi!vm@p3)p?1LQM5HjiHp0L* zaFdZ?#B5mTiUc#`Iszm;?Af zm?&}A!J~F>7LV0gz!E;-$Ea*7r|4slloylV@@UyMq~m-)_l?GQd_f#JJ@Vx8)(yh1 z)B*}b#(e7PhXsSzx+RUYhnqx1Oj`9lw~2=(((T=xd^)liK!~WRd2~i)(;cZf3%M+9y2 zu7gbFlF$Q)X+0EArLk0r=|0&PC&XvvV(fe>BAyM-q4@c3o9`Bjsmw$`;FFD-tTV=VN zv-rk8?mp?+mQc|z@xzA|%%e{->HBq+zU<{m3u0=146A-WjO&F;3dINjxRLbE#M42+ zy~-*S_*OZU2)Yf`)B6w=H}Ce_IYh)Htp5IW=%S3SdNl4Y!o<-E_6Y?QRI!is1h$Ib z%IJ)^c=yTElBO0mA=6@|R)@SkvCS;6SgzPq>CdkB%D(66w)z?-`$C^lW`&^;72_k9 zg`s>nXe)*7(A5-0KKJz&-#me?W9oE19CRx7m_#9Ik4Zag97Mj}VKA(E)Yc>(lh%)x;SLqSTA zvdlCVb*vg|(ECM;_cJTYt1ysb1RXpq>Cm%EnQKWC3FS!YsPvh4q?ZEm<1WTu6l25a z*ukC8xwuDvZoK&+@TJqDPDJjV=}$ySOia{>{1Id!chVFbgHLVK&)IjKD?;qBvPBv4 zak1>s?u`x<@j4)LBNzoK=11i>mJ+28au0g8gh>14y1XN`po!Tzt2l{zy&xY>PwnK{ zn!u6eu{@Bfwz<5$1k@fXv@5&3b-LU={vjsqM_MSOTp}hD#{6=uFTvpBCG+_CBBERM zI}k)URQ~Dsv+aOfkbnfekG6=?$W>+X!5PNCyUWtsKU^SlWsF*3;*r7vQ?~bGTg3 zb~eaF5PNfG*=Ghg5K>)@@V&^Y+aMmdf znhs1a+5~D*S9^XNRIB-_c5_9FK2ejp7q8eEG}tEom+p`?8t4nSq!JJ1yEJy{j;Gb1 zBq}qPC~A1lKY*I`Ia$D+gQ;+TjbU%8=?JHUPUy%4-+n~Ziz$iq#?e*I+cacd6s;zQSeg z_L)Dn_fPFONX|3J{$viZ^$S~4D>O!@DQYR`UI+`Ad;qr{DOUaDMLU?nATwZ<|Hxsa zt*h9ho#k^gr$;WL8R|WiSH;H^w4dsj64)?5JIOd>Kg#M|9<_7AZ_+cY>$JIE#8F2V*ox3AfED}=)&ep-h#^BlyABjvD5?(B)dGB1 zt>u`2-dRPs>U}LEXO-n+U^^AbBEJ-`vMN4M^ZmnWd8pJ=ww;zi#_q&a7@1i(gT8%A zS@Lwyb*5#-E{!V3nuS@vrNxb_LKnNX2sbqd{Jd+#Kn9tL?+APnruGEw<=6^=4+K5g zWZPg_5@L38+lPR4c_PWUM$gm~nJCoVn_y1z+dmNUGgn=CDYfHI-g*n%m0(Vzs&y8I zE`JqiZBb7cU2UMfb@dUaCA7FGt7ma63oB!Hj8wz(@uF z8;nm2eji4V?k}BGy(<647#(^z%ds@`ePBBi@J`@-|1WQOrK|5!Jd|N^mc8(A;|!PS zQQVWJ%hmMy?;)N#{KNBtQP+?;FiG|9e8?teB}BTS31bCs<)%64N)Le2`r5=cKPHTOH&Hh{79dm(L!@0S6w zvM#unr1Su?x(3^8zEI<2%BvFb-kL)Z>G}gEv5BBZe7azt30V4%Of&mKsw(V7Y0S-$ z^?^#6<+-claK&8f*FPV@bg?FHOURF3dwP@pKh(Nxl^9FD!PHdU3_$rFHPr`@8H^#N z5O6A*ba(0GoqTC?d8D@3LqZEeKoPGM!KIpC#F-oApiqjtJ~~}gQ2hO+^HJJgI6fDi zv{In`T11dyZ(ANBI{Shd4ZB0WTQ?-vwe>ouB0JD6NifYXcCJM$Z6D%I+mJ4F_&sz1 z1Z+}IK2_6yM0z@4Y2!!O zg`QA{+E8hXfHc7t*|9qBB^y~jd6aXP?Q8SRz@mmB8ne{y#>@&X_T&N zh4Uq$M>QcDN|7B{w+PbGW{1C=p>=aF{O#?T{Bu#8ANDYHSaz#hu!auHcZK5i=fK-js0F-Pa&!p$t=L!$D;z zxCPzuf2cg9UHVz%Wbi$t&EB(G%(b78stu`lgpB8@C>K%(=UPnE$J_sCcfqEf`;V#f z_x5`Zs5m#XKjstzhmnOT)i;|Hw@3gOa__8+78Vwm!Sq}*+c$6RQg!z4Sws$sSoA+4 zq+%Y1Qq}^tyYpBh;okzCzdJn-#vJ@lx6=~Xz@~4$dp8sU6B4&l;P3zDInaK#>!t46 zgg)K?6xSW^<2OU$S(h&O*)H`+Mx@snu!tbd{SH`!PNxR`FI%uP#VKAA2&JSrZ+Abq z%?ewB)ihy!VbP5^fQYO)|1vV4>O0td1(sf_1|b!8r@MARx*7w|#Rn41xRQXItM?G^H};c+KN@!^Q3VYM<#iIa+9(n#7Wi$LI1jLw%II`(GnTuzx6$2-9F#7A0lc( z^&TM`!H4^CFphOKgbAdRdh$stNnuUT&;Q5hl+Y4*n45klBzVmLmm*;yN*LTbL%wNf>1mTkavv z0(k`7ANJ2V`@(G2$S9y4MJ=p#I>8Tzn+f=QNICp^h*P=Vu0A&$jycs(yH`KVyAe5z#L9oP z@BKRS1WzyiqU(4DW}zqN_5jQZ41U%6arx_5`f^hOcjm&Zm4xOlg{$ZlDvf zLi=Oi30GK(Jw0W0@!7w$$}~GRqHeqhSgeRjEQb%)BI;GB-Fqo6gs#ElEC_5f_D-J2 zGp1r1G1YZ69&9bn_2}tCco3)wHqC_mZ1&IDU^4GJurbv zT$wWa54zv8HS3@5CbXPI9&i^j$}Z9BYFS1eax8-en?tbbuh}H2nTz9>hn?&@j1@|4 z5OcDzVa);`C(TZXU5Qv_;3f7H+5Od+pN7$?UuTh%vRg-0hMui9t<>c75bu9&>-#-( zXM4%uor>c#Xtf!x`TfMm{6lt(^yw)nRQ?f3<}BmgHnuuMEN)#o`xv&bFSvuBT*+Lk z#E1Zxh7#RR-Y_JzwiEVSmW)ToGx^BH9fchDVV2ya=69{@LXfon{S1b9?MnK^u<>$0 zz8ot_-M2Vi3gZ@iNU<1o)rxx{Dg$NA8)Kkn@J(9JV^r|^loV+VWhN>$@v5Z3u{ zRK`%Np!HDcY~VCOY+&CehwEa)P?)#it2?rPDv{Pd&O#ra0Y$83dRn&OB{yR^DOjsGG8^-ClqC1L+NzZ5rr;RfO=Df-nzIn+5hjp`hQrNC zyRTuuB!1;OwzTb3X{2!vMuNjf0Ijl`c+vIGiWxd1NC;Q}W~^ed7;v^FBvG<(Zv6z| zPS%(Y`%9;O!m}Bs;VgO@42k@z2AMO~Hq@o*V)?m+L089m7pF%J=K=PrL^f*IH94i$^4n-Do#I5D!?rzCu&>0k7*GkmiwyG>W z0ZZ_f2E^*_RV$~QZeI)kU}^-X4calWoCz04iDVNA7FFH0;e983W`dsF3hS zE+8JyK>Q*2d-jIOp+}5Zc%aeFRbva`=kzy{**K4W+_ZVK94c<>WaY2BVk)z^?tB6a zS{&A7)p^(3)!R^{tL8F6_gc?c$f9riAs~`Pg5nQaeWgEmN&l&mTV+_C-Ft%W?G&vg zDFtQ*8B6+2^BNILZ#}J2?fd!pYsR}w0(Uht=odH%(t_9y#nWZk@bC#z#{+_U*pfVO z`!;g8CYIJ9|9AFn#x72OPxIP*`4gu0jRcQs(x#78jSB%1S8^uk;?V{`ahAOT;Ei}w zk2z!imfm)~me!}9NPAX`gReF4gajibdyoQ39*;2Au=BZ_x5Sb`f7G@0azhe0@3!yS z-A9j|W_|>dF{6eHgP1hSGVL7WW%`49`p>}JuC{MwBTn-u2J!Su2>i5aAyVX2gs{aY zPgJym2;aTi$?YeH6y_|l?eCgE=Bt>}1C@L%C1`Km>DFHOP=u|yhWbGc3=!VfoRpk7 z{Po!2E6(5AZ>h3i$u^)|JAcG(owON2qoK4+;PEofO}Jp80!T%*P`CKPDsS3Kx%9zn z{cCw=U?f%(=-6M5YCcm_1e`eQlr8pyo&SA4^j+vY@`UXO;bYAQshP4N2Q8P+Ns*~Y zyZ~QVxq9JD*gEboVsk?*&zVpymNRJ~68|E<4pEo$Z4&LaGh3N6+DU`k0Yo$CEi4WI zo`w|WaTipSSHKYeZ^=z)sMbMJVa$f zCGR4q6OfIX4`$WU3c5ndx+v*z4h@fI+Wx^@$yfKT1EE!Fa&qW7RA)ovKpc=QJbr*5 z5dmb@%KaX#kOEM4@-wt~%zW_bkB%$z2@w5+BVVvTEzu$ro<6{USxA-#36 zrWDhqckG^82b~iH+9&rkjD+`pO72D3Zt4ia98>5M!q&Hd1Ndlo_Ya`ULR_D#1kLdu z3!-Le3}8tqBg!!Dxc)DZkK&~l6m}PO2+v_a{S1a(i>)=M53{D{Fra5|(@#WeqgxOm zEWEd$dPD75L{X%t0h)}!QY}Qv+m4PBJ^lW8B6;YmpN4x-WL0<`+3g3{O~zhcr_F9b z&Mk{%1|GM(Tbu!crFl*pMcPKx@O?m!?~Ox_U4+9n?k~dfL&z3WEWjTI`(A;)67H@#sPSq2-9JPk`P~`HN$nh6LFR*Q# zOsY%jl=JZ+IooO%ajT4M+#rG*%MN4-Uj7S#suV@w_V;<;0hXOvjkQ3biNhK6^k>T< zCLpc$Y{DW(l#7z5$gR%OsH5{eM2WGsZQV0>o4}I9Tk3bEOQ|`{ z8|rwW$b&6f^FJU*b37XHtZkGtbJO}epBBWbO0g6x(0^xxcyXSsS1L)sqAq`Blth7<{?>g{U(pZY?&b_hr-6a zXU2lJZ}w8I;c>CUDsSo+cd5S^@T6yQp~*QqJq6zc!)F=y!Oa#!?b81DiO+F5FPrbC zcqOF-B$yDKIyXE2c&z5W*2P&tBJic=+}ElB!4CCyfp2X>k4-`)rVy0NVdGRh_33wo zRt|Gv#cs+P8?`DNvdE2Is;OezD10v-G@(18zW$Sa#8XR3Y_RoL6K~qz^68=Ml(X?8 z82FI5y|byZSm9k>Pz9;N6CR}a5>luf+KPVj4sPjz3n`L+4gq}AcgKq}4zClaB2?OG zrn`4e)~@g3rWjjE2Ip@FzW<_kDK@SD+tmd#U;LG%&J}5}T>et75{5ecTvC$*0{q5S zUl*d?c3<|hWv-Qz^bK4N`yNDrXEv8FK50j6E(^nnW3N{?;1;2`-WyAio5fN0gjGiF zZcQ&j;#!LI;|Q>IXQj6Mrq3lM!!<6&K$NCL#r*?`;|HVH%U?#KMroaLM3;VlTN_Z_ zQtyUALwy?SQmnwd5H&Nu`Z&aUjYB>&Q}5Qq zb^v3IWzeawJAoS{^#ZtO-8v@jPsR!xh_u!o-F@d-v(--VnHFPe^c(70T;dM^59FJEt0v`*0gszzc z#=ociGW7g3m$A#gQh-1aR*w(ZC>lzW=ScN~D)%#7!dN_pt9Sq-v(!(BA{-tr3l}v) z+Hl*Q*Y}vTT{)t!uJNH@e;exdT^P!*ah?!=0+J4iF}U8kQo+~H>eVws3_I4U)bVSA zw|8qm%`uX8)Zu)=kGNSHFR^PL=Zo35{V02laDg^b7}-)ST9W6S5U~3 zv#hZ?w}lvsi*&+W%|7}VCj@A;?oE&N0!4;9pE7RlI^B)hNY1K&7VWLSku$%3IwE`j z9)jrg8a*X3MW70Yha3gyUBVq?f$nC(QDlY0jXVvA3|FCY-JolUGxV|*)nVp5#ordL zo2q_1`U!keqHJ#aw&fU9B{e^3HDk!`T66Nqzw*#-WhY6Bm&Z3tB_*kwYoh%_wj2ud zm6B93(Cf%he?HK;!HZ`J_+7U0=F)mTb`?4QUV2X<>#J zVR!&@-QV|TUQ=f(m-^xK!IhA2<-^*9CK|OTp!|5pku&jEmu+Mb7!Ahr?=OSNRXD<9 z3l$VmsjUzUu<&ZwLKqI{sa0Y5PSq9MEDty$xthw4f>_@sAh7$t!~d*V8q?R~6N-wo z6tzS#)Tx&n)bs3Reb1}*S8;$|I_~Xv1O+j-(~f|PtJq#3UYnVPY#orKd^Q0a@AreL zd2Df-eH@Dvk1lnckyd-GBZy8PfhQ3w{-<9OD2?i7Vq~M~Iit z&Oq8mSHx2`I68+A3+{)oiolcYW6~4n)xh~#!ZPD4gRSKRyt#}rzpeewxvvO$4BA$Y z*?0}=4Ce(O?-5yH5C8-=4e`*aM`c8j7(OK!APR0wT9oA;4W}t*vPgx++kIAX-(uWJ zT%Ft~sIMsRiu8n65=2g5YFky{j%Vpb6OgmaHbR*u6*zKzdOQN%a5)k$!%g%VbQz$QF8A3BrJ0`mMT7T{X#mncpKV`M-Y7z zr6j}X@FP|$(ec-Pi8H8LIhEfICnHTxIbU=(U2wnf{AM%PRj;FG8F&$7duw;NuB zWXLHy*}y53f&I?@Eu_pt*(K*_{SBy&9R-H>IbhN{ws1=%PT=P?5ykXEA>aXb2SVMn z^|K~Q_Um&zyfDT5mp9ftT}|>CC5J@{5VyL`?ZL?D&1Jc-$6~EnKaiRBaq|-n0q4uz zf{E*l3mg*S)phq5p$~fm1W#d>xC+@oTWkk;#XiI!3{0y0j30{*PcV-_en*DXm9w%2Y4y>)nqBh0n+lbHb4e~c=5OHr-7#Nv6o?;Z`UxEZmM5T5 z;;}KePn4Y=6#ix25prOKN^f$SK@x(j!^2bMjVK^r7v04mIk0vh+ws^7H z4JASPAb<;=vy7lz7!_&MmT|cR0#eZof9%N8wGT{iaYR%cG9?-1ti9j7Z>RjB()Yda zt%p_-y6Y?6^Uw56%+H^!vi%mdcHWWl1B6^=7TSRi^mnQyG(vg_dnJaSOA;@tQOG6TY;NO7A@4|csTiKDyTg2BKNI=fJFbKGPyaE*Z}JVlGw$z^_Z8Bzr{_rtO+px8 zkFEv4B9NE27u6`2#BDmqdBho}QbyG$qnH^BlP!ezn;(NtbrCy5ob%uS7u_c#9`ACE zHA0@VjI3W;;Oq)=#-ZVW_0$*QU!dEPu;!^R>pw5-@o|dvI6rtLrqgMDO0p9%`e4xb z&{{iR8uRm&*@UKD8Sb1rC}+d{$vBApaE$bLwC`TnvHnyp(g+Y!e-{m|iSu&Ep^2Ai z(1DNi<$uL=3PBw2R;`C#HdVgMzsaKnwZq{Ze8CG*Q4cBU%wJ&f^tINzG*{LR^tVGZ zues7JV-EcUIl2rgpK;Z3X3eO7RU#C^_@2i;OL`*+^-&6Wi3V!zA*YrRv9IxGA%(lo zqc=(a5`i;wZ*TIH!r-9iL?_FnrI-Rj`VVFghS()a)jGsCqYw!*9<^@5L`Q~!&jgy_ z(Jc<2f7LK3BEUrayZXb=_{J;hQ6T>v8s=JW|Br+YfYIwOa(77|ev_PwkaQzZC{juQ zppmPdioshmNnuzn7~e$&sBt=o<*b^`SsZEQ^~^5D>5|3!xugVdSXj8jweR6dr!fU--wksKKg{%TP| zc{R1Ml?Ves9A=W*y-RaseTV+`dnOeGcfaHp?jF@MWvrFn8g=By_mVyB5;T~M;B0y$_IDbn0FHw?_2!P!`GGjUt3d^h% zZlm0nq_lreWXHSt{}I`#JtGUez>wepUuNp^-B;hLNdAQB5O*v0=xCd0u><}8(vbwK zSj89k-R>6gZB6j&I{79x`=+E4kqcDN$R$o^#(l-}@vo2V0`Su~xzaK@EZ~^7%@RjJ z7}L;RE~V!lWyxSqGXwc>6)vaBHWWBphiigWQ*iLg0HC}Gy!jQH@7gUu6YpMAb|2>^ zzUK)25vRjx48LfB^IEhCsU&JJMkV_C4VoyxrVCgX2{7#k`A0$%EZ(B#_Y^a28bS8} zWU)_zhU2eo_BldMOglTAFJV^8$Mg8taMtV5cCP(6ZDM2vI*e>Ew(y{&pYVt6)S z5b4~nP)TjzGB3Q`8v?-X)*O}(>J@;J9uu-Ts8zccp(hk;`MinftkZr!^BPV^lNTTb zU7l&eSG)X!SEK>?$}~$oG@QF#0E2QGE@&Yv2NC0Wy$9f2t2RJ_w10#ocEu$h|EUPR z+#J}`#Z|WB*UBg&C)POL>;=r}1|cKxI3KNmtiBK(B>C?y0j~3e9_{Hu*hC9%8yJbA zXHlWxDY^%WT&I|shQdcNMPLrt8W*F;0Mu}r(+;ie!qZfq%fki#lz(K@{&Hl1fx1)~ zLV2(!Bk4CS5_>kKVL0Bow$X0U^xo& zP}?)c#Yu#dcPA8Qvj>eX_R>LCNlofzWgSmmx05P=#}JV??<0?-Jx+5 zQA!h<++#xCv67EWx z%R4V`vd(7&Z-4vLA7W?g4b{&VTri~ZQ0E3QM}8O`4r9nKO^%c~*HDuvOEA(nZICu; zQ$7rL!~J2OLYy!_-+xCu#;N(Q}qdS)7#` zJGelDGZt15>ktku6gYl@1Bh}u{$KlA6>-VIBiSw$OKlfiBHmrj9`xr4wg#4X95Z+_N9d%LZ&=KU zkJmjBm%nk8!KR{#@q+Z3b0`EE>#wn0(rQ4AIll01CypIF=T-cG8%yJ&XIzs4w%^}- z&2Z*bV1Ralq4?#BwvX_rPsW@@LKfn@B>`@S>0ey|wNuObo%HBTSurGtK0+IaFoTE=24Xx1D(2Lil!Hig5t`+@V9Twln5a7u#R%EbOu>_U zrQqWl?j1NesZdG4TB%8&aGxoMFHE}%7ob6Uo${3~-0VJP|A%IMDs$T9RlJpt9|A5N zX93^mIucggSWE-Y+*E5j+b(QiPoYEeFlgmV=|v+E zn$c?siDIU#vCz}bS@4d#uiO++@_Ll=hu zJwurL3;ra3{?MGqbZg9=QJ*MQogd$7%bqjX7Op zNojXr1Gq^f`TWmat^1oxI}7YrI#hCeJiNepywmTF|BtCRkB91u|HscP%-F}0eHkI7 zkUf&Igi45tH_DKZofcBeMMBx7NVa5Yu~fFQjh&LUB-=;}vX*_BxxcH=_w)OH|DDI3 z^E$8P-t#)I<@w^}aQB=`3S)EyP9!r@*e#Jh;VoQ>#lyr3H^@v|u;WM6e^VQ|WOy{0 zH3E_^qD|Nv8LieDNi)l{b_=6Pw%3jnJDapgKK&8FvYgi<9RD4b7XacXYAF|YzKc;K zLGTuIO87LA& zx0TiNsy^|rQ#$>uk+tcK6qv9P!$NZR^%wgtzYJA&f*#|5H>HIMN{Lxt^qXwP46U#Y zS?&d&;|IXY+w~_>Ohl%=ZX}qkxYc4Ft|Ertj~Kq*{af#DztqLJSTz~!GnvzF=VIEP zD)4xky#Ee#s0>bg!q+qBA7jS(=u~ew2C}cvD{dki>!#Uy#~saDx}EpMPZ;K^21|aE zbdhgJ7IyGEdcOg-tYtPB_V~Y9x5nN842U;0&!0ha`M4oQ0HrJOLTR}|%M{!_Sn69e`9;bin zcvY*)LC@ke+d3CHZuI8XjazPyn*t~L84tCt_{~ZjA66s{W=ZO2qruIpwq1sP`R!7X zUY~W2<$2rc4oqc#nxUzd*V<3A&c1?|X8stdJszKue3lTL$_Curssj`k%}+KIVp8gl zO~!m&`o%Hoe{VeO-nQdpcV{t0?Q#wH@8%sWogKWS>{ymjeBuj3*ij+Dj!Zd$MHhGS z_<(eOz(9IjFbg>sl&A2IyTPaTYh^`8JwzH8cS`+G6Srq#P&VeCT<{N0>T>Ri&qSf#3T7@No6J?-@MG>L4ksJlMoqU^5{FPP z|Iv#C4yw@#l^fF29D4{KIyEc@LzMlCw1*rT!IN~L#&j!bzHP_y0(}i(> z`eyQK3D(<6V%66H1U=Dusw(?ZW8Q|tY>WS+!a32;A}k*=Z{e~&!^vgcqgy5^m28Qt zo)*0pfI23m$2XUqQNNn~7eT+-TBg~0`(LTw#o@bSkG{@+s5kJdr5>hC}r>h-O?z8679LWNxLffu8#X z*PQbQpU|I&9j8scZ9S=aGxyosj=+g@y3+Ca|J6*x8a9LnEDZkp+OXGw&sbD9$}8@3 z(Mj4_1U*r|4i)7V^9qOAp6yjw(yFJNw?QZUJ-NXw0J096&2^kCIlg@svE#G0*ZU?% zvw{N5C&hw%;FHNZh(b>8Dx_3bpB9$5y4v7Ex89y|B_!lscGxo!#AriW?oeNlh^62? zT(8JJv%S1T~n`Ji1oLPr~+qhL1Qb+Yu-|DhB5XL4@bDA;F3Ea*CX zvR~)QtglSSkmT%_tejnai2T!sBrHGk9LO%bDKLbHFMF;boEYpytG`adGas9R1+A6G z8%h*VPj`42NcU6rdui9{R!)_}81jzh<3@j-K6UoAl~X}z_6*ZtKyLrYI|mtRh5Qf; z3WZIW?E;V!rYia9+&>ctB)WwB&zbmE==cQZ^0gBijVt>epkfC#)4&o*l-I91dgYYu zY`A3*?lAYJQc-6}uFl`#`;JX|NbF?O%%dQQ61`#u{dJ@;OR)*=cSdy8B1@7o{2Kwt z&e)?yy$Kpr9(ubV`SbrJ>TB<*ep_O+_21hhG&>>sXT&b*CdXb(S_WcxLqw#iU+r5h zHuyqV$YG&vCAGY5gT)hxh%`+UL2csk?x7g5tKr7clger-ctQoQUMtdn*JchS-lBm! z)F`>FMrPXr*qg$9Po~|`ilQ*n%=sT;CiLsE>%_q?aPq3fe0D~M!e|kcQo>sQg^5{( zx;wJUq#JHK#B$vTd{OW_P)L9y`$BR9W!!l}Szsy?B%nHzj$`CnsUcG-^yBuDKAC&P zGMR1ZOtTOY5kLp-4Z?BS2snwrMD>tg{n$A9`~TM}ExukHt)cSog+8S7_!~?2R>G29 zy9yQQRp9@#xp=)TOtM{}7XuAZoDQ7;nF=Via!0fXIGVW>A%3@l;Mt2lsQ9Ek@w86# zVGZS(#R*x+V%*OCU_3R-eXE<ZRk&@OoZfC)Mv!;q)uK6)o3d z{f?*}5$gm<#rvtNj2FFveTR(idM8;(GT5Gv)Kmt_lzHRaigxK;II*G6b*%Zvm$_pa zOXbzC#HBoN{vGIjbg|!9zs}iEO)2~>Iep3~KoHiBM0~NODEw^p$vOQ2si-{Y<@)bC zKUuFOPP;)Mbby1rz{rnrb1q>O%LHf?{S%Unm15XA_cE)4_q`qszC;Sf%n@>zaK;U; zB3ejk&!}YrcSVF55n<3$7CISPNc)IKOPuJnLFOpLeMU$Y!kf-spj+FD=&`BB65#8)4Xxucn{RH$C{>ATC5IE@hm1;-iqWCw=Q+ z_fh&{pf;Eq*}yu`Hl$GC1?3+3{EuI{+TUwbNX=OAJqzXt<~Q!)Mh1DINqNB>iXCmX z96G%r?pJG>;c9VUN&oovJBF>!@eRjUrNPN}!R&|Ch+!))nE#0vB$DgKBK9sdB3&z2 z9V22L4_7hx&wnvR6?^xu9+V+{=#JwY^(Ej_J%!+MpOk$jw1Pgh64Te5IaHbHgBWByahZ=IU z%S*bp-s@3L{h>-ez-;F&)hL`);A^_a?jn-3Ri+En8L7_-HoWmTp@BH^4+LSK2J~b7 z!Fs(}ef@?6eGMyfH1)(ml%qMvt=`Daf(rcBgx#oqg45h5sspoJAtlOAJ1TU4`FB(S zkEOB@L}*O?9ZI`uL84dT>A1_oR{MJgT{ToTqX%EaEt`dm{tZax53OZxZufl3rzg-y~<-Pinb{xXfM_iN( zXEqi0jBbKuAxjk@>Lk!M*Qy?f0Tceom8l-6F+CRKZI$|c8xa0dmJ;9DZf=aZQ5Q(} zrC=JR2XgD2O;I;kJM{66iN190kmev82v&>EHR_GUiwJ+}+LODzwVX;i3T#j22WnB( zu#OwnqW?x zn8VkNq#!#vnC7@Zow6<%ZTjGSN4Pn3HWUXA_IFEHA#h{rx-u55_lr7QNQti`j77X( zL3|F}8yZcFEaB8zR2m)_e?tx_9Vx%qZ1Rbgk#%8E#D@e8Z(V$d!ye8K_=VQ1k^jZH zEU~T&$}b1@k35xMYPxa4=eQxeX(U!;abPfx<((Dx#|>)n(d0O>Ya6eVNc*`z2H%HT zXR}`$`fWDIa6$?-N93kA&yXITGm80xuDyk@=cbM|!;+h0kg7Gl_?Q+*6ZO(YDNEWW=GdFO-#ww2plA@&LhwzCo;p%d;lQRls!!6N|5-^x{HMRSWWtm z`zk+V5_!}vcX~T;Ckj&n7$s3VBl3yu7YRochLlC`YRK;4w=!PU44n4;YnON2LrUk) zW;bc}Kgw5Avs~$U z&Lc-L;rU}>zClxzyt0-4a;1lB(!hDAbF+rOjIw@LJ-~_UywoBSsxMd!60qq{y(O7! zXow%`xr(dww5Rx;Z#r(hRCWDE@Df|=v$0|RlkuwqH2};(#AQuV`GiYA#~mTUk9Rj2 zn*LDRIA6vnHj1?^`%#1E(e1!e+Z55GMk<1mG(icp`LQ|L=K=F05_@WrV$TObLIk5y zU-~_C_)dT}Y`7LUXt7A>&e_V72EAA19b^A+zO%GG)8jrYiwp<$53rHdd@Y69nNxH? z4M{e--h-k$1k4)cFmkS@WuD!erHO=(5%O!C-YgHqD2NT-m|M((4G)x%;9pF~G`G%l zFhc6YWS`K`SEOcY{L+MY=DLNyG)PMi%{JdYHn&(RQ2{-)0*SHGVcX6@X9L@=B}nGL zD+d0->w|kxZ5)5@?dJb+Oy>tBMwz@-%^KBE!|uE^CpTuMI_*rj@w9flVP7AX8JH&M zsZ(suudVmMM}^%s&~BsUa$9HedOQ9O$IQI2)J$F|ZC=?CU}CDXu4dd9Gg1^MDL!dd z+G4rqYrxn#&1Q-r4dY~3fZPpZ`|MS7TvTxJr9n&ZVO|1M-ZYK#mKY; zkNHNdpD*W#(}H8YCJezCBs?b}d8qK|W8KD`msoKTsKc0(VL84QTgSJauJl&6SU zdl|&Ml#nxxO@7p%aB6brp>vK|C-^1(dOnpexjf}LIl|n45nR@&@4HPvp{0OI-LrbMRa1DL5mA^c87mec@ip#>~BgL+gVa;8D7$+IrSI!;S9<`2r3CX{3>#viT!N!epyqW+yRT{`x(Uf1Z)^tQcnu~$4ieema-qfa_c4(kuKY(135(OKFU z9lQLqT!QyyoY}(!m3iny1MYpx)MWS2-6F5{4NW z8s}~w$qAZi)SJtKYv;emH#32j`woZ}60#mOe27`5pn)B;*5{lhfu}f=Z$0kcWd+Xf z)7?0Ddo!Z2_NmzIQ!gpUgO?i=P~OeW|Ci7*swoboIO@`~f<;!_WxZf2Z0}lPlUAAR;xM7=U>jvC!~&kmlxRln zmD9uON%LuhW*^a@Je*l>@NJAJF=f_@Y<47{G^b|wx!%j7wDU!-wN|Hx8ut8?M>`-4 zz^A(y)BgnG1kW990pP{3`Cd}>BGSaiw3CekHrTRXf3>Y6IM_$tnb=Ydp-c)LCC55$ z?d!zYcskz@!zUTFr!5Rga_kh+=DR7M$x~5$C}6bkBiPYn=g_7*LvdiYh~+-JA8RCn zH|4xB@Jm0K!2*`1CeHoh&~?K(@y;e-APczNYR^BxIIk%UMIo4pXX}=SX@Q2f69+y3 zs2SLNNf*8PX*k#lB13+d<#c z-bHLmR-bly_2*vV5f#eAPGnkc?rN?=A~MB$NfvG0{{YgFIc7GJAHW9 zPAOQhcS{d-wmkF``oi6z26u@qKsxJvo|}lJnMZ}HOu%Ra`w7aJHRC#3M?tpJZU{X_ zWMaFL6|DNVJwbLnQ%l6G@pPmg5h0>O+;_ZDgr?E z6kcvx&EsFPqB2^y%V_OL;NRX68+{2td8pk1t+HrjCy`D6cA_EqucwN?zVHIq&YwRq zfwJA%;kdJ1VbY*wr%(@_*s^&@lo-Bnk_!xNa0BYEMU`s|DF7k6D8ohX&H<0F`HK>yxiMZaH z*)9yceJX>1UJ&7=_OE~Ptk*lL!lKb~K>#(3JH+vr)-^;Zh(fCT%a)rDlZ>7yy_0N9 zh{a?!d}!I!s~}i%x z$$ws%izn3QV&=Fu8t~v;8v{&Qw=QODR2r5Klddw3OWr;ZYEk#Q{kx>>_^Bz4&|$Qw zH8*Y_AWrIq2mx$xXe=(;bmf@l#)dy2A;R!yd_Q@Miqdy<1-Y5tb)P@KP@!EbzTMsdIuR^qp*K6Hx})(M<&TS3)G@fxS zWySI1nIlxSvxC|gP^e-|cpiEhyB~n{tnYmH<#GnIy09ayv_fa6L`gkD%Pz_x>A!L^N=3P z2etk8kr{6lyh^NY=%)>=WV1%FTt9Scun8(T{1+IPIc>oYo&}`|y*^NgB_!|(2D~IO zSQg}5v5g_AjI09q%>DH0dy}$1PYCteK^jLXvS5ghPU$>zq>0_`ku^H{4O7A67eioN ztksNIU9_^UMlVc+nykV_K85T#7BQ84SC)QC!10se zInVz+|0KHYycM_Y%loK6D#wXQtPF&xV9KoZVpogIVHrrvaiY7Ewo3uiSn!X9*ek+U z-`+Y$K`%n_%{+~FW?)_%V6}R92{q9d4sp)0CEhe)QPh9^KM%hVzV=mc`_=)644XnB z4junH(xwBBxvZcN=E`7(*q9_UhnA)aHdwtHkNwkt(3JWaq73AIv*cT9{KI2x%D4Be zUy(*1r$ic9dLG}RR3YOrTf=kW5i)s+(N9=ywr)ORr1-mDl#j%EdMRlxpOF3d!8qKz zIPQ%!#@z9xD6o6XfJe)DmYnr%-4;+~s*RK%Tt5Hoqmx+k$Dq^ry<%}+_g!g-$t-RG z`<5G(uf&9Z^-c%!wx7;6Fx;ZNnQ=pEH9nnih|d@04Hr~X3;Ca&icz1R9u|HPxK*WE z&q``UR@$$-Pp%~uk_wUkfn-%H`SXzE{c}%E>=P8pt}gtQ!eN)l){9N^XLk3@8|qAp zOpg1V@P0h_4)6Mj6%Ac_V@b1AwS})luT9+jG6PCz)-S3+>$O99s;Q8fqtibit4$}&J z1lgNpqlyjC>-?@l3w$rFqBFOe+P@z7GOx>ym#!A|GK+B}{>Q+SB#DLI9$tuZG+Q*h zh>S*!-U!ymKzUsE6|i6y0h&NjkGd{2#j@rgx%lm@ny&Tt1%I0z?d3y!+u!y4=lLZ2 zN1}Rfc59MCPLBb!cPn8vqive(8a-;<>CLcjTh7H>#r$7GQksLm~(5L+r zcKc6ezfz!+F_R@43L3B)uIi=HO>6f*?>RZtCoHG_rxR>g~^AL1Uus z7OZPs<@8HY4LNTo7ZLn*A$rwO47X<8!a0IO@cV-kn*H zsdIo0Nas3{u7OO>-c`6k!zO8)GxBIs~>?IvWN`ah(bd_2Qe!6Yl2}417+-FY6w|>D?if>2F zrr`jh#G6>~gyYsj6#4uL3ulbR=jYP`0YBbPE5!iS>F+>!Rz^YcsKT*nL2FQErw&wp z{RgOB=WS6FiYTaU9Ucaxhkt1A0ZFMH{(y$AT=Z&Rty z=*fjids);CCa4Ajgva1n3^?CHd4U0SeDD=On*Di=a9ZyHGpGn)Aay(!-7T>A9#|A$ zSvpeYZGf#1aKB0`<^osy>K(@nUgioR&J9QZGy;REc-mi31*&T#$uE1u}LggRhwwV^!i)AqY;!9ss0G|}7KGkUDaY>{Y#Up=b zu@C;h9x?u&aN_|$dWo5A?23S8DpX^`(s3iomI)M{{o7yy`>L`BA2j@V99|d0mNhjf zodHEXP|d86-wmuKf-+HIz*wJ#L+qJ`?1DFTcqiW{b}mL1=b;{f{2 zekL>Q{o^ndkaKtknI%)Pf0tUuhg|LmyKVD3{V_(|z3pR~`yk*>eM=NmZj94T@0u9;C!;OxPQ@kmk9cn@H7Fes|+_q!(NE z;?VLv_Tpx<=3HT(*kcWMu;2SB&WecQHsLHRw1})!C}fAkiksEtGy=Lq(Q(2M&(7l%|90GC%;HK61OCflpbg2i#; z&vs9dsdX*j@LqarV=5geYbGJ^xc4g*hJcm1zPNV~^4O`}6R)8fSt`ZsdFk$y_wyDX ztYh*^z>EC@&?#gk``zOtd;B}_JDf7Ny!Z=66=ZpKyX;Am!bHN;twkz&{+Qmu|+{)W?E|Pm1(s5v%eM1F| z*9Y<0hsxMI5EcSCRVcCRP#|;1t{VpLh~uD)??PfK?wZFa>RjMSs+Y?Az2%O-npVeO zHF5NEYUI=jPG_P1u>rqFo*o$xnpd8_Kl+{0g;Y2dyS@(b=X^#Kc{|CWJPcjep&rJZ z*=3n>IRQiMzG{4vT|3&8a+D4D-BA2oua&X+Gt~=3k*jVG2$lVFyBx>9gBaaEX^Lzg(cv}<@uF{a@X1Y=ue``Q)813KToc}zCFNhtKcMQDP z_S%v~zBvWK2~|qs-GUr1-7)2%;{mG3bLVzF4c`TS09rQQ(>Eo0P|)Z`(pu}Y*sl}& zHIc=JXA$JYe-GIJ{KwMOVZ=ThA9rbSzVyJ9YaGGE4jPY0{c}Zi_8_<42`uG22DHrI zi&80xcrgYTLgaFd|8e5i_XFweDrXQqERhOrloq~zckSn(S-2B-RzW~*;`Nc!jm~)4 z8RleFX?p$drL=?j(4gJAP_S3ab^E^|Dly^NKAo`Vqh-2Pr|XV^l=3(BzBer|n0%{p zCFAT%BCbwLh2UQs$3Lh(XO9$azX|<-je^gi$k)D`yq6f81;hyN#idtg*epXxm&557 zx1_KuzrFnS^p>dGHRRKzQslIDvLPtq{rBvzU}-+QYJ_@!P~nRKiW z+(T{!1VMAQFKJuf3!2e_63h$1%TvGDWJEAxudq^1qyhLaP>T3 z%g2`cSRJ-DqP#PNeq*d~ebdOSZr_ySe934k9@XBv{6-Yi|F?Ag-p@}W@8i-adpfDw zzsTf4+A~l#=tfONgEjUvH25mV`5Xw2*zv0XJ_94(+QtS1!~6%el7AhHC&Lm#o@5R)U{Q$AH4ibz{|hcTS0e9mm~zQ z9cWXaa*pMXn1LY^)g^;x#`;Q-W#EMU3Wr^s_U)X?W_azP3s2-rKrXJBXW7{~fCb+0 zA^3X6;|3i;c>nz{^|nUpOG+M^YIiCuN#*4HU)*8q32QUvTEr2dn}K(!JlO&#!s9&b zZC=o|(~WXT2v=Fs-94g!-Q+h-6-9lrGrQ6#bFK)JW(}WULZIz`JPv!%nYi$P)^iw> z>2h~M2dPjf8&rt)B0iu0L)pHf5@Qep$nz|dI|%xPcO1jf41mX!vn^ENDY6fJo)sJb z9d9wJXTj3V!+{gLW-^a2NP(9mmain+k+UA@l_7CvPb{UuP*l;fDhK#J@`I*=f+lIN zxOiU)X+wXvB+dddilj)yTQdPzU4ZaI@|Wu4|75|-Z$dn`7`_w(yQV!XU`^{CW&Z^fy{wl5b-x`*^g6Ll#7k#I~!;f~TwR&r^ zgLkLn4iqeUP7GI8=n?C_-Nk}!;*HP(6xnvXfsCd~KB9c?pg!6)A4&}xL52!&YLvpK zUB0nu|F&$x9=jcQldSfX#cYOMJ1hf$kw4znMh$yPm`l7z216gNL@DurIsTAP1PVmX ziSd{PnDFk5tQ7R_YeaMmfA}X^8Ri%w*|ols)+NJy_|6+j6-Ly0xHoN_*nI?9QE;QO zvtN_{HinX^P7Umc)CJ>W^`r6#M1mfpTL(Z38x0kM3{Mx-j7LL1A*Z;n{qnfvvgf-=@EQd#%ubA^tD#Zq3wiH>bU;&rE6J4GVKm( zf|S$X>9+-nKNDMX!rnyOhEJ&wOwIx2b0Q&+e~Fzy_rAbFZ!R;=<^&3AL$~OQHi+d? zb%dBXEEP-(Bf6Ex~e-sln zzLKazEPE$*4F#JrPxc&UCeiBh^TlUNoxPfd{4VVxSmE{y49VpkfF_ z^}F>VePCaG#C|1EB<4S)q_0I%dtiOAlsQQdnixVDY8(oG_QnwpNHbX|q?+;iC#LC! zd?7A8e#z&OY|`?T9~6;}zJO`uvN0hP_|uu;O|=xALs9!z;Z+|Dsi1C*8PMd>kWYQ_ zhn=BCDWcyYHju0Z_Z5{Tv6GR)_x7`1%?I-N01DXZpiu1ZKpy<4z~>+eRgyjUY-2~1 zDZ~?fYIvipQX2$y+t)->WKY(M&Fy3X^4Bd|?FW$P?H30uj}#$D=iW*J$2xikQ&51q zd5I4UYXr$^WnXs0Q@i2Q0FVA|qyoHzfjBEVEdCo6K`8)Sc(Pvrgob_p|hxb!P{Pz$% z{z*mVx%WDHH^*OzBX?9W+dm3awtA+E9Sz^b#-}DOW04PY4|08G9dTd-U7|MfV8>b> zM9bX};{cpkQ6&Jv9>YOFJC@Aunp~ieU_Gvwd>VlT3|w4%4p;d*GL;Wf9z0R>!lImN z2M6L;bDDM93_;ok<@0r*#LORy5t6?owO!ObxbmV>HIsG-ld~$KJhKH~6+q=w_o)Nw zT-Y8ol_sE~_Ml#cMUdVTe`#0%4P5*fI%v{;VtXp;08+0n-WD6A&A1b3^}H{WDXTwT zW;}56=JwIWQ@+qH#NPKVMrwy_ge5)<4sQC@UH_jkPo*B7UPj|yUjM&OL z?i-JtP|2$@V913|srCfQFTU=D01hkR0ISx^~h|J{M?(KJH0;u^ft8Y zni2-`I3wjf!YY|x;jLiw;^uj3qVkUf1a9Amht#0h>?(f!8z)aJHWiF+bsHD_rX6G< zUvE~xLisow04P@EA*oKjwHwX3kJqUooM23M90i#_PK^`gxwG>}u>ozQ4TWwa{dC{` zT#7iU&lY`Lo-@w(qYm`_eGi~R?|4ARqqVzt%$%|{#l~L%V(?gl)rs1$}b}j|xbmcoJJ9wcMecp606`q0#p#A1LoxkmuGvmy>o{BpOxLxX>6*u;L=%z>g?53-)O9vBPat@qrf&>mm)Oh`{VBI(-wGn98F5RY=v$J>TWz;GK&i_EU7vfOQm9g*ssipvUDr=!|VKVBkh{LuQS3TwtCC zB%M*;*Y%)Air8TtYHs)p3Ct8{2XZz&jy@H!Ph&2Xvaid&Jr2KO!Xh*_9Z$pnqXD8e z>0W(!hbhv|B%j1eJ;iSAckgls-x?<%#2Bs6If1P6+TytYJXf#UYi^>Er?+QZ`lQfQ zEh^B&v`n_v)cur8hniP|n90-YRjeCHpPsG@6EKj*U=KowWh3hL10UPM2Q0ujmM>yf zQ1axU9ys&GX&ArG4rE~V9BzDF?Qm;Bq=dDj?jA^wNETm7CfCq z%_ZmLB)rYon^lLv*pB#VvIS-AFULiffU$#3&wAomcW@gzW5j0_UVxC7ptbcLFG*jh zF;@#{Z_2}=`dar*CN%WL%F81n+(tS$QMTN-+KIMJykXRmm-4d_PUN2uR zrL|wC^*zX`u&a4eXwA4ac+xekX&eU*WNyqO$`OzKO5;X7O^)N!1y|=r{?M!2%M!^o z@`pM$|Lhq58dv?f`u>Nq%Al`hHXwz7E?c+;@n4cmYRKSq(PrDinhA5i(%sL~! zxGstCCx;EFi6Vp-2|{Se)wgd^6s21Y*Nni3UGx)&ZdE28^wY#JFySm@w6c9(8VT%s z7u^(o@7Sf{#+mJP9{AA;3Idi9Iv4TVT(e_LhY3<(Wll$HM#%dr-=3f<8Jw=v+53C` z<1VPRi&}>ib(9N_YU(UeIL3X&6e|WR6#&FIr1kCs77(W6TkfKAIIdb?=>#>cU5vYgDW z^e<`KQ-OrBQ(S%IgD(LfotV}{+*huiAJq${O?Oe?O-|&KtA|lQ&Atg!YRx^c_FAomSahY#Fpn>00~`$dml80OQ(=v@R#|aV?ic}d3x>LoCt3YFenxp?UT>0r4Q9X@Qs1UU@!&i?19NLvJDN-h+bzka$K zOpC5Ou0GoQg_d;goOcqQ^c(P8moDl5rG&Ja$mJ2kW1ryDR%xya*)*f8n!5?h;`2#Z zV!k`7peFl6IH}+95Fo6;KJ~0bt4{@M?Q6)_Y(E*c<*Gv53HD{}-2RgRo9j2FR_KaAr9 za=&A)bD^M>uZ|r4)JK10d~jgPj97*YTX`GVH@JhDx%`lFJ_|`n2j5~FXa!&-swE0 zD>LCb4PU84_f}lW<7@dfaN)8D%~9K3f6c(96qES+q@Q|fgH&E|`LVrJB#QJ9LEp<; zZiAiCR7Pwb-gw}W6QarNx0HIGS)Z*R3krH+CJL5Q`&IX&G>^d|H_x+FXN!+J*P`co z4a>31TzjqjQr~D0(iyTszQqT5Q09|Uh$m)yaTN(DksaI4^5xCEMy~G^>ZqP${8de> zwLzU12Qp9fC4P#>$5gUx!LPq$qt=ru&Bw$*+r;?|0!Jq!la(_k1G(moCQ3A#P=Tg@PzimyIuGLBs7C8{I;Cw*-_=RoZ#%7kzw0q1rEzg+Q|XvE2=>`>ZPZn|)}E3MB?+EdXUDnHEszh(mB!7HO9hdik9`+( zJY+J(x%h9l8eM16qi)?Kjz$I|1!>zQAMlN^I5DRu_}$p%uxIYIEaw%+q#Iv`WAVKe zfmj{b4Nw~dMwhJuk0h}O#r0i9D!2z5x<>V~W4dXI8k=^4Wfgrw>>>p)YnL^8G;o2M z>;jKV8yZfKX1M-n#3aVeiG>;b_p%}$kAxI|eb$giv(Jkeb;Cqo3^JM8XXE<6y+@e! z<74+_3XntTFAy_JrZBXh&DeB73s%~0%3f)V7s@6qeiF=BZoX}}z~w7R#TdiXJz*|5{>fvG90f= zZ;*a8{Hh~1lhs>KkLAkb@p{7sk~07@Vz1jgZial^`>XDPxX~Qsw~veg0SwRO&H@B8 z)%{1uK|D9O<9|eOq#@Xi|7oau9KB#A^M>;kK9$9oKI0ME8K%lAWQdpN3Psssf+-io z-go84fs;5se-z0YPxJ?JGl`XLzdb$Asf^A3%r%x&fo#+F6J0W?oE^8y5eAM5-{1jH z5DGV`LAw-+iZ_F&yG6zfVnp2GFTOIOwmkP#D%ZV#vD796p<~qqTIza>_VqCZ`f-00aJRf z$MULNj!6*PG2fi;jt!}PPNy)WFXL6|vP(ys@N%CV%CTUM*m~A-45pvLP~8k(38+T;bqN~yZ=@w;iY4d}P>345>&2s1 zSi7(OVE(fVr zrpyw2a>fx}@E23jP;Q+Kk5k>UY*`^@>ApbNuP6Cn;v8Sw0sMjCf^JG4mn9&gy;=V} z`qTF)^VGuXUsJzzhl*p$mocNhzXFk*iQ^Ji&S~t@sN_DIJ0#Hs6gA=YOy+;Y83~WP zk9rrK>grT=tHYQn^mBU?W!}nl$EBFxExB7;6|kUuUItOp+!7}vF#<24FKt=exCBk~i7z_=4o&H%xWg7K`h(@Yy~{MfM9 z&1ra8^a{nV;HGBpbSbRM{r=H~`!hz{K6hbNS-+CW+5ac79MZ>=RPs0 zaLxMC?bAv1@&0<3@b`9BGh$r$&-h!EOGt0(-9SreL&tA?yR3L1SMc@Vh31HK^RSPB zR=deY#se2Ht>sR!0!u60?*Q3E8Jx>Fh2PUC(TpGKn?52J-$k4LAS}U^Cg= zZlU}!n?MewJXS=n;-RM7gzsk37rj9PipM2CDR@CXlh_5_!eLhx^ryKPuh^tl) z?Kq+aZgF%LF@<i`EGw!=O-Ob1z ziG2Fd(J7RmEoIt+(Hlb~yf4|Bm(TR_eB#67`s>BnXWvM)Vw|LXXBKUj*57bkyajt& z0YP)JFs7cz$M*Z?*v1?&W8Y}6@6*j}t*{hr$auee!NWTmC@>r<*nY@w>ctoRIi#}E z#(ZC$Wb29nBIz9$BuzbVL3H@68~)@E?Cb{%Ps$bU8r}Hn+$oL+XAvtM>1lT~cCF+4rCH>3!J0lkk`-qYbq#eZs4Ot6e*a zk9x?t@3!4=q=QhLQDOb#&R|1Mi>Dj-3#rfl69%!B67vCIgD)w?SmT7c75al@nfD0) zOLfCwotE559Ktj$E~zv^VPv=x2P7k}Qhw}BZ&fOl>H&>#^Vzj1c@$XTTzTd%$35}p z)16~OV5B$u=_chhR+>Qiwz#g#;o)eefnJ0VPc`KidGyHTC?aY3>cobZ#5tC^%i)20xx-KNfp7LhitKA5nzE#f{r+BhUZ3YLcz*o)X@0n`bMAAl#eL3o&ihR-YFgeoA_%m^ zkS$l`R=Y%nTGDK$Yg_~qlo=NN69~VOG!WnmH$D+%>}q8pawE>alr87KYwPOnRaIS| zj$^=i`Faf;LwdC8Df3LL5McG+-xk+B;VlaywpctDFL3C_G9;(O8dxc<*kFz}^(Van zq3k;Y?F~dz*0S@)MCB4|8{?kmr!G=P!3Mr&A^GR8ij;DFLMyP<8GdzwG~Ht5FX0#U z@5s7pJ24I~RJ?q^;iUw28+W~xTFtLoNjU<7tTvX?x)0uE$ie!dg0xilvR&unKt1}k{C z*>MPYaYxR@WwKN4EdBnMl&C2mNJ9E9BzTY-UiX5Y%BdaT{@`^Y+BP>@wG(Smti z;Q?k}_ziSP{p?;HyDyI)C<46rz_TxLzh@PDo67`+O*%uz zn>S!c-ht7kQKT-?M#*8iRqSUAC*9)aWBVk}TiSGtQ(lC(C%!z!2b^L?^n(pS)wWS^ z3sTk&JTlJbUwjYuP;y=5!kWIBIl;5x%?|Xm^Hy9MV#je;yvxsUil-(5&K>=Nx6sHw zCACS}P8+={3uiowsaGw(Z8D_`rjvxY(Y!duo#fIFS0d@#-U`JJW&j!a!pwdtk8q!(mZ16JASfUrNrwAzO6e zgkD@zc&vD9wBo;zM9e45th0~*e!2rwAS$;D~Mw$UF+9_PdjDI@HXGl6^d4|$2C-rOSR<~}>M zBn)hh=8q+GZU$sprUaox&5{? z2Bag|E*K!qhTYEroR`!74T(l_$T;iZS72q{5Ga0;zz|fODUuS=e z@ubO(%9ZF(QFN2v+G&hjt z8mShaHo{)W8cUi!3K6Ee_qg3T%p-yg3TS^8DE0^$=)MogRyQNXGaT&sLKDUaCi56; zt$W~5h)JY6#EYif7%$IufuN!dfjgGpJ7K`9&nN_c)srWFS*;F^v~(k(EMfv^$Uw}k ze5n%K{9MLgwe4D_-_Dr8xJWjQcWgqP?zTy{q-(>h*{unbCI|6pyi3A({v)FV|F1 z?;cEW@5nGWFWQuizCoy--ptY_7OVfH!0@7p_J+|NO{_ab<6D94+i4UY*jWVOh#mVe z47W?WFM@fzw%Y7419e3hdRfYCs1U*oUl}&LO z@Vk!%Xtm5D?<_tD=-rrK)J~)@aU-8DJ0u`%bVby)1eh0!_3N7#6#}LhzbDfX5D)jqN&Kcldmrhw{ z1z0x?X6(1I7D(W^L}X1GOrGxqZ3N%LeOvw3*(+j0!}zP@hZl?E8LM?I_9_hYNe!@@ zx=sjp$H;u2G^U1|sYq{!rO`2yQEn{Iti*B6pL2DCbn$9npoejZUo0~IGDqpu z`OD`fkG_XpjQ|>R}L2+)&7n$a#7HnqU~xWv`J+M1@J-o>dRRHL&3(F8-9@q_99y~#F>z}Fsh^n%G}ql@W~){gyK z-NRA%#|BJj1AFVlY>GwFd!H)=@^a1xt8KOSAAjfa-!syD65LUzCqa0-w6e^|13yL= zCptb{;Ocihg)GBuT|E5EzMb+uhCe22^dkme$|Mo zbmJPtoV^6b^$bRCp~}h15EwMxN=_y&SM6l~PQG5sike{q@;%Tkcfo8eI6-k9zxtgWrU0CT%6wJ9?1D#6(GtPGwDysT zE#3IN&us!&$dO0LW1Q8!tXl~t3vSS5F>ZX zmTkKgKQbFYl?J6-XE@gKKAmeJ z8G6ut^fBxU1&kPx$q0T%uPET~cejfJO+X56F6UPe`P6^=N%ws$o9@oM_WWT*(gpdY z`G2I(9zA!=%D1p&bpj`T)!graMMagO-=z2ZB%6)!e*7m;73HAv;rlPpx(k@55d5Q- zgdZ}DVnxz(vwx<;gBE^m^x9+QcE$-|uh?(C{hfvF2$7<5Xfy4wY4n9k?X&30zC2u2 zU@{CeZ#EX~0GFn+ew(Bn1LX=&C>xpOD&>}jF<9!(c%m`0<2Hg{h#chR3V}*FaQjzT z(PoGYr#a4w_@D3=#Fp~3YtyH7OPzi*w|;T|nTWq+pW{Fdqptw$h=-l=X(RfcngC=kUHxdi z0ZS^>bq2OwN_IE~25iFixO&h--?f$(e|F{{*0>CCk*8Fsahv5wS2Tz!;-v}oHUPiDeb}y1V=trB!vt9@vgyx zb+C;G3?za>6w;Y2H-sG;X)(+(6-owYc>SUT<)W3ih58vq#GWBomZp48c)eeEU*OQ)U)u9*VpTT=erIrS)d( zjQChfgL&N$-66*J-_fYecIK5icdbK?0gs2=jn>-07@J-YR(xFuWMLU-^d&jf>8USC zpJwbEJ_PQm3a$_Z{^qll6*x~=f^7(9x7dFhK+8!1tR%!Cee{ z1Pp{c=$Kloc)-cgWe034{#wsoMcRYRz7+&Aa zV1wQHn;I86s_Xk6)E>F->6>#(Id*0pLmZ*bE7}XPt{;aKZf)aONDc9J4E|Shjn`A% z;TUOyNnzSsg&8rf3@U+`eC++xJcRoAS+5w#|7~z!LChlU2RPGtdZpH~9m~+t z$SZ@NIZ?9J!>#;4>9n?J=`{rm^(FdAqWJo8e!#Cjejb427P-#>-FbPYBW?Udizw}m zdRRO&S2K@keVhnb_h0uCKyJ?R<)`?nV`V7Kn^y^()!^i!`Sfy^oFBm0&gjl=hhum{~(4#BH{4q@Rc zLiK+oNId!U!8rSqeEId`aDknme^To$KWorSH!b?pBIYn2`_t~_a`lHdzp9T^Otr!L zc~8i;_1;tf=&n1W9+n?&bc+6I)`4v{@Y^3WJJ4|Mfq0~-&jr{=_Ehvw4iN*Is# z=UEvr)i8G4Zz{YiWC7HtRQvU9)ogjfc5YLkYq2WFW zoTZ`wQ&bpyFu-e`$L{*jMa2z-+gBr=o$lxKTv2nr6uV21G{>_rh>rm<5%6MeR+;y0 zXiATmjWc2h0@*P#HDu7^uH;|dg?U&%O8yjFckbr|T+n6p-PVYOkQKMkJEx?uU7%G2?0!5e!_N7jG ztII}^lKQEt1h8tEIfIt$eNcH#f3jJ5rlZRPXty@h?Z-iLE zo}RbM_-rM=42GdgUpW@#)RJ-ECwflaJ$8l9*_->S*-vTU>q<^s>*n!l;N znp$!sCLaWX+XQZSu#T@wwZG}Y8XjWZj?SrDf(j*YLYkpbPoj~cB?C9#T7Gh{fRM%S zY%uN`#whjZ8VMK!CY=|0f4M7Ul|W@1Vu%*YUp_j%C$M+Bq(u3sw9tbu6>^FB7nbE3 zi42WH$7}cvs&VdFBfH_iap@o7ZhbFHxJR*<=jR}M)|~oreH-4Ho9KxONtz7QI8^s$ zo)#~PZRW(pno<`^0)fJh=RQWBE|tNip6tQzq62f-$u80z7B`VguR%H{d?Ooxi1LMq zxZ9Y?Lin`GRlUxPhVo$3ZtStW{XnB%ONu3{c&20fAakp=dBbKds$*X!$kse(Gl4u$ zC$OWZ1<2jlHS2rg3Gpawd*~L%h}NW`={_=w z7E(U}3?ZSw__t6XS|-FcIQP?(&H0Fwhb)7p8IWH0^Xfu3sL~hMIQph;KHCTAiBKcr ze6mVC=+_AB-hV|VPXDIQUH=UN6_eluSCubMjKD0)4HZtf*kolO5J6_?f&dT50DeGX w{<9yL0rCG--pUL9$FKPRBL9==X8%RGdS+Kd<;^%l0RMJwx7qg4!a3^y06mihaR2}S literal 0 HcmV?d00001 diff --git a/src/tools/font-sdf.c b/src/tools/font-sdf.c new file mode 100644 index 000000000..e28c34eaf --- /dev/null +++ b/src/tools/font-sdf.c @@ -0,0 +1,136 @@ +/* Copyright (c) 2013-2023 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include +#include +#include + +void createSdf(const struct mImage* src, struct mImage* dst, int x, int y, int w, int h) { + int i, j, ii, jj, z; + + static const int kernel[] = { + 11, 9, 8, 9, 11, + 9, 6, 4, 6, 9, + 8, 4, 0, 4, 8, + 9, 6, 4, 6, 9, + 11, 9, 8, 9, 11, + }; + const int* kc = &kernel[12]; + + for (j = y; j < y + h; ++j) { + for (i = x; i < x + w; ++i) { + if (mImageGetPixel(src, i, j) & 0xFFFFFF) { + mImageSetPixelRaw(dst, i, j, 0xFF); + } else { + mImageSetPixelRaw(dst, i, j, 1); + } + } + } + + for (z = 0; z < 16; ++z) { + int left = w * h; + for (j = y; j < y + h; ++j) { + for (i = x; i < x + w; ++i) { + int raw = mImageGetPixelRaw(dst, i, j) - 0x80; + int neighbors = raw; + for (jj = -2; jj < 3; ++jj) { + for (ii = -2; ii < 3; ++ii) { + if (!ii && !jj) { + continue; + } + if (i + ii - x < 0 || j + jj - y < 0) { + continue; + } + if (i + ii - x >= w || j + jj - y >= h) { + continue; + } + int neighbor = mImageGetPixelRaw(dst, i + ii, j + jj) - 0x80; + if (raw > 0) { + if (neighbor < 0) { + if ((!ii && (jj == -1 || jj == 1)) || (!jj && (ii == -1 || ii == 1))) { + neighbors = 1; + jj = 5; + break; + } + continue; + } + if (neighbor == 0x7F) { + continue; + } + if (neighbor + kc[ii + jj * 5] < neighbors) { + neighbors = neighbor + kc[ii + jj * 5]; + } + } else if (raw < 0) { + if (neighbor > 0) { + if ((!ii && (jj == -1 || jj == 1)) || (!jj && (ii == -1 || ii == 1))) { + neighbors = -4; + jj = 5; + break; + } + continue; + } + if (neighbor == -0x7F) { + continue; + } + if (neighbor - kc[ii + jj * 5] > neighbors) { + neighbors = neighbor - kc[ii + jj * 5]; + } + } + } + } + if (neighbors == raw) { + --left; + } else { + mImageSetPixelRaw(dst, i, j, neighbors + 0x80); + } + if (!left) { + break; + } + } + if (!left) { + break; + } + } + if (!left) { + break; + } + } +} + +int main(int argc, char* argv[]) { + struct mImage* source; + struct mImage* output; + + if (argc != 3) { + return 1; + } + source = mImageLoad(argv[1]); + if (!source) { + return 2; + } + output = mImageCreate(source->width, source->height, mCOLOR_L8); + if (!output) { + return 3; + } + + int i; + for (i = 0; i < 128; ++i) { + createSdf(source, output, (i & 0xF) << 6, (i & ~0xF) << 2, 64, 64); + } + for (i = 0; i < GUI_ICON_MAX; ++i) { + struct GUIIconMetric metric = defaultIconMetrics[i]; + metric.width += metric.x & 0xF; + metric.height += metric.y & 0xF; + metric.x &= ~0xF; + metric.y &= ~0xF; + createSdf(source, output, metric.x * 4, metric.y * 4 + 512, toPow2(metric.width) * 4, toPow2(metric.height) * 4); + } + if (!mImageSave(output, argv[2], NULL)) { + return 4; + } + mImageDestroy(source); + mImageDestroy(output); + return 0; +} From 050c5da26365bfa3fb8dbcb4573c7e657ff827a9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 16 Nov 2023 03:30:42 -0800 Subject: [PATCH 003/336] Tools: Move updater and docgen source into tools/ --- CMakeLists.txt | 4 ++-- src/{script => tools}/docgen.c | 0 src/{feature => tools}/updater-main.c | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/{script => tools}/docgen.c (100%) rename src/{feature => tools}/updater-main.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3a07530c..88d97aaa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1031,7 +1031,7 @@ if(BUILD_UPDATER) add_executable(updater-stub WIN32 ${CORE_VFS_SRC} ${VFS_SRC} ${OS_SRC} ${UTIL_BASE_SRC} ${THIRD_PARTY_SRC} ${CMAKE_CURRENT_SOURCE_DIR}/src/core/config.c ${CMAKE_CURRENT_SOURCE_DIR}/src/feature/updater.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/feature/updater-main.c) + ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/updater-main.c) target_link_libraries(updater-stub ${ZLIB_LIBRARY} ${ZLIB_LIBRARY} ${ZIP_LIBRARIES} ${OS_LIB} ${PLATFORM_LIBRARY}) set_target_properties(updater-stub PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FUNCTION_DEFINES};${FEATURE_DEFINES};BUILD_STATIC") if(MSVC) @@ -1043,7 +1043,7 @@ if(BUILD_UPDATER) endif() if(ENABLE_SCRIPTING AND BUILD_DOCGEN) - add_executable(docgen ${CMAKE_CURRENT_SOURCE_DIR}/src/script/docgen.c) + add_executable(docgen ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/docgen.c) target_link_libraries(docgen ${OS_LIB} ${PLATFORM_LIBRARY} ${BINARY_NAME}) endif() diff --git a/src/script/docgen.c b/src/tools/docgen.c similarity index 100% rename from src/script/docgen.c rename to src/tools/docgen.c diff --git a/src/feature/updater-main.c b/src/tools/updater-main.c similarity index 100% rename from src/feature/updater-main.c rename to src/tools/updater-main.c From ce4024a29eb4b231c14ce1d4b3960207ec591bb0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 Nov 2023 03:57:13 -0800 Subject: [PATCH 004/336] GBA Savedata: Fix crash when resizing flash save games for RTC data --- CHANGES | 1 + src/gba/savedata.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 7876950e6..8501f03a1 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Emulation fixes: Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger + - GBA Savedata: Fix crash when resizing flash save games for RTC data - mGUI: Fix cases where an older save state screenshot would be shown. (fixes mgba.io/i/2183) - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Re-enable sync for multiplayer windows that aren't connected (fixes mgba.io/i/2974) diff --git a/src/gba/savedata.c b/src/gba/savedata.c index 512af02c9..e7176650b 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -602,14 +602,23 @@ void GBASavedataRTCWrite(struct GBASavedata* savedata) { size_t size = GBASavedataSize(savedata); savedata->vf->seek(savedata->vf, size & ~0xFF, SEEK_SET); + int bank = 0; if ((savedata->vf->size(savedata->vf) & 0xFF) != sizeof(buffer)) { // Writing past the end of the file can invalidate the file mapping + if (savedata->type == SAVEDATA_FLASH1M) { + bank = savedata->currentBank == &savedata->data[0x10000]; + } savedata->vf->unmap(savedata->vf, savedata->data, size); savedata->data = NULL; } savedata->vf->write(savedata->vf, &buffer, sizeof(buffer)); if (!savedata->data) { savedata->data = savedata->vf->map(savedata->vf, size, MAP_WRITE); + if (savedata->type == SAVEDATA_FLASH1M) { + savedata->currentBank = &savedata->data[bank << 16]; + } else if (savedata->type == SAVEDATA_FLASH512) { + savedata->currentBank = savedata->data; + } } } From b7284542bcecafd2f677502a565d642527d542eb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 Nov 2023 21:36:35 -0800 Subject: [PATCH 005/336] Debugger: Move CLIDebugerEditLine implementation into debugger/ --- CMakeLists.txt | 2 -- .../mgba/internal/debugger}/cli-el-backend.h | 0 src/debugger/CMakeLists.txt | 8 ++++++++ src/{feature/editline => debugger}/cli-el-backend.c | 2 +- src/platform/sdl/main.c | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) rename {src/feature/editline => include/mgba/internal/debugger}/cli-el-backend.h (100%) rename src/{feature/editline => debugger}/cli-el-backend.c (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88d97aaa7..a1e730e04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -539,14 +539,12 @@ if(USE_EDITLINE) set(DEBUGGER_LIB ${LIBEDIT_LIBRARIES}) endif() set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libedit2") - list(APPEND FEATURE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/feature/editline/cli-el-backend.c") else() set(DEBUGGER_LIB "") endif() if(USE_GDB_STUB) list(APPEND FEATURES GDB_STUB) - list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/gdb-stub.c) endif() source_group("Debugger" FILES ${DEBUGGER_SRC}) diff --git a/src/feature/editline/cli-el-backend.h b/include/mgba/internal/debugger/cli-el-backend.h similarity index 100% rename from src/feature/editline/cli-el-backend.h rename to include/mgba/internal/debugger/cli-el-backend.h diff --git a/src/debugger/CMakeLists.txt b/src/debugger/CMakeLists.txt index 8bdc952de..ce2ade635 100644 --- a/src/debugger/CMakeLists.txt +++ b/src/debugger/CMakeLists.txt @@ -11,6 +11,14 @@ if(ENABLE_SCRIPTING) list(APPEND SOURCE_FILES cli-debugger-scripting.c) endif() +if(USE_EDITLINE) + list(APPEND SOURCE_FILES cli-el-backend.c) +endif() + +if(USE_GDB_STUB) + list(APPEND SOURCE_FILES gdb-stub.c) +endif() + set(TEST_FILES test/lexer.c test/parser.c) diff --git a/src/feature/editline/cli-el-backend.c b/src/debugger/cli-el-backend.c similarity index 99% rename from src/feature/editline/cli-el-backend.c rename to src/debugger/cli-el-backend.c index c76bb5d67..382a05c14 100644 --- a/src/feature/editline/cli-el-backend.c +++ b/src/debugger/cli-el-backend.c @@ -3,7 +3,7 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "cli-el-backend.h" +#include #include #include diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 2d9a74ae8..04a62f0d0 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -11,7 +11,7 @@ #include #endif #ifdef USE_EDITLINE -#include "feature/editline/cli-el-backend.h" +#include #endif #ifdef ENABLE_SCRIPTING #include From 319bdbd106a0994d9b57baaf78f23acfeaf19ade Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 Nov 2023 21:57:35 -0800 Subject: [PATCH 006/336] Feature: Move command-line debugger argument handling --- include/mgba/feature/commandline.h | 1 + src/feature/commandline.c | 35 ++++++++++++++++++++++++++++++ src/platform/sdl/main.c | 30 +------------------------ 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/include/mgba/feature/commandline.h b/include/mgba/feature/commandline.h index 964d9bdf9..d4f402241 100644 --- a/include/mgba/feature/commandline.h +++ b/include/mgba/feature/commandline.h @@ -59,6 +59,7 @@ void version(const char* arg0); bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparsers, int nSubparsers); void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparsers, int nSubparsers, struct mCoreConfig* config); +bool mArgumentsApplyDebugger(const struct mArguments*, struct mCore*, struct mDebugger*); void mArgumentsDeinit(struct mArguments* args); void mSubParserGraphicsInit(struct mSubParser* parser, struct mGraphicsOpts* opts); diff --git a/src/feature/commandline.c b/src/feature/commandline.c index e529a2eb3..0fe2c887d 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -9,6 +9,13 @@ #include #include +#ifdef USE_GDB_STUB +#include +#endif +#ifdef USE_EDITLINE +#include +#endif + #include #ifdef _MSC_VER #include @@ -206,6 +213,34 @@ void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparser } } +bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, struct mDebugger* debugger) { + bool hasDebugger = false; + + #ifdef USE_EDITLINE + if (args->debugCli) { + struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_CLI, core); + if (module) { + struct CLIDebugger* cliDebugger = (struct CLIDebugger*) module; + CLIDebuggerAttachBackend(cliDebugger, CLIDebuggerEditLineBackendCreate()); + mDebuggerAttachModule(debugger, module); + hasDebugger = true; + } + } +#endif + +#ifdef USE_GDB_STUB + if (args->debugGdb) { + struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_GDB, core); + if (module) { + mDebuggerAttachModule(debugger, module); + hasDebugger = true; + } + } +#endif + + return hasDebugger; +} + void mArgumentsDeinit(struct mArguments* args) { free(args->fname); args->fname = 0; diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 04a62f0d0..b1cb0efdd 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -7,12 +7,6 @@ #include -#ifdef USE_GDB_STUB -#include -#endif -#ifdef USE_EDITLINE -#include -#endif #ifdef ENABLE_SCRIPTING #include @@ -244,30 +238,8 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { #ifdef USE_DEBUGGERS struct mDebugger debugger; - bool hasDebugger = false; - mDebuggerInit(&debugger); -#ifdef USE_EDITLINE - if (args->debugCli) { - struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_CLI, renderer->core); - if (module) { - struct CLIDebugger* cliDebugger = (struct CLIDebugger*) module; - CLIDebuggerAttachBackend(cliDebugger, CLIDebuggerEditLineBackendCreate()); - mDebuggerAttachModule(&debugger, module); - hasDebugger = true; - } - } -#endif - -#ifdef USE_GDB_STUB - if (args->debugGdb) { - struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_GDB, renderer->core); - if (module) { - mDebuggerAttachModule(&debugger, module); - hasDebugger = true; - } - } -#endif + bool hasDebugger = mArgumentsApplyDebugger(args, renderer->core, &debugger); if (hasDebugger) { mDebuggerAttach(&debugger, renderer->core); From 3e47da2e18e37ee2226b65aca029b67eb16d7585 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 Nov 2023 22:10:09 -0800 Subject: [PATCH 007/336] SDL: Fix minor leak if debugger isn't used --- src/platform/sdl/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index b1cb0efdd..8f75384f0 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -247,6 +247,8 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { #ifdef ENABLE_SCRIPTING mScriptBridgeSetDebugger(bridge, &debugger); #endif + } else { + mDebuggerDeinit(&debugger); } #endif From 18a35b39287196ec3d51d5accb893c51a5f5c312 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 Nov 2023 22:12:40 -0800 Subject: [PATCH 008/336] Feature: Move command-line patch/cheats argument handling --- include/mgba/feature/commandline.h | 1 + src/feature/commandline.c | 27 +++++++++++++++++++++++++++ src/platform/sdl/main.c | 26 +------------------------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/include/mgba/feature/commandline.h b/include/mgba/feature/commandline.h index d4f402241..17af655fe 100644 --- a/include/mgba/feature/commandline.h +++ b/include/mgba/feature/commandline.h @@ -60,6 +60,7 @@ void version(const char* arg0); bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparsers, int nSubparsers); void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparsers, int nSubparsers, struct mCoreConfig* config); bool mArgumentsApplyDebugger(const struct mArguments*, struct mCore*, struct mDebugger*); +void mArgumentsApplyFileLoads(const struct mArguments*, struct mCore*); void mArgumentsDeinit(struct mArguments* args); void mSubParserGraphicsInit(struct mSubParser* parser, struct mGraphicsOpts* opts); diff --git a/src/feature/commandline.c b/src/feature/commandline.c index 0fe2c887d..7e720886d 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -5,9 +5,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include +#include #include #include +#include #ifdef USE_GDB_STUB #include @@ -241,6 +244,30 @@ bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, return hasDebugger; } +void mArgumentsApplyFileLoads(const struct mArguments* args, struct mCore* core) { + if (args->patch) { + struct VFile* patch = VFileOpen(args->patch, O_RDONLY); + if (patch) { + core->loadPatch(core, patch); + patch->close(patch); + } + } else { + mCoreAutoloadPatch(core); + } + + struct mCheatDevice* device = NULL; + if (args->cheatsFile && (device = core->cheatDevice(core))) { + struct VFile* vf = VFileOpen(args->cheatsFile, O_RDONLY); + if (vf) { + mCheatDeviceClear(device); + mCheatParseFile(device, vf); + vf->close(vf); + } + } else { + mCoreAutoloadCheats(core); + } +} + void mArgumentsDeinit(struct mArguments* args) { free(args->fname); args->fname = 0; diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 8f75384f0..f71f1cfc5 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -15,7 +15,6 @@ #endif #endif -#include #include #include #include @@ -110,16 +109,6 @@ int main(int argc, char** argv) { opts.width = renderer.width * renderer.ratio; opts.height = renderer.height * renderer.ratio; - struct mCheatDevice* device = NULL; - if (args.cheatsFile && (device = renderer.core->cheatDevice(renderer.core))) { - struct VFile* vf = VFileOpen(args.cheatsFile, O_RDONLY); - if (vf) { - mCheatDeviceClear(device); - mCheatParseFile(device, vf); - vf->close(vf); - } - } - mInputMapInit(&renderer.core->inputMap, &GBAInputInfo); mCoreInitConfig(renderer.core, PORT); mArgumentsApply(&args, &subparser, 1, &renderer.core->config); @@ -183,10 +172,6 @@ int main(int argc, char** argv) { mSDLDetachPlayer(&renderer.events, &renderer.player); mInputMapDeinit(&renderer.core->inputMap); - if (device) { - mCheatDeviceDestroy(device); - } - mSDLDeinit(&renderer); mStandardLoggerDeinit(&_logger); @@ -225,7 +210,7 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { return 1; } mCoreAutoloadSave(renderer->core); - mCoreAutoloadCheats(renderer->core); + mArgumentsApplyFileLoads(args, renderer->core); #ifdef ENABLE_SCRIPTING struct mScriptBridge* bridge = mScriptBridgeCreate(); #ifdef ENABLE_PYTHON @@ -252,15 +237,6 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { } #endif - if (args->patch) { - struct VFile* patch = VFileOpen(args->patch, O_RDONLY); - if (patch) { - renderer->core->loadPatch(renderer->core, patch); - } - } else { - mCoreAutoloadPatch(renderer->core); - } - renderer->audio.samples = renderer->core->opts.audioBuffers; renderer->audio.sampleRate = 44100; thread.logger.logger = &_logger.d; From 569bc92b9009cbd2213c43d68885670eb92ca97a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 Nov 2023 22:22:01 -0800 Subject: [PATCH 009/336] Test: Use refactored argument handling --- src/platform/test/fuzz-main.c | 13 +------------ src/platform/test/rom-test-main.c | 26 +++++++------------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/platform/test/fuzz-main.c b/src/platform/test/fuzz-main.c index 17abe0c1c..eb42b449b 100644 --- a/src/platform/test/fuzz-main.c +++ b/src/platform/test/fuzz-main.c @@ -100,9 +100,6 @@ int main(int argc, char** argv) { cleanExit = false; goto loadError; } - if (args.patch) { - core->loadPatch(core, VFileOpen(args.patch, O_RDONLY)); - } struct VFile* savestate = 0; struct VFile* savestateOverlay = 0; @@ -137,15 +134,7 @@ int main(int argc, char** argv) { hasDebugger = true; } - struct mCheatDevice* device; - if (args.cheatsFile && (device = core->cheatDevice(core))) { - struct VFile* vf = VFileOpen(args.cheatsFile, O_RDONLY); - if (vf) { - mCheatDeviceClear(device); - mCheatParseFile(device, vf); - vf->close(vf); - } - } + mArgumentsApplyFileLoads(&args, core); if (savestate) { if (!savestateOverlay) { diff --git a/src/platform/test/rom-test-main.c b/src/platform/test/rom-test-main.c index 6a8962743..28621389b 100644 --- a/src/platform/test/rom-test-main.c +++ b/src/platform/test/rom-test-main.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022 Jeffrey Pfau +/* Copyright (c) 2013-2023 Jeffrey Pfau * Copyright (c) 2022 Felix Jones * * This Source Code Form is subject to the terms of the Mozilla Public @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef M_CORE_GBA #include #endif @@ -137,28 +138,15 @@ int main(int argc, char * argv[]) { if (!mCoreLoadFile(core, args.fname)) { goto loadError; } - if (args.patch) { - core->loadPatch(core, VFileOpen(args.patch, O_RDONLY)); - } - - struct VFile* savestate = NULL; - - if (args.savestate) { - savestate = VFileOpen(args.savestate, O_RDONLY); - } core->reset(core); - struct mCheatDevice* device; - if (args.cheatsFile && (device = core->cheatDevice(core))) { - struct VFile* vf = VFileOpen(args.cheatsFile, O_RDONLY); - if (vf) { - mCheatDeviceClear(device); - mCheatParseFile(device, vf); - vf->close(vf); - } - } + mArgumentsApplyFileLoads(&args, core); + struct VFile* savestate = NULL; + if (args.savestate) { + savestate = VFileOpen(args.savestate, O_RDONLY); + } if (savestate) { mCoreLoadStateNamed(core, savestate, 0); savestate->close(savestate); From 63b18687f073deeac7c1aeabb386ffd4d1a89175 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 Nov 2023 22:27:43 -0800 Subject: [PATCH 010/336] Test: Allow ROM tester to be debugged --- src/platform/test/rom-test-main.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/platform/test/rom-test-main.c b/src/platform/test/rom-test-main.c index 28621389b..8c0d4fd3d 100644 --- a/src/platform/test/rom-test-main.c +++ b/src/platform/test/rom-test-main.c @@ -139,6 +139,19 @@ int main(int argc, char * argv[]) { goto loadError; } +#ifdef USE_DEBUGGERS + struct mDebugger debugger; + mDebuggerInit(&debugger); + bool hasDebugger = mArgumentsApplyDebugger(&args, core, &debugger); + + if (hasDebugger) { + mDebuggerAttach(&debugger, core); + mDebuggerEnter(&debugger, DEBUGGER_ENTER_MANUAL, NULL); + } else { + mDebuggerDeinit(&debugger); + } +#endif + core->reset(core); mArgumentsApplyFileLoads(&args, core); @@ -152,11 +165,25 @@ int main(int argc, char * argv[]) { savestate->close(savestate); } +#ifdef USE_DEBUGGERS + if (hasDebugger) { + do { + mDebuggerRun(&debugger); + } while (!_dispatchExiting && debugger.state != DEBUGGER_SHUTDOWN); + } else +#endif do { core->runLoop(core); } while (!_dispatchExiting); core->unloadROM(core); + +#ifdef USE_DEBUGGERS + if (hasDebugger) { + core->detachDebugger(core); + mDebuggerDeinit(&debugger); + } +#endif cleanExit = true; loadError: From dc9a2572d129917442dd023460436d1b09c8eeb5 Mon Sep 17 00:00:00 2001 From: Daniel <790119+DanTheMan827@users.noreply.github.com> Date: Tue, 28 Nov 2023 10:31:24 -0600 Subject: [PATCH 011/336] Add Goodboy Galaxy to overrides To enable rumble --- src/gba/overrides.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gba/overrides.c b/src/gba/overrides.c index 1d417d86b..ccc871e62 100644 --- a/src/gba/overrides.c +++ b/src/gba/overrides.c @@ -66,6 +66,9 @@ static const struct GBACartridgeOverride _overrides[] = { // F-Zero - Climax { "BFTJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + // Goodboy Galaxy + { "2GBP", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, + // Iridion II { "AI2E", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, { "AI2P", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, From a874450c1aeef3dadb23cfb0e8afc235214e6b6e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 10 Dec 2023 21:15:03 -0800 Subject: [PATCH 012/336] CMake: Bump minimum macOS to 10.7 when building against SDL2 --- src/platform/qt/CMakeLists.txt | 3 +++ src/platform/sdl/CMakeLists.txt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 5b8ba3fa8..9380a788b 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -10,6 +10,9 @@ if(BUILD_SDL) add_definitions(-DBUILD_SDL) if(SDL2_FOUND) link_directories(${SDL2_LIBDIR}) + if(APPLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.7") + endif() endif() list(APPEND PLATFORM_LIBRARY ${SDL_LIBRARY}) list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-events.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-audio.c) diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index cacf0bc48..987bd160f 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -22,6 +22,9 @@ if (SDL_VERSION EQUAL "2") endif() endif() + if(APPLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.7") + endif() set(SDLMAIN_LIBRARY ${SDL2MAIN_LIBRARY}) endif() endif() From c7240b0e8e0176baa2d352819c01a2875c045b46 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 10 Dec 2023 21:29:31 -0800 Subject: [PATCH 013/336] Qt: Fix minimum macOS version setting --- src/platform/qt/CMakeLists.txt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 9380a788b..32e1e6acd 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -10,9 +10,6 @@ if(BUILD_SDL) add_definitions(-DBUILD_SDL) if(SDL2_FOUND) link_directories(${SDL2_LIBDIR}) - if(APPLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.7") - endif() endif() list(APPEND PLATFORM_LIBRARY ${SDL_LIBRARY}) list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-events.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-audio.c) @@ -51,20 +48,22 @@ if(APPLE) endif() if(Qt6Widgets_VERSION) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.14") + set(MIN_VER 10.14) elseif(Qt5Widgets_VERSION MATCHES "^5.15") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.13") + set(MIN_VER 10.13) elseif(Qt5Widgets_VERSION MATCHES "^5.1[234]") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.12") + set(MIN_VER 10.12) elseif(Qt5Widgets_VERSION MATCHES "^5.11") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.11") + set(MIN_VER 10.11) elseif(Qt5Widgets_VERSION MATCHES "^5.(9|10)") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.10") + set(MIN_VER 10.10) elseif(Qt5Widgets_VERSION MATCHES "^5.8") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.9") + set(MIN_VER 10.9) else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.8") + set(MIN_VER 10.8) endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=${MIN_VER}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${MIN_VER}") if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() From 2e5836e1792804aef6b3a936765ef4c65a797f5c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 10 Dec 2023 23:53:10 -0800 Subject: [PATCH 014/336] Res: Add entitlements list for macOS --- res/entitlements.xml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 res/entitlements.xml diff --git a/res/entitlements.xml b/res/entitlements.xml new file mode 100644 index 000000000..33cd79505 --- /dev/null +++ b/res/entitlements.xml @@ -0,0 +1,7 @@ + + + + com.apple.security.device.camera + + + From 83528e14f5c357bfd0807f2d1a507d5feb4f836e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Dec 2023 00:14:04 -0800 Subject: [PATCH 015/336] Qt: Do codesigning on macOS --- src/platform/qt/CMakeLists.txt | 7 +++++++ tools/deploy-mac.py | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 32e1e6acd..f996e7c1f 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -485,6 +485,10 @@ if(APPLE) file(GLOB_RECURSE PLUGINS \"${BUNDLE_PATH}/Contents/PlugIns/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") fixup_bundle(\"${BUNDLE_PATH}\" \"${PLUGINS}\" \"\") " COMPONENT ${BINARY_NAME}-qt) + if(CODESIGN_IDENTITY) + install(CODE "execute_process(COMMAND codesign -s \"${CODESIGN_IDENTITY}\" -vf -o runtime --entitlements \"${CMAKE_SOURCE_DIR}/res/entitlements.xml\" \"${BUNDLE_PATH}\")" + COMPONENT ${BINARY_NAME}-qt) + endif() else() set(DEPLOY_OPTIONS -p platforms/libqcocoa.dylib,audio/libqtaudio_coreaudio.dylib,mediaservice/libqavfcamera.dylib) if(NOT CMAKE_INSTALL_NAME_TOOL EQUAL "install_name_tool") @@ -496,6 +500,9 @@ if(APPLE) if(DEFINED CROSS_ROOT) set(DEPLOY_OPTIONS ${DEPLOY_OPTIONS} -R "${CROSS_ROOT}") endif() + if($ENV{CODESIGN_IDENTITY}) + set(DEPLOY_OPTIONS ${DEPLOY_OPTIONS} -s "$ENV{CODESIGN_IDENTITY}" -E "${CMAKE_SOURCE_DIR}/res/entitlements.xml") + endif() install(CODE "execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/tools/deploy-mac.py\" -v ${DEPLOY_OPTIONS} \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${APPDIR}/${PROJECT_NAME}.app\")") endif() elseif(WIN32) diff --git a/tools/deploy-mac.py b/tools/deploy-mac.py index 82b8df4f2..89369d163 100755 --- a/tools/deploy-mac.py +++ b/tools/deploy-mac.py @@ -130,6 +130,8 @@ if __name__ == '__main__': parser.add_argument('-I', '--install-name-tool', metavar='INSTALL_NAME_TOOL', default='install_name_tool', help='path to install_name_tool') parser.add_argument('-O', '--otool', metavar='OTOOL', default='otool', help='path to otool') parser.add_argument('-p', '--qt-plugins', metavar='PLUGINS', default='', help='Qt plugins to include (comma-separated)') + parser.add_argument('-s', '--sign', metavar='IDENTITY', help='sign with a given identity') + parser.add_argument('-E', '--entitlements', metavar='ENTITLEMENTS', help='use a given file for entitlements when signing') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='output more information') parser.add_argument('bundle', help='application bundle to deploy') args = parser.parse_args() @@ -168,3 +170,9 @@ if __name__ == '__main__': newPath = os.path.join(newDir, plug) shutil.copy2(os.path.join(qtPath, 'plugins', plugin), newPath) updateMachO(newPath, splitPath(os.path.join(args.bundle, 'Contents/MacOS')), splitPath(args.root)) + if args.sign: + args = ['codesign', '-s', args.sign, '-vf', '-o', 'runtime'] + if args.entitlements: + args.extend(['--entitlements', args.entitlements]) + args.append(args.bundle) + subprocess.check_call(args) From 7b2fe75ebf3c24ef06f5f0ecf63e3466d3dadd40 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Dec 2023 01:21:01 -0800 Subject: [PATCH 016/336] Qt: Move install in CMake so install scripts get run first --- src/platform/qt/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index f996e7c1f..c8fabfabe 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -457,9 +457,6 @@ endif() target_link_libraries(${BINARY_NAME}-qt ${PLATFORM_LIBRARY} ${BINARY_NAME} ${QT_LIBRARIES}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE) -install(TARGETS ${BINARY_NAME}-qt - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-qt - BUNDLE DESTINATION ${APPDIR} COMPONENT ${BINARY_NAME}-qt) if(UNIX AND NOT APPLE) install(FILES ${CMAKE_SOURCE_DIR}/res/mgba-qt.desktop DESTINATION share/applications RENAME io.mgba.${PROJECT_NAME}.desktop COMPONENT ${BINARY_NAME}-qt) endif() @@ -530,3 +527,7 @@ if(DISTBUILD AND NOT APPLE) add_custom_command(TARGET ${BINARY_NAME}-qt POST_BUILD COMMAND "${STRIP}" "$") endif() endif() + +install(TARGETS ${BINARY_NAME}-qt + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-qt + BUNDLE DESTINATION ${APPDIR} COMPONENT ${BINARY_NAME}-qt) From ec2f791655f64cd1c50d1a7663f0b2c2a1116345 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Dec 2023 01:50:00 -0800 Subject: [PATCH 017/336] Qt: Do initial macOS resource staging in local app bundle --- src/platform/qt/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index c8fabfabe..ccc261712 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -323,7 +323,7 @@ if(WIN32) endif() if(NOT DEFINED DATADIR) if(APPLE) - set(DATADIR ${APPDIR}/${PROJECT_NAME}.app/Contents/Resources) + set(DATADIR ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.app/Contents/Resources) elseif(WIN32 AND NOT WIN32_UNIX_PATHS) set(DATADIR ".") else() From 256143944a8e0450e8f49a3126242b381433e1f2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Dec 2023 18:42:31 -0800 Subject: [PATCH 018/336] Qt: Code signing cleanup --- res/{entitlements.xml => entitlements.plist} | 0 src/platform/qt/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename res/{entitlements.xml => entitlements.plist} (100%) diff --git a/res/entitlements.xml b/res/entitlements.plist similarity index 100% rename from res/entitlements.xml rename to res/entitlements.plist diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index ccc261712..6cac77e4f 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -483,7 +483,7 @@ if(APPLE) fixup_bundle(\"${BUNDLE_PATH}\" \"${PLUGINS}\" \"\") " COMPONENT ${BINARY_NAME}-qt) if(CODESIGN_IDENTITY) - install(CODE "execute_process(COMMAND codesign -s \"${CODESIGN_IDENTITY}\" -vf -o runtime --entitlements \"${CMAKE_SOURCE_DIR}/res/entitlements.xml\" \"${BUNDLE_PATH}\")" + install(CODE "execute_process(COMMAND codesign -s \"${CODESIGN_IDENTITY}\" -vf -o runtime --timestamp --entitlements \"${CMAKE_SOURCE_DIR}/res/entitlements.plist\" \"${BUNDLE_PATH}\")" COMPONENT ${BINARY_NAME}-qt) endif() else() From 3a5642fcb81d3c279f8f385828e95ca3029d527d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Dec 2023 22:05:55 -0800 Subject: [PATCH 019/336] GB: Fix applying a patch that changes the cartridge mapper (fixes #3077) --- CHANGES | 1 + src/gb/gb.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 8501f03a1..0d15c9f9c 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Emulation fixes: Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger + - GB: Fix applying a patch that changes the cartridge mapper (fixes mgba.io/i/3077) - GBA Savedata: Fix crash when resizing flash save games for RTC data - mGUI: Fix cases where an older save state screenshot would be shown. (fixes mgba.io/i/2183) - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) diff --git a/src/gb/gb.c b/src/gb/gb.c index 899d5cfc7..bb9fafa5d 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -455,6 +455,9 @@ void GBApplyPatch(struct GB* gb, struct Patch* patch) { if (patchedSize > GB_SIZE_CART_MAX) { patchedSize = GB_SIZE_CART_MAX; } + + const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; + uint8_t type = cart->type; void* newRom = anonymousMemoryMap(GB_SIZE_CART_MAX); if (!patch->applyPatch(patch, gb->memory.rom, gb->pristineRomSize, newRom, patchedSize)) { mappedMemoryFree(newRom, GB_SIZE_CART_MAX); @@ -473,6 +476,12 @@ void GBApplyPatch(struct GB* gb, struct Patch* patch) { } gb->memory.rom = newRom; gb->memory.romSize = patchedSize; + + cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; + if (cart->type != type) { + gb->memory.mbcType = GB_MBC_AUTODETECT; + GBMBCInit(gb); + } gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize); gb->cpu->memory.setActiveRegion(gb->cpu, gb->cpu->pc); } From bfc830e08df2d7e33454b44f7a1f79f0487816d5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 18 Dec 2023 22:57:51 -0800 Subject: [PATCH 020/336] mGUI: Persist fast forwarding after closing menu (fixes #2414) --- CHANGES | 1 + src/feature/gui/gui-runner.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0d15c9f9c..f4d714888 100644 --- a/CHANGES +++ b/CHANGES @@ -39,6 +39,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) + - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) - Qt: Add exporting of SAV + RTC saves from Save Converter to strip RTC data - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 267b0e0b0..8c25a79fb 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -500,6 +500,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { } mLOG(GUI_RUNNER, INFO, "Game starting"); runner->fps = 0; + bool fastForward = false; while (running) { CircleBufferClear(&runner->fpsBuffer); runner->totalDelta = 0; @@ -508,7 +509,6 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { runner->lastFpsCheck = 1000000LL * tv.tv_sec + tv.tv_usec; int frame = 0; - bool fastForward = false; while (running) { if (runner->running) { running = runner->running(runner); From 333483a69e90d558830d6a6d96e72ac4dde00cca Mon Sep 17 00:00:00 2001 From: Daniel Simon Date: Tue, 19 Dec 2023 22:17:30 +0100 Subject: [PATCH 021/336] Qt: Fix generic icon on Wayland --- src/platform/qt/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index 4343168a7..c245cff53 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -104,6 +104,10 @@ int main(int argc, char* argv[]) { QApplication::setWindowIcon(QIcon(":/res/mgba-256.png")); #endif +#ifdef Q_OS_UNIX + QApplication::setDesktopFileName(QString("io.mgba.mGBA")); +#endif + QTranslator qtTranslator; qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); application.installTranslator(&qtTranslator); From fc95ee27950fccf6fb4d5d3d2e12be67e700aea8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Dec 2023 02:11:35 -0800 Subject: [PATCH 022/336] CInema: Add samesuite, mostly failing --- .../samesuite/apu/channel_1/align/config.ini | 2 + .../gb/samesuite/apu/channel_1/align/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_1/align/test.sym | 44 +++ .../apu/channel_1/align/xbaseline_0000.png | Bin 0 -> 998 bytes .../apu/channel_1/align_cpu/config.ini | 2 + .../samesuite/apu/channel_1/align_cpu/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/align_cpu/test.sym | 44 +++ .../channel_1/align_cpu/xbaseline_0000.png | Bin 0 -> 1037 bytes .../samesuite/apu/channel_1/delay/config.ini | 2 + .../gb/samesuite/apu/channel_1/delay/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_1/delay/test.sym | 44 +++ .../apu/channel_1/delay/xbaseline_0000.png | Bin 0 -> 918 bytes .../samesuite/apu/channel_1/duty/config.ini | 2 + .../gb/samesuite/apu/channel_1/duty/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_1/duty/test.sym | 45 +++ .../apu/channel_1/duty/xbaseline_0000.png | Bin 0 -> 1914 bytes .../apu/channel_1/duty_delay/config.ini | 2 + .../apu/channel_1/duty_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/duty_delay/test.sym | 45 +++ .../channel_1/duty_delay/xbaseline_0000.png | Bin 0 -> 1914 bytes .../extra_length_clocking-cgb0B/config.ini | 2 + .../extra_length_clocking-cgb0B/test.gb | Bin 0 -> 32768 bytes .../extra_length_clocking-cgb0B/test.sym | 44 +++ .../xbaseline_0000.png | Bin 0 -> 751 bytes .../apu/channel_1/freq_change/config.ini | 2 + .../apu/channel_1/freq_change/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/freq_change/test.sym | 45 +++ .../channel_1/freq_change/xbaseline_0000.png | Bin 0 -> 1916 bytes .../channel_1/freq_change_timing-A/config.ini | 2 + .../channel_1/freq_change_timing-A/test.gb | Bin 0 -> 32768 bytes .../channel_1/freq_change_timing-A/test.sym | 44 +++ .../freq_change_timing-A/xbaseline_0000.png | Bin 0 -> 679 bytes .../freq_change_timing-cgb0BC/config.ini | 2 + .../freq_change_timing-cgb0BC/test.gb | Bin 0 -> 32768 bytes .../freq_change_timing-cgb0BC/test.sym | 44 +++ .../xbaseline_0000.png | Bin 0 -> 666 bytes .../freq_change_timing-cgbDE/config.ini | 2 + .../freq_change_timing-cgbDE/test.gb | Bin 0 -> 32768 bytes .../freq_change_timing-cgbDE/test.sym | 44 +++ .../xbaseline_0000.png | Bin 0 -> 679 bytes .../apu/channel_1/nrx2_glitch/config.ini | 2 + .../apu/channel_1/nrx2_glitch/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/nrx2_glitch/test.sym | 44 +++ .../channel_1/nrx2_glitch/xbaseline_0000.png | Bin 0 -> 762 bytes .../channel_1/nrx2_speed_change/config.ini | 3 + .../apu/channel_1/nrx2_speed_change/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/nrx2_speed_change/test.sym | 44 +++ .../nrx2_speed_change/xbaseline_0000.png | Bin 0 -> 1402 bytes .../apu/channel_1/restart/config.ini | 2 + .../samesuite/apu/channel_1/restart/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_1/restart/test.sym | 44 +++ .../apu/channel_1/restart/xbaseline_0000.png | Bin 0 -> 1967 bytes .../channel_1/restart_nrx2_glitch/config.ini | 2 + .../apu/channel_1/restart_nrx2_glitch/test.gb | Bin 0 -> 32768 bytes .../channel_1/restart_nrx2_glitch/test.sym | 44 +++ .../restart_nrx2_glitch/xbaseline_0000.png | Bin 0 -> 682 bytes .../apu/channel_1/stop_div/config.ini | 2 + .../samesuite/apu/channel_1/stop_div/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_1/stop_div/test.sym | 46 +++ .../apu/channel_1/stop_div/xbaseline_0000.png | Bin 0 -> 1177 bytes .../apu/channel_1/stop_restart/config.ini | 2 + .../apu/channel_1/stop_restart/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/stop_restart/test.sym | 44 +++ .../channel_1/stop_restart/xbaseline_0000.png | Bin 0 -> 2076 bytes .../samesuite/apu/channel_1/sweep/config.ini | 2 + .../gb/samesuite/apu/channel_1/sweep/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_1/sweep/test.sym | 44 +++ .../apu/channel_1/sweep/xbaseline_0000.png | Bin 0 -> 2014 bytes .../apu/channel_1/sweep_restart/config.ini | 2 + .../apu/channel_1/sweep_restart/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/sweep_restart/test.sym | 45 +++ .../sweep_restart/xbaseline_0000.png | Bin 0 -> 1810 bytes .../apu/channel_1/sweep_restart_2/config.ini | 2 + .../apu/channel_1/sweep_restart_2/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/sweep_restart_2/test.sym | 44 +++ .../sweep_restart_2/xbaseline_0000.png | Bin 0 -> 1328 bytes .../samesuite/apu/channel_1/volume/config.ini | 2 + .../gb/samesuite/apu/channel_1/volume/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_1/volume/test.sym | 45 +++ .../apu/channel_1/volume/xbaseline_0000.png | Bin 0 -> 2574 bytes .../apu/channel_1/volume_div/config.ini | 3 + .../apu/channel_1/volume_div/test.gb | Bin 0 -> 32768 bytes .../apu/channel_1/volume_div/test.sym | 45 +++ .../channel_1/volume_div/xbaseline_0000.png | Bin 0 -> 1367 bytes .../samesuite/apu/channel_2/align/config.ini | 2 + .../gb/samesuite/apu/channel_2/align/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_2/align/test.sym | 44 +++ .../apu/channel_2/align/xbaseline_0000.png | Bin 0 -> 997 bytes .../apu/channel_2/align_cpu/config.ini | 2 + .../samesuite/apu/channel_2/align_cpu/test.gb | Bin 0 -> 32768 bytes .../apu/channel_2/align_cpu/test.sym | 44 +++ .../channel_2/align_cpu/xbaseline_0000.png | Bin 0 -> 1035 bytes .../samesuite/apu/channel_2/delay/config.ini | 2 + .../gb/samesuite/apu/channel_2/delay/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_2/delay/test.sym | 44 +++ .../apu/channel_2/delay/xbaseline_0000.png | Bin 0 -> 916 bytes .../samesuite/apu/channel_2/duty/config.ini | 2 + .../gb/samesuite/apu/channel_2/duty/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_2/duty/test.sym | 45 +++ .../apu/channel_2/duty/xbaseline_0000.png | Bin 0 -> 1927 bytes .../apu/channel_2/duty_delay/config.ini | 2 + .../apu/channel_2/duty_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_2/duty_delay/test.sym | 45 +++ .../channel_2/duty_delay/xbaseline_0000.png | Bin 0 -> 1909 bytes .../extra_length_clocking-cgb0B/config.ini | 2 + .../extra_length_clocking-cgb0B/test.gb | Bin 0 -> 32768 bytes .../extra_length_clocking-cgb0B/test.sym | 44 +++ .../xbaseline_0000.png | Bin 0 -> 792 bytes .../apu/channel_2/freq_change/config.ini | 2 + .../apu/channel_2/freq_change/test.gb | Bin 0 -> 32768 bytes .../apu/channel_2/freq_change/test.sym | 45 +++ .../channel_2/freq_change/xbaseline_0000.png | Bin 0 -> 1921 bytes .../apu/channel_2/nrx2_glitch/config.ini | 2 + .../apu/channel_2/nrx2_glitch/test.gb | Bin 0 -> 32768 bytes .../apu/channel_2/nrx2_glitch/test.sym | 44 +++ .../channel_2/nrx2_glitch/xbaseline_0000.png | Bin 0 -> 756 bytes .../channel_2/nrx2_speed_change/config.ini | 3 + .../apu/channel_2/nrx2_speed_change/test.gb | Bin 0 -> 32768 bytes .../apu/channel_2/nrx2_speed_change/test.sym | 44 +++ .../nrx2_speed_change/xbaseline_0000.png | Bin 0 -> 1420 bytes .../apu/channel_2/restart/config.ini | 2 + .../samesuite/apu/channel_2/restart/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_2/restart/test.sym | 44 +++ .../apu/channel_2/restart/xbaseline_0000.png | Bin 0 -> 1964 bytes .../channel_2/restart_nrx2_glitch/config.ini | 2 + .../apu/channel_2/restart_nrx2_glitch/test.gb | Bin 0 -> 32768 bytes .../channel_2/restart_nrx2_glitch/test.sym | 44 +++ .../restart_nrx2_glitch/xbaseline_0000.png | Bin 0 -> 690 bytes .../apu/channel_2/stop_div/config.ini | 2 + .../samesuite/apu/channel_2/stop_div/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_2/stop_div/test.sym | 46 +++ .../apu/channel_2/stop_div/xbaseline_0000.png | Bin 0 -> 1132 bytes .../apu/channel_2/stop_restart/config.ini | 2 + .../apu/channel_2/stop_restart/test.gb | Bin 0 -> 32768 bytes .../apu/channel_2/stop_restart/test.sym | 44 +++ .../channel_2/stop_restart/xbaseline_0000.png | Bin 0 -> 2089 bytes .../samesuite/apu/channel_2/volume/config.ini | 2 + .../gb/samesuite/apu/channel_2/volume/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_2/volume/test.sym | 44 +++ .../apu/channel_2/volume/xbaseline_0000.png | Bin 0 -> 569 bytes .../apu/channel_2/volume_div/config.ini | 2 + .../apu/channel_2/volume_div/test.gb | Bin 0 -> 32768 bytes .../apu/channel_2/volume_div/test.sym | 45 +++ .../channel_2/volume_div/xbaseline_0000.png | Bin 0 -> 1021 bytes .../apu/channel_3/and_glitch/config.ini | 2 + .../apu/channel_3/and_glitch/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/and_glitch/test.sym | 44 +++ .../channel_3/and_glitch/xbaseline_0000.png | Bin 0 -> 1026 bytes .../samesuite/apu/channel_3/delay/config.ini | 2 + .../gb/samesuite/apu/channel_3/delay/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_3/delay/test.sym | 44 +++ .../apu/channel_3/delay/xbaseline_0000.png | Bin 0 -> 619 bytes .../extra_length_clocking-cgb0/config.ini | 2 + .../extra_length_clocking-cgb0/test.gb | Bin 0 -> 32768 bytes .../extra_length_clocking-cgb0/test.sym | 44 +++ .../xbaseline_0000.png | Bin 0 -> 897 bytes .../extra_length_clocking-cgbB/config.ini | 2 + .../extra_length_clocking-cgbB/test.gb | Bin 0 -> 32768 bytes .../extra_length_clocking-cgbB/test.sym | 44 +++ .../xbaseline_0000.png | Bin 0 -> 872 bytes .../apu/channel_3/first_sample/config.ini | 2 + .../apu/channel_3/first_sample/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/first_sample/test.sym | 44 +++ .../channel_3/first_sample/xbaseline_0000.png | Bin 0 -> 558 bytes .../channel_3/freq_change_delay/config.ini | 2 + .../apu/channel_3/freq_change_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/freq_change_delay/test.sym | 44 +++ .../freq_change_delay/xbaseline_0000.png | Bin 0 -> 643 bytes .../channel_3/restart_delay/baseline_0000.png | Bin 0 -> 520 bytes .../apu/channel_3/restart_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/restart_delay/test.sym | 44 +++ .../channel_3/restart_during_delay/config.ini | 2 + .../channel_3/restart_during_delay/test.gb | Bin 0 -> 32768 bytes .../channel_3/restart_during_delay/test.sym | 45 +++ .../restart_during_delay/xbaseline_0000.png | Bin 0 -> 863 bytes .../channel_3/restart_stop_delay/config.ini | 2 + .../apu/channel_3/restart_stop_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/restart_stop_delay/test.sym | 44 +++ .../restart_stop_delay/xbaseline_0000.png | Bin 0 -> 547 bytes .../channel_3/shift_delay/baseline_0000.png | Bin 0 -> 540 bytes .../apu/channel_3/shift_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/shift_delay/test.sym | 44 +++ .../apu/channel_3/shift_skip_delay/config.ini | 2 + .../apu/channel_3/shift_skip_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/shift_skip_delay/test.sym | 44 +++ .../shift_skip_delay/xbaseline_0000.png | Bin 0 -> 558 bytes .../apu/channel_3/stop_delay/config.ini | 2 + .../apu/channel_3/stop_delay/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/stop_delay/test.sym | 44 +++ .../channel_3/stop_delay/xbaseline_0000.png | Bin 0 -> 503 bytes .../apu/channel_3/stop_div/config.ini | 2 + .../samesuite/apu/channel_3/stop_div/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_3/stop_div/test.sym | 45 +++ .../apu/channel_3/stop_div/xbaseline_0000.png | Bin 0 -> 1312 bytes .../wave_ram_dac_on_rw/baseline_0000.png | Bin 0 -> 1363 bytes .../apu/channel_3/wave_ram_dac_on_rw/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/wave_ram_dac_on_rw/test.sym | 48 +++ .../wave_ram_locked_write/baseline_0000.png | Bin 0 -> 2459 bytes .../channel_3/wave_ram_locked_write/test.gb | Bin 0 -> 32768 bytes .../channel_3/wave_ram_locked_write/test.sym | 53 +++ .../apu/channel_3/wave_ram_sync/config.ini | 2 + .../apu/channel_3/wave_ram_sync/test.gb | Bin 0 -> 32768 bytes .../apu/channel_3/wave_ram_sync/test.sym | 45 +++ .../wave_ram_sync/xbaseline_0000.png | Bin 0 -> 751 bytes .../samesuite/apu/channel_4/align/config.ini | 2 + .../gb/samesuite/apu/channel_4/align/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_4/align/test.sym | 44 +++ .../apu/channel_4/align/xbaseline_0000.png | Bin 0 -> 1094 bytes .../samesuite/apu/channel_4/delay/config.ini | 2 + .../gb/samesuite/apu/channel_4/delay/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_4/delay/test.sym | 44 +++ .../apu/channel_4/delay/xbaseline_0000.png | Bin 0 -> 948 bytes .../equivalent_frequencies/config.ini | 2 + .../channel_4/equivalent_frequencies/test.gb | Bin 0 -> 32768 bytes .../channel_4/equivalent_frequencies/test.sym | 44 +++ .../equivalent_frequencies/xbaseline_0000.png | Bin 0 -> 1716 bytes .../extra_length_clocking-cgb0B/config.ini | 2 + .../extra_length_clocking-cgb0B/test.gb | Bin 0 -> 32768 bytes .../extra_length_clocking-cgb0B/test.sym | 44 +++ .../xbaseline_0000.png | Bin 0 -> 777 bytes .../apu/channel_4/freq_change/config.ini | 2 + .../apu/channel_4/freq_change/test.gb | Bin 0 -> 32768 bytes .../apu/channel_4/freq_change/test.sym | 44 +++ .../channel_4/freq_change/xbaseline_0000.png | Bin 0 -> 1128 bytes .../channel_4/frequency_alignment/config.ini | 2 + .../apu/channel_4/frequency_alignment/test.gb | Bin 0 -> 32768 bytes .../channel_4/frequency_alignment/test.sym | 44 +++ .../frequency_alignment/xbaseline_0000.png | Bin 0 -> 1999 bytes .../samesuite/apu/channel_4/lfsr/config.ini | 2 + .../gb/samesuite/apu/channel_4/lfsr/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/apu/channel_4/lfsr/test.sym | 44 +++ .../apu/channel_4/lfsr/xbaseline_0000.png | Bin 0 -> 3804 bytes .../samesuite/apu/channel_4/lfsr15/config.ini | 2 + .../gb/samesuite/apu/channel_4/lfsr15/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/channel_4/lfsr15/test.sym | 44 +++ .../apu/channel_4/lfsr15/xbaseline_0000.png | Bin 0 -> 3534 bytes .../apu/channel_4/lfsr_15_7/config.ini | 2 + .../samesuite/apu/channel_4/lfsr_15_7/test.gb | Bin 0 -> 32768 bytes .../apu/channel_4/lfsr_15_7/test.sym | 44 +++ .../channel_4/lfsr_15_7/xbaseline_0000.png | Bin 0 -> 2155 bytes .../apu/channel_4/lfsr_7_15/config.ini | 2 + .../samesuite/apu/channel_4/lfsr_7_15/test.gb | Bin 0 -> 32768 bytes .../apu/channel_4/lfsr_7_15/test.sym | 44 +++ .../channel_4/lfsr_7_15/xbaseline_0000.png | Bin 0 -> 2184 bytes .../apu/channel_4/lfsr_restart/config.ini | 2 + .../apu/channel_4/lfsr_restart/test.gb | Bin 0 -> 32768 bytes .../apu/channel_4/lfsr_restart/test.sym | 44 +++ .../channel_4/lfsr_restart/xbaseline_0000.png | Bin 0 -> 3829 bytes .../channel_4/lfsr_restart_fast/config.ini | 2 + .../apu/channel_4/lfsr_restart_fast/test.gb | Bin 0 -> 32768 bytes .../apu/channel_4/lfsr_restart_fast/test.sym | 44 +++ .../lfsr_restart_fast/xbaseline_0000.png | Bin 0 -> 3829 bytes .../channel_4/volume_div/baseline_0000.png | Bin 0 -> 915 bytes .../apu/channel_4/volume_div/config.ini | 2 + .../apu/channel_4/volume_div/test.gb | Bin 0 -> 32768 bytes .../apu/channel_4/volume_div/test.sym | 45 +++ .../div_trigger_volume_10/baseline_0000.png | Bin 0 -> 787 bytes .../apu/div_trigger_volume_10/config.ini | 2 + .../apu/div_trigger_volume_10/test.gb | Bin 0 -> 32768 bytes .../apu/div_trigger_volume_10/test.sym | 305 ++++++++++++++++++ .../apu/div_write_trigger/config.ini | 2 + .../samesuite/apu/div_write_trigger/test.gb | Bin 0 -> 32768 bytes .../samesuite/apu/div_write_trigger/test.sym | 46 +++ .../apu/div_write_trigger/xbaseline_0000.png | Bin 0 -> 1695 bytes .../apu/div_write_trigger_10/config.ini | 2 + .../apu/div_write_trigger_10/test.gb | Bin 0 -> 32768 bytes .../apu/div_write_trigger_10/test.sym | 47 +++ .../div_write_trigger_10/xbaseline_0000.png | Bin 0 -> 1633 bytes .../apu/div_write_trigger_volume/config.ini | 2 + .../apu/div_write_trigger_volume/test.gb | Bin 0 -> 32768 bytes .../apu/div_write_trigger_volume/test.sym | 303 +++++++++++++++++ .../xbaseline_0000.png | Bin 0 -> 728 bytes .../div_write_trigger_volume_10/config.ini | 2 + .../apu/div_write_trigger_volume_10/test.gb | Bin 0 -> 32768 bytes .../apu/div_write_trigger_volume_10/test.sym | 303 +++++++++++++++++ .../xbaseline_0000.png | Bin 0 -> 783 bytes cinema/gb/samesuite/config.ini | 6 + .../dma/gbc_dma_cont/baseline_0000.png | Bin 0 -> 1115 bytes cinema/gb/samesuite/dma/gbc_dma_cont/test.gb | Bin 0 -> 32768 bytes cinema/gb/samesuite/dma/gbc_dma_cont/test.sym | 47 +++ .../dma/gdma_addr_mask/baseline_0000.png | Bin 0 -> 896 bytes .../gb/samesuite/dma/gdma_addr_mask/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/dma/gdma_addr_mask/test.sym | 48 +++ .../gb/samesuite/dma/hdma_lcd_off/config.ini | 2 + cinema/gb/samesuite/dma/hdma_lcd_off/test.gb | Bin 0 -> 32768 bytes cinema/gb/samesuite/dma/hdma_lcd_off/test.sym | 48 +++ .../dma/hdma_lcd_off/xbaseline_0000.png | Bin 0 -> 1229 bytes cinema/gb/samesuite/dma/hdma_mode0/config.ini | 2 + cinema/gb/samesuite/dma/hdma_mode0/test.gb | Bin 0 -> 32768 bytes cinema/gb/samesuite/dma/hdma_mode0/test.sym | 48 +++ .../dma/hdma_mode0/xbaseline_0000.png | Bin 0 -> 1229 bytes .../interrupt/ei_delay_halt/config.ini | 2 + .../samesuite/interrupt/ei_delay_halt/test.gb | Bin 0 -> 32768 bytes .../interrupt/ei_delay_halt/test.sym | 47 +++ .../ei_delay_halt/xbaseline_0000.png | Bin 0 -> 1193 bytes .../blocking_bgpi_increase/baseline_0000.png | Bin 0 -> 577 bytes .../ppu/blocking_bgpi_increase/test.gb | Bin 0 -> 32768 bytes .../ppu/blocking_bgpi_increase/test.sym | 48 +++ .../sgb/command_mlt_req/baseline_0000.png | Bin 0 -> 608 bytes .../gb/samesuite/sgb/command_mlt_req/test.gb | Bin 0 -> 32768 bytes .../gb/samesuite/sgb/command_mlt_req/test.sym | 55 ++++ .../sgb/command_mlt_req_1/baseline_0000.png | Bin 0 -> 608 bytes .../samesuite/sgb/command_mlt_req_1/test.gb | Bin 0 -> 32768 bytes .../samesuite/sgb/command_mlt_req_1/test.sym | 50 +++ .../baseline_0000.png | Bin 0 -> 520 bytes .../command_mlt_req_1_incrementing/test.gb | Bin 0 -> 32768 bytes .../command_mlt_req_1_incrementing/test.sym | 52 +++ 307 files changed, 4485 insertions(+) create mode 100644 cinema/gb/samesuite/apu/channel_1/align/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/align/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/align/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/align/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/align_cpu/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/align_cpu/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/align_cpu/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/align_cpu/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/duty/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/duty/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/duty/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/duty/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/duty_delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/duty_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/duty_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/duty_delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_glitch/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_glitch/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_glitch/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_glitch/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/restart/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/restart/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/restart/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/restart/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_div/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_div/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_div/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_div/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_restart/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_restart/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_restart/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/stop_restart/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart_2/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart_2/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart_2/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/sweep_restart_2/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/volume/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/volume/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/volume/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/volume/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_1/volume_div/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_1/volume_div/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_1/volume_div/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_1/volume_div/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/align/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/align/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/align/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/align/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/align_cpu/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/align_cpu/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/align_cpu/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/align_cpu/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/duty/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/duty/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/duty/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/duty/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/duty_delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/duty_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/duty_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/duty_delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/freq_change/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/freq_change/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/freq_change/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/freq_change/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_glitch/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_glitch/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_glitch/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_glitch/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/restart/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/restart/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/restart/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/restart/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_div/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_div/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_div/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_div/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_restart/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_restart/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_restart/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/stop_restart/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/volume/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/volume/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/volume/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/volume/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_2/volume_div/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_2/volume_div/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_2/volume_div/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_2/volume_div/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/and_glitch/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/and_glitch/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/and_glitch/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/and_glitch/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/first_sample/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/first_sample/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/first_sample/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/first_sample/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/freq_change_delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/freq_change_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/freq_change_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/freq_change_delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_delay/baseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_during_delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_during_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_during_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_during_delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_stop_delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_stop_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_stop_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/restart_stop_delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/shift_delay/baseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/shift_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/shift_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/shift_skip_delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/shift_skip_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/shift_skip_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/shift_skip_delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_div/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_div/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_div/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/stop_div/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/baseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/baseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_sync/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_sync/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_sync/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_3/wave_ram_sync/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/align/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/align/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/align/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/align/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/delay/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/delay/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/delay/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/delay/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/freq_change/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/freq_change/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/freq_change/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/freq_change/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/frequency_alignment/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/frequency_alignment/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/frequency_alignment/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/frequency_alignment/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr15/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr15/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr15/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr15/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_15_7/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_15_7/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_15_7/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_15_7/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_7_15/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_7_15/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_7_15/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_7_15/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/test.sym create mode 100644 cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/volume_div/baseline_0000.png create mode 100644 cinema/gb/samesuite/apu/channel_4/volume_div/config.ini create mode 100644 cinema/gb/samesuite/apu/channel_4/volume_div/test.gb create mode 100644 cinema/gb/samesuite/apu/channel_4/volume_div/test.sym create mode 100644 cinema/gb/samesuite/apu/div_trigger_volume_10/baseline_0000.png create mode 100644 cinema/gb/samesuite/apu/div_trigger_volume_10/config.ini create mode 100644 cinema/gb/samesuite/apu/div_trigger_volume_10/test.gb create mode 100644 cinema/gb/samesuite/apu/div_trigger_volume_10/test.sym create mode 100644 cinema/gb/samesuite/apu/div_write_trigger/config.ini create mode 100644 cinema/gb/samesuite/apu/div_write_trigger/test.gb create mode 100644 cinema/gb/samesuite/apu/div_write_trigger/test.sym create mode 100644 cinema/gb/samesuite/apu/div_write_trigger/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_10/config.ini create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_10/test.gb create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_10/test.sym create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_10/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume/config.ini create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume/test.gb create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume/test.sym create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume_10/config.ini create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume_10/test.gb create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume_10/test.sym create mode 100644 cinema/gb/samesuite/apu/div_write_trigger_volume_10/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/config.ini create mode 100644 cinema/gb/samesuite/dma/gbc_dma_cont/baseline_0000.png create mode 100644 cinema/gb/samesuite/dma/gbc_dma_cont/test.gb create mode 100644 cinema/gb/samesuite/dma/gbc_dma_cont/test.sym create mode 100644 cinema/gb/samesuite/dma/gdma_addr_mask/baseline_0000.png create mode 100644 cinema/gb/samesuite/dma/gdma_addr_mask/test.gb create mode 100644 cinema/gb/samesuite/dma/gdma_addr_mask/test.sym create mode 100644 cinema/gb/samesuite/dma/hdma_lcd_off/config.ini create mode 100644 cinema/gb/samesuite/dma/hdma_lcd_off/test.gb create mode 100644 cinema/gb/samesuite/dma/hdma_lcd_off/test.sym create mode 100644 cinema/gb/samesuite/dma/hdma_lcd_off/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/dma/hdma_mode0/config.ini create mode 100644 cinema/gb/samesuite/dma/hdma_mode0/test.gb create mode 100644 cinema/gb/samesuite/dma/hdma_mode0/test.sym create mode 100644 cinema/gb/samesuite/dma/hdma_mode0/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/interrupt/ei_delay_halt/config.ini create mode 100644 cinema/gb/samesuite/interrupt/ei_delay_halt/test.gb create mode 100644 cinema/gb/samesuite/interrupt/ei_delay_halt/test.sym create mode 100644 cinema/gb/samesuite/interrupt/ei_delay_halt/xbaseline_0000.png create mode 100644 cinema/gb/samesuite/ppu/blocking_bgpi_increase/baseline_0000.png create mode 100644 cinema/gb/samesuite/ppu/blocking_bgpi_increase/test.gb create mode 100644 cinema/gb/samesuite/ppu/blocking_bgpi_increase/test.sym create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req/baseline_0000.png create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req/test.gb create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req/test.sym create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req_1/baseline_0000.png create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req_1/test.gb create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req_1/test.sym create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/baseline_0000.png create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/test.gb create mode 100644 cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/test.sym diff --git a/cinema/gb/samesuite/apu/channel_1/align/config.ini b/cinema/gb/samesuite/apu/channel_1/align/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/align/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/align/test.gb b/cinema/gb/samesuite/apu/channel_1/align/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..2d3b6c8b18f5bc0931dc9b43104ffe2f0d5c76e3 GIT binary patch literal 32768 zcmeIyZ)h8390%|x%_WUnl3tpwUL`h{vV|CAZSjS95pJQBuE>PqE5R2FIOEV!3PN|) z>owB3(-(q>j8#F|3tx!@86wgtox{PAo@FokLR{hLaKY6-v@6>%n~BeJ*KYOCUHZy5 zexLS^d!Fy_?s@Wgk|X4Q-A2{j?~E(67vwvN_?3Lq)N;f3o0cPFK%5vD8x!rO zX@u}x5JDkQl;sC~DIo~M!@ORSGEycpni(C{v`~oE=ZghR6;7FN!%)%w#fJF2gEVz5T51vvYsJZqEG^YT<}8Tj9ur z%ID*us`9hF{vG{7fe<}ky5ICXAvsCSsj6f*U3c|T zwZ~7K(DiVb)hiQ4T??}2OHnaB(+7>`jF%1Fc-xpWJ~loz&KqAC7mSO> zPsR;n&G^|^H#Ur$#-{P@^7X^rB;^y-TKmzSo-B>)v?~=8)MPTbH6rP>CzY~C_@Mu2 zy}9(8u-06fwQqP-r@hKadceBD7Ik3t%0-hcDor0@WBV0e#zv{g#$vQvS*M-!VMV5i z)IhV+x7GT$FU$%}n^|j6h{(U2);E6Zhk!D+)?iOa)25XTSTFe4r(~bj`90PfON}u( z8uUj4-J#w{df&l5sXaI}I`(YwxN3bEm}1AP?0AhG8at-h;oMm%O!~+|?2|x>oK^X+ zmH%Ci^{KTEcAnZXGG&kKxxT#mb(&-zx}}V;^=zaEt532Zb!xS5J8DZ0);jWRz#pHk zB^zCGb-A1LhI_7PjkEFx(~SlBj7fdU>$GjXtvVyuP3JYUb!NZNoqg8*M_=*Lr$rJY z3rwS*rc;wm8n;zD6@zx^*1LQEH6ZSZSLB&_hb_`pam&1QfqRA3oN@KA8Xnmn9@#yQ z?5;;vcgu+DezL^v!|}*7^A202t>Tt>>w;ZWc$B#BEQ4|1S{}OYEe~Bcmxr#q%R~3= zB`kLN8nU;5#}?b6D}s}@id*Kb3wBYlo047CcounVI>+$Xb~|?8csq9AdOLRCd^>iw z-|US4^-aI?HIHiuKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< U00Izz00bZa0SG|gKNK+k1TKFB-T(jq literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/align/test.sym b/cinema/gb/samesuite/apu/channel_1/align/test.sym new file mode 100644 index 000000000..c2dc87faf --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/align/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05db RunTest +00:0b92 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/align/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/align/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..10bf03557679edc590ec47206aeec2aa9cb6ac28 GIT binary patch literal 998 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|WC~PZ!6KiaBrR1eVP<5Mc0) z^Us(s7$5w1LH=rmH%gLAlV<#!wA6HsO~;0?Nzq=J^PWc^vpKK1l==7Ri>WK#WOnq= z`~6q${oecUXWLqaclMvx_`jzw*Zuse*l#9Bj<=ltw)&#?(f?JS%@{X``8@hqapdc- z3L8DC{gu{V#dwJdX1UX$Wak>0-fK^woFZ~Z>|d(GXv?ax13rrOLupZaFS zzoHUJt!lf@`<1TW_bvX?w|?&XDM3+U2R}WNduyLQ>)$=yX=OJjbKjPf*S1g-db>&8 ze`T=U;71dpGxd#^=2;vNc!9=EYT0iH{$PCghjtiOcg%YqWhElXB`t z&w1tWx8aMA$xH4R`s|;$+E}yV!;fiyAAI>+xp!vqo8|Lt_a(Bve;FxTv$?iQwBTFC z>jbNn|1_&UE3AL?_^F2fRPpZjaqQLhKlX2V!~Wd)=SH)~k7r3enLYRPQ(?=eKlkQ` zUp@Hq1vn6&&s=kB_Tuo<%WKV7&S~52$^7i{Ciy+PLYh~- z|G2c%w$!X?e!1jaX+go%<<|~=DzyKR;C6a>Dr@-H&!4KpkE&&$^jF1~sbRdxO8^7|jAf0y|gUzXw^!sC9h cU}O+=%w|HB7ng2b=LpKbp00i_>zopr0FRLA8UO$Q literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/align_cpu/config.ini b/cinema/gb/samesuite/apu/channel_1/align_cpu/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/align_cpu/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/align_cpu/test.gb b/cinema/gb/samesuite/apu/channel_1/align_cpu/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..b5fe604185ae80b641e73a688f411ed619fa9922 GIT binary patch literal 32768 zcmeIyZ)h8390%|x%_WUnl3tpwUL`h{vV|CAZSjS95pJQBuE>PqE5R2FIOEV!3PN|) z>owB3(-(q>j8#F|3tx!@86wiDonyk0o@FokLR{hLaKY6-v@6>%n~BfeHBDyITwnRd z@3Y-;&-4A=Jly(Hd~_;1A9x{?~+Zc2)f0e)g&Y>c;> zq7Y){9Ov`#yeQWDLWJXnhs}CHNC=6UloJ^NB=4NhMeXtGAw2JKOhXtY+UoA!m-+vt^D= z$mV=zD9h&AT7N@7lOaS+=eC=gCL|@uDOnb*rmA-C_4@sSFfdT>_eQ+lT+XbIMADIT zT6yx+DOL6RS-muoRTVF5cFsIl-=4y(SJjab_BemU7h!YM=C@a2C8^>sht4eSg+!_I$E(V%(nX#JH@O^O>Qdm}hJK4gGAEkm}3_&pq=5AzmRq^r$iBD#XZKFw++h9~k4V*adfp@Wz*J>%w>C z3wMEfDM#C-JoQK%t!~ox0_~V2`nfa9Z+&?7-r2+23)-uis=cetX`gDJYZtYzv`gA$ z?N{xVwx<22t!o?FZEaJ#x_t9!H;K78xzv8Vrzc6nD(#AeI5`@PZjA^k?TN*#5p&Re zyj)%SlUu7U&004+uF_uVG(BY8Vv9PodhN2#78R$Dv9W`aS;j^w&&EQuTUw``^ifHq zk=Q`B(6`n4YZrQf#`UBz$OXi|bmM!s@v}!7TdS}q#A($?dW@G`>@C^b+TUZjvQ!xp zgI;&g)9vdG#194Yp3|vIdXu)Tw-sl^vTpy(Y@OK`>eQE9^jV&S$O6;o zr}5Zim4+?VPD!I(s`38*rUBVKX%)51T89p)Q|y>K7wlePRA+YeFe)vwzguJvT4eWI zWaaIQ?7E*jlkJyl61B`)hYqPz?3gPcb*0|WCFPZ!6KiaBrRT%5L8L4dXN zT+PC|#sAcPKbRNCW}1E)L>ITC$t zlg_t$sgZugNp79nt3~dwPrp2E@{-SUx+-25%-g3WtM%{q(c2CUAsd8V@4EGQ*SgmW zJ}$qk8N9{kPxz;8mGhog&U0uxpcQ3R$9MC_d+ukmuh;lq-tzvp%*OY>1HXmT#Z`$s zwS0f%e$Ar2=_2ocT>5uTu_akRCjXnq|Gk&~SjmlwHDl4~+n1y2 zZ?dlzX1mQ^y?y!Ce|+2d<<{;uRkqOERmG-zFV5`K$#VrCpFPmnF}csRt>f|!3nS0? zsY3r#YLuSsKQu{OamU9WvpzrgP`o$JSN{3Ry~o3Q9#~s?K3)D&&&}ce$2ZMaIiIe6 zaoKC#qqnKrt4|$#bocwgGwk!1KC`jV>w0a~yFGo?ME|lqufON{7ye$$UsxZvy!+e1 z!puqMinSg+o~H8ha?txKFZM7FqJw?f4h8=l%ZQ-xs}2-NO@k{i})k zzS-vc#bf`tT;F#5_hilW?|W|xi=6l1U$)k<^4FFtd5*xS)9upF?JwU`UZ1^ByjGn} z>fze^?B~UQubw?+UU}8!TR-0^?|9#w{=7D;=BxF`rEd-AJlgv^dMAHf@tZ^M1*NR{ zx6N_;cJ|)Kdw+A^+3eW*t>UpAcUaGZMK#qoPpJFuy&f-$gQ3G4_Lx6e46; ex|@f+;2%bVOHPmGuZ<4@WphtgKbLh*2~7ZPlm_4&^izI#sbh?U&FkC5UAzueu(RZHpc#%TQ`vBs`vX>QYGgZE1IMU=$& zl61kB>5fOlntQgpl_QlS_Ru|vlrn?eab@n3cwgba7w?!_c66s{Swe>R$)S9ncbcXV zV&@ze3h}%sKI#hzjvF1d>jfb#q|@W+@o`NHg;>2@$Z0CanwzWH9P7JN*!7ymo)-#* z1R}6G+~?bsc7>B~uSb(PPG)^F-}b;liMSLPWvRu8Lm=}PSZoyEw-pbYu7HDY*8ut6dOCJ*kx>#@@y)s*t{^yG-YP2VJ;&6ZCXG2tx7=2uh-cVQnX=Z0@kZO_Ll5z-S4qhU#{oHXwV-G z^oIH)sRM@xgwEi|c>blrN!9u+FwKs)*zq>)A{VSDt5qbY^X!8Fi$Ft6ef1@W*GW$$F1i zS?MMH;l68H{k-_;OuZzYGpSE`hjwgqRA$ARN!VA(8rk`~ebF3_kwy02gES>gHIxR8 zD~mM76uT9J_UP8_eg7Gfz0+24%e-|#8x`%8v{lny(cV>7V|Gt7tKK62r$zp-MgE{g zUi0Mjy|#lV^t`$^Z56l7TNkuZ(N0NQHSHDcUG>;@@R&We9lW`BJ9u;NcJSuj?cmMb z?O=AtP4|BloFM=K2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf UKmY;|fB*y_009UFX~c_X#fBK literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/delay/test.sym b/cinema/gb/samesuite/apu/channel_1/delay/test.sym new file mode 100644 index 000000000..9d3c63f11 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/delay/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb RunTest +00:09ed StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/delay/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/delay/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..f42030316c7c82a0967a2b14d57249392bf69670 GIT binary patch literal 918 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Rrcr;B4q#hkaZ94E~-5MVeO z7MF3aWB*DSkCj^-WZEi(F21unc_~8fj$1}pbk^F_o2K-oMrN(ee{;Woo%8Q`QQ5C6 zZRFnW?LYo_!}2LYbL+SKc=6Tk@$#tGCcdxDL%mLB{QtEiGfV&aw|&d^7S_IBw)g!@ z`$tdyT&&sjc=7ey7LxxL*Q8HgdS~w11fkQLw#0vV_OY=0hsI}{?Z1oXJ>R-9c2RZA zqW_LH--P~#?lbnioTjwX{A#R8op`L9(yqFmY4uayeEqa~%BLE;<$cdT@9f*VbpPI* z{=Y$|Y|gjazHWYUOZGzjuU{8`&*T2-^1T08`u&eDOFuj`TljCk@8yi2DbMp|dD3@x z|C7F^x^!($z0TKbyKbX_V{y*HZYv1{tTK+ZV@7x8k&h@tI zZ~t}qtMqyIk87JV-&fli?E9}~{`T<27k{poU;MqLPW-;x?bGJ(wBF0vtG<7=eh&M4 z)Bckg&v)N^ez5&>{Lbd@i`5^y??`s*KEJPdZS%`36?>~KPImwJ`=a+;_U6aY{z0*J zcPc+D7mU?kyzkQM2Zt~Ik8tOkeg5WtAJ^yk`#b86R@{|a#rMwm<`#Z;_tWau|Gt%e zn6iia?78Lt)r=nj?aQxQ)%yZy!rb?6o%5#ee``}=Uu9I+V*Tv$`v+$y$LIO)t(3h} z#b$ZG_t|9G`rlR-yY8jLzt4Dm|1In3?0Y}sry416wJlDt7$uOyz@BjtPi;E$HqVEk O{O0NE=d#Wzp$PyPxX8Nz literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/duty/config.ini b/cinema/gb/samesuite/apu/channel_1/duty/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/duty/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/duty/test.gb b/cinema/gb/samesuite/apu/channel_1/duty/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..2ffcd2b6ec27425f87690fba884f27b9b2cd8173 GIT binary patch literal 32768 zcmeIyacCP=90%~1=94AwrBtL%J|rdNt=awE@A0wgHr zqvu?S_K;t$+C3kZ4wVk^sf{SfCwkjM%G3pUQxU(DSBqM5@P5;hg!GA{eVL4CHBBRg z=Yrt%ilQuUkEO663=Z;oNs3GH_;7r9Skt^-R-ekIHC15E&edd^jqN3Py{57IdA(kV zNNf%J{=AY`Sozj|w3HyESiLAFMKK~_AeH_X;(tZ(na%D48TD;|%+>Ln?~{!;t( z6c1Rvb+1NmU!S#_y`HKa8?jeAHlk{LJsxTr@2&ms7-zGD)F(fB;km~Ni41fMv<{Gg zz-v-d;JA`Mf6bS;wokrWTvL9fhs}(u5GB)rbdO)YXO6g{=iEUenqRxE6Yu4(+y&~P z0&P+9v{?~oeT}vhXxkVmo;fxD?%C6urw?;fDF&DWQ{GvHZK34hD%0E8^ zd(?6p>&JJ@j9W9U*XI|%kCFI8>&g(@&q}Pn^fU{irxtq}QB$nH+?HY!?$AUzQtOaQ z^PQyI*L6j!os~bCs1f;0k-C((X;Y=CG$~h$_G@Ol=TEa!V-N8ID|p6R%|nL@$jgbs8Fvj@4<9{eJC=K|6Hwnbrqo#4+3@ z-7VfV-@RZD6?-Y!Q;lPhS)X*GGHcH9U(WG8=lHI3Ty>7`ILCiF$D7XahI72`9RJ}Q zuQ|u7&hd(KTyc(ncaCp6$IH&~E$8^AbG&55#rDv@UPz6X3I0O>0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ x009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|_zwsa{|1IXgo*$F literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/duty/test.sym b/cinema/gb/samesuite/apu/channel_1/duty/test.sym new file mode 100644 index 000000000..8086ebfcc --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/duty/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:0649 TestGroup +00:0a39 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/duty/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/duty/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..915645259a3702fe19537ebe855acae38e762926 GIT binary patch literal 1914 zcmZvdd0f*+7Qlm6V^N3&T=62vVWB|8B68-3AS6asuDYurkO&nh$3_W-l!iU5~*z@J6wTAW)EJ8olG4Yrg6Gs|QI+ z-yPnOWmn6RZCrEowF=Q8lx_Z)=ySZDAq;=R1?k>>_@?Cj=;JS$%gok~53-#4W0a`} z`!#EZ`pXKpWV|=Zb=QK-5Ervb%jY6RVkh#4HSY^+|q553xC?I5S=ghT3-X7wXK#EN) zS!t;(H|R?q&SiB9#}(4;EjfoP@GaNdIty0AQyg1f_{esUgh-Vo$4~Rk)7^++!nX3+ zdiSd@RB>CY%@WkaHadhgX#^J%ylCzDj8h%ILJ+bGqhv8wKnRB0)YQhOKs`NsNuGJT zIHp06iO9Abi`QV{z2UQZ0}vv1c06+mjLj#rptNv;FvIZxZ$@C0`Qt5$A1hR4;%U0WeO35~k{`a@!geO(X zSLGQSsZZ1$cj;GVG~ma>m(tUp(Ig-7OP_zZjz^=^Zm4(9+KLlylVP`P7`3r|;PlMP zd0+ZY`(ZnYC(_Ll4R~tsShPZywOvl)>?qrE#gnDD1)VsQnSgJ~*>GAUnZfC~7C~Yd z;ENv9&ACxp5(C`o#_~N7x{1(fIa>$|4k0ZtYen4kW9eq3Is=}xQLmof>l8v6nHluA zbTS(2{Wv;lm&9Ad_M<`zFMLP{Gun$w{b3WGYO@oJH*eVyO_4T*eK)a5=SlP2q3>5- zFCG%H1xYQOq&jCbasHA-V2-wv9;Zm7XdRE)w$GnU;S0DQqF{YUS%Ydpp05ok9+@(x zA`ZUs6Y%dXGr`IQd8r4ar7F)LEsLUHFNj~`&w0HhPoJMCa}5*!DRVB?`B}La)qs|8pQ*zU$;*tR#5N zW)ozh29u^r1Rg@?jxG~wRf#4GGHefyYauF}CL&@l5}*hFPvLnc0X z+N7%*pVcv0_iBfAm@m_kn_{7IMa_E%2m-th|LuzdfhiY8ErlO6IBvV;EU*C#0zW^W8MH12OrOnXV(`FsW9tas7DFn5UspQe(SwxoqrB+$Jlh0=iFZIdZQq`W*N^_sJZJY&<+nB`8)A@ zI|Vqd%{VYNF>z{H%ZZH_l^U@+j(-~+v`KR1q}y?xO>*UcXWd-s>}Q_!Rb6C_vPx=A zC2#wF$k(pB^ymd~wDVS?B1yoBu4B2(dk{7nJq)f8hGW0bRncgp8ssrys^ahI_gT?yBUL|WUWec&&*5Lyqgj*Wf?%otzkY=fuYkYkw2V`{x11dYui|XS2n8Dm>d&dR<)>?+1By&K8r4dG}3( z#iIGdu|Ru$L#?{(AKlZ!w!$`dYB9m`?OW;_w1X$rB`x}iI&T~4t~Gu9F9@961? zdc!anbJry)6pBVw_3pV6m!z&Pw^x*ul1g=_y1NY{6cT+Vmo;=r41ZluXT`a{h1(m3 zxL+s~QkWw4@bB-IZsD!3Jdcr)q>SjJ(R4JLN~Mf+N))2^?zMXKug`kJzrJ73?(}!d z?(Emy{oF-ecaPrluQ|_V88b7zcZQi^EUoBiU01wen*O>hhr^1}(Q)^@B`(Xoy>1_m zXX2TR@zCDArWp>4UhB`9hAf7^EvP`l_tTBteg1B{`*g$I&s{VO_vk(Un)6(avGU*>k3aSR zW38Qyo$ESTXXII>DzZn*AD<4lPp?;R*$divzQgGW3@6x7B->W2-gf!|iDSVSi#i_$ zy*HuL9|VWF%q3o<<$1Lx@$v$%8Rm8Sn0@5X_{&ERFCE@&J!w5>nbvF8koB(hzIELC z$U14AvMySetQqUFHEYdT^VWj(`S^t$O)L?R^kU7f=H_o>P4HF9Tn&l9;ly7PAR0r7f4yj~P9L%asW%fE6syDz{- zV((Qa*qgfhX?6d75o^etn&CCIBX5EGHsZWzEb?t zD!H{-mk|@ehJj*hsZlMAH?fv*^I4;GRDElp#MC1;4`?s(s@bZ-pt@}Pzh=Zo^Ir}B zsgqA>i*8~M~scgBhI6;%*4T!-@=oTecBD)pp7JA<^AF(R(Mdlf^BvSSE{`WO0KmmdIj}EUuHqA7rsW z7V~5=M;5bW@jF>uBa5qKafK`{lf?{KTq28$WbqqW6v^TOS)3<}U&&&cET+hUlf^G& z@iSRWlEnmB{6rQ%lEpc)_<=0GCyVdMVw^0#C5vy!;%l-vOBP>|#TZ$fAq$5rM#-W; z7GL^>UEi?s2h!@FEBFcl2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## TAOHafKmY;|fB*#k69M}#u*S|) literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/duty_delay/test.sym b/cinema/gb/samesuite/apu/channel_1/duty_delay/test.sym new file mode 100644 index 000000000..b29c8ca51 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/duty_delay/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:0639 TestGroup +00:0ec9 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/duty_delay/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/duty_delay/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce7f700901f697375b801583461220282ab8225 GIT binary patch literal 1914 zcma)-c{tnI8ppL|(pp}5< zC^1r1t*t~TDh(wrgQk{+E3b74v)rWlNkiQlxB1PP7(0fbEzI6$~;J zpS^@=C{!WuIw+k!e#)phj(Dp?YSr4{&uH6gauwB2;}tXla|UYySo8+{nHGx)=OhwU`Gr0^UXZ)m zfC6z8w{cuxSHU0J*rLWGwcB5nTLzQE;NOFmpCGW*5u~^#g~q?h&o4@t%Mmn9g8H;G z_!LoqdgmnQzul!m40_W&67kL_e*{I3RF2L?gT-=7xSugF?wVsC;T$+)of%VTJe@v( zSMixz85z@CxGSKvX<{&%_thh~8}!h!v{!Z51Hb_q2^LdKnMi03u&c|eAs>pg;G_?% z-xYj{is;9c&In?Tk}F868@ zPN9s?mL{|0P2;+VzsY~2Y27`Nq)u;{OJfg8yAEJk{bqfn}z%+#At!WV04Jb9vSPJD`WQFwLoL5<~p z8=fkgKOS6dzY&z_X+6=4XGHP8plK?^1_}?ll)$fP zfy}XH(Q|*So14}*RJSzsz(Uh@(a_F~q2EjmObTBPb5B@wg)`}*WfNBT4{YF9@Sv8M z61n->AFlwfC;OX3)MKgU)mAP8RJ(Yy5~gs4llLv9qBsv^kG65FFkh@dr^G)1#*k1l zSs*IY-0G-{>5Y#}tEUC`UQNq*+!&ZP@9G-}x&~;iaI|&7m!NQNUhj#lm*!Cji?|Ow z**f7;j62Q^oIMR9kM)ok#cEs+qnme-#X-2e((>g@gs7?8iIFAsU=R;!R{r1iF^f)K z)8z@nD`z$z4!uowhqaWk_Z#MugtN^(FQr$E=AeOf18{YndjE||6uIk|1x(qn%E^##rI zW)r=uB(O^F&Q4jdla}~BTCi&vn=Ks%w3yIJYWJ(`BL(?MNSE}DV>dHXg|jh*ubPab z>h9(6hShc-E1R7S6?BTjzLVa(#A}p3dj5D011W~Ui?Rz-%O$nCQ5n38fW`t@FsXH* z1vEo!+1yo2TOXJ

fx}{m|&_1UF)g)a^&gh}$k#$dINcRP8WN+h1}+&i4)E!MqY< z2ow^UZ>6x9+p)?)LeU2TJ>%GrBf+GAh%r0rcw}MiM6mHHQG}!%=*%02Gb@WR?=RDZ z5BFTq1(NEnlx>d0j}oYuN{@oHCWZ=1_f=|Bn7h^7u)Y1wt?&D53}^cY2uU!gTE>C| zgU{~PUI_`kW2Jgs3Q`XtFfM&qMw-f@vYe&K>uAN6RFLEVdIjO@Zt! z3S}&4xept>jYu|rhfq?K_?h);4%)jiJ87CZ$u@rKr#V>zSdSSM)IUe(oP;@v@LNB> zest-Fec#)k;TCr>Z3U8hpCvc$yUzk)w)GmS=tQELRi8Lr7^UzJ!BA3GF{be}96B9& zZjU8@Vxo0O1)&yik>G`6$Z}NSz2Pi691b@(WAq=d-f3N5J_>i#IaB*i6kt)60DFeF zTbL?K>AJk6qb`L4&hj4hDK*lob5P$!#~y8(bb{GE+F|YEzst* literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/config.ini b/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/test.gb b/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..ae71d4fa5e08c633adf875fc2edab0812a6d9602 GIT binary patch literal 32768 zcmeIzZ)h8390%|x%_Yrdl3v=bUL|YpVjE+SwMEdp2-i?bS7bu)mEem7oN?$V1!24D z^&08i=?lRZGFAm;FMK5uWQa(oY?cW}8p~evg|NcY;exAwNLIFCmBi=nX}Tbh^ZmZR zm@%KVuEkqvizCo5qkc3De5_|VO627rETix9JX?bPk z)t6_(zpZWFSpIb7o2S)(i4}R@Lr6h>=58%pEhdAtsm2HLF1uf(*}BCB?-lKvFo}po z<)SCm+ZU2|d24se6Xgke=$=A~snOm(b?LHvUlqTV?^t?zYQOX}A!Fj)SS}|zrR#*) z^MVivh@vb%=u1&Sn3}Tll9ZH^$(iKLjIIX)ET73|bxmN!=e2Z}_4yWdUf0=rfj~ea z65E5XZzt`9GrxBpJtGJimKVjeC?=ChJ)L9;mUq@_wfy<4Q~dckEqjdbmOVD7+56d( znr64o`P=&0EFngwuwO=okhG+wHBEBLF!;RR9}G&;*w};qP}J`)6zqI7nu%sI`ctP) z8AdS3^6FgP(EY6VJo8|EzJ;APjOl5%Tre7lvOQY+^HVtUd*?A!zh7l}Ny@NqX4uHs z6D;qn)oS_kd8hb(nto!I?{;EV)9wB2NnN*F=lpH`e4dcz;)gFh_aq^)$^OZMlVmdd zn$#6OsTMEY45n@#lK--H)Sv0mO3qVK$Z|Lv56OR5WwgH_ z&GjYcfx`wJQqRzl%58S2k*(`jEq15`eTx~QY#|w?TeBPoS^=;Z!>nbnGyH>qkbE>{yydNP~R1bY#Bub)51@`KrG@(w= zh;7Fd`zue(sf6|$mBR=AE0J(bjJPI-T@#PHCgQFM#Wf*!OsK9N?TOAF?TOAF?TOAF z?TOAF?TOAF?TOAF?TP>E(dlobeI0J%mf|jMDQ@GI;y!LEZseBYPHrh~)k;~teHQ=U zjurwCfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< N0uX=z1RgR0>mS?oAi4km literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/test.sym b/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/test.sym new file mode 100644 index 000000000..947b9e80d --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05c3 RunTest +00:091d StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/extra_length_clocking-cgb0B/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..da02bff6c64f343c47ed1b78aea6f4024b2b9d07 GIT binary patch literal 751 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V1GPZ!6KiaBp@Mi(_1NH{!v zP}2HNaNA5fgUOwqJlCUa=Da_7N#3!4YYKU{D+dnUUZs!->RqQ3-abr`_zB4ITB|rQ#AIy{Ac&(ZRgv< zf9jnzj<$@C_j`W3fBokDwf|mUKX~r@^LB~Hf6N6}^Skc*d*bnzoTG}*bibB8_n)J` zeo=qKo)cR8@@GGP`)B9p|3AgweB;k4m*sJfW4D%Pc%7izvHRV7v-KzT%GVtI`K8$I zdi|XCHT{A1An$&v`=Ac=;;(~Ucg3IIXZ3bp&%d{B-{+>!vDfxEp7?3IojZA(z^x?_ z8~0j&z56*+AvW9M{ojNidtN8(uzmetdTQ9WA6c&-JgWa``+R?$?3?et_ph^u-Je-L zxx|sJ&Dda0<3k>v^aKm$!;%u`4itFVdQ&MBb@02A<8 AFaQ7m literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change/config.ini b/cinema/gb/samesuite/apu/channel_1/freq_change/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/freq_change/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change/test.gb b/cinema/gb/samesuite/apu/channel_1/freq_change/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..7cc20d0df08a2332f403d2e8f7def27176d0cf37 GIT binary patch literal 32768 zcmeI!Z)h8390%|x&Gi~*nk8*luM*o!*+Q(cb@;*v;TB5SitI(%E5R2lIP1_+0z!M! z+cna;(-(p-WY`JHUieC+$PkfD*>XJ;z>D5LS3PTygae{lhlQYU1y?Yq}ts=kTrH zXS-{j=l8vPE}#5T%Gm#UOtGtF<@?{p$LHJG!{Jxi42!aM7D@EI^)`#$n4ef)T>NqN z;>DLbrV{UQhG$*^Pz!`&UU@xpT)F%pnO0q-A%FLz`l-7W9E{6&xn7eua~Us@b<8>j19&MgQKHy zZ&(&%qOK^BNIb6V59V4@QHF;_UehvKCNq*58L_NLgz~wuyk#mh{JNRV)7;-eQ9d5e#^aex#>!?WL3!_9^|OC{-W&e)1v7ux-z|T* zV2b@j(KN-`d;W%bKF^q)8{Zywj+;^*8#~+@;?yZ5TiCL+)s3F2!bJ`Tll&)13&V&W95$?tUKjUPP{b z7M|lOS9qII-hA!4-3>3EHf*Xgk6I7NqlB zP4R6N|GrD~o69@te6nHXq_?u;*22=)X_k5Dj&YElXDz+I{4^C(r9`AH+aixOLA>a;!Iyp8ryS!x;@{T z*605)_3znADXHI=)GJNvtZ6^6Len=-Woca= z2#^R836u#I3Ye0_B%Q$ulGdO=^WLC9^X8yH^X{O4q&+14A!`t6hloIPM=ud15-1Za z6fhMuCdg+8X{zeN}&B)vijNwZKw(k+ybwTrA@qzxnQm;fykq-Xq$($1leOx8LSk@XHmWX(enS@%%HZ=X^}XTx7h-rqSmK>z{}fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb p2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZaf&VB_`U|DtR5Snp literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change/test.sym b/cinema/gb/samesuite/apu/channel_1/freq_change/test.sym new file mode 100644 index 000000000..642158c69 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/freq_change/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:0639 TestGroup +00:0ed6 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/freq_change/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..03e8af34a9d58c4842ad41348cc37651220008fe GIT binary patch literal 1916 zcma)7`#%$UA6K24JlPa>M6C3bOHZMT%b4l7r^_k#>qrjA++vf5wLLGRgh=GjFjA4r zMvP@_tD*_Wo-x~Y@*O{m3)uvSBmKI4pnkIGuvw*o8=A4qc~%49Gi zdr@}eP~Czv;yj1NS?N<27ff_q*c0;7#?+5P^6NE4fEB{wDtOaJGPK)2X+3dMsk}49 zCL&YvS_VpGyUx*g28t<#Gr$7)BA1?d^V}yiwXBsK$)(t*qlBCC8LTBt&qguu!k7sD zaQzRxw$Mx0XXLkmVTL-53s2-UE;B~PpT|AU6qDNYqZ}dn(x`}&Mxfm=*y$I+Q-MJSo_va@NT;txJ!t&KuK59+fPM|GB!4u!9uiE*Ycd@X`@?3>z5UM z%a170t1n$b(%}IPZKm{i_&PYh8xkV1Ubk{(--XP9mS*!P2J1HtMncPiE4~AetU}S? zVmR_gb&GXl`3MsOZSba`>+S=`=?Lj@35u}8T-X+t!*&kgMfYeS?2Y1;HTYjyPuB3g zLHZv-YdUGjxdq2hvGVBcVUj@lx9C(Vs z#o1393uD;_Rh_8DxZ!66Mgn}o9%9HIX68j=;AN1~2v5OP_?Z1$bP_?^yS>OP-373g zwB65%3cSUW4(E_ohum2sD!d9<_Oma%X_?J1&W!vuhVF*#d12kDPK(<=E7tr=#SaZv z0)eJo&tC?JgC0g3q2RU>q~Os8ozevyD#xVNo@ff=6ye-Vwtib3;7St}ipJ0_*6rwy zGfGo83Eu9cm4BzyO@f?s7GN7Xa0ymFZ#>VkNQhhUya1?`ImAWyXHeuw)+uW45Cp~v zm^105S&bdL_>%~#b#pijO(PneDVgpWR?tFuibiP0qRa^RoRS zcGhUPo-}tm8~fnNehvef3pVpC-PZ(j>U>jch?AX2N8fAZ zyQbtl@U2gF;Qb(sFvlg{&4a#4bdrDU#=n~qq({AI#yueK@3=(bjmvr>ZS(fKJQ6_}vo{Zh-e(&u0zg41|J+F*hlB*oC5sIoC zoLRSgx-j)LruB+C6>zg0=%$kIHOBr`C3=f7V$J7gLfmgV{fTDt;+i6aOEm_myPI!8 zEGF_31@+0c)gK(cp6O*TUz`{VL;lYK+KmlTGjdM|%@`@;^ET$+z@d2?#PZn&O~AE$ zzK0Wq`%t;XWC_|5q93SRi%GcNmFvf4&Iop(Finf|MH(dNpDQ&cqx!_)e4l^zL#9FV zeOKGg{`4c;a^SVaxJBhrA>2+Y+n{CV5LmZws__74V*Ve0Q0BtupwNt=<&B0bd(Iw? z$e>E232VRjOSQEfdg1*LE|bh{ybY%AKi$O`s5^C4w-S_7Mk{v2UYrRm-0a*x2gKF zU{neovHFyR=NNRny$$f0g!h9CyP+O|02OAwR{i9e%G#}^Rc=RNMsb2Y#`J}N1BaF9 nBeUv7v%PzFhaLF;lX9EV&bg|^_R`I*tLo``(S`I|c;Wb#n}(%zIVfJ3d+4S_%9*~7xH5A_yruA8iR-488@yXuj*u)rmMs)`r!yih14 z5P|LCKHpB-31@!mJetgLGRyOPj_1?qw3bV=1j{?m+HT$Td8gd85 zPpYcjI_KZf&*urz<%?;%@I&2ku6^YD7^Su%Ajy39&PWfYmw?6kfH=*;N`71O? zIohg}X+YsGE(Fk$jw5YdzH6ouP4^c1kf$O(v6DBZ5x5CCM4F2mOaOn+w;u z)#k#Cv)~b(_9zo{pLK;DYTwG@Ig=eKMIUBkdlfszMk&w6Vzf)C(+>KOBGQDEZB}}> zs&D(otk9I1vHH1)c-yqT@mq5NrLfvyPe{?Gl?hnS``BBuw{^ddn~jA=L5v3d(Lh(I zCz9H;zgK7t4vZ9@DIQU+4+4|ydX-(Tu}fpu6uaD&mHfDmoQ-`PkjP2Z{D``cN%hy-Wj5fCPt}r*PO-Yw zMS8;Bi(2EP`2JKQFP<=|PkEiT)LW|4;-<;|&9pb0%{u#IS2IS=viIzxsS1rLf6)%* z4vi~@)Y%M@==g-SF+H|ET+Ldyr`JEVUJ2bVy6!!?<~>^X9{tmM^t$)xHSf`@yQ7Ma zKE;#!k^QoJ!Tq8?dyg)8kN)I6`lI*g58k7T-lN~|j+z~D`@@Wa00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf{8t6ce*jXu B3(x=n literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/test.sym b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/test.sym new file mode 100644 index 000000000..41a009237 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05bb RunTest +00:0875 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-A/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..c15aafeff92f7252a14b878bfa337c077db30402 GIT binary patch literal 679 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Qf@r;B4q#hkY{0)v_jBp4np zdCa*}ImX!T$jKurt{DrNU)TA6RbTp|Pmo7*Y2`fU)OpXRTx$IMFT?JNzuks?KFcz- z-p^f@X~C&D#q&q5Mdiak>FfJ7mr5k>d}JK=zb2^X>FGba=3lvg!1MLz)~DIoao;EZ zijMeyq-w|OKSw=Z@1OPh_4sp`YjD?04{|+}>^f_V3S_-2c@r0@G4Er=~`J+PL`H--|UX=I;TzXx4Uq z^{*e!#~(jGr~dt~soVMeD}FzJ(Cgo|clNsbKZLbw_}a4HFSrZ-7;wcFh%!ef<&K)RVYcn>O)A*2wCw){1Ye?KN|7M{2Im*f594G;L My85}Sb4q9e0C^HMW&i*H literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/config.ini b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/test.gb b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgb0BC/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..7cc87d6d3f9bcf1fbb016839312c6592f927df5e GIT binary patch literal 32768 zcmeIyacCP=90%~1=8~Q>NiR)TuM(R}*+LAmruc{XezPnZ|&V|W?{+G!#36U`2qlq`)B9TjTBekWaUuR}# zUwCdLvO2ePY39S(FCSO_C026#K0=E8>W#WuE2TsAfyO)1CcB@a>RN>j-YnTS5fT+j z$M>Kw-n(kX}zN72JV)gBP1(~X7hQ$DP1ST zp65887X(SV*B9d)H!xu5MKLX=)5GcEVO{5WmX`~vu5ql~c`c{1zPp8;*LC(hp65j( zvOV1A+etg&%x|4XmpM*mc|phtLOPw+b7_`fdFNT%t-D@z%3VLIsfXO%)I+11y`Md) zX?E+Je@9gG|?%;aOZ=;P)HQB*?ax&craKj+WB}~j?1$C*s)`V z5el)qGFmY7AS-vCd9c2_g`GEy!9n)8P@IpmJ+}9EPvOjOoySmuL51Z-QD(pLK0~%A zSl)TocI&P$IOXoA=|@J~-HwcCy1k!0sq1#@oPS5ZP#~l^_3qP8K1xWUzoUOoKk1LW zD7Hk7Dy1`*Lz&BarN1j1%5QYY%KOSmG80jI!qOdU#Fsqnj}pQ9-0$4*7e4csX^?WX zRVmSc!qMgiZ7tKbF;Y2seDRIjTy8f8RfJ@BC$0h8ni2!bVlq!|KZK%{B>@n zIX~?zc*LOH$~fI`U1f*bzr1k1!VZ<953{j-iXCI4RA6IK+NsoOJAFuzXgry1mV36U zcl)MNrm0HC>f^%F?TYn{-~dF@)iEDA7yUSpB&Rg{+iL%O8|~3* zZLFQxF*4zd?76bI{B???AGo0mvh%E^`l?T`iRAI+p6#iYR9~%4W&{4%WG&I?kgAKF zq&w8Lpf^rQ?@u;V>12ial-FrXy`?%OZC2R7nYOlOvu^*fD@x9>_w1#qGL0&K(RSqy zjVWfbqZuTTv2kl-YIJ?5nze3Et$%90!rw2t?mfEZJzDo3{nLB&y7%Zc@6pxWQN>4} z63G3?e%Za?e$k)3M;Eb*0|Qf{r;B4q#hka-1N)j4Bp4Di zzO~#7Tz}GTh5(aSwzstG^Xj7d7wg{U@bGFbt(@naIPdwCO9v`<@6y{kS^mxW$(gf0 zWiQXXHD}5y`|XyRvVZ^Hzcv5;nmwmCUVp1T>3`n;&%ciSGm0qPyZzU%l>DzR-plX! z|NesS>!Mc&UY+>=*YMchlQ$)PG;Dj6xjU`@)pLo*Kl7v5Rs1jN&tEj(&r99X_4w|& ztKNO9scI3JmfG2x8hLGN;ODZ^*evyYpyjWg&YoNpVas5qzI64w^WjfR-jr6eFZ}W9 z+Rpvq-=^p9_{(u<-|RQvs|{jmyZ#-iT5;0<(5o|FnZI7n%r4sf_hc6+X{B*y$_THCRyA8kG<}E69 yVrw%tnA7->hbKM3g88td#JK|nqe9q2;xF?hMWsC=cT~ASY0lHt&t;ucLK6Vw$unF4 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/config.ini b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/test.gb b/cinema/gb/samesuite/apu/channel_1/freq_change_timing-cgbDE/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..c456cc12c06b98a1341329b1e44423c3d4f26eab GIT binary patch literal 32768 zcmeIyacCP=90%~1=8~Q@NiR)TuM(TPvV|CAP4N%&$8ig#v_&Qa{}TLT0cRXKNORVJfeS{R-&fci!YNb@DKG=9i+GO|BG`Ch^gEvd|O@u^+ zl6=aS?udn@O}DkX)dST7_Rvk4l+t}2F?HsQbW0V^O6wIpJ9xMBEFl?TER)X*PU$)! z_B_Y&ydX%@y}lUdxWPd?FN!HKl^RKnjOaSgv%FHs=^Dq%o!7EC)_1qC^SaKS$Md{M zM7D?fd^>3;ocXQu=nBUvEH4OIK}e-idN#!pEblyPyLH#+oO0KXX}N>$Zn=YFn!TSr zscClWoPS3@mm|bbig(LU2+4|CR?|eM48xrd216lH%w+EMd*Z=hv1sSxaV4%O`eR3r z8b&C@^6FT@(1WbpdFH|T?iP05FouTM<3e#h&i2^e-#vvhzjYo%4F*+~7e$5rDtisZ zo?vzTbS-e91J-x6N7eBl8pUwE2a3#yoHSZeB50 z%|Fb#xn{1L8|F7lmxsHE?Bldr>!I%MG>sXwQ;u?4B9Yh{5e?cc%g%^B=s&dCT)57y zHWy}`1&Wtyy{t$r>n-L6<)`>nZvnqO_OCnRapN(Zdxee5mS+q&P!&Bj6_FGYg>NT7@F z2`BgL?-g5v10(ro3P&{SgTN%aUS-#7?9$ma#V&VcIXCVj=b|46WO7oozpeJqx6xj$ z*3R0=9V3&@NZaM5m9LT{^}r2vh@EFG*rd? zk)BZZqTVMhl2X|uxq&9pb0&AR=URWnM?vG?qw$ufb*0|Qf@r;B4q#hkY{0)v_jBp4np zdCa*}ImX!T$jKurt{DrNU)TA6RbTp|Pmo7*Y2`fU)OpXRTx$IMFT?JNzuks?KFcz- z-p^f@X~C&D#q&q5Mdiak>FfJ7mr5k>d}JK=zb2^X>FGba=3lvg!1MLz)~DIoao;EZ zijMeyq-w|OKSw=Z@1OPh_4sp`YjD?04{|+}>^f_V3S_-2c@r0@G4Er=~`J+PL`H--|UX=I;TzXx4Uq z^{*e!#~(jGr~dt~soVMeD}FzJ(Cgo|clNsbKZLbw_}a4HFSrZ-7;wcFh%!ef<&K)RVYcn>O)A*2wCw){1Ye?KN|7M{2Im*f594G;L My85}Sb4q9e0C^HMW&i*H literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/config.ini b/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/test.gb b/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..19fbbd6253dd0cda31820d985a7a053404129567 GIT binary patch literal 32768 zcmeIyZ)h8390%|x$tAtbB)ueEy-I8@VGA+H+Rhi|#c?}IX^ZSd@Ri_;1)Oo{Ch&7w-02IMFJ!C=%3kh(HFuBPlpSx{-IsjhE)=uyK9?LBz3QR z;rB`I;hyLD-t+wKLsLTj*X=C1UgLiFtz2G+kjDbAlNk~w5yHn(@4QQ*w-(0g%gaB` z&dt5@(pdD@h2>kbpUi#zjIu|p;*EWTlo!|Uuc`G)F1$9>cwgFN_tR8ex7g%^igObs zF`<&a?90a!5oy!wonh^G?YJ}bAWbUyzIZ~Jxhg$Wgm0vKmR=azX?lT>eqp@7SQOl* z>x4M#9LMv5AW5yUnB=&jAtx`2IWdu(1XZ!Iy zFA|ZR;qC7vorJr-RgW%noXqlqP!NP%E~giAEWz^bUfaF*yy`aZ`EgA>;hmvV^t-@kjp#GkO?V>T0zr9w;6`F9twrSqS)Wx8uuncp>o;DCzEngmi4F4 zoH2}WnB|r6lA(uK^VXRM8+%7MdBYeUX4{36e3G59eZE(PyS`PAp@c#T%ZsASzVcy1 zb{1IP-D|t|o-eu0J5SS3jd`b?8q;*=JZDkYo!+f~*SJ(7q&fY;^Upm+NNTWa@ZcaB zjJ_)Rqo>pQR^A@qBGMn0{awJG3o6Cc2HPP^n|3~EzwBdg$==rcJ#ID@8$~G^3Pgk5 zd~YOs=x9dl2n~)FUnrf{?2m(!?0SP;Z?a2g*A%&H1%DpBu4^ zR_|o}xv4iUNgqu$ROzBceac(Zzviz^OPiM8=MO|W!<~Mg&mW0~BQY{hIrgS~G@G7i zDi>%%nWr&k6<18!ML9*X59l=R{C6_!3;aK2`JF7kZ#J`&&Fq^!wv#=!Z?;wM{x!7f z9ocu^R=tn1@1xY~`PxLaqw2pEZl7+|>>0OD?^SM}-s{{xy;r(@x>dJl-9Fvg+tY5P zt$4z6{$9}_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< U0uX=z1Rwwb2tWV=|EYlWH)k!;&;S4c literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/test.sym b/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/test.sym new file mode 100644 index 000000000..ba31606e6 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05bb RunTest +00:088f StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..8ba9bc9df354f87486a5abb7edccccfb8089c0a6 GIT binary patch literal 762 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V1RPZ!6KiaBqu2NpFeFfatZ z_|kGOaJ{GfoFJ`P87*z^-u&L=!Bdj$?(CI0?|HzC=ax&a6zs9vJ#UqJkXL2OtYv?0 zX3i>e_fmh}zir;T&!6Q^{oP`FPI>m@swIC~uN`+!*FP(tYrFS(z1@$9{Q94<=`peX zJsU53N!?y~(IvGID&*ZoJ>gS-wOtE+#o@KxLU-#=fmFm+6Km0Gg+dsde{GDU-_T`p& z51+k1W+DIn%*TuRCEwp%<+b76wtH*c>r9LPFWxMDoj-rk`-t~5{>bdBd{(vK^5!q6 zugko;X?LeOtpDfXuhUL_v_Aeb>*w*sj{|J3OxYdP|9avlZNIqv->WwL{@kAyw`O)A*2wCq2PpR0w-W>|^lQm>0*~aU%hgrafK#T-G@yGywpa_-_jU literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/config.ini b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/config.ini new file mode 100644 index 000000000..5c2a99de9 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/config.ini @@ -0,0 +1,3 @@ +[testinfo] +fail=1 +skip=180 diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/test.gb b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..a628e4dfcc7e4f3bad146e84015622c6074afd12 GIT binary patch literal 32768 zcmeI0PiP!f9LL}8%x)%ev)SFG>7;Cv+0ZWAAZ@A#7hI-82x*WW7V%I}=z=i@4IyA@ zr#hLgq;~Wmc#vWglpZ{ZL@6TDDy>CfNXODc4nhMj#RePykTkT#D7*gVO}3lnualRX zzt_%m-k!->*&G9Q)+rH&3c7j1|3pfRO&($M4N)GsR3~uDkS}vIy6wsWxxJ;QgX| z5hd|hF?BxBk!Y+}7QM6Eoj5dc$Q`<$BE^maiAHtwlJY=}eXHEHjcoVBW@HKJj170@ z^D)*8gAjLK6eTGZQ$jCX+F;8CU`98LM*k?$=oJ?jP2*Bi?S> zkzw84&z;nD_spJuSzpr#F?0P7o0%gdE9+TZmsvASZ$2E3L}ahQs~+?)qdh zm(1mi#|H;ZGZKOI>Ttm{!qB{V@Bw{q3wOO~_VfTQl9ZCLM`eHSDcJnd^O$NltipO( z&cWZ@9y8}ozA1B+`P*Jlf1!t+d|*69#-dt#z4DJU6iA&H;w0vLC9n(W z>X*Ve4O5ZUs6`r5MOt2Ys~u8`rNu;eQjN` zu2{cXcdS|KH*3zCx9(aC)(?}n4>yxkK-6byj2$O zyb=uy(NMG0TA$vrzg?~gclG9v76x?Ze;<@jfz6!}1R zKdtVcALH%%Oaq)xEgLz-M(S=)PJfpsnc9154?NF&`ryPFQ%DIblL6y=;v1L~VJI2W8att{Fk5C{eZK_ny)6vR+C;GSxv zTIdO)7z%l12xehfwF$zCE(GIpRH7m{IzZE@6J@nb8`aA+uGZ3oYSAVts&!7SK@%>} zJY2z=Uo5+H8g~6Rh7;1b5kzyM+d=`*&g}vLOW8&i;P!1V4v0@|I}xBy`-av%%vJ4{ zbG4GOgd{F=V~nqfc)ob9T2em=W2Zx;QZ%mLmUwO=V~(|KzVYt^`C>)2lE(QxmrTN%kbo? zN&yg0t{wpaizinrS%Blo)fzY;^5kl5B0&A;s`~v(+VaoAm5eRqY83)r#(%EXq5#N$ zuGRqo%YUxcX93QCt~SI0(SNQsBLdWauBx@h`+f!C^81~8HA3e{9Op+2^CJfN5d-{) zK7K@jAMpY|;wV4jIetW*A8~{q(aVqM=12Jcee97ByG|3l^@1Vz>IFma)eDB;s}~Hx zS1%ZXuU;?&U%g-mzIwqBeD#7M`052i@YM^3;Hwu5!B;OBg0EgM1Yf;ihz;t6ooKWx z|KErIq5(932G9T+Km%w14WI!ufCkV28bAYR01co4G=K)s02)98XaEhM0W^RH&;S}h z184vZpaC?12G9T+Km%w14WI!ufCkV28bAYR01co4G=K)s02)98XaEhM0W^RH&;S}h z184vZpaC?12G9T+Km%w14WI!ufCkV28bAYR01co4G=K)s02)98XaEhM0W^RH&;S}h T184vZpaC?12GGC;2JC+U&cGgi literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/test.sym b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/test.sym new file mode 100644 index 000000000..db14b866d --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05f3 RunTest +00:1a0f StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..76f5c4ff013cfcaba2fe1c9f8caba89031ff3504 GIT binary patch literal 1402 zcmdT^{ZrBh9OlN-%>*}FD@|mTS!x$whh?e3G~YVw#?#KVv^UpXcs*?w~zl|vU>I>t9N!O$>*bYyEx953!)l!wHeAV%rytFsld5oS*uHs%&YI32= z52d~}kA%D9`jOA<-r9FFv|=6g+XY6J7BSo5N>%xjFrJ)Qp)k{Iu+=JovcO5#Zt#5C;>O4;v+2zs9FQqsXR1h- z6uRd*oKR{yFsZ_~+%WJoJfX!=SuuKHibg8AuIcdNghs7hJBE5D2>`O^qOD4ta=#we zX)4B`;QNE*yYl%Y=5*=Su`=AAc`eH(Rx{K1{~1ifdB7bxP^;QsEYoQ@i zH-|Al%gpQ=D~9M+mS=aM3i=HF2YfQ{+b`*Js6|vs4uPa#E4o%~IJU7MYF`7^e(A#9 z)&TGjXv4-umTiI?K<&Tc^1992g5z@wqvkubQmvI+VV!MR0wGu>JUxOY!0CJJ?lMHM}S7 z^(d+nY1rN_8a-m$%Nqg)@h`R7ln&{1Xe%*tWMFdrau67%a(LN+HwI9141{X0BE;QE%TR(}0NX&*z z2WH2OgjA|q4?<5OY`IcyS|pCX{)G^<+_xDz$y{h7?ib; zoRSU)DX7l)`$-QdsG?%U0tYc>u{c_}e7O}~Qlg;xfup(Tpyo?)Bc(oj8(2F|2ld4l z?F-E0lb<3V2_|O_OGS-Mj@$RD*L)sg0hU17{Gu1*o=e2o<{@=$=KlNuaBQDC!ju&g zVJa5d2KxFFo1D|464bZs7;WG`4#}CPKc5jNWi_CObyJKyPIyhLQ5tTXjWWUjtL(Zls$dHtHjbHm;_lJx`D;e z>WOsjgK){G@NWGR)`-K9M`L>;7as#aO3y_gW#A90U@QQvsg|-tFKCmA>GBFGE8OnX z^X}Ix7lYUylhexY_=0L0;8xuj8*AJ!)r3>_K0Vl%vsLv(4p|PmJsXC|(e(3SVZ6+_ zw#eGO>Ljk#pnlGvy`q{~Pt~Qk4tnE5O!G4^15+0hKU=1kQ&m@Y2epCo=9TprhkA7n zr|i&=+_H-965Me=F?n1>V;ba@O%#+lavO$x)0Df14b_NdhRLb1z)6?AHrD1ygh{>$ f>kLcu|C1N+>zY3w9s#ObKL1pL57C?JMZWSMi>SjV literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/restart/config.ini b/cinema/gb/samesuite/apu/channel_1/restart/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/restart/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/restart/test.gb b/cinema/gb/samesuite/apu/channel_1/restart/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..c6924dd22cf464e8385e9c5475cbd14afa5ad932 GIT binary patch literal 32768 zcmeI0PiP!f7{K3VC!4iyHoHk0CuL1$L%Xg)+7u5ixJ;K2+8{jyPlAUAtg&bb0U@30 zbh6so(SzVYim9OV;7KG%5s_ADtqM!BmL75tT6irs*!qXGv8~<4UElj&{!DxL-gp$h zX?NI}@3-?Nzy2}_W$b^w9bo5XjURs>8=Gro4@X~RhgpKPvUs}p?RQx6;@tScrAt3e zpE~u@3**V(<}O{F{`k~aPudR{E34xOV`GnfcWbewW##^D?H%^v)7Bk3^|f`g;ueP1Hn+goKx$%O zWF!Tf>oO+ih7pgaQkJ!TY-S8&Xh`y=nK$$K;r#Hh>&D}PFOHU6#}J#EJB5-sR!d0U zb;b4K@wmxMv4*<7Bqag!mHTmvhEWuJDpg3O^7*`5$O}U7aIMw7`g{pC_4x^>v|FuK z+CAaO_2kfTvI%-3827?#HuZFuhcg-xyJxO>OdYJ0~WSFR_At}FL&|AFJtQN|im??3y@t1Ea{+aKpjzng%Y&u!$YqgfE|Av3lU-G}7zq+f7Wg~{O(6XnyyPtP>yfd3NoZjBvl{2QtyR%t1 zBTq*6)EejiFs?VwABGP+>hT`?0N+x*CT?oW&;3)fXe;s}x_Y z`hKj{&(}w+WGtF&?uz%c<~DBaGh1SV!z0g)?sKXiH6IkO*Tm~}@p8rMka($2&Xgu2 z>`eO8<}CZbk>9QI&kyN7XQ55(4+hR0gfkni&R_l}$MO%|vUiI6xslsG`;-`Dk6i9s z9W~{)FSHfKiD<{6h2DCnH9OzMdJ^3i-1>3r!$b9wb*#c8_8Yuuv1xY7s#Vlu2KM6n zQ+_Y6ZNX!BAD9P^*WRzp?>m0rfFZ}QaGISFp11K_cCukF^A7kIYqx#g$vao?%&We+ zNeeNQsy3$Zd0jLATQgtQ%64X8xCEen&IEt(o7_%>UHPmo)R6*qpIYF$6Iz z2g%_<0D&d}1R4bpXcj=AVE}=q0R$Qc5NIAipn(8^CISQ+2@q%|K%k)jp-CldD*+CV zB}6R}(c~f#O)nDB1S1hmF%r=vBN0tA6468>5luA`(PSeLO*azJgd-76ITF#OBYxt9 zeA39DP3x#8AYgS*9Cbx)M(SF+k`$$jNm06<6s1c_QM#%Wr3*_@y0#Rh%S%zZ!W5;8 zOi{Yd6cr-1KtRYZC*pE)`!}%(I81F4(>=A+(%L823Kk+bxoC*uBo-n$iG^rRVj-fF zScvK*79u-|h3HOVA;Obbi1H+crYFK!PYKEHJ`Q`n0f^_O5HvM~ppP|$pou92%}XI@ zS_(n4QV5!qLeQKPf~KSpG$Vze2`L24MUSK0|=fDAb2`};OPK@rvnI{4j_0sfZ*xWLZ%bs&~zlINe2)-9YFAO0KwA% z1WyMLJRLyrbO6EA0R&G65Ih|~@N@vd(*Xoe2N0D`rM)BgKb!KmQQF7=86X2>fDDiU zGC&5%02v?yWPl8i0Wv@a$N(8217v^fDDiU zGC&5%02v?yWPl8i0Wv@a$N(8217v^fDDiU zGC&5%02v?yWPl8i0Wv@a$N(8217v^0058(0ssI20N3}|000MeNkllI@>vAyg) zy2_RqqqIC85Bcun@u;?>Ao0=owedrYF@$i8WZO1|eISG&9}l~1kuM(K&Fr!zJz*q% z8DT$ubi8c-zuPA=FAnR-Pq1d}`!3htzVEm5O&~APAAMe;?U(3(woil*vWalmM)Xzm z@~h}g6SUP2ZS#ZTpKaUT?{`S>e!q{tv)aqvqpNJ$_!%QDXvPo5&*n=@x(wX+z1k8& z$QM}*TOx}J799ax#8r=ID1O($iz8n}e}khW9)&?ZE{xafB?WV2uxx%6>U1!h|7#`M zb@1wl%5*TBFD*uOFdDx)9n1z=pR~;n8vl$APP4UFaK_6OnpS|m zojOX3OqHK9GrQHRil2@yvs=BY`17mia+<3A0IvE{&l>nLz@TFljq+#qgUi!A2W|Vi zz8~Do*ACw^_+Gy2;MEavU0Ze1;>$-R`@1M#T9oKuluy^e*6RU#e%PSvV1dz$l;N;- zIZJ2D6?%+k#5S#i(`Ylh+N&)dIR5fT{S%grSMLXB zIfTOZYcGKL{a`QA{rQ>H!C&UC<2pp+I#^ni?7y=4==_-1!M|2T(D|h6;LEOPmW~AZ zXgt$=AcI3=F?E(LGaC&qQUrtiYJ@k&?>cyKeD!{CcFm&u!RPFEp2uh7miXy9IPLWk zeSQ3{gI7l+>tJ+M%;rmrQC*J4L)XFDFjAks0ee2t_|^SR7Mp)rhPe*5adTfAKe!Hd zq?q3imWxG$#B{VUuY>y>FVRX$^o$N3;W)G);yM^@hgPA^@AIX_b?};iYp3-LmKG&< zrqsnFF{SaHYfDRJmn{=~8B%GtdLh2`cw7fBj`{sySxZZ0(6%4UhKYF0>tIwD3I_Sr z2o1&KI(T(NUqvsyiZ-u<*|h|nA8ql>WN>z=R<9}H%SV61{~o@KAstWO&gMcItNfIf z*{xnGKaDoCtG(Ldhxz5m`zI_LcG>7BSQURp2Op1*e6Rfcce1X)LZKSf|X z^zp{eN;_glL`KS!0#Iso71c9??)dsQ)u{u=V|5 z>+w`ElfhzF)7mqb8qc>GEcy2*gf_@`+=EEg!PVXySJBqvLH+;SelUBy?08WBC%hjl zhrH$e;OPud5|4Ob{r}_mS!u`Ze#Op48)>@JI$us$X}5YIe!j@cj@rTV`D|V64n>gD z84INCD5vCaIx?oi?=P}Q{PIL>-Hb%}=AVnU&JUoj6%6wIx#-mqaUHDcxoGQrX|cK= z?C67C3)Si1XFTq2`k(Ci>&hSr|3e|zqWYT{?+N=0P4chL*Ku)c-a132d|E(Ob1Jg@9(bpelS`a z*zvRDp^x|bOs!s1+f^CN=A-ee8?PKAJ>IyTqR&Y`%5lqH89-^bdZ~Oger@BO-w*EG zlyNA+L`I@^>x#Z*e-!1T@v9r}jVHJ|ee?l?d^CP-CpJ;_YGT_*J-ah>F}vnv^M|RGB{ry4BFyogkSwuwI$+<4sHI~ z@t}Oy!K)>jyucFt{!6<%hzgD9ThT7$$k~>H24AYjulR9|ZmVipT)eG@uNTuECh4}1v*z+@^ zgB^x2^M8|$QX}hawKqCmEB+rO7-elq%gFXwNha*_K-;M$2rY^163X_E^8LB!)e(Ia zz4R(t-F`3%ZSkY=nAgG9Ge(<#l>hDf!T$2u#s1OxbRE1n&eXxEKGvo?_kEWFnEu?t zSz!CG!ru=z<{zC;*TJhJ`YPI#f0Xb0!N&Zf_zxgsD4@?tWitQ(002ovPDHLkV1oXt B8q)v( literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/config.ini b/cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/test.gb b/cinema/gb/samesuite/apu/channel_1/restart_nrx2_glitch/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..ed3cee586bde157ed827a9e6ab52555f31b85b85 GIT binary patch literal 32768 zcmeIzZ)h8390%|x%_Ti&l3tpwUL`hnWeaDJwZ#|a#c?}o>5A+{@RcCAfHNC9NDYp+e@IuhVb&!+ch_#!H>NMe z@6+DXd!FC-p69tw2qoly-AQuvhwr% z!osmvClbFcu3Ve{Y~kBywSS0}gK>zE((?0n>UyoL#OkBX52XgXpQZY`!zS;Ry_*C{ z3T63RDA%2eOO2rShSh`BgWl9#nUr&b-6?JEf^<(4zLRb{W`6WxGxLND36n#Gg5WpP zB*d$89M21aBt067X^tBm_41;qh>9|Kly3bO* z0?YerZTG?RMZX368RpT6V7H?ahUx9+6;0FY{qye_7mI|nWEXq0la zQ!CSm#?jUW?X1wQDdLHvwU$TF(Z`o`1 zuXf#Dw{P1U_K(Xq5A_l`#2K~DBYk~2nzCq*oaBs5CbKmoTC`7={TXjEe5BD@`h#0* zEzS84JY~^-?Ihjr-eQN^zk2nO!w!|DPqMjvnipfURA6&S+N;%RH+@2rXj&d>RR*@& z;P#DEp;;&A4s&toPsjZs>@GyK!djE9kfkj*7ja(;vA1Mz8+;!d&822RN<_nnNH5Ueo}0_7-)D*P*d1+*oo78eTz!re{8k zKh}5EY@U@qnQ7|M8Ha|ncW6hwqdF@!oQ}UYk|Y<|dk)g9Jk`=RY04Mt)@<6NDU|(n zAI#Do%YB9a_Y`R})^@J_;4YH8iS8=9yYMd4ZN}Z!Yb*0|Qf`r;B4q#hkY{1O1LDFfarf z%-c}@#`5Fhi5pro0s>~7`+Z0+apmHzvCdvEZO#W+oHt%-@~YzBCyTx>FD?3>O%!ml z3tCsE8!E5qJL~@L|5wkMFPoCobKSaCpsjzsWAU9D(|Z5)oKJVy1=TsLpM8I~e%pzk z``W{|hfce+d;87L>C&72Z+D#iGx%%&=l|#Czcv4TUw=dC?q~Ozk4xm&drwQc`|fAv z{M|2ZpRB14w@j&f|1aG7{!9A}d#^Vyt!s4p|F7ED{(f&=bGyy*cl+wT|M?^L^f#}} zbKa|upRKO!{<`DmtIOBk&-Jh4tGo5Vt9JeF-@jJ=iCDXD z+mz`OKUAsyJh-Fg`t2Rxg~I#gcl;CoJlpu;`Gfw^_M!5f?@PpE=bvG|{y(X%s?_)P zKg%DPufIpVo@~jx{l2~Qm7@m=*xHN@<}^O!;Ym-hU_LArA-d*;RG;ZX~?S}R^gER@g@Lnw2BZM?aUmU&?e9;4IELuW9 zNH@CKoTPU3h2RS*je^n_z7jd4h)AlW7KJ6*hQ7!Pp@B)Y!NvzJ4Q*+ZJ7;#2Huqrq z2lPA1PIl(^-I>`BYzTRx+Zl3oQMmTk*w|8(90mjf`Q)Ub8H}9u7w$vOF;GXxx(shsVZvK9SH8nr1$C z`m|+5A}p^@a$k{s$BY8@g& zu{Y$V*eShm>1L$w=0W8jXG{N$9&>YnqDtms+1{w~uR9)4F9zd8a=!_BH{#W=gGCyq z0&Ug{G^7i(vPGMVv~7|&=g+RZ_sO~Y=Z@H~*l*gF{h>W)e_?-RU$VcoFWXn_-|gG> zhW&?KvN!EJ_LlwA%B^EvL=6bWdh?0y?mpUK(M~lk7|CREXGXSYx2k$Gd@^`qyR!VZ zuu)l_^&WV}qCNT^w?9jFw0 zcUu4MjZ>s4r_UV}qRIou{W0kN8q#wcWwt_!R@}aj`&xj#C3{={d)zKBmvc%i9E^p! z#GYvC;E`UrIXpC)dpUo~a6b!8vFmMiy~8e(UDNFHpDbo417sooWk@9#4F0w9pP%Es z#(Ep;r}oTDc{8oIR@Qz{}NMv3aTZb*0|QHfr;B4q#hkZuE>2pkAmDoT zN=@RQV^7TQvS;tEV&Ke8I23cfQt7Oyw0_}B!*`obLN_4?;r&@W4x?{dFv(uDa1b%A=T&rkiDEd6zR?(Mwovo&q({`uW@yL~>@ z@&37;v+6GF+!uZBdTUbMZ!3*&alY?OdtWbb{a?){&Uy9;*ROr=^iF@8Dxa{Lr*7uE zcY3=I{w_PPX6s$Y^*d5GAD6y^vC9x?w8g7 zKe_hm^-VhGpMQQhb#X#eIVOlN!jn*X=|_qBKH`h#TtpV7Dabg%24-^}g(RnAr3 z52pQ{r`WHP7t1GgKfYJ;(?Y(m^zQ4sk2>~!`8F~3i~FaapGyl&{%6>2j-8)jclqkU zhoZma_v=Po-zxEu)BU|hUD@v|pH6W8{qXZv*N5_+s_G2cH}2lIj^2CmWASInwfyJJ z=Xc7RNSa%^7lj1c|7vPex3QRi@mI#b^m**+=|*n${C!5hDhvL)7ruYJSmg8kb$r_x zrC;xP@#ENnnm<=17WSW;ZWS>%cazl(rRG;BF8=Jf<_=QS_ssZLo$;?z(@1Jr}=U<*%1}Q!O2?^s%q-RYKv4=A$500qo~jumAsUS7`qI zgw^YIZFeq}{*|=kUi8Ia_VerVU#@*|zcyxvOI+zz=bX-k>tDoQTJ-;k`HTwNdrzfn zmht6XJfQOD-hc7A$)}Eq7Mt3hZ+>WM``ZHfmMT&7D1ZIB*yQJfY45L zI$3G$=s^&XVk#&-coJEph)Aon7KJ5QOAk2+ExZOBZ2d#p*w$|Au5V_t&F`6z-&;?D zziD@vnfJY!$(Qeilrr|e-VU4k~-ud|mgO@Dm)t0&EW7%K+nA;!k1F5OxzEEKb`#o^k!MpYb7@xqO=xOlth z9mH8OQB0o<4Rmz28`WU%ozCo-+2LKfoo2;>Z5^HFku$~}Gx4=?vux*vA8dAxvBAXT z;OJ<=-)x&PZ(P%&(L};9R?hX5rVS5!ysl^UY<46&GGg1&sNnNs1>4fZ7K~fDf;bNz z;qkUD?iY{amMuI}n)>5yhEwC(BX8Q`4`?@A{%tFNzb z`HJrFo^;y3;#~~ysn#$2u3fKRIO0!u%;CM}LB6GOO}x~WD;Lj|#Y<)QqvG0T)5FA7 zo)FiPyxUyl9sCi~;HmUrz0|+FZEGBqOFUB^sBG8Tjl1Q_x8cgu5p(oy?4l z%8McKRf?}RSdZ1(h1#eQkA&l`-O=9m%%-jVdRt^@Wc0bQeOBe8)4U*p|93u%*=JO-dN8?yLQ6(@NlhQ953^b`37%UY?+xd zs^#FvOt2RVRIKHd4W4_)-qsim&VuvCabp~wH*@UWJIT(L;vGD*jc3va>gIjk>3`2U zOqX|+=FQ@~chGnVr}AE(I?dGZN_|QZtf_*3se<=a!F#G;RTaFe3jV1I-cbc_tAe*w z!9P^NB~|d|`XFP?#kmH*ex6_g7AQoKL?Mbq3Q;6eh$5jv6iF4LNURV=a)l@oEJTrH zA&Nu`Q6yW4BH=<5O}FWGS5Ls=U73N`3s^K?z@q&E77ZA%Xu*I*69z2WFksP$0gF}) zSTtk6q8$Sk4H>X#$$-UE7QY%a`;*xFZDQ3NG-xBpc%>x(c%?M}c%?-Ec%@YUc%@|kc%^j!c%_8^c%_v9cw{Mv9#<8;?lM?w z!umh|;S4N)iAB@I zDMJ=Z8M0W)ki}B2Hk@I zDMJ=Z8M0W)ki}AlY>;xfqf`2yp5Whov?l{(fDDiUGC&5%02v?yWPl8i0Wv@a$N(82 z17v^fDDiUGC&5%02v?yWPl8i0Wv@a$N(82 z17v^fDDiUGC&5%02v?yWPl8i0Wv@a$N(82 f17v^0058(0ssI20N3}|000N$Nklqr*FGMPYKaBOALSpezuJav?^;_+3fq_14tsmAmgbw;Uoyv~?dc8D7Up_dy@%`Gj%Y52q zk~TY3%0lBuhpvO!`5+qqXng28m_0+Qtsm%4SVsoq1COVUsU6>A8`8nHwy=GP zy}{nD*0SSA;{(U9-VEFJp6##N^N-bGFn%;XX#AG*;DVVV&x4O~%Xu(e2isbGd7;kp z5w4A|2*L-ApE`JS2w4X!g6K{(el$L4{5%i77;HXh{BX}j!!z^;BwgFQB1z9hqw&j4 z7Q_Cpr5GQ+D^B`X8Q#br<R;L#z$bg-6mdj86ekNStx!DsS^1H_x)g$4?CBz`LN@E z?>v}v{@NTr2p^3Q==;HttxbBnTB{xKcC{9b|J(Sa4jvrs=fS#{*35vO2cux0zmCbr zuYJ4Br)}mr?^6V?+C!$qXnax!j}A#4JT#xw!GA&Td|Fm;F;%N`%KLY^0@(cN<0IR5 z?=yDMwiX`vOShX8Hh=o~RBwijbf9ecH{ZT$_{_ObezmuhIsfj~FT6fWY4(2Ypfj>Kb_s>P6VD~qg z?r;3P=*b*pYRN7CAKdKU>F-O!D_*vl_KYpRNe4&cgZejqyUg=3a+eB!GyRZBIw%Q`KJyZ9de!C&0Tar{^7nKj3W8}y@3x`YIROctt*(l!lK1z^C`D;sBKa8 zQ9|CX*4k)=U9IgsKATVbd2r?7fkZ&~sb^=+w7umGwr^-^T>-b8r?TU-`Sf&ytF^ty zXY*-)E;`W%B$y7?k|4WWc6>IUa5@;}(|ddrD4z?Si`H0G|K=Im>+dtS@+Uo~{ptS) zTO9lNkHURP5$%ls-1%Vu+dp;i=+N6K4z~P^y|?*N&%)00+AsLGoCmk1@l4SnQuLa2 zr^GN2vJO@R(S@i#n?KwC*F6`FqWAG>(ZRFBfxo_FegE|b>`$`TzpF*k&5b%(%$xbK z{|s(|1l-iH<10Gl^U?n%ty8ji>rKRh-Ys#kIz`{vsc(RRxniuYm+1$sUZ1#hR6KT{<8g32agWDTjF5Lt3E~HCFjAOnA&@_RDYCz zG=I7dJ|I*bKK2bm{ZanW{8I;y4k7E{YHjYKfA4uPsw3HmHa;*8R^BD$`ZCB0W5;Ln zf&FEhY%jN!khk}0A%E?Xx2v`6_-sC?e~S)IbcB}wOL)U?f1 z4YoFaGNqs?l~d9(Zhz5ZWLG51#}d8nDKqB?g3c zqub3%YgZoxAEcNHN*{a@2~tFC(l%*PIMQvYkO#4aNwLA!KcuZ~ZCdY~-Ocrqfx%y1 zeDOEQPIi9t*_p{FEZ-!A{IA;qa&A_-@cYov`6yWze3Kj^5fUYGJpJDLBzF1y@WPcV zKaNjMzWVZT?6>n*E{}gU`R&s>XRPdx1B49y@Y9{e;zBtWS?sTVs4cPkF!0rnGyya!R{ZG4uV8nwcl0R~hLo zl@za;CL!*;B+0U(Xj)^erX;Dq-{n;`r{;14xq$)Glx4;j28*U4vF6Vk`63(pTe!Sw zvh`$HR*A~?@Yi=qm+KGGL^O>K(p)ypTYMtZKU*B(@E>p#<-PAM>vA>*-PcT{`m3)q)W7Rn>J6-w*91X^zhuf$Bx`Pvc-PMe%-e05A1RKbNfsCg#C>@ zWzX2Z*w^hF_OJG$ebc^W-?qP-ySB4~WCD`0(7d~|vxg=v+MbC^Mmn8duBaC6%w)WZ zTMX`As$Kj;x>37$$a~;%i+1S;=w|0SJJja+OEVRAs4U&cYMXQyV^ylKTAX(1i!?zu z=o(FBdTSHi%WZ4@rZPdZl^$oC6xHrmoU=ja*|1)^QDrM+Y0c>gIj;oRcgen6|9xDl zUaXe1SU4C9b;w=O?D{R;YIC@6p!DM4Uc>n`G|H~G*!4EMOm-b)m;dBMaeshJ$G-?= z$j65Jwz?nR$GeS%Hr9`>sEm4*)@yU~r?Vv2a!236&T})nZT1;9kvTlyU7u>oZd+(8 zutG3-a3Ni7*JkHBNLQrul36{beR8l`)Q(nYK!1leEjG=LX-gGC*lWq&;KtX+-Rhau zqXyNus}uFrR*v18x0PF5(Y*SKE>5O1`)gEUvbWN#PMj9Q|FP*cnq)t|gl^MzDp}5j z)W1RmMnN$!2M58KrR8~;y_LTa&15^2IQhZE&}A%0l8Kn*8=2ZAlD4!!ayzrI=+1`9bZgM}QI!9tG9U?In4u#n?2Sjcf1EabQh7IIt$3pp-> zg&dc`LXOK|A;)E~kmE8~$Z;7g}*n$7QgP<1$#taTzS+ zxC|C@Tm}m{E`x;}m%&1g%U~hLWw4OrGFZrQ87$I=+1`9bZgP&+*@S^bVU=g%B zii8vt19Nb24dhx-7|Um{ND!aFLXOK|A;)E~kmE8~$Z;7gLRX8afRC~cinn4aRQnI(P$X# zp6qV^A;-?#qALx3R@|OVFOW6YQ6TYh=I%SA^35QtUc4f@D;NX{b|?f_=y0&k;?Og* z%w^LGzdzdOu}+xY8YUKKGCt`>KFU;kVgOLa`PCzjgG;{^p3Z9JQ-=+=%S*!fXvDhW3? z><0a?>P_>NSXWZ;4v;DKmQwRTqiHJc*I0Yh}d;q zg~!B~$ny)GfylNg2vsa9PwTYfENvie!y4{Yzq(AtLj2Og!kPQ9F|@_lkF|46s0aeT z<>MYS>rc~&8yU#7>bK3*jju!o+S!V6f!p_H9PD1BxV=Yvp^ zpg!4K*#60FG3vI3i)0g%2q82N{%l#K<9H)lKUoZnnQe3%ATwybz_o2{_mA95#r2{Y zTBkt-?c>5jVz!as+qIL=ADAK5E$@g~ilToExC`hP_vrs3rpPs%5fncYK4v3a$$+ou z#1+M7qUe5SQ@CFP7AL{2gUhChxXTj?Fj^m^ms>?C!0|!9=Pp!XE5J@?M9)FC?=g+X zmj!^p(1HcMxc?S9%)cGll7C(KU|y0;yyp#I2I(Pxmpc8U=~u`ym=HT3;zo2??eol9Pb}mqT{qAPSOZ$Wj})?J$lWE~%=!vK z{cQ%=pU4Y4CAcfhQIJJ%-SM9;MFnFQzMEr8=`cuJ&JdG8QzQx9&y#x z@*XSuNp)~C_EV+R_u~m<#qURXiXbK41_8l?1On}i4Di-c=cmg7LbXoZ>u5L zs0>J!a%d)b>R8zAx7$Y+fee;i)`4?vYxNb-LC1P_+q${HncXwASSO(I?oOT+V3~Hc}U_U|%AwlOFNQ6!j})hIWZ^dDTyu_b;G~?*D5P*bpCrHZrsl4Y_WnSf)ul z?U09ZjPdzQlpMzLq>S^6;>@C#jDvhTmj~wPY^)dXSRv*N0@Gf_m*2$|gm1|~5 zbR@=ssh^rota^AJ@B&U0ka2DfGK&3-F zj)HW5|J#<-$XW(ZBOR?hnCBuzO$Z5n8uYtS#! z2k`0L1HjbNTUTX>s9`DFD`zZz5|)W=T)sUrgHf=#dv;`%fBt$Ex8S_T#1Ckfa=> zj$>={f%>KMtYh>0uNK zz&-8ZL#(UKz};iu)sA2kVAD9Yah@|c>?<$ylu36c8ca*X{#a+Lj9 z=0Y*>=vRTl7Z?Vlx=!#EuloFRDHyGuw8l@(tfs!7*={49_G&U4TR%PhB8z#5B|5D?Od zP9`g<9X$vhq?igy51vGV6cK5a)?#5v#?nI$LJP0O1{?pdX=#gT-Sy4P&g2iu&YPot zUox}v-ury#z5UE@7nYF!bvr>WF9<*WJ~p=4N_IrwAhRSvT1h;WdG|e%yuLWTeB;JX zbLY>$`to@4x5XRR=RQ6E%`?gtVS~z{J}B82 zNsyP7I8U zh)&aWLhN}#h{r`yme>1IS`dbYY+jP`Qa(SNA0F2Ac%1RYQB~Ij*4%lmpt8QZgw5+Z zyI(vWmx#pHaPM!EHsQ?I_oEjDp~!eqEQn%0pVtd{MljyFmv?sas?*&3gr**LS5ps9 zX!d&cq^8+tXa5`es!E7a9P^t|B%~l|1x=HjW*F{#ES5+}(!juazb74wjg8rSI$cZ` zi~7^Yj~hlJ!FXk2)X-zBx%12i>$^+XykQ(X$ZnTN$J1;LZ+&+c&U}48h7yY@jF+S$ z`!DV`iuMHKoqKs_H$Un$cRfu%I_|D^bX?Qz_3TMqx6jW0H}pqG38~F|_`>r~5t13~ z7~DQc29vKzP03?Q>D;YE->qHpqw+oFXL`sQiOgroTvF|Al^>Tr83)8jy}Q0b}Kf%I=V(HLI`LdL_c%C40B-=W(ri zwK^gvW6@-DXS}C1w`*^&)DjyU9(i%}m}Y&_JjIST+3^-TbaqU$!%fbslM!+;^?7ra ze5Bc*R{QTts#jay$<9+7My8yR?YEb1ewQQpZTFRfY(J~HeGAXBiR{Unz1~z)Zr}3G zA{&UdPcLVx9rD6bC+SIaU(>5+*FovcxT$?m5)C1Y*V+{dQWXghm+ZHh@d z*dbUuCTNFYJ+~_;OSoW8niuEh`2!&mVIrY2Tp_DA!}I8@Dj)tAAO4sRf5eBcZN|IS z%fHg7{2Q>Fl{bPpX5^ISo!;Su=4luVCC=Q z!OB0yQT`qqNVyMl(!4k~&mRbp2onjF;R*#TfA7%+EPo#lR{lO7to(gESo!;Su=4NX zD1VO)q}+!&X0058(0ssI20N3}|000KrNkl)#u)&zo-1F|b7^*6_gBJ}-3e>L5hX%SX|{65e#J_48Uoy}x#N zYTQ&>gF!4(Co9?;-`qZIqu5^ca@zN_=kR zA1{n50a;eo7KYqHToNe{i zf96j02}>-633figJ^5fc%?GUW!QS{(Q!AvwFjra?T43nK(btFy%nFQ zM3%Fy+WvdaMYnJOCph(fa4F9S48f3mFm&+6eCsW`QwPI$rvX6+FC9fg2VV@W{ioN# z)+<`uzx8;`?L&Wm+Yc}EEoC{|$`2sR*;ecRt;b_Me(2!Eaq9ixB$n3ZgS9wx;enRU zy}ci7J)W$6%+Ez@&n7|_@RSW2RYNhT!Scj$oSpqVC{IU``5x+ z_p8U>;lUl}sQq}r?0mI7*`~35$CkM!Da#s)CRmnBt+(Q9?Fk*cIQsL!=Tntq@}2YG zn)j8n+iA;|i!FMJExJbsXXjhnr~f-yOoJwN4eE`e|#eay{kmbY!l0$541;3l$uY-BJ zhYt3PQ^#go%3GAtls(6-Nn{TG5I*w3i}U->MFVqykPlv(k9_dzIPa;vYM_HX@(DV4 zX+CuD>d<;*rQE(nC$|oT^$7j|K8>5;Y`H$f##ZpV`Ov|ugP?<#=0gXsjt)=FcGBX( zF~Tf5Qpt}A6+3_JTy&aEYAo{&RM{k%4{2Z)J3b5UAwT*}e#>@f&F|O2uh&a88sHj`K8lW`xVQ#7 zIQ)&G=`TJ;#TI<%;K8uAry3>CtJG&ZsqnK`wX9I^&-2Z7FyGRNF1#BbI(T*PY>_}* zpXDT#ct6-7zkh;{>5ONw&d(09u@(GoK6LQvAY&a|S#g)>!n^VDe(>rby$5%n=tvge z6!~2(KPFV{>|F=9myr)Kk5t-TR^@NMxRC$V7r;Giq1JqFTQtr^ zFODm}lV$y{;k@zpCBKt(xBb9fluE`rxD=SsB>B|Y`Q|#9Z|NlHxEmijcyWx>!5@Px z3!Mjkoo}v#z#5B|5D?ml zPA4m=9X$vhq?igy51vGV6cK5a)}k;ZW9T6Vp@ElTgN=Vk8rou7cYW_SNgF-A-yFR7 zd+iQ8?|r`WCZG4sDUAKE$4Pc|R{Qby(b2gy+ZlhIO|cY9vt+jSop)L0`rO#^;^I%! z7cai@(pcuVxy9?#pIrR<8S7uhYTnOQ z4#RO6lk1w6OzOI6KDsw@nl?BndBZ3g#o|zLXvlGrNx@e}s*bIR5w6?is<;ogki6rF z=OvR#gBfCv@cELI1gvkqk5kdKir{st$KLe zmix&?+m=^&|84ixDr0VC^x<$TjFk<$Y}*D5*A3SbiB!rk`uiW<_v8|Z(NW3ga+O@A z;yiu)xa+1;g15#;Tqhw$xGsE%`)~`%yY9h*;&G{5GAH)f+CO{?Sl@gf*GeQT!5c+==?q@qk$HLu?j@gdfPcAx+yu$l$yB`^0tTFk)^UpoWSnojR zz>Wbnka^W;${e$57jC3VH+Gr#{dMbSekd4@&E(m1rrMV_9|U8u{P}p6>A{zA_>#Q( zMSO-QxW-$o8gI5V-dN`?Gra8t^Ut1Mc>CO$duR4~FM6+euJ@id?S1Nf?p^S{@-BH- zykERq-ir6Dx9Y8Vx4m`m`-Pi_x>!D@*~=|Qy1Prf!{wd%tY-K2_HND?F7M9gVMb2I zk8CvN|Ik(%^HUIb!sR{INxmnzC0=UJ(zPqTc&P$^T+HpZBqnCLF6Oel%Ub2_{4vYq zxqN?Prf+lX+xp_q@Pc0o_G@YLPe1rB9z2z>hF9w12?gE=O3lH`G4WH1pEmq`+^Emj zhs{hPo@wq%_M{8D_VyVqiGiWv7eXIlxF7i=%mbAVMNaBvJ+yLeyU#9isk#tJfcJ z_4)&@UVp&V>z_u{U$V-|0Y=hT9L?hc5fV`%kusXfDDiUGC&5%02v?yWPl8i0Wv@a$N(8217v^< zkO4A42FL&zAOmE843GgbKnBPF86X2>fDDiUGC&5%02v?yWPl8i0Wv@a$N(8217v^< zkO4A42FL&zAOmE843GgbKnBPF86X2>fDDiUGC&5%02v?yWPl8i0Wv@a$N(8217v^< akO4A42FL&zAOmE843GgbKn5Ne@c#yq_Zas8 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/sweep_restart_2/test.sym b/cinema/gb/samesuite/apu/channel_1/sweep_restart_2/test.sym new file mode 100644 index 000000000..c3a4f1938 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/sweep_restart_2/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:1e2a StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/sweep_restart_2/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/sweep_restart_2/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..f4485a7d78626d064fec280911dc2d0e11796078 GIT binary patch literal 1328 zcma)6dr(qY7-veQ)eLtwHM5nTXpxIqskH>N<|AgaZ8THz*_v%8dRN;foo?8A)25}= zpww1^vgi0fYx0o_MERl=#<3E01vC-Ugo~tb6LqgT&HlSH=R0T4ocVpf@B4kfIadxJ z3bwahYm32P>}dxALecXM8U-tsp*yC>)PuoTnP>q&9m(KM+?KG%);k1B-_H2gG2<*D z%8lVMo&o+Vx_&>SD|@tWv!8vtW7{`7S~Gc2H(9=;H4h0Kj1keI!?y4-v^hh@a8ZLZ zKs_%27`N{K;^RR>L+MCQ2XOqH9Eg!S^QwVRqaAyAzS4(6 z>)z$qkk0juPde49@5rioQR29_9heJBZJ*bqOe<|-=vf;sB^rNyP$N88WpQ_*?=O~9|#I{M|QHwA0E zV?KYIlKPZ=H|&E^oj*zCN`}P+ZCKWL5k)c5!2b+iK)Nq@jZ1(jXa5XgET?;X>X_Ti z4HFJYuAGz-8lR9r5}=t)sj2@y}D!kgyY$i==YLbkTnA8anRx8=(d8s8Iud_rBM zccz0aRS=&AUv_%?kJO*B2YecAyY|^lyB1rL$f%b~#vomDJ>_8iI;y>gLuc zOfRaIvek9Ovmzdyon1+o&jDvlCtQw7@9`hEU}t&|^~0?cb2eH+v^oB)vg+B*v}SDn zE0iALQHqU=ni!T|(@-r0tN5&1Nj6TjQ6JG4V<5|)?~KxTa^U^u_Acbv3+WbHYajXp zlanGhLi624KrR0AgwEoCOu9LiJWq|}YR_~H4WaRs?__mK4KV?P9Tqj%3cC|}!?%R} zLp`GN0E2mAoRb`_BnRiDHAsfW)X>B+vzj>R1I;QcC^FMoesPo30d@Y;kQ9u>PgN&# zOo-(@EXUU{-wRg%&wjTNlR>a$<9;Ib$N`=cSl3WRHr{rHj) zcA}E>J&hvX4U$B& literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/volume/config.ini b/cinema/gb/samesuite/apu/channel_1/volume/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/volume/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_1/volume/test.gb b/cinema/gb/samesuite/apu/channel_1/volume/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..a5f1b15162f45f0309e61f05016ad3c9f2dda04a GIT binary patch literal 32768 zcmeI!PiP!f90%~X+1c4ivVUfG(>ReenGNl-Mrjf}xQAuB#*jwoA$SrzG+>QIONa>R zL?@Fish##9c#vW$s5yv=$Rb5V(n@Mo7&dF@AqTO6mtsR3|By8FPonJlW+t14BIF&s z`F+W}o%epV{Zv3Z<>95>~^7~lw@nv*7tVd*0=U!YNDvIyrSgT zZ*H%da|$f)-mBJo*AKeQTTeHR4122`8P*MFJ*Q|GPVer2$9Qm%km|&{&prDnA#FWP zJq@e6d&JOR&Vt&*|W@DcRQsh0| z`L;SgKgQbi>^9I4f#kwz&PV1Jfs_1ZYx5EKOx_0?6AC`*oTl^C?H>21n)|N2Z=5 z)54K?h9fh^kvYSW`HUlTlOwb7K*o+IZ0}z%^bmjm1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa n0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*#kI|2J2VN%^! literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/volume/test.sym b/cinema/gb/samesuite/apu/channel_1/volume/test.sym new file mode 100644 index 000000000..a1d34fe55 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/volume/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:0643 SubTestGroup +00:0ac4 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/volume/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/volume/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..54a535e66235423006341ee9e309270765b7ad5f GIT binary patch literal 2574 zcma);{Xf&|AIFE2bsXABNtDmdITb<^TJB~PxovJHchzi)%2CmYW@~Qhb8y_8L`E@l z({Xp)-xtE%#zZtkjk%fSrm#iBmhbBO{R6%~T-W>h;kq7=>v}z2ujl)Ub#}B-kW-a| zKp+ZswpLh4&6bRZJEbKvWc14@1oGpsozyu#F2^DOk)n!DMAnPnSg0(g z4_g%USh^xr_ zhvzNJs(caxFW#UGDRs)AP_2rt)3fv1AuiY5`D;hgQ}f*0A!(un8~gdy(26vj#l#eb zYEz%zd9bX%4m(#CRu}Ip;PEv6T=}v*N#61cxP#hy&|8yVgYWU^`ZGiT3z5MIMT%Y9@?YqLGZ8$HegA7nb-TV(>~(b@;PGy-Hnm^2oxo0m02YM)K)@d2g)lrn2+p zDyE}-F@lTD4Lk(Q9R}4#H>l{s8`F*hiKzcrocoS&!|P{v;62AW=0mt#flnE_@ekr zdysaUx;Q84S(LdKRDDEbim&pPfzfYsES zk!IYracO_&by~?4zfla%U@)Q$k=|g815oca2Tjn`^UKCCM27u^Iv(TEEF*f;3^pOJ zee5o9ao}obY<5Y3-?+o{yIsz%kyJ$Q3JK^NeN2OD@3JkkKR5syHqA&)aI+3_u+|FZ z?cWsYd@4(a3aU>{y>b606MaYNj6ud%x(a33(8PLR|6xMf8>ydHpQJ-^Y=e!aM3z=Bkf zBOW<$e|(8UoMQ|Txyr52P)54_iQO|SHxo=Mw4R?cC&GP7LQ%ateU&kOPHE8kOASr8 zPX_mKa!AKn@|%Zk2Q6*#EnC{4&^<9TWY4d`q@W@gHE%>cycnIY{-nZk)QWii_?VW*=E(-7xeH6g~k!en5)(?;Zbmw zN?=udepLYzEZ7SB$WD^wF;@7ZKqDb(WsdAu>hmN-XY5A$%??;NKshEtJ+_OJ9)q)q zvf93>EkaU7zYEP*Ow(u$2b#u-1-nJ4&@tQz`JJZD;XvQzspsLa1Ue(q4&8$lE+y!( zV6rkXjdKj{n)8#9!#=wmeD|DE13C;@a1^Y0A04_p%cwVkxeKw6{=wsO$Ex&)J;lK_ z85?Y=5#tmm=wE7Rwp874T-H54!BR|zI!O(HY3wuYk=d)2L*?a~#8==2y?5iUzdMrR z=&t!S5Bhs5#c`jejNrvcjI?nn(H?Mukc?i?TrHK>d9HPfzHgvs=p*>m?&i+D@e1YWR;*2I zgj;0Mxy&rRPblG8boREfmqo^nNl$6E6LN*;yXs0w3rw~dD%KVa*(?Y*cnpoD+@k9P zpmO&pm(d${U;a~>rn&)k@XadoN9&03vKk~en1_1noG4*s;IM1Y_K87lD*OJ=$7g#G zEfe?HQue-@N19JmB?GP1!fnn-WG(+fcR}*Df3AmCW6rGszoRf94A4=?>+lf}&Lpz_ zc?&&H1m2sVO|lwDAGSdkn^;)s5rf+8ZN#xdX+Ia7^E_!s{zF9^QIUJf!>z~Tv#nf! z5HbMjiMBz*Vyi;$T#X)3$&AakDE}iK7yO&B0rhNna_sZxiyV%jVcQ)+lyGHe_JA@k z3wmIoT!zG91SKNsAq25a#E>A>O6)V{*pZn6_$sHdu1QKxD5WU2hjx_ zRmU%+ing@Jjq76ws^t8phOxP<4jl@z$c%3nZb`&)O|o#W?ri8h_cmu;{2nY*ShH!q zskvj!Rjs>DQ4=ci$ZA@__*l%8+`$KnQyb1&0gFslZpTr4TZq55>CX~|J)YymG@>-L zEjL`+FjB<kovb3SN`TmBDpU0$c_}(X8F!$ zNNtr&(o6OGYX#8}Idno2)MEh}3W%hP(4V%!1 zgl?imC@TP!GDth%qCcF|0`pc=GkA>5UGZO}W%*V*)-HGmIfUt;i!dgf4y}H$qiWSs zt$pIV5|jUSKg@cT>7OUQDQWWXlyHSV7R2G*`<=r29e%67L&E=gK@;Ak`5R5b8quaVIiW z)HapEoxjPF-n%Z~bn4+E)#_T884o%+Qr-svPUqDBT~^^#ji-0P;b8FFKhN%rqgB~y H!u|gMb80eD literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/volume_div/config.ini b/cinema/gb/samesuite/apu/channel_1/volume_div/config.ini new file mode 100644 index 000000000..26f3fb74a --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/volume_div/config.ini @@ -0,0 +1,3 @@ +[testinfo] +fail=1 +skip=120 diff --git a/cinema/gb/samesuite/apu/channel_1/volume_div/test.gb b/cinema/gb/samesuite/apu/channel_1/volume_div/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..bf03c83466110ea27404eb1ca58868e5047e9a70 GIT binary patch literal 32768 zcmeIyQD_@=90%}!noDx+lJt_a^(wKwD_e*~))pVkL%1EKbVc@1d=h+E!C8lnQV_bU zUa!&4ojwRY$gm2^9()ohGDM|QHiv^FJph?KHVkF+fUO^OnAGUn9y`*KW9d#Lb?ar z23rQnVEi?)DSlEZT(}YKz0oc`u(p-o=uvw#uppE9xY`qw9@-ND`Ft=z1pAwy`-Z>r zb#Q@(DMuqpfrb>0mbYnSfwoQ&>)e@@cRx9M|LkG&CG&ODFh4No%`eQa%nRnX=0)?e z`MY_`+%RvOo932z$J{o5Ub%U+gUA6+TaO&??Chl}gSN>DPV4UO-klK*+9}KKj58TL zzEfWQi`ytK&$%}|Wza6=G(BYBVuw1kcI~po4wa!#vblqb6JxVfU~>uDp={D5eL|6F zTJA3|^z632${TBeW~^R&fQw0gTlP;u`*uhf-6*jqWN6v$4cV^**r#Nl*84v0l$J}Q zQal`thdTJKSf>4Oj~EFLj*PxIc2cuH3r(}@O?JJ-E}dO7?DFnhP^SXqQsT>yOg`3} zZ>#fnHPNH3x3YeE-^{c-({giV?Z*tsHs4i-*?G1y1I6dqf_!GJr?S+P8CY-4vx#78 zX1%-ACKXpYNLRG;nqHchKAkBM>6}Fa%GFwgxh(1~SP8GKmHXu6NjK5l{XZ!_I zJ>##L>KT98RL}S;r+UU;Jk>M)`q`g(ObOMD`KzdA%wI?~WByvI8S|G@&6vNUYR3FU zRWs(*m6c3c-Y*t<2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf WKmY;|fB*y_009U<00RF#0qY+Os<}1* literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_1/volume_div/test.sym b/cinema/gb/samesuite/apu/channel_1/volume_div/test.sym new file mode 100644 index 000000000..36b01a6dc --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_1/volume_div/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05eb RunTest +00:05fb TestGroup +00:0a7c StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_1/volume_div/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/volume_div/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..93f9b150ab6a0e2baa82ebb8dd723027c6afae40 GIT binary patch literal 1367 zcmds%{ZrBh9LKemZ01AG)U*)SDzE8=m8IE$6 z0`g65nuQN%YKVzPrJi#<_{cR)DZIW8B2qvM1%|i%75m}!{@lIqeV>P4J~!ggNJo1w zdm9@YN7Tv4)7E;=O2wy}tZE}O$ZTx3c%vf2lM2~twvcq+XWR7y^N9Mn+u%g%a@ji} zyw1I%-sMD7li7816=&#lNpeA*q4@ln<`mf!dH!KKLacp9tp$(1RIn?(p?GIELsz+m zJ~=2^G~MEVWHRDD#ENE&g(jQnof5gC_p5e24c=?O8zXuRAUckKMRZ{e|KK? zJ%%|P=L(!M`sWY3_BKGNw;qKyYNK`fRa`{Vs;B9t6oaUB7}ZxAio+hi*-oSqQ_(ZL zx?NR)mw(9}4n?1Lmnk%A{0y4_0D#fw&ah0p7ipMR007MMpy*6rVuK|g*>utV^P(Vu zK)@fen9c9K!d?(Oie?-6iVIogz*zJq;Zl%D_Rtx={x(InIS0`=_+)%-l^P88;91+( z81c`|P?g)gMs@ugPR~;Fmwo<(!B1@c+B?#90urWr^@V+L=vGD?ZzOvTog27b!Qy68 ziYVkoGAIdIb*?36K!2P{bt!;PiEjVSkec?Y*Z2A5`XcpDAnH`5yu_G!J;uCoESL8D zay&%U_)|ijh?IX?ka4IBdGF4l1U7yfBgo9EJ^=sQ(X!;6z)g(^L z3nsq8q%_;tS-X*PpfLZ>`eJt9nHDYAgq#wzww4|GZD!oHOTn@47w^gPMUugZW7Nk8 zPA_`*#gq?+o%J|Z_qSK*nr?UHPOsTLz|Fbrj*hmRr<>fAIe*+Q?23oOniWOBe!gQ; z8*sJ;<)Ix}taLf}G5UeL5e2J8NpLeqCh$Iw%v0K0@a3hQe$x4L2qU?GUd`xsa?;PG zX@zeWi!q?!hLT>yCOC8?r6SMPj-T3f<)*?C23kH-{2exe}oqU z%k9jx9nqZ|tGr82qlBqO7(d@=lRkE`D`U=p4^*n; zPfMb8K1OB;FEYZezR9U)C9E`DDIU{V;~7wgHr&6UO<+ zq(EpY41`9oSiVK^kJE(pLb(*1pA`@sxMP=>gOj6OsU0oie`JGU$L_wH(0@>Wv+*!d MQRv9F%n~BeJ*KYOCUHZy5 zexLS^d!Fy_?s@Wgk|X4Q-A$zGf6rKD79EHyT!>!A><&lYmJCa~t@S|-Q(&J?^}*V*$z zp^!u*Hiz?kUdb!$d}}>=RuHnRUKBH;m`bJeOo~;odiz=1XXpN$-JJU;wA>MAw%m~k zjnBtJP2*>K{X6=(93e)wc)uB0LNbz;(KN|!hT-JFU^pyEgM$zHeeqzhSmgEbcs8ER z>W`l|VHn{st5+uqh8|?i$(aZ1J5%s_!x$Z9j|;~`aW=>H{LU)ud}}?18VsteUXrrx zKfB+^@_^Ob&)Pma_ZRHu%%|zc#+})YjcYoekB7R>&-VIv^a}+-nltY`^VDO6B!;_( z_Y9Na=u1*t^tf6&e=VH8wokrW*;Id|hpoJ?tdO~Au0JB*v&MbOIe(0Z*5`ivB6RsP zf0+iUK-<+44X6TbZqoKL?U*E$GpCl{c>naB(+ADx%$H5WeA}EeKQ=!#&zl#_i{>Ts zC-a86X8vrhn;Yg$bJP50`TF4=qWA=@)_%0NH%+??+O5O{Es;oUjYtOVRTO)K5BiVR zn@hh5Yt5xu`-Vpi+NYkR2do=xQ3qD9T&l1|CFvt$HGO4=F{BJ%GQ>ubODLqN^1HP{o9v}vUS)(bxNDcPrWevkFWQX?-% zgZ^lsC)5{7?mO5owFigC^3N8IYu1N>DR#Wdj@Q_svtyba&Yk7lq>n7bJ_#t~tj2$> z{O{XXzgFvD=cyedQ})Q7>&vTOB}wX`Tk0rV&qi{n`XmdKQ>*>kQCo7T){$ic{;ug- zqR}l^mwQNGxc7?QI4gfJ-B^&%RH#pVowlvFRcGXS#d*zaolB+C&OYn@qp$kt(;|tH z1*S1Tlgeb1N=&tfd78A>u-@JKuK{sSyduxcJ8Y4*id*Kb3*0NL=8UU{)$qvv@W}3Y zWOqHXx?4tE_md@VAC5lT@jqLRopUfU9gLa-IVOA#aF6w%f7$#@n&`*4wfB=G(Ee z{guwHzrN{rzUFZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb V2tWV=5P$##AOHaf{D%USKLM|Q4YvRQ literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/align/test.sym b/cinema/gb/samesuite/apu/channel_2/align/test.sym new file mode 100644 index 000000000..c2dc87faf --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/align/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05db RunTest +00:0b92 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/align/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/align/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..c7a3758e7557b1c0573c94d41b1c68984d7f8077 GIT binary patch literal 997 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|WCKPZ!6KiaBrRTr69xAi|J* zzAo`o?=$n8?9~xkYT8GtyB?nrZj|1ea-_=ncC=UKyywveZO&^hW&Zv8V(N-_FFVfL ze*bN||9jp3{BKiYRPE~Bo<1+lvHrg1R;j;x&AfuUb*5D-f7s{WQ)9T+bpG_?k0-*P zKmKU&Z}!>SE4OF({JH)r_p*ua5M7`d8NEYk$vWxZPaOtG0(v zZmnLx8G*qv~kOKufkpIu!^P4>UD zAAia`{mGZ}yyexmXBmDQ^YZ)LPoE5R2FIOEV!3PN|) z>owB3(-(q>j8#F|3tx!@88W0(Hiv^FJ1Ffp6C0!d!G9|NeKC0w^QV5k^AwFTy8NyI^1uNIpQY);tNIIeUAihEKZbGR(_ga zSa|j2iQw;xD>vppTlnS~>0e@byYC_-*KzUgdb*U4``1S+ABbgkJxkLYIvc!~H!p%D z#OI^uU5T#lfLONAX192_c-S1e7bW?`U{|*^cS*c2@!yJfbR{{u-IOFDL;U1WCc|4z zQ3x?}j`R6=UKHznAC`FK38B;%}t)mzW1o$dS6R#uE@#$Mp8 zr96G|q^kP;tX`VTs*0C2J7*rOZ%<*?tLoSodz?S)3$r?Jz`{Bg(#U1rUwGzLu0}fJ?{`=U{6#2j=V zD_58P=RL+T?%v3ImXLah5-llEqZN*u!tlK{`TjzW}@6?xE^m(3y$YrK6 zNMq5dDixS&FZ0xBpK5&A(KH~tC#|BES?katb&4Hx=YriUjOy&J9!8}__IHcyVT$nzkzMz5XR`frO`?`r>(C)}iXC(3f<08UC~4T)oiGhs+a#>-ZIiIRxlO|Q?luV< zwwLUTYac`QwcoM%_1A0`I;2jqWA0qAhl;(F?5U<@QRAjJp=#XrW^u#DH;Ws#zFFL` z`ORW``}MBwM}O%b`I$!t0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb Z2tWV=5P$##AOHafKmY;|`0oVte*ia$47LCO literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/align_cpu/test.sym b/cinema/gb/samesuite/apu/channel_2/align_cpu/test.sym new file mode 100644 index 000000000..c2dc87faf --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/align_cpu/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05db RunTest +00:0b92 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/align_cpu/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/align_cpu/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..5b35499174e37c0a9cf5f10b00dff2f52ceb548d GIT binary patch literal 1035 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|WCVPZ!6KiaBrR1WsD4AmX|- zJ51vGirXo6Z>pRbWEJ;u#hw4D^r7j2pp?_4;GV+BX_|?V(pk?^N)kw{lCrzrMBQY068Z<;wT0VwQdPk{A8|{6VgQgWivQXFlinKesu5 zVq}KXU?1WzTVZ=QX0E`)9O#BFRfj1 z=BLWPC&F)S7grqL{>}V|#CFFGdv7ZLtzP;ef7^{qseW2-Qug#FyzW?fdd?P4zqgWW z_rGaAdNTat{0+XE+xX63i@BHc`%tg(Z;$+GsT=Jz((_!i|9F1V{I#}6bJt$m#b2k_ zZm{~8_&eeKx1MYFkH2l6f9?J}!8u}YZJWjN_1S->JTLtCEJ531vY+d*maH17nM=QW zb?!H^6aE~Zcyp?NO-0T5%7U8s_48Ave7?B+XnD^AW6Q{=SHI}G9k~1WCi`mP+u;|l zdVPEJ_Nm6|Q|(80zi*z&zt0<}Cu+*I(BAFoSrh!r_PqX{=U@DLEq`Wx-(}z554MLtmnb9nrh1v>b~Xc_gmguH!<%0p)IB>e8RogcBbx%`nBa( zG%&onKVN*`ym{-FkCh+pp3jbcoo{>p>!LZ)moihT=6ing;(v6S+c$phqjz!j**3ou zN*|s5e$apQe$#*7em_`#_5P{1{C^(K(Efj#kB6h_sN)6;4l(wFj}#(gSh|}N3I%ld chP~it@yr&dM@KJmtpsIqPgg&ebxsLQ00DRWK% z(i^W$M*mz{zp?nm()TYY9jfbtq*4>9i3v>$g;>3u&uS{inwzVcEE~H^*!7ym-WLjm z1R}6C-1pm+c7>Dg>_?M1PG*H}bF3Z~U zXU^z)ILzvmsl2WQS#xvd!N%?qcD=5TkF(c>?V*n!BE=otku4J2k0l_Ih@xX?E}If6q9dC!{g=$;&T2M@V9{cl6*W z8I8UvbVN@p#Y;EC>6?edhvv5O8$E92d?kr2Mzezv@sTy@lP>yWgtxx+J2#=L-}p;3 zNIBZ66lp-=Xk(jpmT1>BF)y53d;in(56&MoUNzn_bmJpq(fHE%+PGwVXIwU}7{430 zjZNbZqiSp!ca3f1=e1kM`-tS@)Jo^c{{A%W(P^&~6kja{?sa-S?^r+s8O_EkV43#$EXwSRtz z4XTwc*3ayjnQ>+g-dfxEF-cMf?kVGJKU>L>@{25x&TR}fqmJZArAuZL{+`)NqTVZ( z*ZRmnxc|CVUl2c=trx`$CiN-r(T-|Ic}}dEr06uV`*-K2IUOU*>~jy%q%_@78dOl0 znO~9V8MI%w?i~2fknEqfid*Kb3)-k?r=+c#_KNnevKn*ynpyQ0`9Cf4M=kP)E%KTt zukUvpJfY{Kd(&2N%e-|#8x`%8v{lny(f(CW90!lt6UV`udyj)R_Z|mt?mZ6P+&vCv zcaQ1*uYw)|5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ S009U<00Izz00deHnEwKF0-E;# literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/delay/test.sym b/cinema/gb/samesuite/apu/channel_2/delay/test.sym new file mode 100644 index 000000000..9d3c63f11 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/delay/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb RunTest +00:09ed StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/delay/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/delay/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..f4ab7b2dc824152fa9974b191f9c37370f7ca2b3 GIT binary patch literal 916 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Rrkr;B4q#hkaZE>2pkAiz-g zdY?hv;(u!2ABehMSaRg_m89jrPaa@#kLKK*bIMZx^dzlmsV6P#H`LzWUHUe<=-kq$ zA1kK3x0CBXJZ(zQ`yY#seviw~|1+g{-m=Wy!J11u9@nSOTK1{X`rh^_`g!+r`@ZXb z)%5GTKij{g=KWVOzhnPB&znS^x|_**e|l=Dw0PKd;_U)>Zea zxT~+ff8L_{OU9Q?OqoyaJ-Ket$JH-Pg!XMp<_@lSUPs+}BsQvc#%I|61Kfmn;<=+1xfXKnM#Cl9Q4 z)W|GZCkx^qe*NIy&j+_ZyD|Z6AB6s$`uD-!XMz&B z_2yOfKc4&uzxSZ_{mCDK_hwvtwD^9)>jbNv`|sJxJn{Xr@4MUYtrtHoRb8PcpJ)H$ z_KUgt)wQia5ANL`;m$Yv{LTG7U;EGBmb>$nt#ckx33>)R)|W? z^{-V|ezg7#yLo@s!@qSOw!eMU9%RQ*S^;8 z)7`Use&65S^YjxMLjKp|1i4fce!4w8JR2mBdfy~dBtU}1ACA8FJ_%i&9Vsm={5(A~ z^V%yTpyla)sSb()4nH71wk8CPczw zPC4sIw6+E1iZkFFRd#im*{D2Q>V_$8>;x7yi(AU0}qCtB&1gy?agFFd+0hL zJQoDNUle6|Yb`|tVPJswOHy2l$A{uWL%Qzwv;I^zt!n}sPOc@>Z0&5p`*oeY&+qq3 zL}Gh5@8_Mo!_GI)qo)KR#rj1tDT?uUTu;VX2kW=rRiB;b)An$lAJx)_o!!!hM>W15 z4>gU?_W8H1(`iDC)bN90qzFk$T2j*_dl-h3`+R|bB=z=gt-B&V-|#T+k3>?DR7!v9 z_;JGs1X#a1nl*GE8&1wV*xK2G_Z!CGAbVXP;*YRB>iavVu=CCH7^=^wvVKWQv45$3 zMv4cl-+otpcAn4L!`V;MkB&II9Uakhz8?>DozM39x2>~TLTZyAz4-hSghcz>`edE9Ml{Zg) zRG>|2jy9?St*z3gJZ%{xh0`bJ-#v3`CrKTgDoeA1z&~_y(XwhhNvmzO^Q&H>+FM5wuYIApl zrP|z-{lH#>cBv=me(MH1)c(aQ7YpoAG5R>G?NfOht5T8G!n8vz(^mSJD$|J4Tg!KE zj-L8WAx~q4gw-bm<+}yz2e0*{Pt7b<*&AZCW+fV}S3T^vWWTNR_gJaURWowP=M6P> z_`8C!JqNm_CSU(h=B4a0&HA))oLz6R>uq-F?3!Sg^JG3f<{=ltUovAw;a_e4#X-a(ueLCjLqE(3o1I(zr5KW1n1(eQqZ0G^}Tv|1Be~ z;ST9e@s9b<4ZG;rP0Ox&T$`-gq#Ko0b&vmakMFz3_uS)(dwkbD{=+@qaF5sB<2CpA zclUVJJzjB-m)+yCd;FVwe8)Y$?H=E9k8iriOLkmnZTrU;QvJ&W|3d%*5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00I#B4+s?g0uGm& A0RR91 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/duty/test.sym b/cinema/gb/samesuite/apu/channel_2/duty/test.sym new file mode 100644 index 000000000..8086ebfcc --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/duty/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:0649 TestGroup +00:0a39 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/duty/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/duty/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..6a9c96269333307c09e6f3ed481767ba39b145eb GIT binary patch literal 1927 zcmZvdc~sJA7ssh)q_H|=WonL6X)dEBY2wm=nW&RZmZnzbRyIM7TQ0c$6ph|eGnvv? zn=C15UQ@H2Ow0w0+(HvH$3#&i4Ftgz1b(SFSpU9%JkLG%+~?f$J@@&1&&@gI?YTvJ zmo@|f*>da`jISm>(wsjwuGid0`)$IarH}nFdfXmPwd{>x}?}t5Z+<~o>1@y z#n&0udjstFeOI)#HzM>6%uhH?c23;cVNCL5fo%yTP1vDAKAANZ$Kq1|DvV=U?(=94 z=OV#)Qk0kPMz!T~i&)p)GHYmlvVZ;hpf-q2eq3gK6gP&P<^D&w9_>)eNXhp*TginV zWZ=k-QubtNQb1$RXl-Pd&D=ggMoTw#R+(n+K2~iu5bp%HPB-0B%=w?l?AJDTs6F-|O0aF^uHJF^^6>-}f8dUdkho8PZ(?F&>d)K%HcPHp z3}QhklI=|dPO1k`!}{=>Ke&J`XS;y|!-n+O5$2kQ9%fXy4G!j4 zpwAWuw0Sl#V&+D{Fw2_w;-|mE=mOFMXt%xZqjY2G^z!1~*hylz7P%V+Z+3oZ2e-EL z2BxJz68c{CWQ2;QEbB8r=go8T03%mo)9gT+sAtG*(|}2A8C*bW)-$RSVf39~J0qd$ zN^SE=%6dPN!^*?g4`B4+Z731(af6}CbfFzURCbnR6cU`^c~h>RqWmdK{7(kL&!|hu z9hs@Uinl8TO!V3B5~H~bqNrFJ_i0sbuhMU81{|8{h8 z;-#0cosRQ$XZqcgj7a%2hh0)dYQLQ=@o@rJApe}*gJmPArDUsL29qvY`wy!u26aQ7 z|LO2-*h>D|Ti*p%RMKO!H0sZAj-kefo|MTO@5mn`^;V@X^2F(gCIAT^fXQSMFYb2iN%Xy7bO~wdCP)Y_!xEPbB4N+{!DfA}AhmU8@rP6wHU#r51r*Bs^NDVTJ z*h0z|pNuspnJXF6g(1MtrHjmirpbmZIFhj+X5DYKk(NUaIfp;_&b%eue#8X>4@&s+ zQJ0=8^0{#8L$1m~Z=C%cD&!X7bpDfnv_F3w@7q?J^wa@`7^7ltStQ8g^D*+Ir@>)d zqhTieWB3HM)SLbfPLE?!x0S38k!#Ui=PBr4B z8WnaK2KhF(`g&*mMw>{W4V<+?2VbN2iDeuCWy6gH_YF*C=*$u$ax7=TX9Y*N0Shtu zQ%W>E?j;xWDxT%v1Cd7b>g8PLmLq1C@dE(5?Q-sgB z%)?+LYGT$MDm;S68%uB7SQgBbjXs2?5$n~iix1{PUKQ%L=v9CEOq)p}*aT8~#DHTo zyz_YE=>**;Hy3#--0F3WWZMTrN6M9Lq6==7QIcvzPE`XAtd;et4V+-c=R3l4@PA`w ztD?27iN7isxA)<4zrkL77*=Y8Tg_APdmi=FH<)LH26*jGA1e+E+fK8HKJ=*U zwtFaBR;Su&Cx6iEQSY*k4${P5^)m6Wr+zK zdfaM2P9K=~zz~Oth6g?}W--JV1DYYh-Yhu47|EqqhIJx}-%vRTpd{-F;^mX~sIEgPpy- zQEwOqWA3^ng+kG&s@}a;;*!+e?e>b2Qc|g&R8Nm#ghHav^kofQ62o8D(^+xtZ{hZa zA)Xfsg%qZUJ^bgprCWIG%kN`kBq<~MXfz#-rcx;*of3uUy=PU<{{2~R`1cR$*=_!A z*=>WmyPvzL>+acm{}tESEMsP-|IRQojHMMlt?P<6Ow(VN<#1S0Iy>)Px5j0;zu)cS z@k~6EF&^5r%QVAb(QAW!rXh>ruL}=x?Qh}srnzN{cw9Ihiiw5({j94lX!WN*NyPiyP19Hz{D$u4=x?tU_EI)XPMUP*0A-S^?`NN z`q(;dov<5#8G^7wx5hWkz4s_o(Hor~h7)=!-|VT+ea^83WxI?c_*ERTx07;o0* zcmrRnsXU(OERVD=kByZN_6Sef9nL1HUcG5Mp9h@>WvzF%B%YAuWv8Roc{(7zOYz$FVbw*4C8}}93N=<5hqM5aZTh17z!|L1nN=!Xu^MLj;ubHdK52;1l|8FMuFNc5E z%Cr9f#;W_8%T?};u~B){c~q8}IJxp0c`~wFyTKK0G|^n%BmTwKY8G!9TyX5jKQA+C zoerufs!6J9s*9?us?Dg*DGw2fPKhl3B#YZ*af>X9WO0)$Zji+iSzITJYh>{USuB#p z0$I$H#T;4uP8L_m;tE+@CW}jCF-sN~$>IW8{6-c9vX~)@^JMWWSxl3~6j^Yx_=PNf zCW}e3I7b#gk;RW>ah5E8AdBzG;ybdKAd7Fw;v2H~nk>$c#aCo8P8O%h!Xb+>vdELg zmwsV4G%o*wRQYuUUm*Yi2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## SAOHafKmY;|fWUtuVE+Yl*Zd#= literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/duty_delay/test.sym b/cinema/gb/samesuite/apu/channel_2/duty_delay/test.sym new file mode 100644 index 000000000..b29c8ca51 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/duty_delay/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:0639 TestGroup +00:0ec9 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/duty_delay/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/duty_delay/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..2bcbf07e19d89793d9eb27700342dddd00d6caea GIT binary patch literal 1909 zcma)-`CHQY7RQ~`YvMxFB9n$X+uH@i`h%8EOgU_8m;QsJA=RD{0dEU=+&ht9wlNE&W zH36A}baZq~{QbOxwZ24q3U=?(TAiWQAsrn9gunOc3&dh6M$kI#U>vu)&I*F_6?3sG zk%W^LhRDBl0|UK37#}gIm~y)F6df=pC&q#DyN*0^?t#Ovx1c{$MbZ!@zF?VG?wf4f zm*VWVM*lRqx**_0ydTBYTu3Vlie)ti%eSkH-Pt-Tdh1hU?z^!B?nI?HRV*hiuEW$v zx0t~Ik(1QS6+N)7CJ6(052M|7k8+rC>aW(goY2K}W}r9rTE#FD-cIW`qPSj-1iz4U zS#UY=sUEDh*9r|{G;?ia34b4Md8+kCys-TAYyQbFOSSCy&v8I)Cm8y|bp@lecYW~e z$E@KTS9gNwRuTiU0oE)57gsykS1`F&05Q=92VHD`XF_JkYN@&t$b3^_U~3(SQZBe1 zmnNUp&0pWVq{KU~r1n!)!6lH~Z(kBmh*Ds0hrTTu!PV^HQXuj0gwBUTZYTo>neUr8 zE5UfdI9?k}1(yDYnJXh1_Mc?0bNV8okH;AvTi$-$m9RYT_pH`2DR@dG%pz2rj6|R$ zBc)WXu}pP>ux#;?7@lZ9%v}e4eV{rtrAeLp~ag8GT(sZ}ajI4DYM^@KRW83daiU-4WmaW8{$ zy&+TNK4Lc$BUd6IeH@VfH*2$sjy8dpZb#A<5RF&@)?&^cMk5%&aC4IGk-No->=!nI zyP>o$j6qAaf%%u`pm+p<1vbmSXR6NgMW6r+=>*2$ovp=5{YFKyByis-Wpsd2@3a>mk|;{a?RxmiFQ#v@ZXlvdu2-MN>7!e0HOJvuy$UMR!8~(MW_% zYY5^yeVIwPdLR1gH($o32W_D^(R-a&&KSV+wiMXsVdhBs>dpBIN%O8sS=-W3MnGMI<3eE+9UZh>B|L9q4uoIePz)rxKRsu0|=D^EF4#v*)fJhNh`I zL6vw2I=(OZm-++Kj&W4O|U02@>CTC>?YY+3tG4`gHKXjW zBwdTm$WnohlBT78xQnyko-aZuFqat#09xU-LQL!XaJyH!n49J@i0tNEAUFSl0&rD14IO!V1hz z-j0)(Y)a_Wi%$;}lhVI_b^CJjoHON`m9<+Pa(x>ocb*RyQB5BYQ2u^Ul~L+q79`66 zRD3h=C}lfAaLcX0Zm45?vyn$td$ybUh;biAmUhaEkuyg>_D}0{Q<4Ti%YU@-&!ucG z%F0nqo=~1~ES&l*GGp%DGXq;?|Nvn4GG zJ@>iE=>jF%$M)9>%60PWA4m`#T>y&lpxSXR9MHY`dQ83Z?C-nsRz&V eTb};^-I|qIX=Kz|`lrR6@6;cO@~-v5rvC|$r0u2v literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/config.ini b/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/test.gb b/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..fba679c8d4a09bab410af46f00a1868054affc83 GIT binary patch literal 32768 zcmeIzZ)h8390%|x%_Yrdl3v=byGYjD#WuzuYl|<;i*OC4bY)Bkz7l+~fHMvqr66oq zyDIp6R5 zOYY&G=lS0AJollYggnx9j;vIKAAc_vZ-mHW-q*<@36c;AMB?wfOTxEq%+%J`e_C2z ze&wZ^@NYNPZ!LYY{Pi>Hzr;$s?;)g^IDW65tCdp0`efsMd6(TU(A<{A2Je^bn=pxp zCFQaw-P;$EcX?}fE8~@Md+5GGO6if_K6UY`{6H1Ik+&^9Gr3=ShLBNlb~K+Cozite z?0G>51VmAmANHk~AWTl$c}Yr1snm38dRo^50hZ4ea=Iq4;`3T2$NGE=JFn|(y+9x! z5sB@=*SC{)!kOPYkDe8TEX#{xMif)2l%7ek1j{>XwOams&ME%{~qe=z3v7mId27R$!6S^eoV zXAC14WO;SAVCa5Ue4cr*KHtL58^+WWTP_$2#MmCK{rM@J`MvWPs^71&yd-7WH#=lx z?Fp85)@rr<`GQk?KTSV1!*@G1qv`g3_N1=ct#kgiexX1}bK!&Mk3U67e4>Bi-~^cn zzbbWwPphRXw}a{1hvdJk9rb5=teW?f6|xl0B|`Gw)fta+*&88Z^-HgF6Il7eTc&<0 z&~CLveX2m4JG8q@d(IN;;`z0=KfLhZ!cp@@^EJ~j-!qrYPtDKGE9O_`Rr9*}i+R`F zG=DYg=9al_?wH@N-8nWu6px_Qx=%)IRuHI#b8s4~h-C~DI(#P4@kZQ-+C>7aQgbt{6+Di|sGL0#t&2nO| zMp`#knI^4tbxa7!e_GY=yww$-n%``&6_T`BP5Y`Zd)QmDx8=Xb-NtGoFNgi!ux}tR z7)l;GnvlBv6Vv$@3a7Q|$G$msy}_2Q^+OF{N;l#m=*p9IHIbCY19ViPltCa;(;qWdq*6`C7cuFIUzE z$Y3yfQ*T_7Kbmh8rQR&7w<>NHPu6(6N!>+Qh~kt2u-Tv zj@@CV7_B}zs}dSDsz(m|S0d?}7O`z-#y z9W4YP009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z N1Rwwb2s~l});~w>BIE!7 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/test.sym b/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/test.sym new file mode 100644 index 000000000..947b9e80d --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05c3 RunTest +00:091d StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/extra_length_clocking-cgb0B/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..3221aa8059dd6255ced51cf12c3fc2955c5f94d9 GIT binary patch literal 792 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V22PZ!6KiaBp@#!gyfAmZ@w z$Scu9Qi-!?vad3J>7w+&|K!6O|FRucuQp~HwN1HX;=9nmH`wcC>+9|h;imDt`SbPJ zSMBCMJfU8uZDH*J?=#Q8uc+A{S8ct1%lXX57thuFY`VQY;c?)HKj#nc-h2LDefImB zo{K-NK14rF4_Mk|c&~SRxt)HPzUk7E??>Yk|1EC3uC?xO*1Ng!)#BIcMAsPrHEjNV z=0lI)+UaM?@6GK#bKi;M^wmti+4^DeTlb|&cJG(7`@Q$`+tQn?&%gh5s#)kiFW*md zZjJn#ntHos_cwnlnqPh=ZcDx0>8bw$pYxxe{Qcm$_HSChB>D9>U0c_0^*iDD{5k9W zFJ6tQc&>TtEB~6qKm{O0><8>3YPSmSc~^tUaK8M*gSW4x8`WqThcji}S3Xs{MEI+@GIjhODpr4fOuU)i1s| zUVrxa;<@?F-(DR1`6ngl`~Ro67mLrd|5TbdyK=FS+t#}6Pw)NwFMs=UP5ke7mHYYI z&I29u_wx%QPxCug{=WU~AlRq=`}zMp`T4BJPd=h{{U0;W_!9>T*xHN@<}^O! n;Ym-hU_LAVI!IR*j0c$K;!lIB) zbvjvT?dU=9AjMQrdhjF?q=-nXv=)UW8AA^dga%%U4L1HEe`t$I-1YZncH1DjZ}95( zB{SLge&3xp`6pOM}7D@EJ^)`!LpPN`-T>NqR z;>8!ApNRcBw|IT}ql;fYVf;<3XH*2=VarzBp) zSR!6ZoeyQ(J6iQk|174n`)Buyr8_BB%J#Q+7^g1jca8X0`g+;Q4c{A9jb z?hVUgOw<)65{buk{r+4_D$4M%$ZJ|g%Vb6}BO{g-iBLX2R>x1)BR?h`eRd z^&*jo#x&Z)zrIL{gjcWKkCj)HJmur@Ts)r1WUO3<5|sC@RX_XhFL=X$f6*))@^>p7 zDw<+HQ8Z0)_U?bjyij1w&X3<4cAl}EX68&&^M-BvbybZ^ME&HXJz-nI`Mpvy&*ktFR=-`~FruU@+!+fY@5@|u>X z@BAJ+FA9|Ru2nz#?;rDqzn^IxnecZzGGSU`KT)(SarW+i$9!yzvFg-&&piDoW4%M2 zL%W99Q0yhGDR$H-UAPg=-q@{gl{bu^_(69xG?QY}u|i*~zU@wgQs=`77I!}ndoLna zKMT)rl`Fi(DDh@P;nfY^GQ-;@S^4bgg*VTgxqD`x^PKatV>|CS)6U1vr_KfE3+Iw^ z#rfH}<*YcrIIGT@v+is--!9xd*u_#I#awPV+})k!9X9VwB^0x_x3{*U*}OZI@>axR z`0!?R{&!`iI)BQ0!y`8DF^==S?k&2hy-U}wlP%m4^w(dMXL!1tbqAGJ{g1NyP1t=*HAYt|bcHmpy4hy;g%Ev8`n3M<<7Q>P zGOEYaaICp2($kvWy{}JeQHMrGpB+1Dx*s;5pyM?V z*605)70Hrc7gc{+|FQGuj%tY|*k!fiKBcNvItlrHo{mkXw5qXvoSs$}Jtv2E7uVe% zV*grXjjOVNCb%l$^;8FPPx^ohGuR>QvXv@-ug@fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= p5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0{>N@{1=u*bhH2f literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/freq_change/test.sym b/cinema/gb/samesuite/apu/channel_2/freq_change/test.sym new file mode 100644 index 000000000..642158c69 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/freq_change/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:0639 TestGroup +00:0ed6 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/freq_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/freq_change/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..ed3726007902a60bd35e449fd6cdca1b191ca5aa GIT binary patch literal 1921 zcma)7dsxzG7Pc{$WK|{`(j38_EXN|nbhLycecBH1sc0dwE zrE-#SyiKC1XqqtSIPPMtxAB6m$fjm_2NP6o^J|}H|KC5p@BDGz=bZCB?|a_we#E%| zORyc-#KgohD9|?wh(7?QaL*^eZ8EMIH!%SP2Ki!RvL3DAun&8jEq?u4+dWsRIWm(B zX&6fKwJmS&vyQAtPU&}lz6bWEjB}IbQ&IcN#`Y`kiiw6CjqCKonsAsXWZNC{$!Xj^*X9YYa zpxbBGR4vnMnvrdMes+P+hu+Wf>@8V3`taT<;dxV=_3!QLQ!dmeaqu>VdBT9h*ecg* z4Qg-D8jSSH{*8gws;cMIklUt{Wc9a3k#SJ+fS=$;&(8~HQ?ooT^Cze)%)K~mu1}jo zZr1xM-O`K7NBf7b6HA+M;n(H*dsYcB@7SRbZKi-Rv?YFR3^n88*8Uo^bt7et=kz69 zqs!H`I5hQtgSglJPh?r~^s-CWd39&PcdXxLp9lhk6^)C*Y{IOrOs~)8VU+| zFrp{i(m4aoh5I33QggXC?07XFRs0McgeuJwZ?;WTPgxfVXEx8|9!N?PFWuc*&YCcs z1tFO%Iiz81Sg$8|4eBo-w5`d;x0FUgA#zu$7sbO4GDUx<7-fI|p1?u6_*0rafvg*t zq~t3b^}G?u2-L0a&sZNcy!{Z}t%fHiV|*ZGSbXw?{!cHYIMc-9cX}MqXQ9_Xq>=b?(bjviiBcdA2Ox zkIPCJotXQgt@Ffd#FKYodw>7a9;mDe_<_k)q{PsPOEof3IX~t1l1r#DZgcqc0BC%k zD)V3qmZq?qyM#kP9@r;TG9pDSr$$>-POnnkz!VX-@7`AxlI_Kq1o5E|h@%c!8%WYD zC4jhzF}Iq>%jvfOTx09`6N?pj;;V}al7=Dn9k0v~F!=de{B#6Tep2`ggK=@&{^O#LV-)$_Cvlh5Z!mo>krk# zZ>90tDNhZFOdZ~3NmU(^^(ELFzi@aY^dK51~@4Kx6!JdF65l)?`>DjR26 zGkyYQ>T>4LaMBfMF!LTv>ypn3Y%UdZt>COa(d01l$ZiWPrfxpEhC<^)en+fdX$N%KpeJzB z)975-|K#R{j}s+B)6RjK6VvE6W_Ct%Ix;R7r=qz@0}%eF3k`z3iw;bT!-ah{xXJ-p z>hY)ugMR|2Nk6cpICsL#0y|s=m8!#2uhphbClv}nb%!&*W&cQuG&<;Avj_L5->{AT za3z}38nvfAz~B!1yQ-@9A2g3e;}RfmiqF};q7~yEFxe-%c57}Xan5G1^Guvyw+6Am zSzt{aDYrKdoLb8cQ}%b(1McBze9E{0ietk*e_W}B67L}G9Xs}K(uw&zFZ;q1BKVt! zxk>p!z_tmPp<|L8Daq$QwtIi9yn)d*0D8A|apbiJ^xu@>|C|l4@f5Y#)&_DgFC31u zdx>X9r(V9fZ!lx%ScddrLlL7c!&G=sCIw%~DT?+~Z$q19DsHZzLk;40-~(d+G!!&J zGo8Q66YPels`rJeSgHl;`mECSshO+)lj)h_5woTOSJ1D6$53YSo<|LSL$xoXDUJ4a z+eGkuGs1ck(pSVPTKU0+yIqXr{tj4hv`%#n(JAX!vsA$NR(fZB+~cq_YN5l=IXvCl zX;UB-&Ais0I4QB}Xe*oYS^0WW| literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_glitch/config.ini b/cinema/gb/samesuite/apu/channel_2/nrx2_glitch/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/nrx2_glitch/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_glitch/test.gb b/cinema/gb/samesuite/apu/channel_2/nrx2_glitch/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..5db3a126e25e9662d93a832be5fb3dbab4472a7a GIT binary patch literal 32768 zcmeIyZ)h8390%|x%_Y6fB)zmEaML}VOr^5wT|B$Y1!zzi--L*|AlDb#E z@cXp)aL@C6?|FXrp;tow*XVzp7S>$xwB$_MWuK?x(1_Zn4P+Mdv0$ zqC!!=>`S$Ggr!ZdcZTH?60$54Vnh2=#t%YL&* zjI6W3^6p;Sz4v_HZQgmBetOh9?ewUoJLfrzy6*ID{kz8bJR$X|_n&+ANkV!DItLC8 zkb%f6VoT(VQoM3Il)8OL`qSD_exk#6&R3GjY($NRrN8V^pM2RLC4&8h-@W0lf9@~Q zAmwPQQltTeqxB8iTB2>^#JY5T`K=EwJiKtse8GIxG|YF+S@RR~GxLi1rFqr7X8vs6 zHP_5v%&NI=-ZMAM@0RZjcM;jgX_eMf-Q6kLVbD%F%4xm5y<0P)LAzzyopC1pr#9=0 zzjJH##cB6}Ck)!7oTEqWyR4|At2eJ%tf&NioXs6koEV#>0-KA{E~QG_>0w2pF*#i? z#kX4D_Kj7d2`gpyb7AQZ%l_7H&jpm+T8-_HpmjSHuwU}Aw`6bYeUF>9#ad2^1pSdf z7vB?396A;kTZ025x##m|H2b5#1iM~m*Bk88*)_>7@5z!n?j!TjPXjWU(VVZ<`MD8| zYn3+EPwbkRaAywQSzi4nL6QgVD?_ZF^+bR98MYvwUyW}swIup0ZCN(q@0hIg);gu~ zau?|db>Gx$Gt!5XHC4J~QJ?ZAZK<}Dr=(3w5~TD}b-pUGPko8bFGa~b<=C6{(S$r+ zS1wXfnP*}W^D=2Sb*0|V1;PZ!6KiaBp@2IjRWFfasW zR5`t0aeayWvMHz5g^HV5%>C|qF?FM`w6C*Q=DgOI|mAs=r0f-n#15pNrov|Ne7+ZvWP+`A@UY zy;DDSBU3##mwCTqPvM*!+1q~cKj@ossW)lA^@o7c!{2LbY;Np*)h1wPW`A7bckF?H zQvH}`Z-D|%Ro8>R{QKVbUu14w_SX6Lp7WP@udTYTl)nCZ-S#*6@`^2~kx7Y>)4oQm z{`u=g)rxtVbN4EL*4d-RyCdnr-E0@ALORf8w%ye$ISf zqW$5y{|%0PtZ+ZZAD;J>+ji5lv^%Bt)6cKBzn${;ZSWWEYtSY5H}U zS2yjp)P?m|?);^6`e*pD*`}YL94_3q?UU8@Lfhc_qw`;Xzvo}}?N9prs=~kjf6K`n zyX}9w`g{7t=>6>TWA}fr)0-ckfByRefnWdmAHREl@GxswwC?;xrV7l5B_+-sC}3+d oHki}+kcTHd!D3Vhdr0hK_|KRZ7cN%429%mTUHx3vIVCg!0QCl32LJ#7 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/config.ini b/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/config.ini new file mode 100644 index 000000000..5c2a99de9 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/config.ini @@ -0,0 +1,3 @@ +[testinfo] +fail=1 +skip=180 diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/test.gb b/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..06ba9b13ca35f40f0e2b3d77af0a44eb65b9e3c8 GIT binary patch literal 32768 zcmeI0UuYaf7{KRpdzVeTT=tSQ*_1Q47uw?*q`l~a2OircgeFKH4)LL&&;x4>8bUy6 zx4PM$w08AD=z|oaVCjQTB2kKnq)KX0Sdz8$ArC?elVXFde@GhIVw5|-oy{d_{?*Oo z&2N(3?96=oo7o@Vez}B@|8+Y~u1pF){n6h)RYx8RzD`b&2&p4tEb;DpBzk>nX!gd9 zpGU{XUwLUL`uo(4>!at#zj;bsW31@)1BCSNKYwpdn=PgzbKRx0$|78!q}sd zMU=#(V)809NlZDhNbn~^0XBMoQr zd5JZ{AjF*)1W}YEMOo>~aY5+rcH?C^EvM7H>E2$$5Jia36*NN^pn3CpR)fB`gd1-d zz!ODLCNiwy@!d!_g3T}O$H)mn4&o&#D@o~e+Q_CM0^%8~a`x`mSo7{5*0nxwHLY)0 zch_?#b=^I){jch48X;z`f4P}CLb9@+)peOQ)AZ)U;YdW5GntisTRa@@?|0+l@mxHY zGoBb6G|fl^;??1TX@sG9^WX#e-V$!SX&yQRxJX=#!y1+KyRrTv&{IIKdvEa%`m zx5v!66A;f>m9uw$fi-VE-8eert#))sH{A8yNyBi@Z2znJg#sbvlOH_y>^?#gT}@rJ zU8F1es$3NvP>UCDMmlcpQvS9V)L&?ilMjp~$!Jt-uT%bUh62e8!5ER8uY&ACyz*sm zjE1Q|tJNY6sRAu8(CRT-e~j4YPEWt{(U}Kl_FFGluUV$`zBOunYJF~9w7#}3S(mL} zt=rZe>o;r8nz!y+3)TPb3mcBeF?blSww>4hD}b zmaqOP+$mo@#cp`qq;2YPy4Sf4o7y{b?XnG?ccLTdg_2?!}#b~-}N%K>;wcv|m$Tr6EJ<&|hS z7!5UxZFQ+#``hK}a93~saA81qJ_((G<4ri;g2RAg1P<@cG3{7@OvFA5CCP`n`?k7Y zKgQbi*?KsiST%Bjjnv+np7}0C(lz(gL$IIuROjT=Fp)ex(_WdXN_EcG=U^b%I5L|k zH7S$R&7>{Tdd(<}Dj$!O6y=;v1M1tfYOZSXq_SwktEMQK47?MPlF{-7$vq7h&q6Pw zY5BZYhTJz&S=BO`HQh{%OhiR0fTII6l{{8f%T!h;z;z9nwrDFA)LN&;pe-)Y?5SYQ zFIHVT^}GKY!wG5J2%l6cM02dA0rDgDV^J7+iU^gn)5@@g#$a6Ean0S<^fd9^VSp#Jk}<@1%e?calI8QaLKbqIJE|9Q0$1wj7u zY7-E!{O8r?EWr8Ct1WRr^q*IcA_CNZUaiy`@ADNTm*3Ca>k&FX;thVpFh63DA2Gm> zILePG@FQO2M;zuyJkO8F^CSBB5xx9~ZhnOCzsDYW*>&2&TQ3-buU;?&U%g-mzIwqB zeD#7M`052i@YM^3;Hwu5!B;OBg0EgM1Yf;i2)=s35PbE5A^7SAL-5rLhS;KB*bR+# z<^O&76AhpNG=K)s02)98XaEhM0W^RH&;S}h184vZpaC?12G9T+Km%w14WI!ufCkV2 z8bAYR01co4G=K)s02)98XaEhM0W^RH&;S}h184vZpaC?12G9T+Km%w14WI!ufCkV2 z8bAYR01co4G=K)s02)98XaEhM0W^RH&;S}h184vZpaC?12G9T+Km%w14WI!ufCkV2 T8bAYR01co4G=K)SFkt@+v*$16 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/test.sym b/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/test.sym new file mode 100644 index 000000000..db14b866d --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05f3 RunTest +00:1a0f StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..81bec39f11c00011bf62426fb51fdc3a7338c5d8 GIT binary patch literal 1420 zcmdT^|2xwO0Cv?OXDzWT!r87oITwpvOVeUZdPJEo4Y50wFQb*|*s{5}#z}M@T=_Cd zHO%OytrO#BZjN}uHp*PvowGSIBV*6jhjTyPpKw3CU!M1;_j!MKzdsum46<^tGBYy+ zg`5hE*wP1ExNEs>i_Iq2C(X=0#)ky@N9NQn){gNSKiwTT$OQs6&ndM>d0<)C5B>+Y z=ijb75x!%}Cc`zA@Bcw%k zwjT2%!uud}QeL!l0J=_B3ckQ-9&bRBa)k+d5N_?g5mhNGh{~4^{A?`c!jkeEg0Q@9 zep9x#tVERN6(u}C@tgZl*->+Q7zq`UaV}0 z;gtdQe|ciLt5=h27pp8e}O+kjJe&MNNm)H(gQJE>b1IT1gmNyhsU7lPhxZON|13`nx) z?^`t5b}{a|Q_8CoPCS7G!w!Hi-3i!xh;RA$wM%a!#x?FR^4IVhgPvtru4_r?n{8Ok zyz*!&xcOCOOFSv6Fgft7#k5^-RQ-#JM83<+=P@6ERCyc_Bgyp%T})+(1Zvs0PYh19 z1E$w`{tPX&$$q6CAGYdbek1K2UUl?=n8^N!N}eUSVC$J=(uZz2#owgAB#nViU-L(q z@Xj(TbF$)K;tn>g360t?jY$q^ixOGJo6E-y002yvO+>Ax-rcG$Xp4RM_r=y8GQ{bK zW-meRXwwIx>L{A+)-uO z>cSqlVT`Ivj~%!|(j77yxLY28aZ=Qxx&EllHz$GJLdM(`+_B~A52H?cHVs%m2br}i zV|oOHJ9|`!D_U{AqO5hBEcF&6`Uk1HG|muN`o1$I%NKVQFU*bq>&Low>1~VVuW|^! zkyRwF3@q~onZdqr9N+P>wlRmaGJCvJk*}+;+ zTP6f1D&`;dxPjFj(r{QNM94hR<9+%S8d^8?n`4xxON=8z`OqF5A=dG-nmi_Bn_ZeT z0P*T!zb`pj(+WdZ+|-P8YbVS9(<~DL;wC#=hiPu``b=Hpe#W4-ImIf>3pU+gAC#u6 zNScizu#NFghWOFeK&z>XYaB-_ydck7ABmhtGK?%VYD5@H$+-NxGDDtSqMBkd)z7;7 zENj^98P_{{HvI^&8DDDZ*GqAfA)8_J`MUGh+j21XN(%GLEHvZ2p9~sDiC0s+P(IN8 q4%WLs=7r`3*aA_5NcI1V-`gWgZZYb;tqKxn5r zovgNY^dNYUVk#&-coGRxM5I-!MPW(T(nAhH3$MinTmO(Ywzb>3>-)Z!G~0sT8;{~Q z?G8Kh{dV5;mtQ8KLj13{z2ekt?1$gR$4|G52cxfu10pHfMIzJt*4rX=?)1d``SU+c zA3y%$^Ao9GPoF$|}D(*5{OJnkso zvWn_&alK!Jf#UI6%X|I#G2HZeuD5eSueNi-^Rh+P5o<&QEe%bu==Q6Vs_uU%P#$IuXeojb=o;`gs)J zBu;%6osn@FlWk5}wmLD{Sd?uua`hfjIec*L%_E0y9@-c@6TBSw!8^fp@Nw{Ia4h&D zI1zjk{2W{kt^~gX3&GXkTCf;=H+N}Um&iq8?tI&h?(Tls>B}{_Ow8@=?Oi%!`La8g z!!vL)x}(-O^Ly+{QUanK;);oZyvofvDWn`DL zAUotkjxDpffyPYV(za>&O=U*rEB)2Yv3C1brTT5O`b69ry;4_K$je5xzqR^8MExt( zzgB-g*6L^KqjoADO|^Ca}0J^e1OZ zdm`dw=9AW(c;AKZR`~OMrq7*Ut@itx&g{c8t1iu5_&P5N4_tS)s{6T`-#q)c8srXM z=vyAOeFT$kuccAxd?N9+&w*Gu-{ii|j~%a(MPczzE*+kmfg$u=2zcX zXM_YvRU1?Eyl$BPWtiVF%x@d!HN*UtVg9FKe$z0&VVGYx%>OXV7Y*}k)Le*AF*IXT z4#3etAVDU91Q`VqWEMz}VIV=Kfdm-`5@a4okbxjUCV~VR2@+%`NRXi*VMrxxD@`07 zONd$kG2{Y>p%*|5!2n_?1`tCsfEbzq#1IW2hH3yYWCMty8$b-<0AeTy5K}tpCr-#G z4g73cK@9;RYkK17D;hJ>*D{r)DN{_EGWDb>Q&O5TRi!CYSei1mr72ThnlcrpDN|&c zGIge@5UDi_ zv(gBelt##$G(x7N5i%oQxP6rV>9YpAK5TVn#9WtF}j!XwYLpq4i=^#R4 z(CHvTr-KNc4kC0qh|uXELZ^cWoem;&I*8Ee)Iz4y%#rB;Xh;VUIvqslbP%D_L4-~R z5jq`2=yVXF(?Ntz2N60QMCf!7q0>QxP6rX4PNk!>`F}Ryw^82M02^QfY=8~00XDz} z*Z><~18jf|umLu}2G{@_U;}J`4X^<=zy{a=8(;%$fDNz#Hoykh02^QfY=8~00XDz} z*Z><~18jf|umLu}2G{@_U;}J`4X^<=zy{a=8(;%$fDNz#Hoykh02^QfY=8~00XDz} z*Z><~18jf|umLu}2G{@_U;}J`4X^<=zy{a=8(;%$fDNz#Hoykh02^Qf{{aJ)zXA7Z BW556a literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/restart/test.sym b/cinema/gb/samesuite/apu/channel_2/restart/test.sym new file mode 100644 index 000000000..b02f7d89d --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/restart/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:063b RunTest +00:1a82 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/restart/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/restart/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..23b8dcf154bdbf5d59b6c9c184acb94325d393f7 GIT binary patch literal 1964 zcmV;d2UGZoP)0058(0ssI20N3}|000MbNklYfpZ{Nc=j& ze*EZo+5ErZ6-6%&>nKmK9&FntSKGF2m-CIHEYUA*UZU-n=s)2VF~(vd9JY~s6}|i_ zI%tBn`k`%pQ2YrYJfF{);rV>-ZD;xG*1f6r1b)Vd2hI4w_}P5%0ma{`lM}s(D-L`aNd;n)#S^^QQb!7i^r%AhBIES(7Xcl?YyJB z$Taymv#^g^Rq^xD74}i9D*pT`x}K&cKZ2{iyk`x38DP}0ibnY}`@!{T9)Y&~UEdFW zuWLIV&tN5d*TJhJ;kvfj$q`>ZD%syf`QlNcgHb+R2V1WP?D=7Xu7d?eGg5}b*5xdn zEm!D1o)O!$4$h-3>}IRBc;NW!BlS;MF_O1@_5`sfR9ieKe`Y_pKFvG&`@y^J+%c|G zd3@6T>oi#V$MvO@Uj^aybRM;K`1OIpsTqLs(G1WQ56X8PygJg4>0t3Fc}^RR2j%~q z4o1hzj-NgM-+L}vNd|~V+jH7hpNo#<%?6pHsN?27n~%=t%yZG~s^T~iAH5%3$+1IzQ%h@UK-7bUx`i_-j`*OGkoyG@fZb zkiqd_F?E(LGn))9QUrtiW`q~U?>cyKeDr>Ban1JkgIW8XvwSv`#8213d8?P`@5k>t zcy%PQ4n|kSY`%Dm>T)z5x(?Qck^1xr*z<|TukLrU*!-_$nCoC0H}|#iqw8Qtj`{sy zxmYxaPR9}Eb#R~KC0a>|p3%W09ETPpTnD3mXcg-GK3_bpgVzLHJFRE1c$D0kQWuZJ zl*f0jEuO-zJrjHxQf(i#LVWA-xDH+%^ZUWFmX^wJ?S3#DM&mKBgHc^5800r2G!&2P z;MI|Q6}|K-+Pn^C*AjGow8b-%!NsN8yrzUNAN>vgYxpvTd^~--m`8lnyk6Nkx zJleu;wrYzX=GP;l zj@Sv&!Fg+8*PaP}9!6m|Tdl`~_CL9slqYWCZ1RJe-K6Fb4aI}@f2Iz$wI6Ifopsp1R^8LB!)sb)=tm?UF>wNK8-4Ay3!LEhs zbnvt;B1V3H1&5No^HiuSK99(w=vH*-?w1Ph8kC$+6=z}n)W_g{ZACv{F( z?MD|`=MGqjPSw`GIvpHAU0CMxyo( zCHtc&AB|t#c)xan>)~B9V33c-uWh{Z&qX_IAQ{)eY(5&lw(*+R!ECVShdtgC_JgIb zbDxV=a_0z*Up#~R$LtDGZZ@EHjy^}p&3Ehlqx0!Hcy-9>Ociqfh;3p&*n0m>PkxA^ z^`rNL2W{z1J}z8BwU_9<>ITO$NXB*Wul0}e&Ff$^e(U|in8?UxCr5nwsN{-9<6+0o zj;CDC4cgMtTfPKT+s)Rz=fXZ}h4^SZ?D*O7eDr^l_FFSW;yQGpzVzN^XOnQmuMZT) zGQjBmtG0ONPw+l~{BL2CKRrRUebfr^*%PWQo_QU7zu!k_j*F3Ib*+3|;H&6~_}TH$ zb+9&F$i7d9#!tU*c$9e^f3uSgpL#`W>t9<2m#c$8TRIxyH^0^NBz)1Kt$%hrDBpGP z>S$(LesR@ylaPEr_!Vp&To>dv|LEkUcPDsI2REl6AH!KEKuQ1Xcu>CU;MI}HI=I>D ztLSxfFp6K>uhpo7A-{Z7a_5MhVcIfyQU{OQ5>Ra)wL*LuQf(i#LVR{S?D?6|!45;1 z`M*hfsgd=zk{cb5-}paBFzVWpmyz&VNha+2K;hI9gqB2h31#<>^8LB!)scJ^z4R(t z-F`3%ZSkY=nAgG9Ge%qgDF4&tk)YbK5p4clnPioCS9O ygYfr*jrEVtr|aO=k$e?xs(+O4`@zQgNAVB)D=44@hfFL00000_8D;i literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/config.ini b/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/test.gb b/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..734c80b578f665c43fd2ef34deff4fb9a9dc778f GIT binary patch literal 32768 zcmeIzZ)h8390%|x%_Ti&l3v=bUL-bmVGC!FwZ#|a#c?}I>5A+{@RcBJ0cRXKNK^ZdT|JkNbXC?WsrcA8wRaX5Wc|G0X4U9VS^*!oEGJ*mO&XQ;m6u*o|W?9|%jE$Kl&$GN*(oKV7EvOp>osEMnyu4|$^?05a ziOBW{*7uTL!mn?i$5c5^WqCm;2!f(0W4WEWzXi`v82Zs*H~r{@;qB)Y z4a4jG^Y0q#Iw6)?e$XtHkb-Cw3`6vrWd-$UG!_%Z!NG^){&X~2E_?ZOT1~5}`P8XX zmKBS!yf#s?%qVL?oq4cvu!WbmtkF@nTrAC}*&aLl2dD7s+vl;gXjEf)QB>Kldcab> z0?Yer?exL(CBFsx8Rm)cV7C+FhUx9+6;0FY{qye{mr8`RX5N49*(V9f4EGN28z#ev zSHzCQNv(46Ml640zjV*p)PAN%++wIIlevVRjZ0hZcu2kwP7=ZWBJAJrS3eI|X_Rub zQ>)O3#?jU$?X1$SN#dM4v-H*nXYZapWWQj)YFqZZ_MH8R{h58y{?fi=U$K9&Z`y12 zulBmVVc)Vh?eCUWkMt2a#2NL@Mu3Wp~utVkO<81DL=Ec}771&&o_G#<1n?9yVG%XLds@d%} zuyf;7Y0k;JLtI??({aBIyYmsPxYlGV#yN8Fb}>@C^b2H(dJ647uX(#QA5 zbNdfv#m?yPSn>JNNyGgpGR3af+4TmyOmRl?E2=`3aGtFM9w$w-Z zW2tLq^St!obW@kkIW(lbNjug%YBN&9k^bIDl3Zr*IY4vrWJ}wkA`|OlRyIv(iuc#O zKSNWNdyN106lpWocCP*49+G>B?kT&s@E+4`#@*ITdmn<^Y&Uqn-QZTc!F%ln8-CE~ z?s0;Dj_4r(0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= T5P$##AOHafKmY>&B?0Fz{`T6z literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/test.sym b/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/test.sym new file mode 100644 index 000000000..ad1017c62 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05bb RunTest +00:085e StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/restart_nrx2_glitch/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..21dfc5ad6876fbb7e8b4693aa8422740c2d3ff30 GIT binary patch literal 690 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Qf~r;B4q#hkY{1B;p!7#ITI zd}+CNvG@}Iavs*lEi6(o-)jR83rzA|vrX~Xj@;-IIk&}<-;~LF`INhS zpC7LYzxe$3n)O=jXY=p=&skso!+pos8iT9hT3g=lzxv_2^;`3b3$?GVUeBL5f1Yyv zzP`s>7FN~#$hehcYgh9n@AdX`&+o9`&;6@jU;br}?=64FmsWc$lK1C)+4}D4_5Q2! z7f-ccUNAwvzB0x>u;QJ__ZKeLUyD>-{L1}Yo8?CBhr8GMpWnZ0l6h|Ri_f+D>Zev; z{Q8--xc^!FKf515!)LwDFMXBwt={Z~FI$_j!JNj2JUr)B8nIl0GB7sQ%d+(F*t)+?5>gq4^ z3k$EkG7H@$qq84+K~~l}+oKz?xgvl4&+}x8QkQXX^z5 z0f|U#4|jc@f*4pdc=hIGepP$syr`+ArrzSPN zA1`Ve@167S8>iER7^&RDW~2y7N?KCWB&QjMTlf2eK}i}KdNl5f`u({a&qt%FXey;Y zd+wZJ1cNNEPG$|=&zf6j9&GGx!SjYOHpZ3S6NYM%O3fmXL^Yk_u55$n>0m3KeBc>m&Y^JVi5(=b0U=grT}FU_mwH|90-y7{|# z$J{XgFw5qqxn*vfKd!8w>>-Lr&`PbRdwUbK%b?v#M9}*C`*&v~gZ3(lGs7pnr+2E$ ze+wJcXhk0IQVuz0pNUi>n@ytuvvzq;>Z<<|ivFmMi>Fk?;bkuQ7-xvcSTEC2f` zGN6?@SUL#VlEqW&U%M&-0#tx_7+aa$33Ue(v?< za)c}@Le=&Jl&Pxyz^BA`Z&86E4Kk-5)k7tweMDWPy;QIxnqhag{cl-3xZH7YIec(A zbZ|L%aQV=|<@TDg-KIU})te=1-@aL*7NA+8)}UFUmZ4dqR-##=7Nc3B-edBy9*v25 zkH$p3M`NPiqcKtM(U_?BXiU_5G$vdRtFy~;zFO!Y009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf rKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2teQo7O?&UE2bb8 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/stop_div/test.sym b/cinema/gb/samesuite/apu/channel_2/stop_div/test.sym new file mode 100644 index 000000000..ccb41512d --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/stop_div/test.sym @@ -0,0 +1,46 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05e3 RunTest +00:05f9 TestGroup +00:0801 ShortTestGroup +00:0912 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/stop_div/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/stop_div/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..99bec969ba3e7ccdd3effa5430050afef251e2f9 GIT binary patch literal 1132 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Se(r;B4q#hkZuE|#rU5OCeN zI$mPG;ZNUp&8s)>P-t_^I9vE$o#}Ythk(;pZU`jT*v(gb__OAi1p7DX*$3>}{&%u& zzqC9&e|Jf$f4kj{&dVytwry^?#5rC3>9$`%l{Gnw>pBhfPA7Fu+4A4#_M+V9o6c>C zEi(VRq_}qboP3VmKXYFvlz++l6>@n8U(}cV=^ymg&Aj7if9hav)AtLXv;sQvp`@#fo- z1@eo{`L{Jb%=KQ8bKUJC|CQ&vUlTk5K0&-{Im|C38`PuzOdhhM95lehjW(daE*z<)Vx z#n&x%@^fYWXZ`$ggQ6?W?`QGwdFo z{J4Ia|M|y<-d4QVzrHqa^S6S%;`x8x`v1Hpx98phA zTz?hsYOH;|>-J=|H+vT^*?fCh*te1w%g|g*`Eo{Nb@>(P`ZBxCU*G+l zX6)IVR=Bx11?a-`_<-*%>d%d%-=E$8yt1H7E&0vo1pUqP+2!k5-|e~Qo&0b5>So=9 zy3d0Mo$uEXwr%Gr$kEjij*i(l;iYJ0ys@8XsRy~XB#1^o8fMXg@n_w}jb(>o%-yn7{vs?(ttz-XGhve@#)W zmwEa(p;W1K!0MVtIR{?|G0qHSrx z<8^ymZ{=L;`8J2U(R2?H1*N+mrs~~GgkD^LyV10U%ItWm@j5y3q!ScjH)=EiHPQB0o<^>=i(8&!WVPiJ<_?2wmkr&+OoTSupPv~qtW{0!G!?qob3O+wtuq{n&{pRfwM z{ihXnPgwGKa?rBm-g|#=UMMi;-@o5+Vlly+6QhnD5t~0Qe28=Z5t4VDojb+tVyS3KJfrb^|1G@nrT1~n zNW>JpuII(y{AMRF2L$iktFiazk9wQ`Jj>oY?munsxMj=d$wAwed++_h`RFKP^~v|1 zdHONNdIvWQt{Y^7@t5?L_&&3EYA)74x6!y)UNnE?yDB50QkqT03w`az{mOVKeKMS6 ziOT0;?;v{avv7$=xW?PeB5yS{USH&GCBFUuD<3~P`^Jf5caCj!pL1V!9rtZ_%Kg~= z)IH^X;huKSx<9$s-0SYo?t**6z3DEx-_Bm$)y2{w&6;o9)7{7~WH@U-(VCUcYd}oA9W^d(4A;OXZq)sV!G7o-K=)%J4_Twauo)#8sXU z*OI);T;LsilWFi&dZ1qFTiUiY4$38-Dfd^lYwgC}a^;(F<*A4{a=j+*km2=8e{1E1 zkoYRaSL?6GYVAU8#E3`2@z$GkTNYYoCXH&@ z|1sn5i(>nyb2%or#<+jxpEr&hBwUE1={DW&$_ZG!%QNtL0gL7fShQcjq5%UIEf}z9!hl5^1}qveV9|;Ji)IX1 zv}3@cAp;gI8L)WD;#Y%ae-g{zCRWTrgNBn7nhxN2)&U$ZJAmVH2XMUa0FEaf!12lh zI39Wc$6F8JcqNm{8d&wKyLpk{^eO}^#fihf50pC4|t^o z0C=Sp0C=S(0C=S}0C=TE0C=TU0C=Tk0C=T!0C=T^0C=U90C;36h#prIz2-7lZNl0= z|KSWQ{{V}mA7GK}11yq!fJJf-ut@3w7RfxoB8dlBB<}!=q#a<9tOG2Pbbv*24zO6t zwPsUZWdf2im?2(m?S%qaEM>@IDMJ=Z8M0W)ki}AlES554v6LZ;r3_gtWyoSFLl#RJ zvRKNH#Ztc4Y|5)lKvD)X(3ByIr3_gtWyoSFLl#RJvRKNH#ZrbWmNI0qlp%|y3|TB? z$YLo&7E2kjSjyFAQ(k2Pk}{ZqrVLpuWyoSFLl#RJvRKNH#ZrbWmNI0qlp%|y3|TB? z$YLo&7E2kjSjv#~Q!aOO2L7kV|92nl$p9H317v^fDDiUGC&5%02v?yWPl8i0Wv@a$N(8217v^fDDiUGC&5%02v?yWPl8i0Wv@a$N(8217v^fDDiUGC&5%02v?yWPl8if&Z?7@?Vt7zBd2> literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/stop_restart/test.sym b/cinema/gb/samesuite/apu/channel_2/stop_restart/test.sym new file mode 100644 index 000000000..dcdf4b403 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/stop_restart/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:063b RunTest +00:1f92 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/stop_restart/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/stop_restart/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..842c0c6271f3318bea1cc3b6613f22f2c6c9c03f GIT binary patch literal 2089 zcmX|@e>~Is9>+VCvr26_Q8zV9KQ4}#E=Mu!kol3v$*)+g!`6=n5-Kr2`p(XsN>2H4 zi&V^zlKfg>`XMvrN8F4uW`4{)!!`^v_S<)N?z#8=@%eoI`8+&kbW)EkK9e`_4B$R#n8HSkVRil_fyG5k}&s&vzA*MgkLtJdff2p zCr@rwtX#aQGQPIDsSIaTa%X+Ihe7AC=cEdV`<^Wf_KZ8MX!OoU8X4KB)atK_G!iMq z@30SOsk^$$ag4d4;NgO}EuV1V@t3p8qay*D*tq~J!xe9p_v`|?eMC;;D@cBaH+&9T{`y`NHp(L-%cfv*C0(OoGh)$b^m`VY z%??b$zO8e831k{vx>YL8FCFW0G0Tb0{D2EoTMNfFejL2tCO<^E;>?vkmAVTmpy7L` zY}F=vtvu{QUI{&}iJCWTrFLiQ0Jopana7Ng?TX8MTbZQDw`1)sS%@r{DLQd+Ciioq z9V*SiElMj+wCko(XM3%_|UbWnZ>vyiF{1pAfc&~P|qmKU9CO(yO3OezEGWu>zOqT8Jgv?<~p zG=kk1J-cme^K2IZn2-(}X%vhw%;7PY4Mz&NhI5i=n>7VjwKMJXSo|;;h6P_aZ|%tG zfMlWL&3?5Do=l-*a%F^fP)4JA$%`sHFuDhCbn{RB+h0RNH}+Gbv{8E9DQ1BEn*M*y z-@P3vLi)TTCS&f;-}Mp{6du04O7=U_0$>x=*xfDvKzBz@wuqw6xc0aDF=6ta<*Y8* z^p9;~!T>rr0R@&op^d~HHa>Rnd+N)++rxUMb2?xZ>4D3Wh1gazL>{`^q6j+p!=Orp zjBw>+RQiq0501j?JH0#Y6BqwT7Asiodt+!2h!Z00uW7}Qy4?skdw^ASoFXRJJYLr3 z!x1a`^KL9<7<7~6O1tkv?M~Gq)2kmv0isoof~(+1S({(MUd}ITs%l)*#+3#`kl9ih zVU;d6zBMNsiW0H{|Iqw;?pqtNck8MfX7T0f!#tBL7z(@toge7V+@3p%L4LRkRcHu# zFjN6uMHlEk$OvCmvsbnI00)l}KIAyVQ7nnBA-0Zia1LOF)EC}-tb?7Nh^%>BN;11g zA%SWuK+9|D0Z@^}X|(;xobbOL@)A67PEPchnRuouhk_d-g!Zo~cPnw!;BoR-lh$c} z1j31&s^DTqaNNa$OGm9@z-4J=_|`o=BkdD%9y zJMF30^${rlqBh&{fjBtpV`8AMqx@F(LPwh+lr z#UM+FxiY;k*l&DE$NC69aKoF1OXGVRTp7T9Xm$r=1))tWrM|?R!&grxu&$!=x_CnJg?Aa6~KgCrlOTfx>-EUDq!01(c1C({PcvsCK z_XLaPwzR*`%#AOYOcq_zNQfP_UfxlKne-Y>zK<^OItxoF%X5oF8EE%A4w<&B-IF=kOd4@S99w zbEcwk-%;iOTJMgG!HRnh!|_L~Xa(R=@uU0g-dFbT zT#n96x2aPb-wGk~b9o$|*A^Szk3p7J;4%RC4PJWR((1i|n1o$H%+s3|;C;QydfDzF z7N5^|jmtcG+$*uBCG6E?%HkZb*&l^luGB*g$Knx2A}!% zF*0vWkK7;L?EL>rn~ESe&PU@pL92SMYQ@fPPV{GA^1TDF0`yJFLAS<`F6TG6!uKM! zE6gkL;GX^th}VUwv7j}4*bxCo1Q*}?Sx!8=Ib{v)L$)dJaXs1W>2!6DXyTLSUsU|^ z0~}Ers%saVP0%g$On)<^-HkCF?tOf*RlY5@>G?k52~WMlC147EdFH-7OigB}yU`Oh{v%cnDZZX8{Tl)g| MVorM2dJri81`?HRyZ`_I literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/volume/config.ini b/cinema/gb/samesuite/apu/channel_2/volume/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/volume/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_2/volume/test.gb b/cinema/gb/samesuite/apu/channel_2/volume/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..34b005a47424bb27f8a616135b9104dc6c05095d GIT binary patch literal 32768 zcmeIyPiP!f90%~X+1bgM?rvt2G@ZzroeAx-F481;a1X*S!Gn}WLFvJh$Ra^RQYE!044Y}_AqSy>mtwaz{vl~-i&1ucGn2HzOZV>g zm&{|{@AsSc-h7r_LjKorj$Eq=*Z(M&mlNbb^i48H;v_+&ROY?+N%H3MM15`T=lR9O z)2~h>e_vj^Ise(>x6d2@5vzpr2q9&oe1FrdS90;q(Z+}B4!@se=9bHo4=VmmlBDE{ zb~%#o>Q1OT;pk6m$7;v?)B}xF@`GL7#@rS4p&@^#-gE83=%cU;gbc}(L&c&Tgl!Yz z*9Ae6WLZ@o&y}YdwJlw+Xw{5w=*3epxQaaxRy%3pw7w`-8Ri#_)MFi17JI%RCY8W}cX|{Qdl* zW%*-p{(W=PB*f9nkHXOjDJWLKvXmekC#;KNJgz81LyzbEX;Cbf{r+@XPwTq<+}X2^ z6OZ$LW3uGfB9E}nJ@`D_!tZySu`#|}JT0a99(((TrwHo1=Wz^CG`S;CBB|@6BAHDSAvxHa zr7d~Js4U!y=WiWU|8}>HU)XW47^!MxK4}gl)PKB*h;})eBC_{&G`NwjeHE=TkqNBb zsIZtJu;w;vud>c5;$A$z`tHXU9$q*~U!iYMhkiik>F4xIx9NUF?vdva~kTtPbqP;NFc} zWmz}x4GRhNFW37a>Mg{K;zon7kY!CTAM;*|@VDe|8-5>m8Y_*WniQkSSg+Kd$R0d8 zptOr4PocK6>q8QKucX6L6_Ur?S{Y77$E=w2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izzz!L=Ae*tAp BKPdnJ literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/volume/test.sym b/cinema/gb/samesuite/apu/channel_2/volume/test.sym new file mode 100644 index 000000000..bd3d42fd4 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/volume/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05b3 RunTest +00:06e7 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/volume/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/volume/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..c8e022e1856fb0b467006640e7d5cccdcd9eb1dc GIT binary patch literal 569 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|OI-r;B4q#hka-qVr}uFgOIR z*yR+V{CZBEi|ZAYz>W>CV&;A}ZJSsbW0NM8oO9bu7Ko4S$o~DWFml?*>zj1m=UG-w z{P}y@?*OjD_e*`))rrw7su@=r7N-*!B>JW7I4PlMhOVr zRj=3R=1yM-zL2phD0`uAM1l+v>6Fc(aHMD1i@p$7csg8g^$+dJHmoD@xx1z-A|~(s zKJ7iZ=lOl_d7gYoLdgHRogvq2+z-E(N=s3)KllncOClsn_;~uQw@K{g(sX@w^~Z(9 z#g|@~j{UZ@dUN5U#jl=H{~=cK#{oi0pPah4q17wd$i_tDU1^)$&r@yFW|Q|T?oEuu zg^GMBkn2lCrER}=hqWWMBkt6FnN)HkeF^pK73qO0d@bFzjr_!JGxCIt3gyv4LGYSk z5aQN3j^_nIk{*r46vs_WxOq{`irMT`c52Enc%J2zqGsqEYkpnNYi#Uq;pPp4t;h4c zNJO@WzrLGv6JCAiJchz?3d;*ZUJ$a`tdY;M1j~DCwR-<~&1?SiWnDYw@1`9q>+XJT zQP_jw{uXZDG$$w7a*-6DVtcgq_fO%~cg|y~;jqf`qNuQc<)Ep! z1(x^LYW4o}MX&k$>Bfm^f439Uy5a8U77fGgz4PxG7mI{6=ihtwnI{NIkN1!FjFa)$ z%VJmTq*}RrE0Vi4ApK=;sXx=BP9ad0$wEvUj!F-m>41DG7$<`BMbNw9uYVq_(lF&{ zw_2egm7~oq+Fhl+GsM1dZspDQ&p$YS*m~YNWtrAH)`Io1^_g|q`qH{$U9*0%?pW*A zuhxdOY2CH9tnXHCA59WD!0Gkwy%~2hcznCL{0Fz* zTt4eP@VH5b)HC#ubB7)3(Ate_Hak>?KE~z_s&0(UQi09IX;R&wee{4T(Ud&etPbzA zk=Bh}r5QWtjB!!vPuux6=+r`LVZFgt$k3*f3ppro zni)7eEOv*-rwY#%PwLKxp;>ml%C6VgWw2|GUH+3*Z6-jj#y<_o$Gd5t2Qrf+m%YWTxP#Dt=DGL|KVx9#>rKArs@0?k~z1x zDaRN_Xog89)rVAMOC3-xI!HMus+kVQ|3@IwF0j8{pr>76U%LR`F3{aB5dQbT8@mof zbCMlo20F;}caTYRkm>6n6Yn4+bdc%wGIn3W_CHDJApijgKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb u2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uXQo?7soxkf)mf literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_2/volume_div/test.sym b/cinema/gb/samesuite/apu/channel_2/volume_div/test.sym new file mode 100644 index 000000000..8409a414e --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_2/volume_div/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb RunTest +00:05db TestGroup +00:0804 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_2/volume_div/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/volume_div/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..e25e4f2ad1ff1039f70ef66aacb09c3424697c07 GIT binary patch literal 1021 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|WCBPZ!6KiaBp*I2J875MXf4 ziqFXV`1^zIPo?SwVXEFt-V)dRmj7PjF*$Jo>qV6_pKW}DJ!UM+ocDb3v&a3@PpAGn z{-JwrWxky~XYKM!(l zmEC1sZ+i9fPw#E>-71foRF-bluAA|^@@95w=gU9u3h$hFx?`8r=?JDvg_gpT#Fv`? zKlHYYTd}6DE^Pe{<@#fvwtxHmyZUYBmwWkH%T@m=YiCHbWi1R@cm4IspZoXi^E>;0 z#?S5Z7M z^`5!H*=)GkQAAHrGw&nQuYx1XW?^rB* z{xPhJGxLZxkS-rq>IqSC_=U@N(_|e@*pZ|Z6vGB?rk6*E| zvn$o&yuNYV^UX}X9h|>s%Aap`66f7H5-m+!w|?Z=YBoQwsbr7X|N0rrH0LQ!_nvON z-{9XDyNI~cFKY`@b}YC0?DJ>#m#z8Y^7kLyu(y@D&HjHu#qWfQn!2t$#di~X+S}Ls zV7xg4Y{{O3PqUKuPoU&8)az!`^*QV`aw zUayhP-lh)xL&mD0><|AE2{J^aQ#yx2NMqR_6~q-@hYPO$pk3L9RTAIbrCSyMu<-tJ z-`CvZ-jDmfmrs85LdXMMCdrkG@a?aK!cvg5dtWBABtU{h3P(?$A)#wagM;_meGySC6zuttNG6iW z7>}JeVVZ#eo3BmeO+#eG9cLb_?Ji-@H_g#e78i&}5w^z8`tB~A@#cO^O%ydYUr{pb zk=bu%>;X34$=a#i>+?==*VBz-WDp0>xq&`icjV+jCpo$I%bST9+ob=I1im#oXy zPu5Lq-TK+uur{q*)|U14%8f%kB<2zHn*V5TZ;E!Av^y3S^k_8N>`_eG8;dzTcBl8~ zc4PTBVZE_D>s;`NN&B=(dZ2ofZR)_<)yrkJsRVtP_3hW}X{?vZtS?M^v<=!xAJSAB zi48VN@n#v=IVqQDqMWJ@2|@Mua`h{3^#`ApTd%W(1Z`APzUuQH_AJ@6bw7{W_2qg_ z4T;{6uSe<&CieBm6~8z^Cc4KAj%LGZb-quFhel`xw2{lWwS=c+(?*EtWK$t9Q z9{RLQn8pC(qlxdr@jX3alMVK=FnrCTebwNMSv}ItDJ;MQ zk!M)Y)#td(b4s#GfZ^C zxc>J%%kwMpEuLX-@(g=}XV@8@VW)Y9Sv& H1A+2i13)?d literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/and_glitch/test.sym b/cinema/gb/samesuite/apu/channel_3/and_glitch/test.sym new file mode 100644 index 000000000..21f313c3e --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/and_glitch/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05db RunTest +00:145b StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/and_glitch/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_3/and_glitch/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..9a28b07eecf420781baad91eabf32e1660cc5add GIT binary patch literal 1026 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|WC(PZ!6KiaBp*Uo2a!AmX|) zdtbo*!26$i&omoPaoXawr>J<-ci~4XGjC+=^m6VgocDZ!;rZg8kE{M|vFuC!bKas) zvE|3)50lN$Eqg`#xYk~zh7y1>i^AO ze;t~GKAe5>{DJzD&(#NPf1YdN@9XyY_lEb=*FWJKZFvsgjF*ZLp6Pn}{Gw*n`DOMS zyfA&5mBsz3^4aS0cdoR`el9&P`?G{~efXD&Wp%|T z@};7GUJ2e33=D#=u^txjTYNvi-TdOwpBpEa@69ZJVZOR#(t5*F+pipaDZ}_b=H~)t znMaHG_HETGnZR$p&gBQ!?S6^vzdlb^$bWCYYR+@ZvmakMi~3(u{p{bLFn2j$n7Wzm zOt0OaI)C33l`Zw>(>BpN33O8Bri}czwjhI_-(Q!}o^_%7;)e<5>zjjjYsBK7W4E ze7O|u`DQa+%R$D+zGD|pvbDRmLGRb}npAs(T%<6~GZlj9o`+r{Tdhx5{ zcje{Cb?txVzMgabS*5&AU#0Avf*|p@8Sgir`&2B5{vH0&;&)T$e!gi_ zy20X4{v-K@ z6P-*}5;J-bJZNcDlpZ{ZEK)=yRa%R}uo*)SIS38B6ua2?hoqq`M%nevOtuZ4vKKFY zUovm!{oZ%pd;4K`3He{QX>zT`{rG#iyb>qf;aAB#iIF%FQkl2jCW#v>llArWpO%)F zUwUCO@!QJ!jipbPzkX8tmslkjhX^Tuq~G1r>y=z=Ypn6Eyvy$AsJ`v6;=PJ@lOQRv zqFfB+dwS#YZqR$f+VR?PuXIl#mHco|uQq>KzORYj$afsGF!rFC1wux|sgYt)^qXlC z;>~lMAc&$YKO9SGjvE{E@{*L3a=D4z#Dr-I0?Vr<-84AXf_bB$vvIJ6mp4teo*)Pk zk=P!=`d-pY`15<`F;$LJSzZ(iqL|C&%tDSOSl(Z&)d$b(ehZ$TGW3(dZu-e7!`siB zGz_oz&%bZ1>x5Wp`9ZT(LJE>mFbv6WmKDtNd@LqOBO?#TgK3^Gm%V&Ct)^AgeB$g` z%ZkNVUYjaeCeK(Fd!72Rtz4KTa&uc6%Nh~?z6Funb}Nz?Rt|NQ&Lr4k{{x%ZxZ`f)-sqkW@YqhvJk zvec0{qg5{5jOA}0lK*mcw4dn-w-~A_WGSH!#pS=<$&hj}oFbz8W!S$Fu6+@%Ql4@& zs#R!2<7jh-MyoV=jyUHR*53SJ@&4jb`+55n+p^!Wm+VjN&+SY0SN3K5s{M<7+upQ) zwYThT`;NV1f4_F?L_bkNoKcUS8W_maUW@iADbC1bGJ6%tq63QJSG;2Q)NXV24{o!$ zI`2R5m_-M*X?n!H%?@>BmcN*2%laxVZeM<9-)*mm^wnv%yx#(x#h_xG#p-yJYV+_&)A7RvSe*!G{x(eqk`4 zJ#=(Pit?iq#pgb*0|S$hr;B4q#hka-z4I13h&WtS zdL{bEbdz6I0;}Msm)rhy78jpe;gFwDxHjl&#P!n1X&X1|oZhu=d)0p1bD#I@oAtc1 zXX8H8d%qTbzWw-Lwv64;#82x!U*5IuvdP@}$0f|;=Znj)`<{RAH&DLaj{nW|-{$Y{ zX8t>$zQ4aM`2qXw|LpaL|J3nUocUwU{_p(zNi+ACH1DbV_w<8}@8zZTv(mpA9kZB! zeA|}WAK!$%Kkv8vav77&T)+Q+QtfN&BB#B)`Y_n0=-=w%TfTp`{eAG#Z{_Oh4b>k^ zv%fzmyj=Zu>F0L`3y%kXG2LgEQu|`_-wjs#WxM6f>hCP#zkFD%_Tit+xfg*d-W~it ztDHZtYFqHDyUd^W=2dn*j+13eJ##2abz&6Y1Xvlof$+-p-iZ8`~Iz^bbCmhj154>55DUJ_$Z7;EY2@DG1xG z-rhz!clAN=LC30~?7=6IAVWktWq(k(q_OOwh_J%xaKY6-r0f1*mBe%JX_juVUVZYx z?@90JJ?Hnm=bU^d13evW20EH-(oXy1fL zSS%{1J*n=VPI-&>_OQIKyw9GxrI2E3xVuN4KP%r>#joY-mYyEJ)ATeUBjWT(E+;xo z*9o!ff)EIZqAa(@QbZ8O$L+i%C8cC?GC4V^>wy5vXYyHH6IkPQEuCd!zJ;CFb+%q0 z5Riz(_TcN=Nju@xx6h+z1R=xnqL>!NWHPCzlPtmV&RWf$Kc96Pe|}oa9^kuW4@_(J zes)pQ?A|&5j&U|ih>&xH@Veh03`)|-NNXI8`2B@~osUE^kxWK^ z;>Z!h2nJbRoz5G&pEX`*9&F6Fu=9p7F~OD#MgkGGM{|FE3a7q(9z*r}RhE~e4ExIr z7#X|3^3Gb#odGGZPis^CiSDoDJSBxJgtGBY`LD{9M>*{c6S4Az*SQH?{M=ij zek#y*wMc!cKpUI1y+pf?66@sgl{Y^)ar?xO`MmjxX_)Vr3+5;0XXY96OY^LG-u&6T zX0DsRm^E|5yl!rq->zKU-$xXWpjF!s_V=e~k3oBtu%N|avF#bjp#6&C%-ECOgIkT| z--Y$Y^1SoFBLapWOHHKr`BjUeMpsQL>Xz6 z;@fSwd1IAm!b(*}g--bot8&3xDf`sidY!G1pp8n(S9#IH-X(jt{QJ07U#{omkl!2f z^#!7xi9JJcsog&|nR_mOSgU;Gn_<^$?0TJDI=g1s#h)x?k9x?t@TWe7oYL%XtNr>e z9M`H{te@F2Gvmy3TwPiFCP9)9+*Bvnc{UQG<)>IdIldNemf8}d)vgSi@b=7BWA$FS zywXRa!Tw8n{gnLSY`rL-w5UgYgSOS$%5(CTb>l|uu6FM@OwOqu`iw}FM1u;9V3;PD z;$F2uA7=lfmB*%4FO3?N_dD*FNVp~jT@wSYiAP-%ao2?6nvh)++~c2_xTUy@TZ-Gb zrMQn$Lnw`9xEE!lE(OSUYVNvpfZ;=ifTLjVF0fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= r5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0ucDm1gyUS&QaK5 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/test.sym b/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/test.sym new file mode 100644 index 000000000..8487ba99e --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb RunTest +00:0a95 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgb0/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..dc270dfc354061eb11593182d2efb200fa3b50b8 GIT binary patch literal 897 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|T>%r;B4q#hkaZE{ZKukYL-o z+5d(0tL#nU^PX<_lM)hUbuLD-rpsc65U=La%6aWgmGgqVtf#H#`5!!WxkI`g+pMR~ z543*1npB%)J$=amoAZ}VOjlcd-l(j4*<|hGHIL<;-R{Fr^=!pE zrvDdqo}Vmp{FBYJ)X4nfdq3?=e%*K3ME7*j*P73H)&JM^9`Es;^03_<#LZ%>rCw*7w1+fS!I#67*8e))c5`sc^?ZTlD- z&-BlAe!QXP^Y3RB@__5+a z$&bn>H$Q)k{$g!Yb8=Oi-+7z!e|GI&AuW zlib0t5A>fLpK>Wm*4-si&iJ}Ph%`Ka&xV*fm5Dpw4@U6NhBhW57Y^JlRiZ}ajq=(nlfC-gZWqV$eA>+-|r zmCu8;T4co)+WzSHDgN%kyh*PfIAs>$whut0>zeUv~7gXj7!`@G(^9`E=D%37YTelF{r5}E)xi<%Mu literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/config.ini b/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/test.gb b/cinema/gb/samesuite/apu/channel_3/extra_length_clocking-cgbB/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..74a355af1376bdb5575c05f3d447f6becdb7732d GIT binary patch literal 32768 zcmeI!UuauZ90%}|<|d6bNpIS&-p-iZ8`~IztSvs6hj154>55DUJ_$Z7;EY2@CQc;78gR~e(%d+c#kn z5zERMPr9c!ByaN8?pF6#_uE5v6jDwP_w=fB=jFSq_@#W)(lg`RrDq5k5vNA-dC@6d zC&Zo?gg`(PWx3s#qJl6!Zs#Q_C8bi6smV!Q4+K~~Tgd5}z>3dnnH=l$E$qCmv-JXj zfJ7v=2VdV#+6iZV>pXf^5V9;UiWyN%rBZq(#S$#8CgOyl9tgl$tlC&^L~FYC`ltD?S3rk_ZN$HJ{rwNvswMI zqel%R7-V^Ms$l4TR(zg$us+|y&Kt(W1Y0f`4Mf=f|vb-c^*(q&**WWvN_vAkFS@R{+FyAug&5z7a%(Ld_=6Um?`J;Km zTs40(*UWYErnzB$y>$IRKT$k_R_{DCFp#Fb2JKTKf)`+51S1wxYP)WL%jSZ@HjEz!}jYVj`x<-5G1FB4;%1E=4 z*s9^yja8vZD_t8ELh^4`?UJ`v^{M&Q23sLXo3*sB_PmF^OZIO0_i?ka*vQLazc=jb z55z*rJ^K<;r+;iR|4iYCR{Ov=&8}D2^(wn`cFnMhKUv8g^NtS3jSPp}E)#7d$y)sY;ncW2pvw|Ax zHf|~Ib*0|T?Zr;B4q#hkaZq9-j;5MkYz z6!t={boQC{i!96;7q2C&oc*)uV?{ef{y0v2TK>+yeIQR_tR0;-$%-_Iz`uCul(vz^sMsUv&hd(ca`o> z`Dl7@CG*^-*MB}Xe0HwV6VQ*ZbKQUFa{ro_?QhS|vw9!?^UyDw^RIW^v%SCP_NT*f z_s`|;OFMnO9V~K6-k74g2+3<}v*H66$_fS?GW3j#843icPzt!oR+` zoBcQM=Ozopr0A#D3w*UYD literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/first_sample/config.ini b/cinema/gb/samesuite/apu/channel_3/first_sample/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/first_sample/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_3/first_sample/test.gb b/cinema/gb/samesuite/apu/channel_3/first_sample/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..5bf9cdfd74ed5edb16c9127f4ef7c54be3829ab1 GIT binary patch literal 32768 zcmeIzZ)h8390%|x&EQ!QMSGEv?tSP=QFV5RhN>^k;@Ri_;1>EA$Q3}F( z)$29Vxl>T^g^X1}*$ZEZ1SulYDVsy#NYAnteIcy!bZo)ZKeQ{`uu9@{cgci)apoPy*nZ~hjH{;lp>F?)H znx@|e=if6n3_@(J{GizyAqCkin5G;w+YaY>J|36leE#8hFvaubvY$_-w3Mbr*A$;#mvlnFkw(Tljg~9v^4R#Zy9x?a|slJVh|SdmdZod7b5DS!2K2L0j`D zSUy;*)rZfQf)?&)S|=vM-A+uJmcO4rX<2?BoPW=_R3fA~_x^LwJWfb@v~RR)l#Gfm z%N^n=y|Q>Cp1W~C`P1FjZ_=Y)F;Z2@f@lmSl)t>mh42&R6~7ogzSCU!o!e-x z%m)uVX464^njZ3QvqK$PzjnoChsw}LS?!?i$5@q0td^wx`X=q6kLU_bsrhDgXtxcw zZrm!(xH)fxODKQ1-nUV2F{T$c8f=9OZF;$wcQV3WC405u=W(a8(kLn-9~EQ$!eAnE z;P8;#$&XGHpD&#{eVmG7iicP3z*N0kD9hs4Ox5f(5-r0J((Wlf_`^jK@ z;F{IApnN#nP?Ym7jp%RCj?IqRoU-EvUo)a8Cdp+zLZ6igdzHiLNRwt-9J_z@pJ-m4 zZZc8kraN@dOU&8c)9elZxA}OR`TcF?yV}g}YcnsjneS{f&j)$8r#F04!hZnhApijg zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< L0ucCb2)KU(P(Uzd literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/first_sample/test.sym b/cinema/gb/samesuite/apu/channel_3/first_sample/test.sym new file mode 100644 index 000000000..5a9ec787b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/first_sample/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05b3 RunTest +00:073d StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/first_sample/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_3/first_sample/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..d37796fda4d437f9afea1b9b6ec982b66fd0f564 GIT binary patch literal 558 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Vn%PZ!6KiaBquIp#fb5OHv{ zo+Vs$`sW$bYB3FtQlU(@Lw*%2qe^G<8`YhtkW7B_d!NmX@3lQ2*F66Ic3bY_yW4V4 zZ@RPnvUGgazst>+m(Eb*pBsN%;`Oe3-%f9`sjZE!*|kr8=iJv%i)NmCFZ%qw_%E{$ zJL+scU3C0h{NSbXv|uLx_4~g3@#p^YeD(L@mgDkAEI%{Nec*8100cW3!+ zc>nur)nD7s%cbTm`s{yEe*YQax%Kux;@soU|1Ygb*mwPpyid=8LZ;)KGU^3$Mj3qv@6TS6#*LiGZfKA5kS4(g?_t?4A*4Yn96kv?^uT%+Eg>K@ z8{KSA60`as_#mZGQ2OAL$RR;QQl+&hESEL(A&AhxB-q2oKO_xpG0L5@JGnOazklH_poH8MvMBuT`~z}xST)XkO2#`^kCi_6O| zzc`utZDsxD;>XKhJ*EFktjgOFLMlr?-rY7D)qG-mtofd@$L=psW5;Ek_p1I)ie#j! zdO1?)>P{+qy!M;*6ZI2**FBX~3qxJq`rH-ezAk;O+;Oeq*n?sf2^p5AhD#+WD3(Qt zKQ0KOC`pR)uq|f=VQkEgm*u>i&rjqhCM-)7S-e&@EK^{GkDEnML_(H_haa~4v+;PP;>TyRT2|AnC(oU; z?L>mb>r-XhinGGUnFnk0CH#2X9v^4ZC9-0ctg>fwp#OXN{)M6Zhi$+FKti++R5Eyx_d**v`AoqVtLKnX}}4>0EKHIlnl!oh|2A zXWQ9v?l`;7cWbv!_7XKBn2pZUeSHPmZPOk#BbWmN1N%L)P5V?e=+!-I8C_P_3YkD8WX4v&QyWU`z#jaU)@ywcWK0>Z$K8>m5lIg##{^$G5pxH>X zdgegSOwe=a*4oB5Ig)?mu0GE8vy&UCKg|Zz`HjK$P)Ba0k=9s8w0pKO(Cks_YrUjD z(RagYUQ#}sZ5ql&mqzqAX~%X){erUR^1m69CL|pcJwl(ANQPWxPdmhTXs*rD{#B=2 zjFsV~`t|uuJ-+FsY};ECLnI`_CM3cp91fe1wn9EbDr`bBY(nC{CoF90La1}#2_epb zCxkc$o)F?3ctVJC;0YnlfhUAG2cE#s!R_j9zbyOj41OR00SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ v009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY=v1l)fB4Gpz` literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/freq_change_delay/test.sym b/cinema/gb/samesuite/apu/channel_3/freq_change_delay/test.sym new file mode 100644 index 000000000..82413a291 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/freq_change_delay/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05bb RunTest +00:08d5 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/freq_change_delay/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_3/freq_change_delay/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..9c3996d97fe8bcd1b23f4369f8a163dc7ca90df1 GIT binary patch literal 643 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|S$nr;B4q#hka-1N)i`L>w+A zrL}H2wr=xh$DCKpk{zWNPTR(N%=6ljynIQJ*EvhmqH{~9#65p~x=`lyU5h@=rJpox zi|R`E?aO&zw&UvC6t4Gg>h9FVTg1f$@34Cwe*Bdz-|@FIU!_0JW)Wcizxmg96Q1VJ z>(5```0LnY=J$K@o|i}I9oYUtrj-{BJfw(R+#)o1yaPWkC>=3io;_r3Jt4%^LJiualPK2vaKUgWM5d(Iy$C=~zO zRe5p6?++W2)^oki{r>aeyG@@9JNYi3RQ+}Oc`aYt?xoMYv)6y#oH^?ileO>V`Qc?H zcF$wPSJ?iS)ie74_58tiT-*2BZa8b*0|VoEPZ!6KiaBquIc6O;5OHwS z{PJ)62g|FiD?R53NqGeSnh_a!NqzQniQcW(w&gxPwJkS$t@yk9^WV8YzP2m%pX%r0 zwWiPSTu<(~UvclOW&hKEHG7NC|M7li@AsO0|B3n%zCUTd(bZXviEyF{qn`_lRkewRsBr(`bC|B7Jd&b j8XvRt36C;}2?RSv#?*O-?*!I$fnwOx)z4*}Q$iB}8I|Os literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/restart_delay/test.gb b/cinema/gb/samesuite/apu/channel_3/restart_delay/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..21f6777e7b6ee37e8d0777e200c8d861bc848057 GIT binary patch literal 32768 zcmeIzUuYaf90%~Z+}>uJ-d*;RG;ZX)+YRk;9@1R!!FyP?M+j+<3WrZZA9`RtiZ`s4iK z;;S!D#D7~_y*dBM;@8g_{}QVP^AI7G(d+j%ij8VEx-r^(U)^TUv$VMBvc>yV{tzb# zxvE_X<$8K!>UJ>lY5hq32w%Fdk!o(Jr`MRftUfU0Z`8Z4RTzEPtO6l#dBuSQ4_0e2O3c~0p&sUVJlFg21$Hy&8l32c8E?TC*S`ar2MK%wP;Q5xt_LC$@ zAqqPq*q>+e3_reeA4?Ymo#o4NL6)=GtX0Ue43_Wj)gFWTqTho0Nwat?IIVbW(&Xpy zplR~azyGdzu}FxmR~|N7C#0a51=CdgX4^qr6r)i^$>$%T-k`yyPUA{A(- zQKb<>psg+1S)<)&h4`IEv zJm(iYWz&=~MGtv**rg7w-MH$qOJ(SjZ0(@I)7UDN*;<138ymETK4GXdspVU>!JRhL zesF6vPMA{x19@^35uxtg8y)pob=&RcEgp{>A^L($666Yd%OP#JMKf)Voxj>ti)sEu z^W4pFXv#Z3LsPa_W*_(rB<-cBb1y}rU*z`my1~B(j1YhT z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ M009X6R|MRD0G0_w?*IS* literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/restart_delay/test.sym b/cinema/gb/samesuite/apu/channel_3/restart_delay/test.sym new file mode 100644 index 000000000..5084d7002 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/restart_delay/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05b3 RunTest +00:0760 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/restart_during_delay/config.ini b/cinema/gb/samesuite/apu/channel_3/restart_during_delay/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/restart_during_delay/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_3/restart_during_delay/test.gb b/cinema/gb/samesuite/apu/channel_3/restart_during_delay/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..0d57843da43ac77e7d429485cec3d0cdeeca59da GIT binary patch literal 32768 zcmeIyZ)h8390%|x%_Y6INqR}UdL6O33tP55DUdnNc{0cRXqN?f#kq-* zxKNQV26Bn6sI={k&a`&4cGOATmq{hppXgF&uSgG6;cMxxrRRqqhMp&6K$sXP76mtS zoe*c8<9J>WB7^uo*K2}Iar9bTPfP66+CxZP&(7oYrd>*XQ zFy&~gTA?A8qs=YaTBV(5h;{zl@>?IwJ(xRUzG%K?8s@v^y!nawnR&_l(!63`Gk-E~ zo9pJ!=7zax-Zi((Z!2FY3D-r%K`Q)*{}89$L+>qqbS9~!C0t= z?~7*k9Z8F=;i1vu3#HSV{ZVL&U2m}KO?K(*nr4^xWVLW6K(59=4aww!=De-W=eu}X zt9P<-YENd$&9tvAuYQvu*|vM?2s_VaX0Y}wTaeGKrgxWGGK2L_g(ZSr)AdxNTdFPh zkiJOolHRx=eK_5yNarmYP|wnqjh5Psv~78RGw#^JBAEDVJfjBa^8$&JtMX*iUJWrY zHabH6G_$5AVriC1pZ(|0Dr4X8aI15)&%QImhNld}KGFWK+Z^_%&6EDL$@$afkUwp* z{rWO;Zae@0 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/restart_during_delay/test.sym b/cinema/gb/samesuite/apu/channel_3/restart_during_delay/test.sym new file mode 100644 index 000000000..298329bc3 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/restart_during_delay/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb RunTest +00:05e1 TestGroup +00:0a52 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/restart_during_delay/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_3/restart_during_delay/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..bb317a73ea02074792ebc1d9105c681ba10e0aa6 GIT binary patch literal 863 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|T>~r;B4q#hkY@1E(!k5MkXq z{e@iV>@V%=U$PyKTinQ6`bxR|fT^Q*kA9iv(n6Wt2Q2zDmxlfQ`PP8vgLak zTDP+o_n-T&x%8*jtS)Bp-~8J@tM1AE zcJl746FU+sciF4j%m4qQT>6wt@AkyWpZ>=j%y$2*`O~$(^n-rhR%vz$XU$K>|F`)OHkD1kzEHO2^J3={%fG+A`>A;Q=c{X1**=^7+<$%Z z(+f5ATK9A7#ii5tG(A3aKQEg7zGA$r?D4{n=4(qo1b@DI@so4ZwS%|M zH-A5K{?ES}xmWT2^~*C)^*7ctv4<5{?o!`xc75*iWj}evxXZIy_3Ib;r=5Ruc0F&X z_49x8FQ&-;IrHb(=B*Oj_}Ys9)?X~r;%Zx*U@=OdhQVjvJNH@s=FW^i3d%U1u6{1- HoD!M<*3+AX literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/config.ini b/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/test.gb b/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..652f49d4f24ab566070fc984901c6367f051bdb2 GIT binary patch literal 32768 zcmeIyZ)h8390%|x%_Y5cNqT9!dL1#j3tNam))Zfu7soA>(iNEyd?ol|0cRXKN2Sf-KeQ{`uu9@{cg_H_j{gvNJ7Z}dQ6k6b>X|;DwU-u*&BR?%##R-5;2~7>nw@gSek6CuKuua z@#2fmPsV;-TD`IG;l(eW(ElM;_16JHD&M|wcca*-W+NM8&3BY-em}>Gn>G*LtGYKa z5|^s#g+Q*aKdNl|v%9Pxt{-+o_f%5N4fply^OuzSy7Z-T$2JRN4~AJFBri?nOC`x0 zrb&pK7X(q1Bt?0+mJ@<7Hs;pLa#qe}C$bY0rYVZNUMm+(L*T>D8-*fY`&+p6rpfz> zq9_xY@8S1%E8Pk&zjGc_69kRdOHx6Sve~Rz$npwa@AYcW{_{m|_|H!n#iRai#iLV( zyPumh40raW%6s5U;dM|;;8_+9RE0^lJkc9ZFT>y#nVQk zm(Mf1A~Rm3=hn*FR~eGsb5|ed=h@7R)Su)D_4Hc0o$AVrGo5Qq2LSzA{LX zk)i8m^Stu@Y*SIr*({*H&bl_b>T}Ar?f=Y>m>ytHOC(M%^LII{jozW(;d zd*@S*e-MBG1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf SKmY;|fB*y_0D=Ed!2TO`+RN<# literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/test.sym b/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/test.sym new file mode 100644 index 000000000..c71922409 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05b3 RunTest +00:0887 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_3/restart_stop_delay/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..6b865f6a4f0fbf142acdf31b05e85c815277a5b0 GIT binary patch literal 547 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|VnLPZ!6KiaBqu1^P8Rh&Tiq ztear#x4lzdE9jQVwJTEj=YC4HT{rn6bZX1G*AmIMB$L;?{%ZSyuh~A=@Yqw++54^bv+j#|U%t;z_RyTUx8MG+ z_&b-|V$Iq6GxnQ*c}P-HRhdF5{Id1*a`R&&qTXZ<_#O7~a% z+4#GAK8o4K&#PGT+@Al|ySHCoH~x%1{y!m!rBB$x?}0_*<533TKzPTy?wonANl!p7 PDDpjB{an^LB{Ts5quBIe literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/shift_delay/baseline_0000.png b/cinema/gb/samesuite/apu/channel_3/shift_delay/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..60bdedff2533202d6d03e8816c9bd218d0a18dae GIT binary patch literal 540 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Vn@PZ!6KiaBqu1!grnh&Wt~ z*mda5#Zo_e9i^;=3p*PxSKA%3*w<0v{K4$ljORbM8J_racbB~+jTGy6G?5c0onljK@W`0@90c_~gF55GxfNsPpam`tBNM-n%e#_OxAKg};L zzV^y^;4By)@>XmG4W2EtcvcsNdsIlp?#rqZhkRVB^ zqFxH+I=kY^PB8LmZMZhfm+q^ik{jsk(q}I#+q(3va@V!;BM+LDCuC5X7%UbgzgZR` zJT3^LC`pR)a4x3=VPu5o%W_uEX2-H)W0oa~EMF@bmMO3n#Lc|H=D`s>-?G?#qA1El zW@iNZ^Gu%M$9L~zX@a1!d`ZenQZ}2l@>!O_^8LM9V^DASEvTO`jbp)S#<2;LpT~oy z$w&YGd*+5gh^>_$G+QGiFPnMOl>KJgK|C6b#bkMK@Zr2K6^)k5JU^AvQkrHxbLy0B z$6_pBpD5W@l(itvJlH%qg6G@z=qTGRmJ(C!jMn+VE&TZIeQZ4%)mgqQYwTA$WNSRY z^8LM9V^Cl6TX3Ffofr>JJ27rr{5&4CEI#`8-!m_j2x-oI_~P?V6Ot};7Y-CiA@RE0 zmN=Mpb-H+zB=Z-ipJ8w9)bKaSEK6Acs7M!o0%g$Bj7w3+%?)>U( zIGfI0XUn<1a{FixQA2`RZ$IAKo1&@j^ zzu+mG_UV)Kuy==D>hRi)t1i1#hCa#G4(U9Ntx}1tC25boK|ARax zZk1--oHr!Il|NnY`>?kV(TnR1wnK(Cy0M)+-WQ~ib^6HPDFadzIf)~ zk$$;7S{N(7R61#TpG2lue~b0ES+`i9W<98^8mB|#O7ioFN-moG+sc1_NcNlc4mM8h zS()-z4%}W@`z}MWkKNNp*?l%ML$&8vKs~e8-wL&5hUy&}TL^be*VBz|rMA*T`eMB| ztj0y<rGh+qiTD1@K8oJkPtm#k6rJ5qk+YwoIlsv5>~e#D4;Uc;0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| J_^$}K{{VhELf-%Y literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/shift_delay/test.sym b/cinema/gb/samesuite/apu/channel_3/shift_delay/test.sym new file mode 100644 index 000000000..5084d7002 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/shift_delay/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05b3 RunTest +00:0760 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/shift_skip_delay/config.ini b/cinema/gb/samesuite/apu/channel_3/shift_skip_delay/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/shift_skip_delay/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_3/shift_skip_delay/test.gb b/cinema/gb/samesuite/apu/channel_3/shift_skip_delay/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..5ba0f55d50805c0d61aa19eb70b223215f3efdd8 GIT binary patch literal 32768 zcmeIzZ)h8390%|x%_TjzWCEs<-{N%%C<_XD(Gr2-R^qXlC z;>9_R=S5MLAC09X$4yRp`I3~8GMVYj^t5U6Jj+*$x@mB%1#u&x5Wp>0z@}Lh_Q4Hw?*dmKDUK(O689a=Az2kz_PlDtY{!$bULJ+E4VDTL@JZvLxuEarrN|98xZa6GU`B5BoR#_0Pgp8l@cV z)haZiakRZdd#kkX9C0q5Uw`xc3lAEoJAlS-~#9o=nX zog1f0(@xeM=i>4oj{8m6U5;pltrlA$P1|lZ;=UMSPsyG(_&hdSYpsGTM8iU4h#!fk z4;&eldZQE5h3AWB4EMvx9J^j)*X!&u*)`9upt7o;3z4gdPa+DrWO$!e@AX|`)TsBd zes0gqoIkVg_WI`6X_9&Do;JnKvz;EVJ;MUZ`OVQzs3$#M?^D@CcwoMsY7NS@^&v76 z8@^$-F3BIvw`BRELqpmdw5QQiTacTM|1~2BLV{e?LiB`4*i()v<87MmaP0oqexx~N zwoMPxq-HZ~rswuASndh-mjC;TMAsE!*A;zTR|s8K#JjGDbzQOFuWb*0|Vn%PZ!6KiaBquIp#fb5OHv{ zo+Vs$`sW$bYB3FtQlU(@Lw*%2qe^G<8`YhtkW7B_d!NmX@3lQ2*F66Ic3bY_yW4V4 zZ@RPnvUGgazst>+m(Eb*pBsN%;`Oe3-%f9`sjZE!*|kr8=iJv%i)NmCFZ%qw_%E{$ zJL+scU3C0h{NSbXv|uLx_4~g3@#p^YeD(L@mgDkAEI%{Nec*8100cW3!+ zc>nur)nD7s%cbTm`s{yEe*YQax%Kux;@soU|1Ygb*mwPpyid=8LZ;)KGU^3$Mj355bgz7l+~fHMvqr68VU@(^?wYRn%KA?H zKJ7iZ=lA^NB5+iXUCNpQxk;Ki#@%qZj4|59( zue>y#_+@eB=G?~%Up=M&O{@}(LxhwIWB1mLdLqCEwrKrO#eg9_Z57%3a4Q4DU3nK*)eJF;FZ@ezPn> zyu2WYq9iHG!?BzagyCVYUY2umE;pJR9knb`y~uuOrsAa527J`T3<>Me_}CyJs> zWWGnRzE|m0`1$SgSehVcyk3$Dl9bEktU``g@Opo(Rv*ka{1(igFpaTbH)CwV^!D?T zrs?(m`FD*CgAiLQ?=)K@q#&CG)0F*Y+d)1Wjm2bnVBq06or*@wWv@P!(o&jcJ$dq^ zZO3A~UY{u0R+P6O&pr4!*utx~?U50_Tr4G~_#UnOgH!nV?eo}rG^+D@S=RW!cF@+m z1h4nkYW2bVlHY>;OzZe~u-ox*)AIK7l9uK5{`q%}OC>^@Gw(nD%oBuUhPsFL4UwV5 zt8!c7gkG7y70ch+ul(U`>OZohZZT9<$y~zdiz|P+<017@I7uY;i?DwqUi&;;Wl<)u zcD=$Py1<&7ti8%QP7&wA>E*XSIP>7lVfrF{joS1)oui-7&*(h;l3u1)=}+_yU86tK zb-F?C(oK4O`S#HsqJ{*s-hQmNH_y6k)~zN5Gn2_|M`WAzs;VFHg5hIZ&86RjwdT^S zKjCqkrS(a6$i2f4b!hd*Rfiuc%MS3^LES6kQ6}+NlJ)58tdl*aD=eiBG^>5vt-p2S zR9V)^yMsbp`Q3594ZHIZy|~ukD`Z*I%}3mqL;NZE(+1zit;SNLs3fA{M5ISd$Futn z_sQ+iq0!-h*>`(+^_wioJ#tSU;pf@N4%VLL3H9`9Un|v?9jtd~JP_`hu4fwEN^QA^q+`7| ztj0yb*0|VnePZ!6KiaBquIc7BnFt`Tl z#xATbnY({+SEs$bZ=D>W}n@lk-h0WGbq4MdUx75ub9wA0wjkx!-*VUH!~I zO@maR^=g3zRDo93Y5g>9K1J+vXBOXl|Lo@3!`AcGE0$@!V@+8fTc27NtuL%g))ng~ z>z1`@{cM%2HS4yuZe3ekInquPpP(1(k9BmUX{$-wl$f9=5{c~*$)p{M;*Rh^|FNyg z!f(QAWnt1yc+{kw>KHxb++v41w0!-F%?_2M53{j@Di33$RAgf@+OC#p3w=nHX45X1kKK~p*84tgl^4o6IU4jw z1MQ*CNb>lVIkVhVovKUr7Mrtdz~6ehm?*c& zbBpbyGu(0AD4&-2uD|EX(tt& z$f)TQ8aV2|N(K@Ez8cw&#ZX z+ilPF_LsKjZvXHmc3m&O|9ALcX1M0erkXPwtC@C7tL^=KKnno~KmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z x1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0{Nr5B8xQ|(0MtQ~VYiEJXWxwO=DRM=b^V`Yd-D8Yb=k@eDZeTHUpYDqqsrSsC_n$vx}V->(L9m zDDebMmoObhcE|Q4g>`kDeJTW*Z}L9Q+%Ko3PEoeSkb;v~5PI^DO7Z{9os8P7pGe!l${N{*R$079oD5?-4Q=6hTi|cipJ*T)LBDD1!9pA zC~+QV)FP`n=plAB znpxw}<>>^Z)wIBfJOOrr25>j=$!Y0cIHnRe{`DpMKJEE3UhAkXrUxQMs@on6uRo1N z#so|eS=^xJ^dk$+$sU|a1X3?~wD$?I+E+e31K$#fM2Cq6 zDhTl!hLAAJ?V|-sg0by$`U~fRDRM;k=o_gg0Yc`fU9ruLl?WYGB3qF%Aeh2T;qx~8 zB4xETRiin;Wgp)P;2-=vR|dSymsH)W+c`*iwfXshTf8k$Jb)B(3zfOuiv^BMSZUmb zYZ-XEXo2~%4+$_VE)R}NN5|aaTzQj}?fsJ=U|S_fU+1u|#F<<1Mm`NpG)_qJJ(a?N zR3|ULM+K2!vJ(r7-Yp8#mXyxvy`q$d%45QQ@sj5F)`Nj7u>WBZ%0fM{7kiJuxySa= zu}>J>nu$_|B$6Akrz!&oN+Y<*RpyJUj3+QKWxV=DKG@sB6{0L|I0p7)NOEJg=s!I? zdOras_m=L4Zm}gjj;#7Hn&@)ZbxN}#jUb8`s~6ca)D`I*DWUwTf;ae6KG|ns8jij>? zr;^jNpR5kN%+KHq%|Bal6V(DZ293A)47@!tLMbLZAVN#_ezO+dizJG!*wMF1(*vvD zg_d#*o&x`FTY@X|P8ndd#x!ZhH$IPs4-!?1VSM>YU!LNQ>!pCR)PqE%S XeaHFDtY3(DulcCt(16ZQ;;;P+&K8Nl literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/baseline_0000.png b/cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..f1c82d03248fc5292a9bb74afa1e09351ae9add9 GIT binary patch literal 1363 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Tp+r;B4q#hkaZ9IIX{@U(oi zUQ~TdXR`Juv6`hKij0RmU!%Zf91IDzW*-qxOJb5uk)pqQdu#DrbM(gLZJTwE`A-eG=hL~mB<#`VbD!6^d8fx8n024k z=Ig|e=auu?CQr$`W;DAb%h50Ys{5Vedi>FXYpLrWr}(~QiZ9n3QSa67*%Y$4!rit~ zWBtra7hhTKoBsFI$0N_JE$%;E*c|W!N^G|1QDhYd4czpkV^NRDe1v=N}%r{?MwTIbZ z>RF9@f%S5ybe1l@I{Ec_ncRJ|gm?0{O;4AP;hVa1-Cg$Q47UrPm%rbO1`L;qH{En@oO6AU)AY?5Ddwq#Y^|KKm18M6()ZF!s1{V`Z| zYWU0kug&grN@3BW{`=tDf9oEaxPP9{{`=q?c54&YaKFvgA3qhk6^DJY{xYR*gH5lj zzWYu7H2WF5+>eEx@y&3qMQMsL_xH+;XtK3zS@en({e_0Bu&hqLeh z@8+BQ_ra1PZi{>MwPp4@&MdpSKhVD7TZEoMVgl#fx9sj0=kgxTmvMhJ@#pNmiS~T& zPxnftz5Z_RdfV`I!&ZspTcHj=Yt22R)8qA5o=SUvdUY22>-sSJh*{T}uGQ#XdUsCh z=i$k}4>reh-2a-%_xD%A7p84)FVQ#*>;7{0P&cw&HA989~Ua>!ae6V)gvm<}MAAI~#aD{wKoZDNM z^$amH!C~dT+xoZ8*-q>C&GtLxV~%E*xV`%LhwZfe?vLMCwme#<)_jHk+|OS9FDwsi zzaMb^0_lOm~ ZULWAGEVJXMFMg{vd$@?2>{*Jg-ied literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/test.gb b/cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..4489a70a5aa0d2a879a869a43fb7b93c1b289905 GIT binary patch literal 32768 zcmeIx?`s=%90%}knoD}lB)zmh&7w+|37q4`i$g${zScksw1vI%Pj_5Yn>@>;rLyZ;K1A>gW%)VU)!0_paFr`XB85 zY46+nem3yX`d zy)qg3V`=r~!l#Shj_Us}<|Cy3lYMtHS1+eRoB8GkN`t-6(cD&*CGVB_ON2zFvU+}EY=lUGJuM2`G zN|K^HoXasm$me;#ET`mDY9ci;VVa`I`n6)tGz1o2-N@$H+&hBzn&6h)cH>G3kFLi-XDu;F-tFX;Qf|0KF+oa#l#ppqkX=23%9;|A4?Agb=EJ-8vE4_SQ;;|es{0- z=&dih;hkrg$0xnhj!zmUKaUqplaKEG_sok$LRxblzVQ50gv7^s$M%hpvB>LkN92TF zzPKJrukTm>uI}i+(j!j6S5e7AB$o&)|2UIA^@2Z2BbcV^?|yXV{+WaJ%k~?#WxsDP*q_;7+86C_>`V3)`#1ZxykWl>UVw#=!K0Y+aXC?PCDSc>SLdheOmAP*k~>{3rZyDj|BR}!Ekc_!Gzoy z9GfV-R6Jogp9E&u^A>yFW{=69S@w7#M7z|H9I1C{EaC5&t;d_aN^PZ&42Jq|n9cLb z$Ft4L%DF1_>F>~v&5qif(x{SXVl@9^Y5MHK=Zj0LcUu3QA0Ex8+jXJE5Qb?|&(k4S zmKjDemG#i|Xr`f(%T9NY5fAV`Y5J^wm_Eb)E%XW<@MWa!P$Iw&L_h!n5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZafk#iE F`Y(i7)$#xU literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/test.sym b/cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/test.sym new file mode 100644 index 000000000..a67599160 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/wave_ram_dac_on_rw/test.sym @@ -0,0 +1,48 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05db RunTest +00:05db CorrectResults.end +00:05f0 RunTest.initWaveRAM +00:0612 ReadWaveRAM +00:0615 ReadWaveRAM.loop +01:4000 NopSlide +00:c000 RESULTS_START diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/baseline_0000.png b/cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..8c633955d33630d5519b3587cd820b9c219da528 GIT binary patch literal 2459 zcmZXWX;@O}0>?p1Di<0xYcxAqp_!Fh**HpAxtB|3j=PdG>A2H^F?k4+v9c@`8?D^N z$uzYRv$Wjc*d(K9nk%6KW<7ZW6d@6ka87mabnkONocEls|K;~TZ{{H%cik1nD-Z~T zuBV5~Vfg(!{NyatfKSB8{0IWEJj&B$-w{%gIBdLWa?3J1*~Q|Ru>!HxiS4SZ&TriJ z=5Z4qpCDvz&h;4iX*Gg`D_z#fn47@f%)&1}}KlT`zF?eV5-Z=A`R(8J2vHU}3sZDiN z|GGb;uf#=%^*3T#Tmw;Stgg(oltpVL0~rP8cKIBXZ(3=uMXM0sQ!3rgI=+_W_dIvf z9&xOsw6rv(S*cV8CzTEf?w6g{*ivCu72R=muUh@lv5y(hIQ2Yx!l3JwV~-9l<#K-5 zZ8|$?uE`B#`cIot4p`QX2=_|Qw8rtb>=EA!KeCfr8|9ld81PJ)=5(*-jaPN9>U*{C zLa}*zvc+Rl$(zKR4wtsMHcOZRLkEh<4Nl%N61It*GTGw??3eoVsiI9HmMQ-S;(lT9bxj_5!>4))}5&O>+u>{b1@Q@+>aD{_{U7LMARDr z(gXD@DBvcbm?vlF$`CMeJx17Ihe_U!K8cVc4x9yJf$Fd8VyJxzDr3E*d@)B!oov(Tx-rnNlcQhPL#j*7g6ldT|`6Y z6?3o5lz4fCPU;Ahf`v`NGK+U81>Y{tifHC({6;+=949Ffa_2$sOP#Tb)uM1ODHN49 zf0sJz0voJG+vN}?;$wV=$6hihp5c_#>Mn)C3(a$)Jj!GsJ*iY2@GjZ|M@me?WVI!X zb63{NSlbIEu?w&(&s%phX=m369=Vrw)=pB1-IW?x>UYCE2Y&3R;i!w+QK2?K?o%1r zM*Ik*fGRB3$M&NxCP`I8>L)m|yMX7v-_!Cr~4&J>I;@5qc#EUdU1<&hZy3+d*i z9~}uj^`ERz7N4>z3GZJbStt>_ri$gORBba~W6~K5-3y^K`hxw7&lFB}z5^ufEjVNC&gA{%b1Y$j1+Yb+j@$A_%#pAEp z3W1zcVvP56(xJzD%neA%Ht{`*?%=RX;$DuSLUW93qGd1H``GPhYlgUPG+W$j2@;%B zu4J>1tNE8ZhVvUCJtmv;@c z5iTCm3`X%Ij8u#%>ZEmStU?SDR)x?WxK>B?ykeA>$)XS@*A$LHy`0D11|GKMed7we zgaUYtb~J^}LPCnlXuLdiUw;F;%*-vaAt_NGNU1^^Nm<@Ls?--NqH#fiQw!K-mg#}j9d+3>l;^@XC2MuRMa%eToXumiAeQK5$XK2=PDs}_)kfjhcWJ^2zI zHAXUwF@3x(J)1!lC;qSeL(e_GqN)8(5N)Nzcd92;I8HkN%(TaSS)SBF^KX~?7g@g7 z0tp3;Rc`aB9|mW0Lr=|b#sGIk>v$Vd22N4lGa|3p(#+T4Q=3m3Cw!sx{1GSLH&o5- zMDdMESrSqYyRzf+4Dqb)Hqt#SCD3SBodK}6KD+gigw=_v3QxCoLmJ^uv=$o1Zr?fhSK_#ihK?}7bA5264hpupe7WGC5vrdN$TYs9ihNV_ zni{-#!T2u+gfrC&iqP_|qZ8R?AtMbFA_JG%PLxpY`zpI$ukDE_6o#`q>46D)rgNAx zt)Ib*cK5WzWTB>c1)yY_NH>KgTcZh;UjHvN_q5G$(MRVCWLwxkB(GjC$=^_VGm^N$ zG5(SaxfmKKg)A+)(id0n864ofrv7WCH2}6~*H|vStx>djxFJ@<^1R_qkpA#+!D4Rc zdpl&l%_ofWNCgKK4~x4{wTrl*Ca-(C^m0IpV^{v+7ZbRodWbtpbNV~ZH)h8f->&=f?5xPQ)oO5LNloVr)lPTm+8L4cP&WtdaTeJ6icyT-?eHny zH+e+DD$C;-z{~C%&=C@+Stkz+zTj#rLxw}7(8v&U*XrNjRzmzo+OrS)0+W8VbQZ}S z1Bq{~mk|s+4VaPS^t%4DHCx9LBOwbw<-0tvm0E>zh!lR==-MhOyP5ejRg&{Hd?~P? Wd)T`TN!$48(&g#u<8psLKK*YQTJJ&t literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/test.gb b/cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..38c67595dd4692d42ea5216744c8740ddf3373b7 GIT binary patch literal 32768 zcmeIyU1%It6bJCT+1bfjcQ-Rh8Yf|s%q-2a4$^Ea#s!Dz5JDTI4?z$F9~!X6q9p`` zW}=hHN@}M*2ziidYEg>#qR1jeL{epIus9@Z=tBgdftz3#8@1$vwi;#EJ2UyJ^wlT- zH<@AXIp^MU_cz%P^1mJkXJ5+ z)cS_FycyiR>FnXz!(QmFLh@>7eSpYgmaT==^gq$E`G8rqEVHK?2-)s9GtT+4-tRFUwV?j6L*s$sK^OC0N z-Tm|LnHvTnwl=skY>kkdWadm$@`r5)d7h8OBq^KSowp@CsYusGyLkgprENf0u?r%B8SKgwhvb{~UE!;fXM3fL`mTQkUH>JmuXVTRtu@E(YgKL z7HHa4OI=)C{?jde8!kP?>-{SgwnLg$OKPO_Vu*c8_GyFf<7Q>P(l00Ya3azaZHuS( zA52NLd{1Bha|0*M(g%@IcD=@~*V$#UYm8mN%7Sq^M2h045rw>Gdf!&>=bD%@%XREN zx+gN~NA}%ZSo$VSG7sI+kFfKsrMqUIWC`WWQffO@lkO_lX)F+K7%R6|8s*uACejvb zzHU`6$nTF;4EelEL;4%EX0>K^T;6n5F?Fc-*};)>Q=d%FE#9sY^`!S^80F zt0ua2b!M{o;D5G=LI45~fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< c00Izz00bZa0SG_<0uX=z1Rwx`|4P992bmldc>n+a literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/test.sym b/cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/test.sym new file mode 100644 index 000000000..abaa17e35 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/wave_ram_locked_write/test.sym @@ -0,0 +1,53 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:063b RunTest +00:065d RunTest.clearSMCBuffer +00:066d RunTest.subTest +00:0670 RunTest.initWaveRAM +00:0683 RunTest.copyWaveRAM +00:0697 RunTest.doSubTest +01:4000 NopSlide +00:c000 RESULTS_START +00:c090 SelfModifyingCodeBuffer +00:c090 ResultsBufferEnd +00:c09c SMCWritePtrLow +00:c09c SelfModifyingCodeBufferEnd diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/config.ini b/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/test.gb b/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..d6662f11ab5189ebe9369c4889b1c39380f54b7c GIT binary patch literal 32768 zcmeIyZ)h8390%|x%_Y6INqR}UdL6O33tNam)>Z}c;NQ6X*7*DG-^9xPJU~ckYUl2jQ7>mBTceG4m0fl}OO5R+TfA51H!%{I z%IcLsF3}TJcKwl0YsYKH`O-a=lyifL9)0eba$lFeQtni({OE(Q@`MaYlS74qUqxW}KWf`F=cU zntb%me_(DHgxFf?LD(80dD+aHrtF1n`}uG<5|QPhp@;Kb+k3qyK!-3x7Y;Iz8dXl%eNbcuB??$}&S+GLGRG{s8 znTB+MHg{-yg?67K)k_yv-hBV!{foz(7o1le+j+;CcRqGLb*?&JIMbj>JI;>t?aIc9KB5K$v)+EHzduKNY}%{F1v8aO?XAc*?N?QAg)atA?KYQw6E>Sm zbKV1w+H^plqDS4^>`+J7mTy$qp)&L^TRWojGPX)3wic&-`W8*lM|6cI)uCo3y%&S~ zH`NNwRCDgI5LJG!y59udg^*s@Y_JX)+H`Xv_oV>)l`zsKFiQlp^6!ogUmPaKG5 z4joI&?ctH}!t=#5ru$)Nnq9B6>kW2U?3!Vh|768D7a-T;pM+F$+2p@g{`xMSHtXGN zoIbEJ?X7fftgL;VA=!?*`WQRUc4oNtG)t%#*3$c_w#;z7TVo5so|$^8(W}%}`p7_} zf7xnWRz8?%7|Nw84d~}-+g4j`R@tqxznL}`!Gs@A#mRL&K%bR}I@NTSL+TTJA#(bFb>JA-nyJl^7oqaF literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/test.sym b/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/test.sym new file mode 100644 index 000000000..c3a3706e9 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05bb RunTest +00:05d1 TestGroup +00:07e2 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_3/wave_ram_sync/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..c29819498185375e86babe12cdef02c57b773d62 GIT binary patch literal 751 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V1GPZ!6KiaBqu2j(p{kYGp* ze#^O2dEc_{2iLy7rM5^X?nK7E_O1i>IV2`IcxdL{7Sp=DZRwPCQSou>UeDUM=5^G1 z9_7i;PW$ZLUK#$|bgTJX{-;0eG$N6gd_ig*W{+SdMHEpS-W8~g{ zUy9-+^sd*pA51$l{qULDzn&^*-^=*tzvKLd%e|k!+JBq=d-s{=i}mb-%Gv6cxnH$1 zjIVEQ6R`WW-MaQ6v(4ITo#*qk@0N?-y>EI&?dmidsr^vdK70CEN87Tx{OsS#v+L^0&qn0= zl}B#g{^rlbpAWC)-kvpo`OEVMzwTbTp8fKLo7Izw>+w{{L2Z&-V4~>wTZcXV~pnZ+Gym|Cbc^Z})!g^*ubb z^6&R+CO<8A>=RtUd)=bG=HF3cS6iFEmJ#1~eNyx0Pf4&~J}fD5?mz)so3X*1#)mvS f>7zopLgF7&&CmC89}AvwgA%f*tDnm{r-UW|BE48h literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/align/config.ini b/cinema/gb/samesuite/apu/channel_4/align/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/align/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_4/align/test.gb b/cinema/gb/samesuite/apu/channel_4/align/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..ec45dc61e89dbc1e7b5c4b6617757063aa4eb8ef GIT binary patch literal 32768 zcmeH|QD_`R9Eay}o6A}6E_+EDH*!sOV|$!Ingk!bhhuw$kOrv`1VQkj0c$K;LO^IX zy4jqhcJ)E(tE5 zt1k~HZp|%ToBC|#+o$yhj1|0bh>)QJKWvus%Y{s=+*|oT-C_3=G{074lUoJnCP9*N zK|3GnXlRV9J6`V$XOGMtai+F3Qt0SxXw)Y!s@uB!ow{B$v%UA4nI)u49_bnwklkjQ zgg9K1qET5^)%#;5B}u)#PQ9XJluV{S)8B8J(I~6W4dzWlV$I`5HqXZ17EZlsvh||T zs6rIBhqt~{=~TFU_dI4!l5(tGmb0>)$z;rIhE=e7cdfnNdp_?r@A(lUf6Uu0e{95X z_H&?NIK6v*-#DKq#L5lbYgUestYTyhLvfpBc{~z{#T2Eh>;AYk6^RTDIrXVjE|trf zPn|ktS+N+a*GC2|Gs2q3nGZJhws7h#tFMnO7fVG`Y>&PDy;Hb+_dJ#!iRi3eQF81* zchJf?fYrNe?e*UCgKqQoGt3ji-fky`4b$1rfu`y7?)iP=!9hZ*6CXbR?30AF^)&VD z>mfaf*OZ#XNxg94daUF6e)aF-hW;BpS{evVYh)^sZ;z}0l!imv`EZiRrLV*8P4voF z;b|J760Oq{`*ZtC`-1(AebK&b z|8C#3SL{{0Y_Hkt_J;k_!i}TNL<>pAa^3NkmJZrz(Izb^8EtKCyEBSKTQtp`aVEpZ zcdGMuq?PLYr2D`Di?-^c^ib(0JJg}2tCx%HP-*%&n>(mGWo(wpY%WQg^)hXskLfB+ zX0(EzTZ*f9i=`jKrPW$}V5P!VNYiSmqqg))hDFy^oz|E!{o)3{b9<4PYxiMuGwqpg%zY`XdyeKSKffLlmGtMFIL_6revx0s4a!pg&0g z`lA$}KT84n!xW%DO#%Aj6d;$UK>cqd5h$0aK)FZ-%4I50E>wYXsS1>fRiIq10_B1g zD3`22xo8E-Wh+oFT!C`w3Y3dipnSdp<^vWmpRj=Why~1NEMPul0rM#fn2%Y&e9i*q zgBCEKw1D}j1b*0|N`Mr;B4q#hkZu1E(!k5MkYT zevQGpi#d~jo_JZ#!NHWpw0-ryoIPwlniDJM%01tEf7@BsoZHX#?q7Ac?#p|N=W_k+ ze}7ci+_8SL{^aj?_G!DztYreMj-1;2WcTO)eEiKTJ6Z2{#oC_UG~vI`zr{`3$9?}D z`r}{alWlHb@~_$dV&L_5|IR1ppHJUCf7J~BeP`6)KM*LtXmvj7(7pKB<+_SfE3-YT z_51f5$ND^AE*$br z54Zn!hoiWfyYkw>M@RfGrdRk1ev^?qdqdA&_G!l1^XERDZv9!&)z??3CO6U-Np`p5U4D>;9Cn-n8J`e)y%5 zRlAA2+U4yFiu8Z}t5JCt5b8;v{ zF?MHM+x0Qp{z-oF+4r2!@4MKiI|uVtSnqhr z)%5Y@O7?bf#~o{9`S|JCe^FIau|lf{YqQ{Kn0m)~f8|6nD%_w(iP z?1vd;%RdCXP5`=j-|boa{svaH`{d6|Ki~Hm80MB=|2}vjwM4E)NLw^!#&Wru3G-{a z(qwh~(rs^;9pZM{EqCU7^Y@kiU0ybSlrJ~sqPntjX?|hh z(909y8;dKK=RaBa`Wfk8VkLX*A*6U{=bc)vT1o|LqmB24I=i2xxpkdQ-YuCoVG@m$ z#8aMhcTY&D+r2rg?5*rIr|ycRlpgHvk><___oT=-!fjp2j6Q5ihLEAi6Fw+K-auxGbxWL^6>`DwR?)DOSPit#>)S{d~@9_Vbf+Zoj=+ZvUig zu4jg_Z1&dvw~TW+Ley;WVNW8)z1C?V36mBhBn6oF~7f9H0xurY%H5q zo<4F!Rf9oRFHIIy#m}0ZGY>YlmoV#9b!?2iE*J~M*c#6I_AacvwI5aT`z2P-^I7&k zyGzZQ0jsy(<@EOR1*_TX$;!bAd$ofTvSO}hhKgeL*8aDQ3k5=&vmZSF+*5?aM|wxL zkC2h@t9(cJuv9vIC78alL%6SRNWas4M&45v$$U7M2ni3236FTn8zm9rORsekIRAyW zO#PIjol=SVB#t&WXlI#r9VPmSW6N)Uc>Lb+J=%-fYnrOPr_F1hYM*PTwXd`@+BxkH z?V7fxUDs;bx^`RJ(7s>3y04Fj9!{=y9_a5+(;k)ficwCE$K$OTUZwq_Xw8_D-UIdK z(k*VSxin`z@PtYSq$#@FxW+cMd-dWuooy;fce1%%l3B)PX@t#1X`fW1-SlxupfPc% zSx&UtpmU>_X;M!c!(2%COE8Bx%z~`;1pS?3C=Z_V-wCEH&~%*zXPd z`T_%?WFzSBQ4o`0cmST;WPO|$C_cD>0igYdcI4OKI(lKttD z-Ezrpx@0$8vgb*0|Rrlr;B4q#hkaZ0w=9j5MeER zwbmeV@lCb&ho!n3lvJ#;!oN>%ROXs%ai_?sr%>kj1cSchp2GFtekRwbw|uCudDh>5 zTzOCN#6Nc?oy(gQb#v0W?J{fa>MEDMOx4?ei}b;Z^{7r)rqMSrrt z`8-i#omuYBw)p~ww)~!T_1x@@dv9H@u$%vR*@K@odG}uL{8=c|9=~kmRNb!^tKKiS zt4pr4s0uIr{@n5XuP^7mzxeu}Q*lq+dc}udt9)y#x1KjX`R&X070v0FZu$mmM<1$Q zI4O2roH_sdHNE#|%O~{&e=pg1x4%7Q`SjY|w}I|Hp0a$d>~!6i8DFQ_pN?ife6sxF z{S7-$Mpf6WE!UNlyPQ(#-@A8yZ&`QEuBxSnj@|RBd+1e~ zc+*GZPwKyngY)<3^>`|NIoSF3`L}29{i2qdsx%#Pl|Nc!&??s;sUw3bJRd?m<1gnWb?DA9A|4}Mm8LSofy^j@6b5tt|7qX(y8rC0b)ekn>FVdQ&MBb@0K@;ldH?_b literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/config.ini b/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/test.gb b/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..8c9aa69de2665e746f75a9ae508063f5e4364da2 GIT binary patch literal 32768 zcmeH~&u#){Zs^QRhFeV;oBCbS9)5HV@ z9j0qQMh_+)46&GKICwIqF~k@H8jxtRDJ$X7g9#)9kw)-G3IvGN?E213zbzqOU;h9; zZ<%4{ecqjS`ZQ0I3UODDJ>t|%RR2I1tI@-mG{R z36V-xGDkxBw)R$iAvk-tGh1f1cvCksqLS}xYd7{E*KZlgZ}n?ct1z@Qtb!2z$%+2a z(WE~tO9+ogBC%L9sq4%4S~?OL8uHd_T29O5Msgz~mKBT1^~JH0Wk%!(xLGL4`(O)i zy=BSg#bPl{XmXF>`QA!zh0hn?$0|l5MY%qiEF_b;T+S-wUHB6cWZ4lG@TJsiBfN?{!eW@lsOVk ziDd1ouzwLd^<{Y4jk*!H#i+Q=M#ODgcUz|2mAggt(1F=^4j;UAaHI2*^SWa@?>ke@ zXU-SSQRi#txO39^)w%3kaei~=ovY3@=eqO5?4_-pA`^<3b1mDuy7F$j?RI2R5woYK zXK_Ze-L6c=pYbNc+ZP&V{)}8{oZ0Vx;C|cfHukt{YnSCqt-WyeWL3UY)?F><))?M0 zIqN3nT*~b<=G`{;K0|lYnf}If@8amAi|VwSt>$Y3kyib$YVG@QZGF@jy;7G?$hwVM zzPa{FNPd^{yA66=sGq5i>WOGL(cBs9Zq2UR*sHZf2S-L<9NTHuK55=7k2mG8uOCyr=G;no-h123UVmoArP&MLWkv3u8^*AFpR3t{ znavVp4qWIZ)RY~VTUnG7;r4xVJ@pQKX0}sw$Ggs2^~3td`|3hJRCPnf+iuf*)6As4 zP@NA(@Y`njyg0q|-!ciVmcY`*|E%~goDwId+oah(H=EhhkUyD>5qEp#&*_2Mvy*mh zpo3>43bs|jh864?1shVZrxk2a!JbmEl7ekfFhjwfRIs9gJ)vNaE7)TSR#33b3ihai zJ)&R_E7&Fldq}|s6s%vt`V?%Vf<35U8x(B4g5?>uTG1adu0LX2f5f={h;jW9yH@MA2F^!VqAa3xc-Q7{So8(BgXYd zjO&jW*B>#iKVn>e#JK*5as3hF`Xk2mM~v%louWTtTz|y4{)ln?5##zJ#`Q;x>yH@M zA2F^!VqAa3xc-Q7{So8(BgXYdjO&jW*B>#iKVn>e#JK*5as3hF`Xk2mM~v%_7}p;$ zu0LX2f5f={h;jW9yH@MA2F^!VqAa3xc-Q7{So8(BgXYdjO&jW*B>#i zKVn>e#JK*5as3hF`Xk2mM=a>C+SXpZ^AAMa!vGAx01UtY48Q;kzyJ)u01UtY48Q;k zzyJ)u01UtY48Q;kzyJ)u01UtY48Q;kzyJ)u01UtY48Q;kzyJ)u01UtY48Q;kzyJ)u z01UtY48Q;kzyJ)u01UtY48Q;kzyJ)u01UtY48Q;kzyJ)u01UtY48Q;kzyJ)u01UtY m48Q;kzyJ)u01UtY48Q;kzyJ)u01UtY48Q;kz`$K%p!zSeCRdvP literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/test.sym b/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/test.sym new file mode 100644 index 000000000..12e97e4f2 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:1431 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_4/equivalent_frequencies/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..38a3795cff29fa7b476c89f6310d74c770f38890 GIT binary patch literal 1716 zcmai#c|02k7RTwQk!~x}cB-i@v1Zn|iXKXlGK`_B&QdFcXf5r8s){D5M2t+RV?>)y zb+!`JIO|9|5l2uRGAM>DvSgKa$|Ki%gJAGE8k%O^>zXd z#W65loL@YZZnN)sA1H6v#Af=sqp}V;avjKWA0>K0f6Z3Bexm&7h)!|}Np^=`gVKV^ zz#`{WL6h0ooMj0h5EP`4}qj92U_$V2ZJ&!yI1q*H&o{I8?1foQ9vZ?wurc z4sqKZb?`CtoA*vU6$atXnviK001*}PojvIJrOyt)>_r#AwFoqj;0m&A?EFH9&dk59 z`AXhHdS{{2Pg$TY~a6p4(m7C=bX;G(0H^sK_`m!om z%3?SRN#7P)Ac;~#xtOCu7Qz76#+wA@YOaY0xb53_lv3aS!G9($AKS_4U|8Kv3ddAM zNv^)aiaArd&KC`<*^Qm5$w3%StEQwIFEvDAt%U<=;|nB{4|)s-UwW3VffD@tp&iM! z#8`G1O(e{rGU`o`PQrJ!J`k;HB0bd7QR#IGJxE0lTH@|S)@pkfKk{D>fZ?J;AfQh{ zNh14Zz!2B-#eUc(_Jdf1%y3>q`R~i7sum@&}=+*?=OuMj| zYqH3Hf!<^0LS@q>t8rHnlj?L*Y(#=Io{uexIbEsP*o-=MBZccy7~H2qs`6osX!uUW z{lZvcjn{swi!ksAjL@fIe>Lmc@Xf}~h>SOOVFMT}Zz;EA&h@~a8{Sa5NYgn@Jm#X&@Oegr=c!8{h421^G7(*XQMenicl=d zkQH?f)!AjYX7+$~Qr_5$n+SB^)$?c<-b4%I{W(6$SNI=YV}@B*I((d}#3lldk^BU^ z@P?+_tR8r4Oe&Ry0FX;_w+1!cp-YIh>#Nx#80KXWPJOOk)n>aBktpw76n#pu_xP8gu_< zJoZoz^>RKTf%xQDzl@hohPTP^iK&|+yMi$#+F20|lOb1olWNjMcZbr-DZk{H$9Lay z5;jSTI+~>C10=4gv?H1itPTpBjw1hWQoE-~zs&9EKAm%Q{~LLJ1=lgws z$vxcjJl}hs=RP!)kcYa?kma)Qyd)*1WO6z=J+1430Ly3cSzQxY@p&zsWqrPdo!51?ULX*V zh{X2b>)S~?;mq%yN6!dChUG;uEsDuxQcovYg5{mHnk|1m>lA-}R?8mayJe5fYW9Bi zq^8-ebN-foHcN<+DeRY#AtWtnX-$)yG7LWN_XmTLG&=gAKM?i%3k5qLjb@^mjQ-@Q zQ-%=?vb;K*H*`NMKF>T@pKoF34P$DGEf}wpb{_BVPthKO_9_uUi^XDlBa%V;6~!5`2ffF48>@c^ zn~l{)=Yhip9Z=8E;mU1xsNs$4*DQ9Z1bvK+4XJjFjZ%?~MQEQ|quumTRi;s8v{8!h z)kyQkD$#_Ms*DLC`A@6zowu^=Q*)bjwnBn7Dk)#(B@cT`_O|@@xLaSX=j5>88}{`D z211ELN8(bae_}fKeEy_X`N%iNuGiW12D@~2&9jR?S<0UFkgJi;dd*$+4 z9~lVtU)Spw=Jy+>=J zy+>=Jy+>=Jy+>=Jy+>=}|9Z6h8);pKo4BR8i(87@xTUy{TZ$XGrMQz@id!{PR(FrZ z|F@%s00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= P5P$##AOL}fOu+gF(Wobw literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/test.sym b/cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/test.sym new file mode 100644 index 000000000..947b9e80d --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05c3 RunTest +00:091d StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_4/extra_length_clocking-cgb0B/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..6119a5f68b2fcaebdf13c969b7d82d2f3f11c356 GIT binary patch literal 777 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V0qPZ!6KiaBp@UMzZ~AmNZ$ z@T=vdvD$i1{TW6&8cC~Si*4?Qn*Dqn)}OkhZOWx>xeGVtMti;Ne7^a^`m}wL^X9K- zpLKhBs^=ANaS*_WO=GFYA|`T;2Th7w32VgHJ*~{JDPjc1c$5gXvv{ z&zk?3-P*QxPUf`l$)BIzoq7CPsc!nU(!Upeu0H+p&nN5RKNlwbeo^y3XZ^gNn^iyF zeWrglpl9QsX&euP>Za|Uv~5k@d8>NwxT4Lw53@h}JZWld>?6BGyKnnnK7UkI>~8hb z?#9oLH9ne8kqLRXbm7zxTJ$@^b!F_4RzuUe8}rdG2%g${ER3d4_@RUl+AH90ss zn(~`v5yIycB_2OJipLpW94lF-!dftI7D}uiY{7ZU zV(Z1@ah0fSk6?XHa>Ab%^;ktkDKb8lDx^~ReBLVL8Nqmet>trYf5~sb{gY;CN3dII z$E3;kEydTb*WGZ?R` zMfO|VU>ErW!l4TUxqX-9>w*-P9bhvwe<gTXO2N>gksO?!+Q?V?W_ z8qMf~jY?Lu&C3^Vh34D=Z;R5Y-FLkoqu%v)V|2dGR>;wYH_-0A7Ga-~ecIrCT&ka| zk7~(SG}+!0@9WI1+muy1VnZXNFOTguz0cbBv*T@cyu%KQ9S7JE+*v8@jgV96FWYr; z)Z}j~|2dn^n$47@Yj<_^pyi40^Z8KBal3S|Z(=18l&G$F0>(uB0iOB2#6FHK0Ryfh)L z^3sHab*0|Se`r;B4q#hkZuFIFv95NO?c z-!8Gn?enZRu4OM<0-0HaE&lx%ZEc<6hxb;|wq+uq)IJYTc;i$i|=hI(!z_tvlVaemDUJ$db>R?d^} zJ(C);s(+J(;9qxMJzoB$zs`Jr8uUxve)$)(3&!@BO>F&^U%XWjk$ZLj@m=da*T;2f ze>uJBi1W=&I@hn9Up#+Rhq*pS^YepyU#?Y{`EROC1)rjg*+J(Lx8L{YJ~N5BG4Juk z#xLKV%y$vLU2JnJz+XyQZgp6o2C= zUp?>gm4&Ykn#rhszj5Wb+<%{ax$ED=2R+mHb^qHkNz1g~k=0c^{}%0A79%n5b7M_f zamV@nf&cbisNS`Xefm1ZFLIv}N}Vc8Gd?S^|JwWhp#EyZld*C0v@TZHmRA~lT&#Qd z>A|w&(cjAcyr|OlSeE_lVEE_zvo z1GBG4$Gpm0DKRTxCVTh}?)Zg9{C&K;6>dE{SSM23I?pCz?uDE0*`pneYJ2v3U!86D z=6YfD*5v+rwfo!j5A0uZCh*HfUpbv~(fj4+%vn17dh^?VZt*Mc^DLjK_d3Q zxq>d;lj+S)dbfC<)h?h5=9Hgq4R#A;+~@K4`J#T)mKT0sOe+g6`Y(QPn#J$prC*mn zKe)8F?%U^>zRl$YPk!vHYn`_Ql!hg~-gN?bJa5H)n=e1XiRj6}M^~;lKaR9=JM`@9 zgUw&f_N{#7f4+I`B!Rz`w!l>LXYY&nwjcH$OMkt4buhhn>y2W|=Jjr;|LV2H&8MCHktiy_8n5n72RmvR!+sw9vsL>ei7yh4CjP0!ig`&~Qk%otzw zH|_52%x7k2zn@EYCMD#5UG|c*Q=xBf4Go=ZCM$w3k^>}4nn@(l`P%CwcIn*k%;n1$ z$HvE>duBLx^W5c2W5>one^mRMv4U3*5HfV+&3l#nOd%7k^ew!l&eQ8rJ3m*VjrR-A zMT{ikh1BstcS~!tI`5sG>eQC0El$(@6e)CXYH8IDoKhcX@h{aoB_rEcFGiM-p7==5 zz(CwBhCztKL!n3{9#_@Hx{?fq`ud#yijq+>nf^?FzhOiow0~|eZ|EUfJg#T+wC+ve z^fwH8zepsa5QWa+-QVfy^l*9Yd5l~rl%xIQ@oYSv$z+UdhW4QS-Fv~=8=rTJH-1FV zZ}(=)Zy(W}`5dV0&e?tbCG~us5HmMaFJ_LAtfFUiU2%(PdORGCMir%}XR+Rq42Oq? zoc_sVE}6?2kL=!Un$aljuZ;|vMwk|lQy;YMP2u!6&8=JM?V`y@lFkA1dr#r=+VhxN zIIPkBijt$hxpijF0kpq+FF1SS2i@Y$ryDzmz1emS>xMI*0}aDDyU)L*J~&87b@c5g zpV&Z1XYZ=s<-Mdg_Po*%+ocswUX6BNU9J96x~u(SZz~T3iYYP{%Xc-af0l;>spG)} ziI+bOx)+hNp9G6`*bdoETETAALU#48-Bh$!?jfba2d7^>a_GUKjn>oF3zliUVU1ZQ ztdFge)@Rl!Yts7Fx^B%{H>`>^XWg;xT3=6J+tx->fsj7aw4=Sf+io@ORjEWs@9gZX zwJ4_Do=UkbPGfM#eD(b8&}{Ym0e8Sdrrn|Kwbz%g(}!Ar<-%l%K2+LXOWW3IPB+?W z$7x%_Zqq7ui@iou?PRK_TI{NoO>j{v+UZhvd2^^){k>HFDp-CztPRXA&^x5%#MLL?(t2cHjP2t}Dfu{y{>E)x1`{?l!Jzl1VL680P z@J1H%dje!4@lj)nyrVmRtpp+^AXJwMIlMQu>>e-j>o^QhHNLZ%FAZmnzb{K>2xr^78`a=LO2o z3zVN1C_gVye%|G^ycfAPfc`9{KS}A2QaUZAKS=5KQu-a2W~6z6^78`a=LO2o3zVN1 zC_gVyeqNybyen#XC%HC&PDtq)DLpNvUrOmIDIJ&6FSvAVE$;~_{ZL9jkka?1^thD1 zC#A=v^eC4`rFnt!^8)4P1D%G^78`a=LO2o3zVN1C_gVy zeqNybyjf{pp!~c*`FVlz^8)4P1Qe!*#6GzG!x%<->y9Fj|lsupl>JL2kf;+<*nS0Sj`&7K7b@)N=!7S7aY% zmt-Gi*JK}N7iAx2S7je&mt`Mj*X25fWm}LNupl>JL2kf;+<*nS0Sj^i7UTvj$PHVL zNoF~#YXLkV$7kgDv>daW65rhHuEdAgZHW*6n|(=rFl<}c7r76!Z*m`IU*$f`zRP`> zeVO|(`!@Gs!Rs7Wb9O&g9}QTL8?YcZU_oxcg4}=wxd97u0~X|lRb7x9upl>JL2kf; z+<*nS0Sj^i7UTvj$ercxSL)w4U_oxcg4}=wxd97u0~X{4EXWPm%Ux<|b^d>Y1r4A9 zG=K)s02)98XaEhM0W^RH&;S}h184vZpaC?12G9T+Km%w14WI!ufCkV28bAYR01co4 zG=K)s02)98XaEhM0W^RH&;S}h184vZpaC?12G9T+Km%w14WI!ufCkV28bAYR01co4 zG=K)s02)98XaEhM0W^RH&;S}h184vZpaC?12G9T+Km%w14WI!ufCkV28bAYR01co4 PG=K)s02=rY7%2S(0XBp`jd)g9^&a=ZFJo~urMv!#(=&D`_0}Pj=x_?{BohFQ!e(j6RLEG}QOg*pdG8 zA5bAJK#|@hVWj9nT@GD-i~r~Ilq%@(Lhno5{LP;gXrr-oUvk_#bM$cmPrp>khT(RG zUd__-$T}L_DVI_)aIt%_Fe1BM9ar;P)>49hKAjM%2tp<|1eR1Yd_>o;JCdKwMB(Mb z7C{0wOdLv#M|9mmanb00id=tsTbe*O)4kSt=SeA*hFw$OP(WeQdmWns@60WqxAWp< z_M;x{H76F+D)f?vLY&N7`ZKYjkeIpaWFKov;IR~)0zXmB12b4&O_d>yeEvcrXg;hw|^F>tYE1T*4zW9W`HY$nV#fJlk?hkll#*1gcT0hFu#)Kgxs)uY1Km=pNpwR1a;yvLmY&T!i>t+?IU|Z*A2Fg4uldb%gKa&@ z#36DgS`z?nWPY7Rtm=#w@+^r^`eqh%$UU{>zzqtjVIz2m%nq=shoRcSLI{;##-Klm z*}nO7@QvzwOyO&};Wq2V1hhOZRn|E|vF}|paM6iXa1HqTvUlNv3kmsZ$$FBK%eDoD zC?~eRZhcRYKPBIe$w7^rsRuPId_T>ztbExxP~%km3aho!F0tkuzD6zS{(@U{5`%_& z5Ce_UFrFPv$s&Bb{8tTjO`jmAIiGLk`D8{J<)s?69KzvlEM>Z;_irfMZ9v!m944D| z*}iLAyGfET?qjJ>tLOXXJ9gXJdE!SK+6?{j&6j-ARJ-FgH*x|$PqF(ojmswEIZDzE z9Z}a|BxgjIK7P|S`^{j#$c~+3kR-HZo(+^u#jXC4S?)q>F*RUTZ@)=OSS$ud1 zgO3IiiTns~B3vLN(tPduwvbU*rQs z_qMIg1D9$oNHe(u;EN{({Ut4(av{~_cm$|rQ0S$brqWW2Mzw_dH*c&N#wgT;G<0xa zISf}&Wl#~eKC&>Q;$%$kR;jV=qCAo?w?D%SCdcxx0I+v5glBFhtn*^k>_Z|>W#gU3vS%|&8q6}l_9 z5+ls>#k1h~Jfi~Ro8i?NoH@j{y=z+fZzQK`|94MfJ&bWrDeD+M*z^fBd0Wl^sr5BR zNBIOU=a2h#8g89UUdwcBKIt#uF-oiXhRwNi12RjB_^^2_jCIUu{)N+=DHB_?agL_Z zExh8{M6Gfu3Pa0R7#O@7jXC*3ar;ZmezBCAmYVASJpRV9ep%@Ul>S8S@=9+OFqFy; zAnEdVDHS%bV#QJD3ow4`Kv8XjQOQI9+7zhdvUKiv+Wx}Tm{IqG+FF>RDlsIiEHOqD?qS^)#m~sA}N-kXPf!O88 zhM5X}C09ppKaq;@Qpbe`#w4Gh<#9r;9hg^hZ`arf|DBwMN=Z~D3NJO!0AR?0+G;c` zbUiFQS=&B75rGx_;U!?UVNQUd5`;&P>pGqy?e=x^0c4l!iV0HZEru!bi3G$sU<{fi d!I5fyKpzWnBAZ+|YvrT%azAp2<$C(+e*ljd3ikj2 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr/config.ini b/cinema/gb/samesuite/apu/channel_4/lfsr/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr/test.gb b/cinema/gb/samesuite/apu/channel_4/lfsr/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..879492218870c3d753241cbb6e07f34b57973302 GIT binary patch literal 32768 zcmeI$|8Em@9LMob*RCtjm3H5_VcD)_)H0B5fKag>bMF4aM&u;foUMRuJQi8ZZZe1rW*jj+1PDuD1a(`uYcaf3~~yK9A4c z=k{Fo12Fc#9t~_yvu)oW)zvMjtdDgOTfv+xl{q}QtDj}AgDtgfhYtO+VcWL3vuj9@Vwm^W$&qq%w@7)N zZ0u*CEF0&<`(Jk*i7=*ytFI0<%veZ}L$WL+hN_xww>zDJP*`~FI>&3bS63VBz22}l z99D)dSfHv-CtoksRjP`e57T)Mer;}HtXI|2QvNun*Wu-R^z3iGMZ&w^N0sb$iLV!g zF#itcsbK^7`oyz(&gT7GWcb(Hyn)JT)EVgcC>oXfyU0O9vo2JdzRP6@z`k?p;{!)VuAJ`S+FBQ=H^SM09SjJ~{H=pz9 zSyH>6ruUOX-RmptYVvoFf}RhtCOr_#j~Cfe#Xn>5-PZUJyHs(qlRqJ#cg6FQ<8v(h zr{q7a`S;k-xxceQblI)0xo&1jVy5@8*26mjEZFOURLbAyOrWTFGzZ_x z!~Pyh3KX^V4f6?W`tr8i&J3}+HH+mqvkxep8^xEGcQSEZOt(l+=}GNL&5dG5OdUJ( z@rGr~rQCbxE?N?vQSjjWC&vtMrQGpI;gkjSw>~_q-`#VDXFE#=-WQxS@87(Xbjm#x_6E~{F2i+93}_dhyv>P=aF z?(};cC9{fz^6C)}4V^sXf&9$g$w?L#sjQO~)x&l+rSY-_dcfDv#eXwC$)WrC?`dHC zN~0S0Wd6H#0J{wABCzwo&H`%(b{g0zU?+hc2i6AcD6k{IbYQ;$I|%GoU_S%<3D}Ro zegO78uzkQrl6SQ0P>tW*8(f8$*N)&cA?u#3RX13L?>9oXrF#oD6d z`fq6-o1PXk|67mFRDcRl0V+TRr~nn90#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rC zfC^9nDnJFO02QDDRDcRl0V+TRr~nn90#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rC zfC^9nDnJFO02QDDRDcRl0V+TRr~nn90#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rC ifC^9nDnJFO02QDDRDcRl0V+TRr~nn90#x8yf!N>G&#>MA literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr/test.sym b/cinema/gb/samesuite/apu/channel_4/lfsr/test.sym new file mode 100644 index 000000000..8bf35e53f --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:1511 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_4/lfsr/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..f58f4c214f2253f75f3d28fa59d844d59e61934c GIT binary patch literal 3804 zcmZ`+c|6ox9~Q})q1?zeA+(S!OR`)`&Fx;9Ze=UGEQQFvjDBf~kwT@#G9<}1LZg(J zCHppG&)8-VBZD!v+04wV_x=0*jb8sLZLjOz`R5>W z_+*W^xTfZj`Rr&gHQ_D*fRV`nP(=OeB|u5*=c{%w;w{H}I_B;)DSdt`Hh%6gV$|#= zjM#y9o%1XLXM&>RUKobz235~~sCO^ulqle50*2{XzS0DN|t#fRGI z{DigB+%4LV8gDEHgDDgR`ss8!84J9M$E>k-u56xNA78pswJ^6_n{Me<`<5{%5yvtU z#HqpVaB1e5yNy81s1qE8313PUg(=>gz1!ex1j-d$x?uHwO$Z_6{ zpjD{!Rq^!H6q)Ty*=^ZVKQz=r4A8x6GT^JF-5nj8MG5>|1N*uXUxwc_-DNL1UJr_BuA)dxLng>9%)aKk2g=cZ!@zo zCk!(FM@iX*ATjA*DIBs>fFmWdPZtsA@ww@ipQ>LB${18Htr(YZ-M{sSWqtb!Gizyh z6~(Nu@}ct>-McfdnJb@UOf&HUGt)Xa@duQM){Fc}W9%?HOGVVDd-KuUVQCdV1Av%(kA?mvx#|!!{-PZ0k3_AC6 z)%&K9*5lkDkd8b%O{uT1f}~}DXA9HvrlYjeW!ins_kvCu5=ZZ|hg6rK+a+pg0`Lig z7(20;y`~B&I95VzjNR6kyJYDK@|=!nYr7Gd%%gY0byzhUUpFXK%D3N`@vIe3Rxyzy+;I`3o)tdY z;9PVRtW~zyXtbcF4FAEXRBPR-{$Qp%N`m#K`x_l@__h~#^A5~OwASFh9gq{`8f3=H z4@ql+HpaN5XOMm2$MUyr{)7wNn}4qvY7=l=<6e8n7>fM@{{J94`Cn|HNMZ$Kwm*#SfE<%4vF;q)9So2QgpHVEC|zhahdX! zO9=&ToJ2Lwfja%RGEsNeAKJ3{Xt@F76+Z%q30_=1;XhXI(F{(;yh|_+tRoFe^MbTj z(f<`6=Fj>60jA5m1%nN_f=1$gyj=&ZZ^=7L0=zmjT z^|+!Qc=8#l?nZXNOPZ!>Ndo)4Aor7=e0$;yTx`4p&kjQTBgfPNNf=HG-UYrx(Ig=sNqxdzuLvJ##F_uZx3P{GaOM*Hm? zl(MS*E~Qm(({;rQuFt4kXYN?DNZ5n{*5gqF3JOE*&(Bv_utz9+_f^&>M!&*%Z4_7E zuyqtKh>=%R!WH1`iOoKWnJr~UYb#b`tu3bale;A0XM{6emEJpE_`zuf%zmxbTYBVL zU%W|C|G4$j#Y;PjGF6O&UUo>?#hP^8_X;-Xw)oS)#^#XnvkO1U22$ewI zuWiCVj7FG|Z#_=^0K`WclU7Z|U*8+Mue91-VR`W^SW=}i^q?CR&r{@kuvfsI5DH3jtE2>39+!R5;Q0kN*~C2;rCi$brE(5%YnH_?^!OS;d>DiB zZoQdjRE2Fk^2V+?Hw*_T{!4i-*>n=5Hn>08bro{QeCZ-fp(I}^*xH#t!nU=R2dH@0 zhA6hOY6q>wwLDZGJ>lJ0ki~iQ`_V2S6Cod9nx#rLv*1O}{7ky)cU*Sn059ZNNVxOP zbW@a+;1@UWA@RXs$w^(V(@U0aBarpZ171X&#NH|z3qTMp!`W7bv%6lWe?OE%0J4ry z`Of;zO52;vY|;IRWR(S9q)kAKc6dhdPKSh}FJ3JR@=LCv!;y@=_0Ik}s})h;)p)** zhN!=M=)vMOyutU2LJ!mHq9J_-M?@xyaqNPs=;F?n}aAS zqdt&t6|V(a_20&(O$wJ|(gw)%rQHr2T1EmoYCWI-)CL<)_&x4p{$VY7bLE_mHqUsr z7-l~A$3X`}bB!$@Nfn=Qz|~*%I^bsGW&7ZOSV+{Xl@2LtJ1z<7pVRGgvzpzzX%XaBJb-=a9y(0xU z^zV~aD9`%!_q}(&_f;GJvcQEr(h$oRddc8BnxKdPGopJ24s?h9<|=L(=_zehH!qk+A?c7Rqgyc zHW&5)YG}a>mrR`xk{N| z9u5f+bi+p7t9qBLWgI=$Z{w(@4~KSv z*_!ES5f_)!9LVhv==*v=#cmSN%*A9V-f0&|gol?J8NGQyOk_xC?YmcP-?SmI=p`uS zPT5Zf4Ou3^fhz{OX2x_l_irjXKspd%D=2PfLPfncflh8{w=JtIl(~b{^_1Chz`e)u zjvWqsC8+e#66C!81<6u;zbM+|>9h3U*$~}O<8d)tI7rdzrGA9BcQbJt(#oFPc8_*B zPukoZz}c13@$#$|KAT*p^kjB}v>o@+bXqLqk0(+A^ebi@x;LiF2AS*0xcobY#++sH z#MWMLeWJhdy9j%7=N|#mx90E0@meDpVXVULT9tDDGeR=4_YeuaYxO2AH11TTz@NtZ zFw`hkBr%6z=IqAP*QhU?=*4?xyCk$vRc|a7lqF;N0*dp_BV6&b+2d_z@X_^rx5MX| zgUoOI`$H(0VC;tK00y^0EKYXw@vc2FeS_ta0?vXI`Jv{hbhv=e4HwgPMEyN5F9zpkwVXkByq3P~rb7N+>lwap`Ck==EKj zYS`e<<-fq*TSbN*Gc}A-_P-4m0&`OmnZ|;YeUQq=bgkRt(_iv@$YyNtX3c~ z`FJ7hdu6<|dCP-8w`ZSX%Zsb8`6ysDBFd#jf`pl>#)F5wQ2A;@2S(K~V7s|H97jQP zpo-8-V`9AeGJO2O`Y6UBU)684_FouYrc0jJP#osu!}f64-pUt#aBdN3L`fB#x9oO5#c IVCQrHKgTWoUjP6A literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr15/config.ini b/cinema/gb/samesuite/apu/channel_4/lfsr15/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr15/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr15/test.gb b/cinema/gb/samesuite/apu/channel_4/lfsr15/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..82164ad20694035df2db2768d4b8ea6c660a7dd8 GIT binary patch literal 32768 zcmeI#e{2(F9LMpeYu8omx^^40BXzq@XzC;|#AsuhTeB?NLWo(2KZqJx6bC`FENa++ z$F&M_VAK#ph(iNn)EH2U;_o30P-5N6#5jM2>5V{zfwOEdpv>0i?lvIC&;KTVAGk~J zc|FhF?Y(Tt82ew34tB7|cKDCh*4{#Pz4ZyUhB;Xwb9gG(Z(y#Yy=|$1fuB3Ox|TfB z<~q|maI|w<*JpFZe-w+E*A~WFmo%PFM^dq%GhLtEC}jBOs1`Y!;FDu9{ez2n+%f-l zOLcKcp^!1p`ejdTPpv*R=4Y|$*~KN|nmxh=(fx%ml8{67SB4y7tj675)7>bR|-jz*BFXoy4~({dc8F@SFbC4c6)29zTW2x z`@&&)=JMr=;&k%$Vtb1s+xak^_u$v&BlPu(($K(f=kz&z{27zaH{ZhWiT6=NyIth# zz1}eYAD*s+b>Qobdrh9r{Vm2YpC`$S+svmeZj)sFc{<9nem36!n(LMp#&Xe33+CO- zSY=&l-IO|3=UV2?b1fBPyN@}mk4+UWCq~8NT4S==68E!CSEQ;?7*DoY{M)S_=1zWO zH9j~FzHg0dcFm?0h%qf+v}w6ftst%ytze1GYx|$wvhKpVS?UAoW2&OQpmwTns_&}1 z)lbwt>VEa4dP*HqPpfJ5tU98Os$cb=Xe?uXi%m)uEGjRr)=Ctu)bFuLm6eqfGhRh2 z_xp_*ebTxplj|F{4dwdQ7#nU>v{eHPnWLgGFm+ayx4>T4)V#1|sg&HBzmgxT`0*4!WPYsXhq*Hz zSz)nvdv@mg*~^mt)2jbFzEaKBzUOKNQDr6G;*G#Ni zOJ5w%=FAb@_uHQrF8?)g8Li#c_xtFj361Vs6#wz``HZR2+R7sJ;NZkweP2h{z_7Vj z-?wCLXK%{btM9vS=RG_6hxEPrz5=Voe6ELe$BTK{*;>Hgk>lSPe_X5L-=>?A<54BK zq4ZxVgXtosF-+$$jbKV+8pd=6(-5YUm{ORIV>*UO!}KerqnLid^b@8ZFny2dJ51kV zI*h3o(>IvD#&ihNmzWM<>c+Ge(;iHpWBL@+$Cy6E^Z}+_nBK$m4yGNL-p2G6rZ+IX zj_EZ_TQR+gX$z*8F>S`Q3DZlMHez}a)AN{~!?YgLI!tRZJ%cHRNx>vzT7^l%v;xzU zm>$Q}j;RgPa!kuGEydJ|X)&gUF|}ZN2-Aa@?#Hwc)4iDP#0058(0ssI20N3}|000e@NklHFF0{OU#q0gI^xl zsvoClqBa!)o@hU*EhYaF&!^+@cntEnhE{$`X<3%%^VzCD=e(82J>s>k`~)8TgU7TQ zJq3J_?T0^q{_Nevx~^YeUwgMA&>rR8uA-~|!PTp1lmzD`PlDhUdaVclvsJgm^~;nV zw4BHvdk>wr%m+9A$HWnADlf};hVl{Y@s$A){TZ%Yh^d~!Pvk%H&-KE_m{k_wg-K~a zuvSU70RR5|JIFUX;_=Y47fN{TNAPuk)dA_00q)?JLa#eMB4Dlj`Ds!a165Uau9B2j z_Jq$t^qU$8&FtAvO6lwCs~mPR`+4%Rs???Uo3J%+o5EK& z(MrDj6gy?|c)UU#jkL%4MdEt4sdSx%b0=dK0)Io@4S!6^K+F>UIkz{NBe_5S% zBqIT?@N;{BBNDF`IbQ47kDRZ1Fv3^mxPD?!0-(^N32?o+`-JGZlZCZGzG?y`i0zO6 z*RNkyep$Pf_u~`$)qm#}nD6gzBH57PJ{?Lr_-D_9gXz!+p3f(ak6FO==IJZYcvs*> zk|(Vi5k5|do&=F#A|*`KbdWF0(sBLC|IapQTvGPohTs&v0iW6|1F?G^{I}s$^Iw{q z2R{I5QeHUDCwV0DmE%qJG!5m}q2IyZJrCvf(euc$Rm~B;>V*iOG!eAl zwAqt*K1TTEfrNjS_23{s!E?Vs{rQUP%_*g?uP^nFsR(D!gAvzzl6eI6`viGj9&E}L z2PYPDj!OQ?8<&^Lo1VM&p4ue(GtAo&m#ZB@_{cH&f8BcU-q^c8n~~q~esJXd+VZ^z z?*up9F)bM{jBa4rGhH~U*Em1@^q?G7)xQf98SAKFn36ID395(}2)kgHINhoN)?U5HeFJQz;lOHsQBf`gb z6*=FtZF_=;^SK6PRkybI+m|H3oq6!Xc}8F&T9rSa&uv9vE5r{}S?}CDyVSOmM{iya zR-E_<8y}HXzG=316i#pG5w|M7s}TBYj(BCi>Cv4BUmYDIc#rpk$r(C@f7tuShw;rB z&frU_l#Z9tEYl_I#~?qVt(!lx9z2CF0iMA30uu?|!2uSWc|EwBF9`12g_`FFSP4N4*@(=t*U4e)`PqG*mQ)y)ykbLgKw%sv*JdZO1v(M_^B`}Po2wewZ}v0U4&mU zP5ycFU=P<`4~}~m?fiVN2Lpd(J(%-N%RLU~2k#TydGOWIF@pQngVWDRrwHB%h~|0V zj#LHtq(#)M+*BT!d}+OPe{A$9$hSSjt{Ev~!{r+ywkhC%Ds%qUM0tO-+7?+qM!rZS zOGb}8`|0(Fz0yAN4myi2KkES<;@*?-8OmA z>N}Bm0ag;zqnN){=+^b%vLW)* zl;@VK-0r6^Tjva36`UdNJoxIEID$>(Wf@1Xsj$i~nONej$b;Xw{(8VZT)TQ#--jz7comJcrot-UoX1Q;u7PXF zwJ93SCf)`4r7?t0da3;R@pD2d6hJh|^QXG(~99^bSd zhx=*2`=qa;BV}cxXMwT<%U-RLRNj9LXfVO~!5-}6kJ!)8fDGtNle{KNG`$}j>AsNw zAV}?*pSwOHz}wk}GpET%%ktFykWKxbg!6+vYwADkK3qKkRwi=3=~6!N2tN69*JW>G zyfBFU`(z1i@9WIU`>(TcwdbyLd%kN9S&v^fB$#*=ZR+<kD7XX@9Ecx_7Farkz+F);j^bIBjwzZ z2bZ-~iB~Ij?!n)#s+#nBlDIt>U@UvJRsKt!o&CU&0IQZv&R_=#_<75>rO7{g9{lOwO+x!UkGx=e`2PO(7Eac|eX`Wq zM^47^5s+Y<5vDRV$X}*@H;LG9O3;iPyNWIec31uHu`Qm2lt~phIs~+)M)1!Mm`05xR zsmZyzPPOw3$3zM9UMm>^yhY^C)z8;!bKpN7^?MT4x;dlda*8ewh?ghk!QOMis@FVM z1!UhV1lMmK+q$n7>gPATahEG&-z#Xbye2T1USO&L7N|V9Bf!b&AVF}CjmB;}&@?-zs^65D8kqj+ z0X7L$yMqBHobFwD6f?fBR;&G7g8JjT@(}&!eLpxJo(-+vP4e`|_tk3E&pkr@t=~b>GY z{hlLLe$bw|{OAlPrBWI%qejmxG%>~Uyi&sN%8u*b3M23DPT@;{C-8#-!?K`zJvg=R z*sRW3&hOA4tR*dW^9APmF2^nb4wlP?ykTuxX7bVOiTbMnHhYFx*u=-CBmAuvpQEm* zL$kWe*pMK8RY`hbqW)@tr(1~d)^|Cwe;)Tg7d?(ynd>b5fsD!ABwp8GZ63}G@z`-bdh}jjKfjX|IZayw*18<|wg8(-Dn?k~9Teej@YZ+dbl>Sm@H_M1 zV=zCnJRg|lI2|3Z9vm5wtxssQuJ4Xtweq>@Bv;XQ9(;Ao8mY)vWIW%iccxCu4?ba{ zx+Tb$+BtkFmC|ZiX~8m@WtteQ-J35?b@LHYYre}w_(T%ty8*`7kl<}6@|5?3j}LHZ zXXHP=JHQ?Ms?EH1o$}oz6q@|fAY^j)2Kju-MOD=fRobvcQ*9~&%=uo&2Ki>w{Q+Ko zwnO85yVb_pJ@^~q>#t_OcH+0%Q$pqa{dw>KJ6Ih6FH7c~+k}HxmnVETiH~W;FB?*a zx32Hb<>OHYTt%BUp#HuQZ_4jH`0D5w!KM;Vt~lxp4UQPafBSRGcOGn*WtteQRg&q? zEsIlo@UNB!9}wUUKEa&_SAvJJ!~@l_DB)8yy5u$I>G%4=>j9IdtgZ4@Ij+Ce9@6x` z#B+}A(myg)3djzQ+4@#)>jheehGkjGCu%t#tsS?J*S7K#c=VBZ@WjmWYF|m(H4nzd z;*)CdIcL+bh<i*aohpEIPL&n9Cv^(jyu2? z#~t8{;|}n}aR>O~xC4A~+yTBg?f_pLcYrUBJHQvm9pH=OKfhgIa{&o;#{d8T07*qo IM6N<$f|^-99smFU literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/config.ini b/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/test.gb b/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..211fda0688dbbafd458b7d027d259360047a134f GIT binary patch literal 32768 zcmeI$e{2(F9LMpeYu6R%x^{zc)3RL$)H0N9A%+?2QRjrI80W93A%q!Vpx~S#vYXs) zBLhxi2pSa~LtKGC%Y31dH#f1s=@X3ueSN1oySkPy zX$<^&qVII)j;@2Vm46g#caB|*HPkM;oK6h1$NcGfFFu&JW1E@%%; zV@#}jJU(AAD9bmGrLf0SQzN`2#iUrQHdb4!X+9tK@%n_OdiZeG)v5$Pc5WfOrt$0f zd_IXu{2tErg%rYGAAKGz?(xLA4+g7(!B{M&RmHgA-oDn@);T|659j5=fCARkzh=ZH{2L{oUtlNtx{FV9=h(Vd%b?YBvn-0JT4Af;dOo9JbpQU*caya7`wmo6!!Y)^XQ7#t8gz# zasCmXrpLts_x82Mw$AzW_Hgc}YD*iPyDe>0HE}<&sA*zrKmRSq_4SNp+TMHW(HV@D zR8OoPU(KomFH2d06-xWQGybwOljQ5EA>}7)zFFr=Mp$PcQJO3NVK%xVJKZ4`H21sh z9pACN?xf|lJXVgG!}B(1zPEVXrg?}lv~uWp=WEHqXcy0O{lGXd3 z*fV0%y?8j&^PA^HQ~myLHkY~hSINIx z=l5}Vq-Uf~4tU*x>_T60ZgkSDQYpt_}*Lc7%PXir-f8`YKea4&?D|%Pli4_RRRRz5Sm@S!~>8WgdT?!Dwao9KH})-(Nbm zlohQU$cys{cR}kw$;d>xySI=P`-@I$BirQdts_j{nzCHVIx8!k)!il!r_y{dW^dEt zllZg4w_@++yqMwB;$;JS$C(q(nHHSC#D~3cE^Mzl6ZXjhJ5Df`4zVM=Yq=GTG-vqt zC6csC`8R2*xv5R@S*5!9OwqqA^B;5sZj0O|g3Qdcfd?}GgyK3B*Pyrx#bqdlpcsVW zcPK7GaRG{RQ2Y$VStx#lq92MMpy-3*dnisp@f{SsP<#u;Nho@tFrny%f_nVzkE)r1 z#lD8(I26aAI10rVP#lJ$3yOnK9Drg!6#Jmq3q=x&Jy7h1;xi~dg<=;JpFpt_iXBjV z1jTkJI-&Rgiua*-7m9bF*aF37DBgl%6BGs%8=&ZbVjUE1P_#m^7K#=qnxS|diq%lO z2F0sTyaL5aC|-hMITXvFSOUe1P%MUG5flrdcmay%pm-LFr=fTfiYK6W9E!)Fcm#_1 zP&^F9Lr^>j#at*JfZ~2A?t@|u6!$_g8;VLO%AvRiikVQ%fZ{GFrb96miU<@XP)vd1 zPAH0?m<+`vC<>qmL6HYVE))}>7zafT6xmR?p>RQw(c%Atptx>}RDMCq{*M`Lr~nn9 z0#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl0V+TRr~nn9 z0#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl0V+TRr~nn9 z0#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl0V+TRr~nn9 L0#x8XTOjop_325d literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/test.sym b/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/test.sym new file mode 100644 index 000000000..e6060af1f --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:1954 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_4/lfsr_15_7/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..2c83204a83b8e73df98da0d389cad4e86b824158 GIT binary patch literal 2155 zcma)8Z9Ef-8kf#7*TM4A5oxP*LLrw*GS)c=!)T-^*}2Nw@)DJ?H(H%aMVfitHDO*l zloJbw(XMl&v22q~CL_$t62@q=*9<;Fk^-0n1lM>M-81@qBPSZvfWm!X=@*F!yG<)q(K21UrOHs z)=u}zLk}gYWtqe7%M#g1a;`i;wF0+GF#;7{xd*kSi9{m(<;~5_eD*W-UU2r;dkqsI z@uVo!1O?5w#J1RFAG5jhbVlQQC`QZ-FRq2H!X@k03Tx>EJ3F0wF6Ga+w;feu(YXD0Gny3TBu*nco6fvQFbnGlRbqTFf$eke#-r zZW+%CqEIZOdQvTay(Gi=>W)gv3_UCZySRPb#lh1%Kd)37L1eY)Sd6V1g(R@=9^4y0 zG+qvfk;hg9c{UGa?Q0H_3k)9Xye@^N)Y;r_RyuQh(k`CQm1pgFRyferAV*w&Y#QD& z$ZVWtB79Xz?4nQ1wlFVHr(2G)@N#qhHY%*7)%eVjsSEe{*niLOP!#?XgCf=EbwJQE zSLwizSQc4mYN690`LP9v$4xO=Yyx7x&nVA zY86gF&=1?paDZwF={=M$p@vdlbeKgl2i%4ii>%ST~uR=9!Uz?Xt zV8{IZUBYX#rUbXtJL4Q`Ie{$$_3^M_{~e9y{xl`i*u`575avP9=>^FQvqaqQJipB^ zQltce(5okm&3wo)Z)o!gWY0a~9CilXNIy9hxzZSeb;S!W6rc>~;Rh0>Pd)1&lpvC^ zaZXQQDwB+5aa-oa;sf%e;~t_$wo`Xq=Zbwrx0$;*7=Kf#hf7vEE$QVS1jdM2+stfS zzEt)b4W)DYT4Jfzh0;biwGM=u6!ML)bvDGNsD|d`0^!$jX)2TO^2F|+ZnU>I+6*!% zX?h}IP4dKGAJOIR7Nod*6AlGF7lcrjX>+(e1E126<$zw}$dx|hJ>R-n!g1l_)CTbd z(St&1$=1<9A}tLk+e2xk2gQ!)2Ain)3$Zn=~OKuaon_R{lmYw-hImtOq4#Z0t{q}D<6aX1_nn|7U%@^~|;v7U4 zhZm|!nDj9U|L?@e`6@zC7)@@@-KG}^((it2vMYo~IO|bX8!^Si z^WDs$SkBe}1g*$ONrSlSCM%jaltj+MpUrViy`tndXiXSD&FrX(OXptKhl{+e&VohW z9X#uDV3KFT(t;uY9Tc{h%EG*?n2DnoZ+2Zl;fk@-Jvk7Gd(=!DPuf4Vv&^Ez;p+Z4 z1E0}pXl33p0`djkEHb+bwEy+SDq!7X^=q7X50!f8V&1GCr;hTWp4<%NveP%uiLY$1j|l214`mTJ z<9$RQi}h;67I8g6du)nwX(itx0Mnl2m|*f@1NlNixK62AkB%n=VJzcDNH95Y zboYPxmLnyzD26-X^Iw`O;NR#B6Y0b#e+)9RkP-gWgML~8`J-r6oH~Z{?cWg%Ute+L zTPb{nOR^D?;a4zdVgnX`KThZC*OY??k%l5!Mw96Pz1Kci zw{}^!QMnyefp!Omeb(qWEeP|Yd-5d@;48i;0=z1dDgqL7Kd@d9GBNmbtX8~;PG-oQ zmsgce3&hllU+TsR{>2Y&w@rKn{h~S<^^7oB`N#DfMm}K4aQ>lXL9hQB+59ousx)Ez zb0oWHAy2Uo9*a6M{1E>cCeI;O>(p9(McDptTJ9&=xpS21`~;OrNtI@(ELBB>sFqgQ zn=K4nOK)1B%2u zyZ6*xW6NXnCsK57gQzzPMyxDg7^~4tordu)jbc?1DIUSa+x6yFC%Or0i#e0xN2!a6 z%}p^1hd(WiI^w)H`!%Z@-QTadB!k3ZE7L&E(M@dnjjkfdE~hgk{DSDL`X7pU$y1(1 z`{Tcf(^YuF`AJxL606#|_@>wJR*c7?RykvW+^i+A78ffI0GI3i+~-?Y0NZjktIBi= z(q=15>FPKs@(0=7X(Yg-OS5;%o7a1v5EOl9d8*L7&zI}+q-;8 zi~rZ-1E+en_a2xl{i9fyee7VYxxV94CNb0%^JeO@Z;PXRztczzr}*UME_27vf`P8c z4o5{%u}>Vex8`AbetNz+bveSiDk_VLrS5~`6)A8?yqHpI>aGu^hOw$ZYgJ=oz#59e zn7Qt9c|3uDDBd_0LM~Tbo#_Q3Cd6V5v4#dk@p!n8HzgF=#fQBv*ChC{eGAho3csGm z;}Mv^?_poxl%}xO$DT)tyIgVZ1A&@AAQp=$H8C!@x2`q5wa-sj!#=-NPAs(VmRQ&- zoA)ypW!cQz@HmQo64||>W;K%kYOs}f-_55<)kSE0NF@AshDXjIe=TRlMTjE|2 z;`}o{LyemY+*{Wg-`eLlS;M}ctSoJ@@3yo>R?PdEi;7}yt>?e#xT%S;T<3dFJUolB zaP8#UiM6cO|B{gBUm+ArE!?VNUA%V@*eMQubo)_-O}35z&f@=(Fz($Wf}ST!a`f-X564v)E=ETwk|!!Zg(=liG}#`dR)^GY3x`N%4n@8n^Me8IsBPtP$XIL8C;< z7)8cZNi;%{s$8;sY*dc#q>@H7RiRhAeB#xV{-sl&?UowPW%(7NMozED*Oxi?SINIx z`}c7)+m~$={cfi}zr<7Ki%ywSE)=+H8ycT&S|RHn=eP6M>-@ErzZCxJ;4k~kWMYkj z9S-iwkFXDA^S9Of_$pW~4;Aul`%N?L*385+{ez!JS!}{3sh&U2aI`u-k1s^l50;NF z@e?IX+$G!IsSc# zNFJk{f0w4~n>v$5xvD=^`Y+4;2OWW1BDaVj({r8Rf%HG2xCX^lD6T+p35pRYhN1W! ziVIMjhvF<0KSOZ_iXWjEgyIJ%2B7#Jijz=$2Sq;=-$HQ$iascGDAG_+kH7s<)l;z8 z*H9dT;wThHp!focLs0ZWaR7?_Q0#+ZFBE&ANJ6n2id|5A2F0gP?1bVID0V=x9g2^j z*ak%p6dyqGJ{0dl@eUMkL9rQ%H=)=Bg$Bh2D7v9o2Sq0o9Z;-=q8*AhC|-kNH59Kx z@d^|#L$MNy7ok`V#WEe)1bH= zic%=1LNNu3Vkm-86hh&HViFV+peTSM9||WF4k&Ue{C^M>*DR4LDo)w|IHN5UpaN8Y z3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl0V+TRr~nn90#twsPys4H1*iZOpaN8Y z3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl0V+TRr~nn90#twsPys4H1*iZOpaN8Y z3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl0V+TRr~nn90#twsPys4H1*iZOpaN8Y K3j9|Kr2YbaP)Ftf literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_7_15/test.sym b/cinema/gb/samesuite/apu/channel_4/lfsr_7_15/test.sym new file mode 100644 index 000000000..e6060af1f --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr_7_15/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:1954 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_7_15/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_4/lfsr_7_15/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..c965f51b71b4135623ff44fad47dfd2ef70df272 GIT binary patch literal 2184 zcmV;32zU31P)0058(0ssI20N3}|000P2Nkl;51hOO}8;E8_#Y7ChMFBf0=lp)Z6TO-hBG+H_-zu?{+mZh-9YKdiU}}^dJQVPF^x%5~&+n)BLwB&Yp9bkyfOa|b;C~f= zZ`(FnGX<{TE2XsWzMyMiGuF$#_6we;1``*-4(JF)H< zZ9UM|SF3-tUFug#>G$_{L-_su-Sc|ccMK8-1F+g%Dz#kEza7!?4;H)zyk4)W1&=nV zei(7kE`8Iu1B!GjS7I^q@dzl=)m*Lqs{dArz5Fx!BMx31x9hlL|{0K3HxzP0B~~^)J*P zaqtPe<6v+9mN*z^VP91~9?^x+M@BSQgmJ1?zd5eeu5gZVFs>M0f?9mAYZtAa(ez6Yaq!}>oCo7UfYaKqD*K+lYR`AIdc5^J)z>`^)V5vIJ>S*p5%NKyFfP~fp+sq%4I^Uzyd)iQu$HgY!|=836LIi~ zo-TZ?9)_=NAIo`gF_ZwOn=HJ(jR38l(ez7TnZYzy$d4KP{0yFMga&v-94ytN7KUx^TD`*Vv}|MCd+a!`qNg$sd4GJkWNzxU-c1J zX!VSyUjlmvYkOBqz5!Z2qv@Bx7zZ1AH}D9IaWEwCfQUHwik^sr>ljVHH?-~J9tRh* z91E?UU&0u4y61cw|5M`NtroXY%Up4-mao;%@T=_^aq#Ej((}Q^oIBlQ!2)unP+kv| zJ_3IPxSt2d5^d1mafyyNcyT-#2hSDPYWbfM2W$Uh#j3zV+n)EG2j?SFr}JH~c)e!| zwJgRdKjPp%o2;sTX4CP=CQj?WV|^nIUL04C3zO!3Sa>{|%Y6`demtv04tpHTb7F}e zWQn%K!4ghj6y&?!lSOC$v+uFeKK+M3+w#EYcHwL5JAEAN?SC|A>+2o|n@8w&MCue5 z0-WM(EEuE3*XmK%7upoJZ{IXniZr#f_$?2)@h<=uQLUz2kJi7?a+{urgBOSWJQ!A( z)5D32MbPDL7U22!6x`!r%!EI;esSmK90zOt19;1AdLj;99oab!1~|o?VDWxCt<(Fi zz4Z)tFIo%jTB5D5_gdwx$M~MCRNDb{xfiYFgM}^tUE*Nu5aV=)3H4~}tDf#bj_M`-z9KP`#xu%g=3SfsrhNXyqYsJDKt9-#%& zJ>%f+=fTzS)RFHEZ$0$CWL-p|rjW&?iw`oKYP!n|(DJo2##_HukI(|?h=W&0ww~|O zG05MG{*d1f_SRFKuPqNb$L|N9VYIkbiw^gqp$YhV(X?XSXG}4`pFIzj-neLNluqMp z={@RvTxsQLe#NGZUhM;##w}Q+Te%Vol|<96+^O~3chP`i@Y3|u4K%y{Td&O)a<|^s zRH-V;rzJwVs%LinOZ|TE>>DBv{c$gPaahiSwe}Xeya$TGv**Es=pXK0bS$$x)cW(~ zCm7P-hK>K`i!b-KI2bI3Z;mATz5T1(2R?&8FG)unEa!LhuWlb&bL^DqU_ivd!rU(Y z)$K!Tj-4_cM(y$?x@QHBJ_}Wp&otj@2T1gL``5P5GtUQ8OP4PS7z?eY;foH5ekQkz ze{K6j9K1Lp4)%(J2Z^&I4xS9!_UUjQ48Hh#(N6Dy0*f&2gc6{5pSj{nLNZA+(tJv+IvIcy;8-<6vBo!m{M^#9IFJaj-YE?K7Hw%M7kM zY4HmVAU*w_tWV)*(*_Fr<@s0;l_<;&zL|gNca!$7S|rzt0#D)6wb_kaM5X)8m;ivIG?mbx_ z2g3}mIys&3qdYHr)QpRJ_IY9_ez}VlrZc;9PPJY4HpatPxJ4LCCc%Z1es6xn!K(v$ zD-&RQl~WkIoCjBzpq2+rqv=*ItxL;8OJPU--h6up!xM8tzM+8_OP3C2EVK$v`n~xP z2d|Fo90yl(g}czg^2qtCw|;N_aOc5Vc*oh(x6kYq2=Iu9&lX2?@ZyLLUL4WEiz7OC zaYP3%j_BaU5goiZqJtMlbnxPc4qhD5!HXk0cyUArFOKNo#ql2|gG~As8!wjt0000< KMNUMnLSTYzQ*Y`3 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_restart/config.ini b/cinema/gb/samesuite/apu/channel_4/lfsr_restart/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr_restart/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_restart/test.gb b/cinema/gb/samesuite/apu/channel_4/lfsr_restart/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..67806ea6cd46bfbe208749fada47373a22dbfc61 GIT binary patch literal 32768 zcmeI$eQXnT9LMor*RCtjm3ABBHp_M$qn3eVJO~x*QRmzyB3491K$tv~N9P2D1CCo2 z7CgFRyeyQ8BW9GDK z*O|s6hwEP3v3;=gk76sXc%Ekwfb1BXh24$v|^`tS#p0Ro{uZRvg<<$GFIZQDTzef$)PBW z8S6Hi!{K&|;*D#;YqOP=8D0z516**Qd{*b#yg!^A=KVEtc$B$YcvOvS z>}M>>vT;tn|4rB7Fk@;cdVQ!N#)5(zlw~0~RMlL!+nr89C@Hydo#(aNqfx_qy&-QX zr1YORPgR{x?xmV4Rk8D7uJa!J+T6nMs#;#oALsNsynK(&{mr*Xu3vi}RkGV9?gb&l zze9y;$XMV$`K->fd4E-MnET1f^lEdr>D97g>}M=0ig8Z9|4r9bRg87it{*e9FJt+o zS*2Y|S*dG|km8yp#kL)D79Hy${uRF<9oH)o5lg*~)w#k2>EhKywZ*r^>S6B0r`F^L z$G(rO^}1cR>1k3-PnB$X#|1sDUhlq$#W$>MdVbTY%d3jDiP~IE)n3%hcc2YZ~oz{NWTC{W8dF_JsP1A{rZ057rJS{uxi~wI=%6rO4@a{sh0?ktj+{%&_pE zlK-^k-(y?*!S;ygvRhrL*^az)e~;nV-_D$j|%iEc_A+B4bXZ4hpl!jWdEv~2| zraZNH*>WlW!I=w|geDJobnY|5d%4o?d7@Y~qtcZ+XC-R`ekFKdH78b6mkrfZyU7x|r4$%F+#U1=NnJUVtdbj0c{9eL7)|ZiwK-Ypap@m2%JISGy*3PXhz^T0>=>05%>*(!wCF} zz|RQ$gusso{D8ps2pmA55rOXz_!fcv2z-seUIca{unU2m2z-ga7YKZYz$XZNjKEd| zK1ASs1l~p99R%J+;7tVHK;U%*HY4yV0-F%nh`d9U1O_2cf{Shca zAb@}$fkFfd5D*c_L%@qbE&>7q*$8AIkb!_30T%*J1iB*NK){ZG4S^H{7y|7o`1it9 z1lka|fM=x{LX#f*Ibiz(H$x)bx=x3NJ#d= zdB@9p^Ygv_XurtbC^W&I5E7E>xZr4iHL-XdW}k0#LZ<4Y;^!gjfMhnQ-*^+eI9dM) z{fhg==uN1Cv-7z@oeSDEO~l1$^%Rg+O%rQ(`!=!48kz84*aka=meMtsDVL&#yW4A! zI0TjX)YOOdqQ5<`s5t|pgf_po+gr>f5@VDU&E;XiM!mu{1BRJdblM(5&t=5(%JeH&=vm4k8PSX1FS_1I8ob z#1K;BZvDJR@25kA`yQibqE*4cE#KBFP81JWZd_gIC|ER-n!|n3>{#e(IBI(=dGQTS z*%mysNLDVgu`}s_QPks$EtD$5!oP;;Gqkyz2g?uCif*jGmRfV#lic;PCj&fShgo4`a%$BLl-QQ~tIb5TgxG6uF%pp|R6$}Vox{7bWxM(H#}y;$ z%eA^6;iM>NUm`ifh}RCZPzm1t+=gvZ^x?U=xif+M)BQifpRg$Oh*w$MnTG?Qn*!L; zt?JndU8J)A6}{3tF8t4~_0BkLgh$T57xjNg*nEQ6t3u)f4l&*y3(nW@Co6lt-W+A% zNFczq@WtfYfrF=k zq!w2$>FLSKX>j(sy*$T2Ue_XNMbor}r zndke|;JCA4-a9>u5hioPbUvw-dsVuy-*!44Q^O`)BeiqV2@%{30qTE{Q(_aqznkc?uddJ zL!rHTX{yLw3RQo^QBe6mJhd%RTshZU{hXxU@>I9v10GD4`p?*!lKOlcI_Uwc_`-+u zOX_lj?!m&4Si;u#c$RGHYbY6T5y!aCKhMT5=pIo&OR9A@(DtT1)!7N-y~6*V-bYQm~4w z1##9?&wQGt?IV(tgIJvn$pI-DA7k19V^^h_!`i=PRBc(TvrbQXVj9oSYSjE0XgO}x zafLF&CY&n!*!8kUd)HX|aVlZuF5s%}1j2q-)k|Q8@(}}iB`pSr*mf#b^+zG+Ks$b? zmmtggI zH<$S>tVBAeaYQH2-%MelrtNN`TXm-3I4!-jki3jVU|c52CpBP(C8Pyvt&1Xq&w#CJGiL>tMp*u?6y!8Ldco=D|Xw%5)5!+!1tA{{7S@$~Wbkb> zF(uScgQ0(W=HAZSrv*p0+wWgpa5@|5K-hn%-YK~@drw65iU)_Se-4tEJsDesrTP+8q<;)H3d zynh#}Mk{)1>PgcE#k@qEK4>HlZr{tvR_;6kbR|{u0|KJPO8Zb&asoN9v9`(lwsu_=>d*vJ*6q)l*LIe>N@176dwWEBr?N^fb|bZ(Yu>WC?Qu=8$tPh>CLoLW(=8HwZ_d@0_s*1v#I5l3XQdxP(Ez!MK@`F#zfb^?Opd5-_ciB#~0%vB(FO4haW2R z>;Bz{2ZLs1O9x`oPl!CRa}kDs{7R-#OM1x)1tPZ&EK-nuVJPS}<*x{7Kz{N;4=p`# zZjUHUL`<%dld09_$&3MeuOe@RL0ssA>7WCx=mk_gA=eaLdfXj_@G!hBXe4(wi z?)d)R+Py5->3j3ip?}mF`ujb9GzkPbo%f0Vh3JGHSi^p{r+1fYT&wz#-zK9MgS?DR zpb#K!wX{Kg=wZ2JJ;A_AnMAQi9_mh-t~R!7bH3r)HGw0Mu}h~Ia!aSyP5nlosZMX^ zy1ba~oqFD2+~o%ajD$GWCcP*Ade5VWqx>qP*ho*_Y)7m#@SPisA!TStO`qhtswSC! z?R0ji9U+Bm1hkSSgRmq}T~}jcC{3 z9vCV!0&LJaAE)?fre_!a__)P4f*Lkvk<@Yj-JhsSJb?2W%uw(%Iwg~!EOh;*@hr|f z?mRKxz)Y-hN%A4$ZcgslS1^k|-`er{PkU8I3;Bn$l}X2`Pnv=W5v{WKEq+$wwYk^O z&A8N#+VLO!ux+VI+Fe1&_Wk4f@+Lc(w#LrHQps^7r z9kjQDwATa<@VPG}2x*n*#!iw#`X@7Ix2Q$CteU2*TK%ov7$4=gDk(LpDBzE=Qd@nmYlVS~0 z@gWq5nY^x=M{&4>R7C?cWA00GJh~@sfOh-D>Li1tTZ!YmrtO2M6XX+eY^{@hd9a$> zv$xtk<|YhzPjQaH;Y8z;JKo#tgvqXH2r=Tq) zTJ$C_;C9+YxYoJ247(Sm)ORv7HhBC;7#CIYTxc3SyfQny5!IY#k1Aw*W1Bu zKN|MTOB73x2mQbtn=H@H-8<<^#qP;pcr~;!#DMmWURJ%Rmsi}DcB|)H(Sl%6VM$>7 z_${m-Yc9B!m}HcvC+f3PeVlf&Pw2*~!kZ4!wh7etH1>1$lo@GuK0w7dzdeghXug~j zX)R&i;|SC`v*pG8w@{zBh<-FD6T#-WtD4%T>BBF}HiO zaOwGjb!-0;>qQT*23Kpf}7%J0a7m7Nu7CrE>-W==53>5*v4YG%)N1cKhzV#p*cV?FE~%J7_NHMXC=RwkIez zIbLWQyWQ>7ID^S100QnC5j|(Gqu)2vb1A9o?q+Ik06;M8{8C!B^DLetpzdBd1%g{H z7J!AMSGTJOBUy literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/config.ini b/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/test.gb b/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..46fb4e4180b945b2edda530ffe22e16704d98579 GIT binary patch literal 32768 zcmeI$|8Em@9LMob*RCtjb?r9B4a;^dqn3ee1B8n8R^}WN5ho%dAWXgtggGbRxWRF& zf*cw(#1O*JpcpmAZ$t4rNcf_}x)sETQ3K{6umB<%-(ix?&-FGSCcgdw-ktIVw>!CxxH*VcJcUFz- zRLh}*jc;uIdYJT|Vo~$j!dTVlD;L@#tyU=#euqK6x=}d~h+3JL=nH z$xqKn72D0TaoJqlTx?8T^s#7uL3)O?Vw-qLa(^qHjVYnhYeNY!R_LxRtf+7&hN3WL zxXtEpxZR?7{aWzaY^9~fdO-*Z!C-l?yj)Qn4!%BI8Bt^#AEwKp2){PBFxD#yf1bnP z5SYOCFrRO%G*%?M>wT24%@*eC-R_Xv9SjDQP>`?S>l4rFKAZPP62rW|R*sA_cZ-ax zm5u!jlx5?bc>f!&BN4{baMiV;h8YV9a!8hi#86e!?RKYA5DE*gU*~x3_Npplz1JJ| zhQrF>>S|SWI{A93wo+B>e3;IA@N07mW4)@DmGQ?py$&zmqkDhzEfU`KKB{E5OMJZ` zg!y+kPYoNu*C(FUeKzl}Obl~BS(#m9?l!wdR*d}&R21W!c>f!&D=Qi6Y*;&C>_EnH zOEOD(mar1nd?Cp-Pl|3i;>PCBZOiC0*fe5}zG@u!Mc<24rFCaZ_J7D2FlqNl`j>XokJn;O6RhL!`(WYt(G*x?9Yt-J+KGL>m zUuxU5o!W8jgmzNwv(OvRwQodr|LP<5`94Y1b?XkhxhM{@s|qdefeCTWGv&ex|`2= z^em}OPuKfMqVDw-b~gFDMnU(7Sd$)z<;RO`sp6Gbe3vyo$Szf!?BGub=$-NW=)NlN#tf#4n`SOUf%ISI(2;8)kL2K6 zdD!1gNr9r)v@oBrW-M>b?Z_0H4`i_%XZC)jV}tnG@(w1hi|H2WSv{#OskuRHk11;L zjHi|?TQ223Fn3XXczVGj3!WL(&y{lb+XDPNT2)W49#|y^?xupasKUnQ|;E# zV#U10OYh1_8#C+a(6pM7Q=c4h%l(0jd-Em?%p5x)y@##D=PsYU@DA_zTOWF2_>|kS zdfnsqI7(+03FE4UJvw;OpojB&_e@T*ut;UCta#XtrgUDmKo9tqbn@SfPjcvf{(I`L z_m5v~P~*O=|I>D;m!V#SdLHUosBKVBLp=rcB-GdIYKt^-rh=q5c8&H>kft z{RQgJP=A8D7itUCAEEvLbr00ZBrr%*RT{TS+pP~V68 z9@KZCz76#)sBc2u2=#TS8=$U-x(@1EsINj@1N9ZCFF}0~>T0N~pss}a9MmXO6{-St zDO4G19n{587ecLtS_8Ej>U^m4pjJVh4Rt2eN~qJJPJ=oH>SU;spiYE30cr)*@leM> z9SgM_Y8lj0s3lM%P$j5gsH32UppJk#9O_W0g;0k;9Sk)eY7lAwY93TSR1s%N zPz9)2P&1*XLv=%SL3Kjy3Dp7B4%G%V2`Yoyp`w4`UWM8Y^)l3pP|rg>3$+dE>4e5w zqhtDRZZ6J9kD33?NoOiR1*iZOpaN8Y3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl z0V+TRr~nn90#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl z0V+TRr~nn90#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rCfC^9nDnJFO02QDDRDcRl i0V+TRr~nn90#twsPys4H1*iZOpaN8Y3f$ZUV*dgd&_lZb literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/test.sym b/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/test.sym new file mode 100644 index 000000000..31a200412 --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/test.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b RunTest +00:1621 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_4/lfsr_restart_fast/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..d425c2d3f4e1d9835b7fcc3537f6ea5b2c189ee6 GIT binary patch literal 3829 zcmZ{nXH?Tk+s5fiuToS%ii&`Miy$QiAwYC#Hrh%ciWDVuqy}Py4FOS%E^P%-lx3xf zR4GCtB@`jDB1LHdLQqN)LP#Lx|Dw<5cg~ra4>M=x{LX#f*Ibiz(H$x)bx=x3NJ#d= zdB@9p^Ygv_XurtbC^W&I5E7E>xZr4iHL-XdW}k0#LZ<4Y;^!gjfMhnQ-*^+eI9dM) z{fhg==uN1Cv-7z@oeSDEO~l1$^%Rg+O%rQ(`!=!48kz84*aka=meMtsDVL&#yW4A! zI0TjX)YOOdqQ5<`s5t|pgf_po+gr>f5@VDU&E;XiM!mu{1BRJdblM(5&t=5(%JeH&=vm4k8PSX1FS_1I8ob z#1K;BZvDJR@25kA`yQibqE*4cE#KBFP81JWZd_gIC|ER-n!|n3>{#e(IBI(=dGQTS z*%mysNLDVgu`}s_QPks$EtD$5!oP;;Gqkyz2g?uCif*jGmRfV#lic;PCj&fShgo4`a%$BLl-QQ~tIb5TgxG6uF%pp|R6$}Vox{7bWxM(H#}y;$ z%eA^6;iM>NUm`ifh}RCZPzm1t+=gvZ^x?U=xif+M)BQifpRg$Oh*w$MnTG?Qn*!L; zt?JndU8J)A6}{3tF8t4~_0BkLgh$T57xjNg*nEQ6t3u)f4l&*y3(nW@Co6lt-W+A% zNFczq@WtfYfrF=k zq!w2$>FLSKX>j(sy*$T2Ue_XNMbor}r zndke|;JCA4-a9>u5hioPbUvw-dsVuy-*!44Q^O`)BeiqV2@%{30qTE{Q(_aqznkc?uddJ zL!rHTX{yLw3RQo^QBe6mJhd%RTshZU{hXxU@>I9v10GD4`p?*!lKOlcI_Uwc_`-+u zOX_lj?!m&4Si;u#c$RGHYbY6T5y!aCKhMT5=pIo&OR9A@(DtT1)!7N-y~6*V-bYQm~4w z1##9?&wQGt?IV(tgIJvn$pI-DA7k19V^^h_!`i=PRBc(TvrbQXVj9oSYSjE0XgO}x zafLF&CY&n!*!8kUd)HX|aVlZuF5s%}1j2q-)k|Q8@(}}iB`pSr*mf#b^+zG+Ks$b? zmmtggI zH<$S>tVBAeaYQH2-%MelrtNN`TXm-3I4!-jki3jVU|c52CpBP(C8Pyvt&1Xq&w#CJGiL>tMp*u?6y!8Ldco=D|Xw%5)5!+!1tA{{7S@$~Wbkb> zF(uScgQ0(W=HAZSrv*p0+wWgpa5@|5K-hn%-YK~@drw65iU)_Se-4tEJsDesrTP+8q<;)H3d zynh#}Mk{)1>PgcE#k@qEK4>HlZr{tvR_;6kbR|{u0|KJPO8Zb&asoN9v9`(lwsu_=>d*vJ*6q)l*LIe>N@176dwWEBr?N^fb|bZ(Yu>WC?Qu=8$tPh>CLoLW(=8HwZ_d@0_s*1v#I5l3XQdxP(Ez!MK@`F#zfb^?Opd5-_ciB#~0%vB(FO4haW2R z>;Bz{2ZLs1O9x`oPl!CRa}kDs{7R-#OM1x)1tPZ&EK-nuVJPS}<*x{7Kz{N;4=p`# zZjUHUL`<%dld09_$&3MeuOe@RL0ssA>7WCx=mk_gA=eaLdfXj_@G!hBXe4(wi z?)d)R+Py5->3j3ip?}mF`ujb9GzkPbo%f0Vh3JGHSi^p{r+1fYT&wz#-zK9MgS?DR zpb#K!wX{Kg=wZ2JJ;A_AnMAQi9_mh-t~R!7bH3r)HGw0Mu}h~Ia!aSyP5nlosZMX^ zy1ba~oqFD2+~o%ajD$GWCcP*Ade5VWqx>qP*ho*_Y)7m#@SPisA!TStO`qhtswSC! z?R0ji9U+Bm1hkSSgRmq}T~}jcC{3 z9vCV!0&LJaAE)?fre_!a__)P4f*Lkvk<@Yj-JhsSJb?2W%uw(%Iwg~!EOh;*@hr|f z?mRKxz)Y-hN%A4$ZcgslS1^k|-`er{PkU8I3;Bn$l}X2`Pnv=W5v{WKEq+$wwYk^O z&A8N#+VLO!ux+VI+Fe1&_Wk4f@+Lc(w#LrHQps^7r z9kjQDwATa<@VPG}2x*n*#!iw#`X@7Ix2Q$CteU2*TK%ov7$4=gDk(LpDBzE=Qd@nmYlVS~0 z@gWq5nY^x=M{&4>R7C?cWA00GJh~@sfOh-D>Li1tTZ!YmrtO2M6XX+eY^{@hd9a$> zv$xtk<|YhzPjQaH;Y8z;JKo#tgvqXH2r=Tq) zTJ$C_;C9+YxYoJ247(Sm)ORv7HhBC;7#CIYTxc3SyfQny5!IY#k1Aw*W1Bu zKN|MTOB73x2mQbtn=H@H-8<<^#qP;pcr~;!#DMmWURJ%Rmsi}DcB|)H(Sl%6VM$>7 z_${m-Yc9B!m}HcvC+f3PeVlf&Pw2*~!kZ4!wh7etH1>1$lo@GuK0w7dzdeghXug~j zX)R&i;|SC`v*pG8w@{zBh<-FD6T#-WtD4%T>BBF}HiO zaOwGjb!-0;>qQT*23Kpf}7%J0a7m7Nu7CrE>-W==53>5*v4YG%)N1cKhzV#p*cV?FE~%J7_NHMXC=RwkIez zIbLWQyWQ>7ID^S100QnC5j|(Gqu)2vb1A9o?q+Ik06;M8{8C!B^DLetpzdBd1%g{H z7J!AMSGTJOBUy literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/volume_div/baseline_0000.png b/cinema/gb/samesuite/apu/channel_4/volume_div/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..189f5f28961501ad55dae3c4b4dde02a9f9e5458 GIT binary patch literal 915 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|RrEr;B4q#hkZu&h{;~l3;y% zZBOF+UGw?lE|)*lKK;-;6Tu%s_h!b_9A@AyqCQTK08 zF6%za)|nnubk1~QP}Q+Q)#rEqMf5-Rs6Y0M|Kxw~?MJ*HYi%+9|L@_IlJJ?Z+0&rqtEdy{kLS{%pUR{0Yl&bMdF&zhD2u z+q$W{@AQ{j&X||Kb9a5? z_K&K^v&|#__8$}8z%D;&JNx0!-x8|!-Dtj8S#2;!*LKJJSNpT~vFpFdea3%oyY-H{ zpX%kldml{Mxnp*Jx99J>yEi}MKa>CRV758a+Us;yevCc+E->1!=d;d~%>{b0EAs@6J7BCs!Pc_(ZO`rZ zndwjLwXJB5t>lc?TzYH%tXpBr<$AYkFL-eJspKC~sx_^REb z&kru&xYzvLSnp!~B%rINr#$h!ajE%w-~7X~znm*S4K(*g^Fv_J+vM}NZT?$X5UoBv zf72}{BjZi#`hpPQWd642Zx0rn`?p`~X^IGs`@w>tPCU1t;j<#pFUBGcl-WF8{an^L HB{Ts558qx*~fhJ_$Z7;H*PODG2LT zuh(ejP9FpxWLO1d4?c+mnIh6Dn?vD9&$5R;3|9DexZ*mMc4ZrOlK8*7rtL|x-xwDdt5jXO0Yeu`@5%b)_2aM%fX<`@`8|K z|G7hY&R$@7=ULU>y+7|XcRy7-IpOYhazfSY{p>|evwP?K`^Nb^A(hz=pMUNtLi&cf zhT4b7Q1n%yC3;FOT)Y|1+&m~gG`Hkm=`m}}SCq(nR7pm}zpV+Mbip4Zy!DOWc@w(& zmA^=Xl%uV3fd*ubR<>wsk#?LR=J~VB?|gjj!MP*Gi^gk)ZoF^I8=o6r8W)XkjZ4NA z<2U2Bv2NTkHjGWI_;8ToZ8pdw=*N?v`3Ph8GF)y zV!N{RC%0Z%nsaV=LZ`j*6g_O+W`{bwdhLqI4wa&hv$;dE9b>bUXLB*yEpO0H`j{-z zgfvhoCU;tY^^IAiDKldYauM+_)B4eG-3iEJ>t*(Y6s=g9fc3JEeMco$(e-?Toi( zYG=Gt}!F5hYYN=B=W-F>fK&jd^RSZp>Rwbz|O&svGkbRo$3d zS7vA2bbqnXLjVF0fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz T00bZa0SG_<0ucD`37G!?43xH% literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/channel_4/volume_div/test.sym b/cinema/gb/samesuite/apu/channel_4/volume_div/test.sym new file mode 100644 index 000000000..36b01a6dc --- /dev/null +++ b/cinema/gb/samesuite/apu/channel_4/volume_div/test.sym @@ -0,0 +1,45 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05eb RunTest +00:05fb TestGroup +00:0a7c StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/div_trigger_volume_10/baseline_0000.png b/cinema/gb/samesuite/apu/div_trigger_volume_10/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..3cdc8e21b55307fd46881cde942d960dd12075c7 GIT binary patch literal 787 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V17PZ!6KiaBp@IZm2wAi@xM za;oql$;9WzTHIP%k%x>D(sHc+hDp@T@iYy{@bJ*|y)43Y*<|SyzdQHkV)Rx%)%sC-?l+5jddRvcabR>6V`#->mujGvm*4t1YK~20yDlpQ+@ruKD8UbG(^UYs+Ka z)Nc5;>xor`%yEc@C$$BYLQ`(D-(x@S^fkEbnKQ@t-*zi<9*8D#mvF2erp3DG-pcP-wF z{`skG5nsPQ^Szb+oBy`A{#(!gw*P+a{&n{E<<{Pd-{v2&`tw`4=ke!u^R-!jw!iz5 xTT{CaVY!8TB0_jL7hS?83{1OOW;bsGQx literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_trigger_volume_10/config.ini b/cinema/gb/samesuite/apu/div_trigger_volume_10/config.ini new file mode 100644 index 000000000..8f7eb1c12 --- /dev/null +++ b/cinema/gb/samesuite/apu/div_trigger_volume_10/config.ini @@ -0,0 +1,2 @@ +[testinfo] +skip=80 diff --git a/cinema/gb/samesuite/apu/div_trigger_volume_10/test.gb b/cinema/gb/samesuite/apu/div_trigger_volume_10/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..942cd804958fdd5a09f1307712b764f61e48d918 GIT binary patch literal 32768 zcmeI$QD_@=90%}!noF9^B)v3ky-IBE$`)dfwZ#YXaNI&EU6DNmp9CKkaK@pdRD|}b z*K4G6rw@V;GFAm;4?c+m87k5_Hiv^FJyP5j?ovK1dh25nOO z{*wE1|NsAY|KBg4G%qFOe;pI#N{Rda_k4anL>}?JMrKHmgh(I~fBPL0zCJ%%URwHb zc5d#a7e>Rs%`aV_{dn%{r<8w)72LUpkUanDowZE4kPNO3Ro)Xf+5I%lteb4{Zo$3@ zlL%js&UsSp(U7?5j`p;4xOCWFx+{@Fs;@n&%v=!fDf~C$ZBt7R-488INIyT;pUv`4 zXc{5*KF0+DJTHn5=0c3)hKB5XK}ZV8Fzh7bbf*`ZE zd_b4&4VLemRUh5wb56MRRPFevTkZI$s@e7IO--{$r~hs9T#k_H^!v{~^8_LB!H&WG zgJdxLvd|Jfp%l)q1XC-W;-BV*@-sbRWj#fS%!V_)A#uwZ^+@Nu5yD$vc%7TTmCwCJ z>ZcrSRSMLnaJ0HXTZ^=9oS0`$Exz@^>3gRS8P6N97`pMUF>8Ecd}f?CzA`QtmyKVH zo5rf~tFdOR8@G)ORig0Q?9TjjIA9|>@>DYdA1gzUCJ75r;jQkjY<90 zVs9<_>NjSQCd`yIz=gy=OzT^(^^;G@u2$Fy30k#MKI=sf`;_d{y1&QG%0eY8hW*~K zuPe|KN^~CT6 zNUvIMW8>tul}Tr1|Bc1viwTn4cSjj!{j4VjN>8&5>C|#>eXAugP;Qgif;T!Uj7dGpo3v%Er8F&Wnr-z6*CJF4_Sb4hDWBXb<;5*i;V+7R znGteH;;IwY5591sxYD;mqc*9sPTQ3k_Kl5Ki(iUfYoGStN9$JSzno~5d^>XJ4xYQS zNALLQyHQ}5YV2N_U9Gg+#TrnrF(n&TwULDzT)Xk*o1%keX`+exXs%Y8uA63Ts7ZTj z-nN>$vu1B@5A?S;THG^T?xjZeSg#M?uGtMjv_ literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_trigger_volume_10/test.sym b/cinema/gb/samesuite/apu/div_trigger_volume_10/test.sym new file mode 100644 index 000000000..ceca33fa2 --- /dev/null +++ b/cinema/gb/samesuite/apu/div_trigger_volume_10/test.sym @@ -0,0 +1,305 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb WaitDIVEvent +00:05cb WaitDIVEvent.waitOn +00:05cf WaitDIVEvent.waitOff +00:05d4 WaitDIV10 +00:05d6 WaitDIV10.waitDIV +00:05da RunTest +00:0602 RunTest.done_u16403 +00:0608 RunTest.done_u16405 +00:060e RunTest.done_u16407 +00:0614 RunTest.done_u16409 +00:061a RunTest.done_u16411 +00:0620 RunTest.done_u16413 +00:0626 RunTest.done_u16415 +00:062c RunTest.done_u16417 +00:0657 RunTest.done_u16421 +00:065d RunTest.done_u16423 +00:0663 RunTest.done_u16425 +00:0669 RunTest.done_u16427 +00:066f RunTest.done_u16429 +00:0675 RunTest.done_u16431 +00:067b RunTest.done_u16433 +00:0681 RunTest.done_u16435 +00:06af RunTest.done_u16440 +00:06b5 RunTest.done_u16442 +00:06bb RunTest.done_u16444 +00:06c1 RunTest.done_u16446 +00:06c7 RunTest.done_u16448 +00:06cd RunTest.done_u16450 +00:06d3 RunTest.done_u16452 +00:06d9 RunTest.done_u16454 +00:070a RunTest.done_u16460 +00:0710 RunTest.done_u16462 +00:0716 RunTest.done_u16464 +00:071c RunTest.done_u16466 +00:0722 RunTest.done_u16468 +00:0728 RunTest.done_u16470 +00:072e RunTest.done_u16472 +00:0734 RunTest.done_u16474 +00:0768 RunTest.done_u16481 +00:076e RunTest.done_u16483 +00:0774 RunTest.done_u16485 +00:077a RunTest.done_u16487 +00:0780 RunTest.done_u16489 +00:0786 RunTest.done_u16491 +00:078c RunTest.done_u16493 +00:0792 RunTest.done_u16495 +00:07c9 RunTest.done_u16503 +00:07cf RunTest.done_u16505 +00:07d5 RunTest.done_u16507 +00:07db RunTest.done_u16509 +00:07e1 RunTest.done_u16511 +00:07e7 RunTest.done_u16513 +00:07ed RunTest.done_u16515 +00:07f3 RunTest.done_u16517 +00:082d RunTest.done_u16526 +00:0833 RunTest.done_u16528 +00:0839 RunTest.done_u16530 +00:083f RunTest.done_u16532 +00:0845 RunTest.done_u16534 +00:084b RunTest.done_u16536 +00:0851 RunTest.done_u16538 +00:0857 RunTest.done_u16540 +00:0894 RunTest.done_u16550 +00:089a RunTest.done_u16552 +00:08a0 RunTest.done_u16554 +00:08a6 RunTest.done_u16556 +00:08ac RunTest.done_u16558 +00:08b2 RunTest.done_u16560 +00:08b8 RunTest.done_u16562 +00:08be RunTest.done_u16564 +00:08fe RunTest.done_u16575 +00:0904 RunTest.done_u16577 +00:090a RunTest.done_u16579 +00:0910 RunTest.done_u16581 +00:0916 RunTest.done_u16583 +00:091c RunTest.done_u16585 +00:0922 RunTest.done_u16587 +00:0928 RunTest.done_u16589 +00:096b RunTest.done_u16601 +00:0971 RunTest.done_u16603 +00:0977 RunTest.done_u16605 +00:097d RunTest.done_u16607 +00:0983 RunTest.done_u16609 +00:0989 RunTest.done_u16611 +00:098f RunTest.done_u16613 +00:0995 RunTest.done_u16615 +00:09db RunTest.done_u16628 +00:09e1 RunTest.done_u16630 +00:09e7 RunTest.done_u16632 +00:09ed RunTest.done_u16634 +00:09f3 RunTest.done_u16636 +00:09f9 RunTest.done_u16638 +00:09ff RunTest.done_u16640 +00:0a05 RunTest.done_u16642 +00:0a4e RunTest.done_u16656 +00:0a54 RunTest.done_u16658 +00:0a5a RunTest.done_u16660 +00:0a60 RunTest.done_u16662 +00:0a66 RunTest.done_u16664 +00:0a6c RunTest.done_u16666 +00:0a72 RunTest.done_u16668 +00:0a78 RunTest.done_u16670 +00:0ac4 RunTest.done_u16685 +00:0aca RunTest.done_u16687 +00:0ad0 RunTest.done_u16689 +00:0ad6 RunTest.done_u16691 +00:0adc RunTest.done_u16693 +00:0ae2 RunTest.done_u16695 +00:0ae8 RunTest.done_u16697 +00:0aee RunTest.done_u16699 +00:0b3d RunTest.done_u16715 +00:0b43 RunTest.done_u16717 +00:0b49 RunTest.done_u16719 +00:0b4f RunTest.done_u16721 +00:0b55 RunTest.done_u16723 +00:0b5b RunTest.done_u16725 +00:0b61 RunTest.done_u16727 +00:0b67 RunTest.done_u16729 +00:0bb9 RunTest.done_u16746 +00:0bbf RunTest.done_u16748 +00:0bc5 RunTest.done_u16750 +00:0bcb RunTest.done_u16752 +00:0bd1 RunTest.done_u16754 +00:0bd7 RunTest.done_u16756 +00:0bdd RunTest.done_u16758 +00:0be3 RunTest.done_u16760 +00:0c38 RunTest.done_u16778 +00:0c3e RunTest.done_u16780 +00:0c44 RunTest.done_u16782 +00:0c4a RunTest.done_u16784 +00:0c50 RunTest.done_u16786 +00:0c56 RunTest.done_u16788 +00:0c5c RunTest.done_u16790 +00:0c62 RunTest.done_u16792 +00:0cba RunTest.done_u16811 +00:0cc0 RunTest.done_u16813 +00:0cc6 RunTest.done_u16815 +00:0ccc RunTest.done_u16817 +00:0cd2 RunTest.done_u16819 +00:0cd8 RunTest.done_u16821 +00:0cde RunTest.done_u16823 +00:0ce4 RunTest.done_u16825 +00:0d3f RunTest.done_u16845 +00:0d45 RunTest.done_u16847 +00:0d4b RunTest.done_u16849 +00:0d51 RunTest.done_u16851 +00:0d57 RunTest.done_u16853 +00:0d5d RunTest.done_u16855 +00:0d63 RunTest.done_u16857 +00:0d69 RunTest.done_u16859 +00:0dc7 RunTest.done_u16880 +00:0dcd RunTest.done_u16882 +00:0dd3 RunTest.done_u16884 +00:0dd9 RunTest.done_u16886 +00:0ddf RunTest.done_u16888 +00:0de5 RunTest.done_u16890 +00:0deb RunTest.done_u16892 +00:0df1 RunTest.done_u16894 +00:0e52 RunTest.done_u16916 +00:0e58 RunTest.done_u16918 +00:0e5e RunTest.done_u16920 +00:0e64 RunTest.done_u16922 +00:0e6a RunTest.done_u16924 +00:0e70 RunTest.done_u16926 +00:0e76 RunTest.done_u16928 +00:0e7c RunTest.done_u16930 +00:0ee0 RunTest.done_u16953 +00:0ee6 RunTest.done_u16955 +00:0eec RunTest.done_u16957 +00:0ef2 RunTest.done_u16959 +00:0ef8 RunTest.done_u16961 +00:0efe RunTest.done_u16963 +00:0f04 RunTest.done_u16965 +00:0f0a RunTest.done_u16967 +00:0f71 RunTest.done_u16991 +00:0f77 RunTest.done_u16993 +00:0f7d RunTest.done_u16995 +00:0f83 RunTest.done_u16997 +00:0f89 RunTest.done_u16999 +00:0f8f RunTest.done_u17001 +00:0f95 RunTest.done_u17003 +00:0f9b RunTest.done_u17005 +00:1005 RunTest.done_u17030 +00:100b RunTest.done_u17032 +00:1011 RunTest.done_u17034 +00:1017 RunTest.done_u17036 +00:101d RunTest.done_u17038 +00:1023 RunTest.done_u17040 +00:1029 RunTest.done_u17042 +00:102f RunTest.done_u17044 +00:109c RunTest.done_u17070 +00:10a2 RunTest.done_u17072 +00:10a8 RunTest.done_u17074 +00:10ae RunTest.done_u17076 +00:10b4 RunTest.done_u17078 +00:10ba RunTest.done_u17080 +00:10c0 RunTest.done_u17082 +00:10c6 RunTest.done_u17084 +00:1136 RunTest.done_u17111 +00:113c RunTest.done_u17113 +00:1142 RunTest.done_u17115 +00:1148 RunTest.done_u17117 +00:114e RunTest.done_u17119 +00:1154 RunTest.done_u17121 +00:115a RunTest.done_u17123 +00:1160 RunTest.done_u17125 +00:11d3 RunTest.done_u17153 +00:11d9 RunTest.done_u17155 +00:11df RunTest.done_u17157 +00:11e5 RunTest.done_u17159 +00:11eb RunTest.done_u17161 +00:11f1 RunTest.done_u17163 +00:11f7 RunTest.done_u17165 +00:11fd RunTest.done_u17167 +00:1273 RunTest.done_u17196 +00:1279 RunTest.done_u17198 +00:127f RunTest.done_u17200 +00:1285 RunTest.done_u17202 +00:128b RunTest.done_u17204 +00:1291 RunTest.done_u17206 +00:1297 RunTest.done_u17208 +00:129d RunTest.done_u17210 +00:1316 RunTest.done_u17240 +00:131c RunTest.done_u17242 +00:1322 RunTest.done_u17244 +00:1328 RunTest.done_u17246 +00:132e RunTest.done_u17248 +00:1334 RunTest.done_u17250 +00:133a RunTest.done_u17252 +00:1340 RunTest.done_u17254 +00:13bc RunTest.done_u17285 +00:13c2 RunTest.done_u17287 +00:13c8 RunTest.done_u17289 +00:13ce RunTest.done_u17291 +00:13d4 RunTest.done_u17293 +00:13da RunTest.done_u17295 +00:13e0 RunTest.done_u17297 +00:13e6 RunTest.done_u17299 +00:1465 RunTest.done_u17331 +00:146b RunTest.done_u17333 +00:1471 RunTest.done_u17335 +00:1477 RunTest.done_u17337 +00:147d RunTest.done_u17339 +00:1483 RunTest.done_u17341 +00:1489 RunTest.done_u17343 +00:148f RunTest.done_u17345 +00:1511 RunTest.done_u17378 +00:1517 RunTest.done_u17380 +00:151d RunTest.done_u17382 +00:1523 RunTest.done_u17384 +00:1529 RunTest.done_u17386 +00:152f RunTest.done_u17388 +00:1535 RunTest.done_u17390 +00:153b RunTest.done_u17392 +00:15c0 RunTest.done_u17426 +00:15c6 RunTest.done_u17428 +00:15cc RunTest.done_u17430 +00:15d2 RunTest.done_u17432 +00:15d8 RunTest.done_u17434 +00:15de RunTest.done_u17436 +00:15e4 RunTest.done_u17438 +00:15ea RunTest.done_u17440 +00:15ee StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/div_write_trigger/config.ini b/cinema/gb/samesuite/apu/div_write_trigger/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/div_write_trigger/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/div_write_trigger/test.gb b/cinema/gb/samesuite/apu/div_write_trigger/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..43c2ce2a9dd2210bebe00c7336f6f1f5721920c0 GIT binary patch literal 32768 zcmeI1PiP}m9LHapX&TogoiyD#mDo(mZirE~tscxF%!X3BMfMOp2_81!8W&wkL1?Es zokqIu=t1xxi(Nt4gC~(7i|E>J-MT0YX)Jr_LD<4;af4g`khF9ct0umgNwcjaVg6mj z-)m>c@Av(FfA8f}-l+)vuh$g1nWujEEt6UCqKBQYp*iG1UgY+N-hK!9Zm*0N*VliX zUs!ng#c|)SE9;;lnL(cmXgJ6)KeO%yvOd5&$BpLmPzwoR{7vV zemWbz;)rzxyzHL#R?7Uz{7I#CFO0IWfvx~Ix5(b-=iqGMx%;C2&#BApa?iY!g%<4IC$TPS`(AoJXA zH-i|mhc;hvDh^ezokvJeRD$?vI!@EkXjF(tiG%pnS^IA-pH!EYpWu_HwcV1ZCwOH) zMdW$qt)BltolGJmCNlLUCJ>4`O<~8w=Q42fANI$g7m5+O7BYZ(kIeq(pBk8X;E61ewOY^ zThcF5Nh(X*(vI}q+MQE9DD0s4V#k@@-WU#uxI65p_)sWR>o6kj4Tsf^(sZ8LtFHb| zZB>^`T5@8 z&lfw%d-_0UTJ0RUv$nAmLD7eHxlwYSa%3p~3=zT?Hv0Faw#ZPiGeH{8z)Uez>1Ok5 zJ*dyqdrPQXWF_F-4|hm?sH4^gI<>mqsn@m6fm-bx zs!4~Vm)O6jWIwtQrm9oENN#gr69>3&$ls}pTgKhng~`6gO5q7tOHqfe&!XF9#AwiK z+-@piHe?}ZEowP!#{ipVG#azi^d8iemN6pg(Dhk#yNnnOdX3vnCCr8_d^IBbi0fg4SJ2+O(o2R zEaa?3EvM}mVAG67W4>;B59&(G7!h^o`YgI#MvMl%#_gsOWf00e*l5C8%|00;m9AOHk_01yBIKmZ5;0U!VbfB+Bx z0zd!=00AHX1b_e#00KY&2mk>f00e*l5C8%|00;m9AOHk_01yBIKmZ5;0U!VbfB+Bx l0zd!=00AHX1b_e#00KY&2mk>f00e*l5C8%|;J;2l{s+eX9=iYl literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_write_trigger/test.sym b/cinema/gb/samesuite/apu/div_write_trigger/test.sym new file mode 100644 index 000000000..f78eebc84 --- /dev/null +++ b/cinema/gb/samesuite/apu/div_write_trigger/test.sym @@ -0,0 +1,46 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b TriggerAPU +00:062d TriggerAPU.waitDIV +00:0632 RunTest +00:1e76 StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/div_write_trigger/xbaseline_0000.png b/cinema/gb/samesuite/apu/div_write_trigger/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..a3711182199aab9001e017fe5c57ed23b4161b42 GIT binary patch literal 1695 zcmai#dsNcrAIIq?UQ#S)-Y|aVrpruCmcs;eE={_qo13#h#mu?p#-?Oyp{+QU2wCPY zw4bQUN^_>5vrO>P*HBaxyfh)Ff>$a?6sAI=?A!UBv-A7!_s8>m&gY!xocH_ve4f{N zXp!MZEX^IwArOcqF6{7^VEq+bH%&K#J4CW7fj~^Y#U1|at4!A0vH|A(e{Iig5Tg^8 z8!Omv4&KQn`@Y_4ZT)Zl#cxVBbVH`Mj^1`Y%}}of__WE?_A^0i^^5q{qdVyxkDcP# z#UyhItvXS3eSc91gGMsNL}Go0vF|#~s1b{}WWo&bP1`WgdUU{y3Ue{wqRa39_^0{j zLwktqus;Baw)l{4@Luq>WYdkC`r-6byvxy}-f>U@2`4Dmlo$}klnjJQE<*gam$w(eADUzT7i#2d}5G9#_|_H36; zS(8&bHq*}=lJKduqfVa@Q4k{n;^Dr0}6t10yso`K|{y`yM5N8_8?=(lCAX#s2gI5s*2wVd8BDCYFi2X(VloIkrb>$kL+p+oOI*DKbX z$KOmuOE<~501L?I2An5zNna$xkLMy&7gdIZ??Lae&jY;>XuPm%eMbjuWnkoh!h{KW zcG7?K-|3udxjIB0+>+l#++wiac%i0t#X0Kbw)zDJ!jru2&xK{CYe50iL04mc(IsGL_i zw}+2ioR;^+IGp;7IcaCv?%8m1P0}+J4BP);{xNb7LRI?Dv(eOyW=+{=N4-k3ya&At z{eTWYbS{)j*r$m_ACc(K1!lTUhU-ZC6$@1!wah|IKQD4cs0d|hy44#c+&>OohvTKL z8*0h{V8Yp`itbfDur`LTFqwCi*Iq~) zmkTuOKT#yMc+j(*bWK(i67vykqOu%S5~$cxTGa#f?g6D@8!&2N^-n$g@NMN1-^KF1 zO3ImiKPLH$7}VuwVSXBR?Gi2-e&~49pyGcpOPrBEKM|e6a&OIfIs~b>x-}c+O134V zPoA?ItA{e3d{hU|^8r!PUaMWm-4x3X0-Ui-d~`trbcTD?^dpoW@DW%dDL&B1b(Gma z)k#bKp_kq1@)NUBb=q~_cRRDVe*iAFP>`YcciJyJEO?|{hL1OfjDb2cbi3VKf-ajw z&S^o}J3h*Mm+@>W!@4SKY-aAa+4D4H<|b3#Wdmtngn(7M*XcTSnO5|}YzAI`ABig7 zSM);{kZZxOeL;wHq6|A2PQ6MisEMx>7ToDmlyv4I2Lcx`C!5+B>FPU;q$6+@A&+W2 z=J^_{6LbL)_=_g9)S5aMkRnQ2V(`kcmRCo)1ZOFI1+P5Zz(MQZpPGqSr!+P8<6Q-0 z-h!jyV-O1k#kgAOViOEku`UtdhEFhFR^3mxW)oDhwry-+%-FDaIOqw43)a8HwMO)qOw~vuj z?w!?8AA^_2o1ahyV&@L{GlyI-Sy2(b`zD|otZZ` ze{Xjl^M1eY_xs*{!aD__|Mi$aH}lN*zmASBHKT|9ub~+fM9nA=j=ud43f*2BE3B^m zFgrK*@{41kUzS#H&wf02^(paR#In}fhtTM{es42f$R>iDgT?oRUGhGS(_0!T-p?8@ zAr$7avCF=m*0yG0*P4xG{&@blQMw;P*`D6kHgRTNcp!4ugl$bu4pxSoM5vD&@5^L3 zbI3A6MxS8<0ge-d{WTw9n886q&+`dBkr+-456f~OK=i4Rv@9`XSbZs(CTnX8LodrD zFAxauh$nkk`G(R^nEk!;$SHuWx_d6=B)YQ9~bzq#~)5 z{N&lQiV_SGy*NIi$SfIFpYR}SYYRiKC__UeE*J?!$R6eWty7r&z4Is{%ZfzL^C|L8 z9Z^z7gXqny@@)A>%wg>($*0Gx-A<25vaz4hlx1T!&wpS&GJ;TP`u*pgeH@|aK>NU< z0W=VLg>ML*5wlm;gFWkqg+H_%@ke|@&-ijNG#g5HHw%C2W4_pBe;9H47k=|4aPxD2 z4zrlSO=1=|iVQC8;HDgIIft~1=U3jkbm75;W9kd)tE!^DtIn#QsGq4<)GyU}by59E zy{m4hKdYPSmb$I(sNb&KInjY)K1M1uo$BoD!EFj|kA)d28jbE%cm;RHVrIoC`cLha zmVaY5O3O2*;V}hwi4*v!ewQ5T=-RDCjT|bDA0@RTq9G$y%#m6ccZi#~6+a>hI1=kC z<+}GqZ}~;b;keeL_cP7H@0xzYuRqO-nT;Yzh~tvp)2P4XBfpaTTI)XU7MF_|A;kJa zjU9om=J?@b-Fy=}Fr0aQjb#E%odS=qMC$X(^B6O&AE_dZ{YohScS*hJ#1bCF;T}+jv`C9j; z(yV7DeR~qyDknmRTIX_C4!0%>ADxxj?L~k`8Q#TINt&y5Zz|1tX41DOv8{31wTeQ)$*SlfFHPZIu(DL#=bUD~DSXg^$ik?e-$TqYUq2sw90?>)uqF^~|Ji zPhwl;MCefKT<*%@)vr@ag2=FMwyO_Nst+h?F{&5X65C8%|00;m9AOHk_01yBI zKmZ5;0U!VbfB+Bx0zd!=00AHX1b_e#00KY&2mk>f00e*l5C8%|00;m9AOHk_01yBI zKmZ5;0U!VbfB+Bx0zd!=00AHX1b_e#00KY&2mk>f00e*l5C8%|00;m9AOHk_01yBI oKmZ5;0U!VbfB+Bx0zd!=00AHX1b_e#00KY&2mk>fKu19P8)<;$F#rGn literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_write_trigger_10/test.sym b/cinema/gb/samesuite/apu/div_write_trigger_10/test.sym new file mode 100644 index 000000000..b6b5cc43d --- /dev/null +++ b/cinema/gb/samesuite/apu/div_write_trigger_10/test.sym @@ -0,0 +1,47 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:062b TriggerAPU +00:0630 WaitDIV10 +00:0632 WaitDIV10.waitDIV +00:0636 RunTest +00:1ffa StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/div_write_trigger_10/xbaseline_0000.png b/cinema/gb/samesuite/apu/div_write_trigger_10/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..b8f75bf0b698c1a5460f5464e052395cee41bc34 GIT binary patch literal 1633 zcmV-n2A=teP)0058(0ssI20N3}|000IkNkl zU3Tjr41{sdU19pz^(EWnKKN8el>mdl0hF01qJG%eGT2k)C&U<^&u3tIKA$nhf$>w} zuXvZ368Ir}Ae46-+op&ZB3%%<0|4L8A2G(`IL@fJD0sZ5O`_qA%yehOsS=N^{9AGL{?r^;0=8G1`fH= zR|w(tdL2x!*X#V-sQ9VluXvZ_$iR=`X$F(K8s2X5ZQ#f9@WIY``4ruw%ZDtno+QT& zek?z81|$B4IDD{k!3R6%;e)*^n(DjBC-N!vU;&8u7LSOFow{+PmI$JzqFr-lgUQx#TV7!pMwJlZ0c-4c*KW zK+hWBUDbnIuend);e(ya;)DO#EY@Dl2a9|8XY$+oV5~P6iZ}aUz9aqgyMd3~ou}8F zE4Q0`u-*}A4Ny#zV`M zi1@%be6VxP^uaXOb89~Me*ShJjP+o$B0e8nT=m}HJ*Tvs0X)Zw-sKHU!lI+${T&K zA-m8N8GSG{R;~x%&5MV%HTmu9!FOwWA0Kb_!F)$tXK(`_xjRp~p2`bA#5eH4d<0@lThxQ^=5-=Ss0VxC=@u4Os|Sl`tEMh=frIBFfNCE7 z{LC4Qcqq=`A#sZjuJp>#3c~kft;>stH5-q5@MPV-7Dm*Aee?91a|7FYN2ERKsk`$c zG5Vs=?HWc8LJuew%>(!$yuBW5c*qi$MUBq`-^)*&!HB;h4j=4XGkq}4bw26AkL6Jh zb}q~BCY_=dcMOY;dO_9Y1^ZR^Y(-igK z1$oqiy(_lYefjha8SfNO4_<_iY^AMi#}*%~cSPEwp1M1)lUGid-h?^9@zjTn@NfP2D78ggZx;M0-qr61gV)0QqMZw$ z4|dL@9_(Fla~~`K5#OL*dpA$7IakwO#0TpGA?;DGy_-)aqnt3Y-MK!vaKOAv%?a|! z8xovj>X+zpBAfUeQ#cVH#c%&TS@gIV@A;mo-Q)1V&gIz$izWRt`R#o$){?R;pAQys z+E(S~iFvQHOLAnDeDXnq;_KII@8<13IJe6jqq}TTPu-p0-Uov(^Iabwt!(qHQQ~=A z?;89l9`#`7y#0OA&=&ISgTV&}J{Y=C?5+pX1DnhDMeD=lanJSO+$qa3y2~CuQk^Ig z>cJj-aN&gVE;R|5!$)g^b$d!Z_-;PO6i)O~{9FIgksRydae5q$Yt(mJ)^YFpW1s^<_7l4R=e}C&uHSzGllX=QeR7>gn-w%cl?&k{$<6UYJoaSRk zf<@3}J@{@u$LItJ)$-Ar;4_^(i)FrWB0f1@lgOSpe6V*#_~5BLe|fn<@z)w2K6tV! z*Gv2Mkzn7l{OSs{k&s~LLV}$O33e_d*tw8k=R$&=3kh~EB-pu-VCO=DoeK$eE+p8w fkYMLRf}QI>iBkft5Mm;400000NkvXXu0mjfrjb7N literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume/config.ini b/cinema/gb/samesuite/apu/div_write_trigger_volume/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/div_write_trigger_volume/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume/test.gb b/cinema/gb/samesuite/apu/div_write_trigger_volume/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..c8c137e5104b5b24f158b2decd1815b8e8ebdcc4 GIT binary patch literal 32768 zcmeI$Z)h8390%|x%_Y6fB)v3ky-IBE$`)dfwZ#|a#c>OzbVc?e_)74_0?s&el!DM+ z^?HqT?o<$bA!Aig`odQtL57NKj?LlVNYA<#6@(R@78hLoL%XsKt0q2omu^K6L~N7d z_m|wmJuBr_yL!i0||UVEKHuFsEFmX^Mo zJ%9eWXGSAG%`aV_egFLDkEwqVD|&MuA%*$5+iTfMF%?=Hs=g&{vioV8UANfcouYFS zAyJ_y&-v2rv9Pr1jn1@uxO~`Ix+9Zfy01N^&Rmf0s=^o2ElbY~-3vWKNWU=FpUVku z=sF?JKF9IAAV|{vxftiTp&=(<6jNdpDA+ z=XsHctcG{Klj&r*`}KZwh2s>KF9;byNTpJGCdD#XzI)cz=sllx!+U;A%O3TrWsi<& zPCaK+)11-mf7?8pCB#q)_rg#J$%tA;(?mB6!`lxALm^S@@4r9qi3fv)f|DPQD{)29 zA3b@}FhU`gua4ynJ;=h_XC7?sm2mP6V|bVy7mD+7R%5Ha*M+-Z@5fMsL6zl;qQc(F z0Yh;%SiXDK*62N-cf+fv>BmRCYR5-4-Kpnn>bf(!{coG+^Mur<-+uCmM+iv_b`0(x zB!iLX#g@nkwRmnNlwRqSezP{z@97ac=PSu%Hj?cPOTXKrK6%a`C4&8l-@W0leC#jL zAmwPQTBHG$qqPm%TB2>^#5!|o@zr-u-#vZEeA;}$G|V^6S@Q$)BlDd3nR&syZ2n;0 zG*`_Z%{6n~yk%~fUoGA^(nVw+r&U^yb$6#}%%B}|l+zN4M14gxXtyl8E6$?-*k*0v z7jCt-FylV(ut9s&33|}J$(lO2eC@Kuno81#*xCWrNn@*2U~5s@rLNI-`k*S&xZGbW z_12?r>&7b4q?NV@xUlrAWq;|nzYVCl)hat7No#gGU_a|)pOSrA@AtS_U8v@yNYEb% zbn!jmWapt?u{Ah2l6xwDLbKlsOtR}GcD>9lon2Gx@}4YZ$9?2d^uvHm&T7uD)p=cw z_G*UX~i40KXIoH-NAEr_UIiy zeK!j1QjOg!v#XVMyI2G2HKt_4sy4E4gKIawd{cDLEKM{~AI;TD({C9?ScOGMvHr<%e~a-zwgy*k6GS75-~ym0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa V0SG_<0uX=z1Rwwb2sE#N^(U&(&W8X1 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume/test.sym b/cinema/gb/samesuite/apu/div_write_trigger_volume/test.sym new file mode 100644 index 000000000..b0f84055f --- /dev/null +++ b/cinema/gb/samesuite/apu/div_write_trigger_volume/test.sym @@ -0,0 +1,303 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb TriggerAPU +00:05d0 WaitDIV10 +00:05d2 WaitDIV10.waitDIV +00:05d6 RunTest +00:05fb RunTest.done_u16403 +00:0601 RunTest.done_u16405 +00:0607 RunTest.done_u16407 +00:060d RunTest.done_u16409 +00:0613 RunTest.done_u16411 +00:0619 RunTest.done_u16413 +00:061f RunTest.done_u16415 +00:0625 RunTest.done_u16417 +00:064d RunTest.done_u16421 +00:0653 RunTest.done_u16423 +00:0659 RunTest.done_u16425 +00:065f RunTest.done_u16427 +00:0665 RunTest.done_u16429 +00:066b RunTest.done_u16431 +00:0671 RunTest.done_u16433 +00:0677 RunTest.done_u16435 +00:06a2 RunTest.done_u16440 +00:06a8 RunTest.done_u16442 +00:06ae RunTest.done_u16444 +00:06b4 RunTest.done_u16446 +00:06ba RunTest.done_u16448 +00:06c0 RunTest.done_u16450 +00:06c6 RunTest.done_u16452 +00:06cc RunTest.done_u16454 +00:06fa RunTest.done_u16460 +00:0700 RunTest.done_u16462 +00:0706 RunTest.done_u16464 +00:070c RunTest.done_u16466 +00:0712 RunTest.done_u16468 +00:0718 RunTest.done_u16470 +00:071e RunTest.done_u16472 +00:0724 RunTest.done_u16474 +00:0755 RunTest.done_u16481 +00:075b RunTest.done_u16483 +00:0761 RunTest.done_u16485 +00:0767 RunTest.done_u16487 +00:076d RunTest.done_u16489 +00:0773 RunTest.done_u16491 +00:0779 RunTest.done_u16493 +00:077f RunTest.done_u16495 +00:07b3 RunTest.done_u16503 +00:07b9 RunTest.done_u16505 +00:07bf RunTest.done_u16507 +00:07c5 RunTest.done_u16509 +00:07cb RunTest.done_u16511 +00:07d1 RunTest.done_u16513 +00:07d7 RunTest.done_u16515 +00:07dd RunTest.done_u16517 +00:0814 RunTest.done_u16526 +00:081a RunTest.done_u16528 +00:0820 RunTest.done_u16530 +00:0826 RunTest.done_u16532 +00:082c RunTest.done_u16534 +00:0832 RunTest.done_u16536 +00:0838 RunTest.done_u16538 +00:083e RunTest.done_u16540 +00:0878 RunTest.done_u16550 +00:087e RunTest.done_u16552 +00:0884 RunTest.done_u16554 +00:088a RunTest.done_u16556 +00:0890 RunTest.done_u16558 +00:0896 RunTest.done_u16560 +00:089c RunTest.done_u16562 +00:08a2 RunTest.done_u16564 +00:08df RunTest.done_u16575 +00:08e5 RunTest.done_u16577 +00:08eb RunTest.done_u16579 +00:08f1 RunTest.done_u16581 +00:08f7 RunTest.done_u16583 +00:08fd RunTest.done_u16585 +00:0903 RunTest.done_u16587 +00:0909 RunTest.done_u16589 +00:0949 RunTest.done_u16601 +00:094f RunTest.done_u16603 +00:0955 RunTest.done_u16605 +00:095b RunTest.done_u16607 +00:0961 RunTest.done_u16609 +00:0967 RunTest.done_u16611 +00:096d RunTest.done_u16613 +00:0973 RunTest.done_u16615 +00:09b6 RunTest.done_u16628 +00:09bc RunTest.done_u16630 +00:09c2 RunTest.done_u16632 +00:09c8 RunTest.done_u16634 +00:09ce RunTest.done_u16636 +00:09d4 RunTest.done_u16638 +00:09da RunTest.done_u16640 +00:09e0 RunTest.done_u16642 +00:0a26 RunTest.done_u16656 +00:0a2c RunTest.done_u16658 +00:0a32 RunTest.done_u16660 +00:0a38 RunTest.done_u16662 +00:0a3e RunTest.done_u16664 +00:0a44 RunTest.done_u16666 +00:0a4a RunTest.done_u16668 +00:0a50 RunTest.done_u16670 +00:0a99 RunTest.done_u16685 +00:0a9f RunTest.done_u16687 +00:0aa5 RunTest.done_u16689 +00:0aab RunTest.done_u16691 +00:0ab1 RunTest.done_u16693 +00:0ab7 RunTest.done_u16695 +00:0abd RunTest.done_u16697 +00:0ac3 RunTest.done_u16699 +00:0b0f RunTest.done_u16715 +00:0b15 RunTest.done_u16717 +00:0b1b RunTest.done_u16719 +00:0b21 RunTest.done_u16721 +00:0b27 RunTest.done_u16723 +00:0b2d RunTest.done_u16725 +00:0b33 RunTest.done_u16727 +00:0b39 RunTest.done_u16729 +00:0b88 RunTest.done_u16746 +00:0b8e RunTest.done_u16748 +00:0b94 RunTest.done_u16750 +00:0b9a RunTest.done_u16752 +00:0ba0 RunTest.done_u16754 +00:0ba6 RunTest.done_u16756 +00:0bac RunTest.done_u16758 +00:0bb2 RunTest.done_u16760 +00:0c04 RunTest.done_u16778 +00:0c0a RunTest.done_u16780 +00:0c10 RunTest.done_u16782 +00:0c16 RunTest.done_u16784 +00:0c1c RunTest.done_u16786 +00:0c22 RunTest.done_u16788 +00:0c28 RunTest.done_u16790 +00:0c2e RunTest.done_u16792 +00:0c83 RunTest.done_u16811 +00:0c89 RunTest.done_u16813 +00:0c8f RunTest.done_u16815 +00:0c95 RunTest.done_u16817 +00:0c9b RunTest.done_u16819 +00:0ca1 RunTest.done_u16821 +00:0ca7 RunTest.done_u16823 +00:0cad RunTest.done_u16825 +00:0d05 RunTest.done_u16845 +00:0d0b RunTest.done_u16847 +00:0d11 RunTest.done_u16849 +00:0d17 RunTest.done_u16851 +00:0d1d RunTest.done_u16853 +00:0d23 RunTest.done_u16855 +00:0d29 RunTest.done_u16857 +00:0d2f RunTest.done_u16859 +00:0d8a RunTest.done_u16880 +00:0d90 RunTest.done_u16882 +00:0d96 RunTest.done_u16884 +00:0d9c RunTest.done_u16886 +00:0da2 RunTest.done_u16888 +00:0da8 RunTest.done_u16890 +00:0dae RunTest.done_u16892 +00:0db4 RunTest.done_u16894 +00:0e12 RunTest.done_u16916 +00:0e18 RunTest.done_u16918 +00:0e1e RunTest.done_u16920 +00:0e24 RunTest.done_u16922 +00:0e2a RunTest.done_u16924 +00:0e30 RunTest.done_u16926 +00:0e36 RunTest.done_u16928 +00:0e3c RunTest.done_u16930 +00:0e9d RunTest.done_u16953 +00:0ea3 RunTest.done_u16955 +00:0ea9 RunTest.done_u16957 +00:0eaf RunTest.done_u16959 +00:0eb5 RunTest.done_u16961 +00:0ebb RunTest.done_u16963 +00:0ec1 RunTest.done_u16965 +00:0ec7 RunTest.done_u16967 +00:0f2b RunTest.done_u16991 +00:0f31 RunTest.done_u16993 +00:0f37 RunTest.done_u16995 +00:0f3d RunTest.done_u16997 +00:0f43 RunTest.done_u16999 +00:0f49 RunTest.done_u17001 +00:0f4f RunTest.done_u17003 +00:0f55 RunTest.done_u17005 +00:0fbc RunTest.done_u17030 +00:0fc2 RunTest.done_u17032 +00:0fc8 RunTest.done_u17034 +00:0fce RunTest.done_u17036 +00:0fd4 RunTest.done_u17038 +00:0fda RunTest.done_u17040 +00:0fe0 RunTest.done_u17042 +00:0fe6 RunTest.done_u17044 +00:1050 RunTest.done_u17070 +00:1056 RunTest.done_u17072 +00:105c RunTest.done_u17074 +00:1062 RunTest.done_u17076 +00:1068 RunTest.done_u17078 +00:106e RunTest.done_u17080 +00:1074 RunTest.done_u17082 +00:107a RunTest.done_u17084 +00:10e7 RunTest.done_u17111 +00:10ed RunTest.done_u17113 +00:10f3 RunTest.done_u17115 +00:10f9 RunTest.done_u17117 +00:10ff RunTest.done_u17119 +00:1105 RunTest.done_u17121 +00:110b RunTest.done_u17123 +00:1111 RunTest.done_u17125 +00:1181 RunTest.done_u17153 +00:1187 RunTest.done_u17155 +00:118d RunTest.done_u17157 +00:1193 RunTest.done_u17159 +00:1199 RunTest.done_u17161 +00:119f RunTest.done_u17163 +00:11a5 RunTest.done_u17165 +00:11ab RunTest.done_u17167 +00:121e RunTest.done_u17196 +00:1224 RunTest.done_u17198 +00:122a RunTest.done_u17200 +00:1230 RunTest.done_u17202 +00:1236 RunTest.done_u17204 +00:123c RunTest.done_u17206 +00:1242 RunTest.done_u17208 +00:1248 RunTest.done_u17210 +00:12be RunTest.done_u17240 +00:12c4 RunTest.done_u17242 +00:12ca RunTest.done_u17244 +00:12d0 RunTest.done_u17246 +00:12d6 RunTest.done_u17248 +00:12dc RunTest.done_u17250 +00:12e2 RunTest.done_u17252 +00:12e8 RunTest.done_u17254 +00:1361 RunTest.done_u17285 +00:1367 RunTest.done_u17287 +00:136d RunTest.done_u17289 +00:1373 RunTest.done_u17291 +00:1379 RunTest.done_u17293 +00:137f RunTest.done_u17295 +00:1385 RunTest.done_u17297 +00:138b RunTest.done_u17299 +00:1407 RunTest.done_u17331 +00:140d RunTest.done_u17333 +00:1413 RunTest.done_u17335 +00:1419 RunTest.done_u17337 +00:141f RunTest.done_u17339 +00:1425 RunTest.done_u17341 +00:142b RunTest.done_u17343 +00:1431 RunTest.done_u17345 +00:14b0 RunTest.done_u17378 +00:14b6 RunTest.done_u17380 +00:14bc RunTest.done_u17382 +00:14c2 RunTest.done_u17384 +00:14c8 RunTest.done_u17386 +00:14ce RunTest.done_u17388 +00:14d4 RunTest.done_u17390 +00:14da RunTest.done_u17392 +00:155c RunTest.done_u17426 +00:1562 RunTest.done_u17428 +00:1568 RunTest.done_u17430 +00:156e RunTest.done_u17432 +00:1574 RunTest.done_u17434 +00:157a RunTest.done_u17436 +00:1580 RunTest.done_u17438 +00:1586 RunTest.done_u17440 +00:158a StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume/xbaseline_0000.png b/cinema/gb/samesuite/apu/div_write_trigger_volume/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..1faa3d9283f4ed52977fad1102999b5ae26b8601 GIT binary patch literal 728 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V21PZ!6KiaBp@UCe7%kZ?%M z_|~#-@jkWP3d%fd*2=D{s@kW0#s1inoOMgMHJ4V-b55Q2e9EN*pZ{L1(fl*5uDI?* zjgRJ0iO+=`4?9Z5l6BfEW9PrLv`_iB+Vb9x#p_n^{yG0izpCOF`{|#1Kj-u9`QG~Q z&%K|~#WKk{_N+`hS_M8m-#BSojg55azL;M7S>CJX$Q$kdYU#`J@qIcIp2Mra;@w6Xn>l-z7bme189@(!_liC)lrhI& u;@p7(wl-sfIgJl_c+wLrm=BLUq3^sQKg>mv7akS^rC3i_KbLh*2~7Y2nO+b8 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume_10/config.ini b/cinema/gb/samesuite/apu/div_write_trigger_volume_10/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/apu/div_write_trigger_volume_10/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume_10/test.gb b/cinema/gb/samesuite/apu/div_write_trigger_volume_10/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..0e911652c998f60521d88f749d0edb4d6c5d29f7 GIT binary patch literal 32768 zcmeI$Z)h8390%|x%_Yrdl3tp&UL`hnWeYLL+TsiI;<$xUx*~fKd?ol|0cRXKN2WFR1j8pTDIWoAKH~|7&Y;^yJRcA5E-;d z@%u~e;hyLD-Shk9ljcnc`CrErxl-b;{+iD(hR7q{SIHa+k`M_*;%~i8!q*qa%PT8C z&Mz#y^ul=fm&KLq^B*mI^_21tv4T7I5RwnxxU-Qd7m~q^k?Ol*h2786%%;f}?-uNv zFp2O5>6|Ck84ZaQceJOa!==Oa(p`xZQUje)W$uD_PvO57Z<|_r6)K~yU#q>+$~|}>-y*@J1!Ut#8{0+eYXo|zuu3o`27mY7X+ET zkr)tN?-D=0jRn4wvZ)%!7I{j~(=W>M9X5V}EnI{N|4|fgk zA11@$mxZ?Q38ip;Etp#C7XL7}lpFMjmGu-QG9S+Lhr~avagTJ)8zH>)x!1V~T=~pf zq<+fLcBMdl3P)>Ow7p0>CW(3G)bg9}pT2kcknz0nilH0t81u%*#;3-4<4fa$aoPCE zxMi#xKN}myrg7WYGQM5Dd8CI(9!@Q{AM5Q+(Wp+lqzI?R2De{R=B4<_m*J{7M zi}b7I4mM72TbXuN_TOAyy_g`$eRq^m*3V{QsPr`3kWQ`kH@4amL*)*cEqJ3d<#@GA zEG_qtzF_Y)t$J4cV5V9S&zRJsyg}PG+Dfxx#q4NAxE`T;u)kJ2tnYnOrovwo|1u-w zlEl@f*h)B2TpL)UQJYiQq@Btf`?e-)#V!uYOYSErrx2=}$ ztks*_1O4rd7WYh-d#TYq*6YK!Yj#FW_aBuQApijgKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= X5P$##AOHafKmY;|fB*y@Ucmetkb@3f literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume_10/test.sym b/cinema/gb/samesuite/apu/div_write_trigger_volume_10/test.sym new file mode 100644 index 000000000..48706594f --- /dev/null +++ b/cinema/gb/samesuite/apu/div_write_trigger_volume_10/test.sym @@ -0,0 +1,303 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb TriggerAPU +00:05d0 WaitDIV10 +00:05d2 WaitDIV10.waitDIV +00:05d6 RunTest +00:05fe RunTest.done_u16403 +00:0604 RunTest.done_u16405 +00:060a RunTest.done_u16407 +00:0610 RunTest.done_u16409 +00:0616 RunTest.done_u16411 +00:061c RunTest.done_u16413 +00:0622 RunTest.done_u16415 +00:0628 RunTest.done_u16417 +00:0653 RunTest.done_u16421 +00:0659 RunTest.done_u16423 +00:065f RunTest.done_u16425 +00:0665 RunTest.done_u16427 +00:066b RunTest.done_u16429 +00:0671 RunTest.done_u16431 +00:0677 RunTest.done_u16433 +00:067d RunTest.done_u16435 +00:06ab RunTest.done_u16440 +00:06b1 RunTest.done_u16442 +00:06b7 RunTest.done_u16444 +00:06bd RunTest.done_u16446 +00:06c3 RunTest.done_u16448 +00:06c9 RunTest.done_u16450 +00:06cf RunTest.done_u16452 +00:06d5 RunTest.done_u16454 +00:0706 RunTest.done_u16460 +00:070c RunTest.done_u16462 +00:0712 RunTest.done_u16464 +00:0718 RunTest.done_u16466 +00:071e RunTest.done_u16468 +00:0724 RunTest.done_u16470 +00:072a RunTest.done_u16472 +00:0730 RunTest.done_u16474 +00:0764 RunTest.done_u16481 +00:076a RunTest.done_u16483 +00:0770 RunTest.done_u16485 +00:0776 RunTest.done_u16487 +00:077c RunTest.done_u16489 +00:0782 RunTest.done_u16491 +00:0788 RunTest.done_u16493 +00:078e RunTest.done_u16495 +00:07c5 RunTest.done_u16503 +00:07cb RunTest.done_u16505 +00:07d1 RunTest.done_u16507 +00:07d7 RunTest.done_u16509 +00:07dd RunTest.done_u16511 +00:07e3 RunTest.done_u16513 +00:07e9 RunTest.done_u16515 +00:07ef RunTest.done_u16517 +00:0829 RunTest.done_u16526 +00:082f RunTest.done_u16528 +00:0835 RunTest.done_u16530 +00:083b RunTest.done_u16532 +00:0841 RunTest.done_u16534 +00:0847 RunTest.done_u16536 +00:084d RunTest.done_u16538 +00:0853 RunTest.done_u16540 +00:0890 RunTest.done_u16550 +00:0896 RunTest.done_u16552 +00:089c RunTest.done_u16554 +00:08a2 RunTest.done_u16556 +00:08a8 RunTest.done_u16558 +00:08ae RunTest.done_u16560 +00:08b4 RunTest.done_u16562 +00:08ba RunTest.done_u16564 +00:08fa RunTest.done_u16575 +00:0900 RunTest.done_u16577 +00:0906 RunTest.done_u16579 +00:090c RunTest.done_u16581 +00:0912 RunTest.done_u16583 +00:0918 RunTest.done_u16585 +00:091e RunTest.done_u16587 +00:0924 RunTest.done_u16589 +00:0967 RunTest.done_u16601 +00:096d RunTest.done_u16603 +00:0973 RunTest.done_u16605 +00:0979 RunTest.done_u16607 +00:097f RunTest.done_u16609 +00:0985 RunTest.done_u16611 +00:098b RunTest.done_u16613 +00:0991 RunTest.done_u16615 +00:09d7 RunTest.done_u16628 +00:09dd RunTest.done_u16630 +00:09e3 RunTest.done_u16632 +00:09e9 RunTest.done_u16634 +00:09ef RunTest.done_u16636 +00:09f5 RunTest.done_u16638 +00:09fb RunTest.done_u16640 +00:0a01 RunTest.done_u16642 +00:0a4a RunTest.done_u16656 +00:0a50 RunTest.done_u16658 +00:0a56 RunTest.done_u16660 +00:0a5c RunTest.done_u16662 +00:0a62 RunTest.done_u16664 +00:0a68 RunTest.done_u16666 +00:0a6e RunTest.done_u16668 +00:0a74 RunTest.done_u16670 +00:0ac0 RunTest.done_u16685 +00:0ac6 RunTest.done_u16687 +00:0acc RunTest.done_u16689 +00:0ad2 RunTest.done_u16691 +00:0ad8 RunTest.done_u16693 +00:0ade RunTest.done_u16695 +00:0ae4 RunTest.done_u16697 +00:0aea RunTest.done_u16699 +00:0b39 RunTest.done_u16715 +00:0b3f RunTest.done_u16717 +00:0b45 RunTest.done_u16719 +00:0b4b RunTest.done_u16721 +00:0b51 RunTest.done_u16723 +00:0b57 RunTest.done_u16725 +00:0b5d RunTest.done_u16727 +00:0b63 RunTest.done_u16729 +00:0bb5 RunTest.done_u16746 +00:0bbb RunTest.done_u16748 +00:0bc1 RunTest.done_u16750 +00:0bc7 RunTest.done_u16752 +00:0bcd RunTest.done_u16754 +00:0bd3 RunTest.done_u16756 +00:0bd9 RunTest.done_u16758 +00:0bdf RunTest.done_u16760 +00:0c34 RunTest.done_u16778 +00:0c3a RunTest.done_u16780 +00:0c40 RunTest.done_u16782 +00:0c46 RunTest.done_u16784 +00:0c4c RunTest.done_u16786 +00:0c52 RunTest.done_u16788 +00:0c58 RunTest.done_u16790 +00:0c5e RunTest.done_u16792 +00:0cb6 RunTest.done_u16811 +00:0cbc RunTest.done_u16813 +00:0cc2 RunTest.done_u16815 +00:0cc8 RunTest.done_u16817 +00:0cce RunTest.done_u16819 +00:0cd4 RunTest.done_u16821 +00:0cda RunTest.done_u16823 +00:0ce0 RunTest.done_u16825 +00:0d3b RunTest.done_u16845 +00:0d41 RunTest.done_u16847 +00:0d47 RunTest.done_u16849 +00:0d4d RunTest.done_u16851 +00:0d53 RunTest.done_u16853 +00:0d59 RunTest.done_u16855 +00:0d5f RunTest.done_u16857 +00:0d65 RunTest.done_u16859 +00:0dc3 RunTest.done_u16880 +00:0dc9 RunTest.done_u16882 +00:0dcf RunTest.done_u16884 +00:0dd5 RunTest.done_u16886 +00:0ddb RunTest.done_u16888 +00:0de1 RunTest.done_u16890 +00:0de7 RunTest.done_u16892 +00:0ded RunTest.done_u16894 +00:0e4e RunTest.done_u16916 +00:0e54 RunTest.done_u16918 +00:0e5a RunTest.done_u16920 +00:0e60 RunTest.done_u16922 +00:0e66 RunTest.done_u16924 +00:0e6c RunTest.done_u16926 +00:0e72 RunTest.done_u16928 +00:0e78 RunTest.done_u16930 +00:0edc RunTest.done_u16953 +00:0ee2 RunTest.done_u16955 +00:0ee8 RunTest.done_u16957 +00:0eee RunTest.done_u16959 +00:0ef4 RunTest.done_u16961 +00:0efa RunTest.done_u16963 +00:0f00 RunTest.done_u16965 +00:0f06 RunTest.done_u16967 +00:0f6d RunTest.done_u16991 +00:0f73 RunTest.done_u16993 +00:0f79 RunTest.done_u16995 +00:0f7f RunTest.done_u16997 +00:0f85 RunTest.done_u16999 +00:0f8b RunTest.done_u17001 +00:0f91 RunTest.done_u17003 +00:0f97 RunTest.done_u17005 +00:1001 RunTest.done_u17030 +00:1007 RunTest.done_u17032 +00:100d RunTest.done_u17034 +00:1013 RunTest.done_u17036 +00:1019 RunTest.done_u17038 +00:101f RunTest.done_u17040 +00:1025 RunTest.done_u17042 +00:102b RunTest.done_u17044 +00:1098 RunTest.done_u17070 +00:109e RunTest.done_u17072 +00:10a4 RunTest.done_u17074 +00:10aa RunTest.done_u17076 +00:10b0 RunTest.done_u17078 +00:10b6 RunTest.done_u17080 +00:10bc RunTest.done_u17082 +00:10c2 RunTest.done_u17084 +00:1132 RunTest.done_u17111 +00:1138 RunTest.done_u17113 +00:113e RunTest.done_u17115 +00:1144 RunTest.done_u17117 +00:114a RunTest.done_u17119 +00:1150 RunTest.done_u17121 +00:1156 RunTest.done_u17123 +00:115c RunTest.done_u17125 +00:11cf RunTest.done_u17153 +00:11d5 RunTest.done_u17155 +00:11db RunTest.done_u17157 +00:11e1 RunTest.done_u17159 +00:11e7 RunTest.done_u17161 +00:11ed RunTest.done_u17163 +00:11f3 RunTest.done_u17165 +00:11f9 RunTest.done_u17167 +00:126f RunTest.done_u17196 +00:1275 RunTest.done_u17198 +00:127b RunTest.done_u17200 +00:1281 RunTest.done_u17202 +00:1287 RunTest.done_u17204 +00:128d RunTest.done_u17206 +00:1293 RunTest.done_u17208 +00:1299 RunTest.done_u17210 +00:1312 RunTest.done_u17240 +00:1318 RunTest.done_u17242 +00:131e RunTest.done_u17244 +00:1324 RunTest.done_u17246 +00:132a RunTest.done_u17248 +00:1330 RunTest.done_u17250 +00:1336 RunTest.done_u17252 +00:133c RunTest.done_u17254 +00:13b8 RunTest.done_u17285 +00:13be RunTest.done_u17287 +00:13c4 RunTest.done_u17289 +00:13ca RunTest.done_u17291 +00:13d0 RunTest.done_u17293 +00:13d6 RunTest.done_u17295 +00:13dc RunTest.done_u17297 +00:13e2 RunTest.done_u17299 +00:1461 RunTest.done_u17331 +00:1467 RunTest.done_u17333 +00:146d RunTest.done_u17335 +00:1473 RunTest.done_u17337 +00:1479 RunTest.done_u17339 +00:147f RunTest.done_u17341 +00:1485 RunTest.done_u17343 +00:148b RunTest.done_u17345 +00:150d RunTest.done_u17378 +00:1513 RunTest.done_u17380 +00:1519 RunTest.done_u17382 +00:151f RunTest.done_u17384 +00:1525 RunTest.done_u17386 +00:152b RunTest.done_u17388 +00:1531 RunTest.done_u17390 +00:1537 RunTest.done_u17392 +00:15bc RunTest.done_u17426 +00:15c2 RunTest.done_u17428 +00:15c8 RunTest.done_u17430 +00:15ce RunTest.done_u17432 +00:15d4 RunTest.done_u17434 +00:15da RunTest.done_u17436 +00:15e0 RunTest.done_u17438 +00:15e6 RunTest.done_u17440 +00:15ea StoreResult +01:4000 NopSlide diff --git a/cinema/gb/samesuite/apu/div_write_trigger_volume_10/xbaseline_0000.png b/cinema/gb/samesuite/apu/div_write_trigger_volume_10/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..5f5f952c13aebe03b7c335b4941095c53462ecab GIT binary patch literal 783 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|V1FPZ!6KiaBp*T`X!=5Mfok ztbZl{%Kat$ev(|rj!iMyakqBY15VF0<)?kTnoCn7oepl&(Ola1`R&!WK|lO{_5IZQ zIU}gcFz>OzA?;Va63KFTrIweI_IdwXEG552BYcV2pW`{^RTV$lQ~%}sJKJgR6-vE z=LfI$AFlcTN4WfhvhmeNyT7WwYgqmKZSzZ&-w7r6>?F<=@c&t=Z~K3B5Sz=v0udhf dQ35Fpo(p>@C4TaJ;~xS_=$@{AF6*2UngB!;VITki literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/config.ini b/cinema/gb/samesuite/config.ini new file mode 100644 index 000000000..6b38213c9 --- /dev/null +++ b/cinema/gb/samesuite/config.ini @@ -0,0 +1,6 @@ +[testinfo] +skip=60 +frames=1 + +[ports.cinema] +sgb.borders=0 diff --git a/cinema/gb/samesuite/dma/gbc_dma_cont/baseline_0000.png b/cinema/gb/samesuite/dma/gbc_dma_cont/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..b016da2915a2734ab6a52a059d4848df1a6ffde1 GIT binary patch literal 1115 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Sear;B4q#hkaZ4^CUGAmF<2 zd`;rEzqLC~n;UUgS*R(jP0jprcCWVdsYw;g8=b74%n9~Nbo0`D{^rKLZ`0Oodm8t# z_0lBin&Zjm7QH_CUt{OrpND(O zj;%lQKh%#;@rXon&)4&gzu$Hk?z^imzARJg@^_0>8{WUqk8Yb$toQGfuEnDt&%HM9 zj_JESZTdvs=xg8gZr+{0e_M(E!x{gt|8V@b{@c{}37^U~&fSsr?%m1wbF%3M&*SZT zmg=1r%8kAh?DbK8>FV5%z3aE{<2z~o|AF#n<@MX8>rb=`$F#2(IAr2mc+A9i>G{=r z-|EKZcIVe9>gmKk?@!OJsX01h|G5XdZtalQw>`35ci+dK@o(>6laQA@Kd<8RkM|!Z zOkF!)`TTR^rC)07_)qOOI{fd?x7E+z#@k*KzTbB|KD6!GU(H2=vst-(Td)@ap`U&i@|8G0(#ZvaAhN-pZEdTHFy8UVW`3?5_|GtVW zH`nAzKl8PG^&#zTf36&S6!Gdo<#n6uJNVWy-u>~n^vTbk+;^3(*8chSr}DS+9(WX9Kzr{|q={K+nUcYb}{eE+-r zdHVa=4r|8!TztH)VD`as`yJMYwBB6#`(VCtyKZiN@5)~9JSzS0_@l;s*C%a%e_rSQkx+NqIm~yXiTm!4 zZxw2`f8O;r_I2FPTGsO9UBa2cb*FjaE^kVU*k`;W*Zvo8Nz;SBKc~J<_}1(ku)dl7 z{rB!GD<6N{zg6N>FnjmnKf5y?9gh9?v!|l?&-@LtVPB;;zW(2QJCiH?@t(gAx^*J| zNAKClm-g;nTTPg3&ENZq-p7F2fR2{)hv2?+*+1DfbNEX)RM?bmu$pNVVKvVxVovp+ z6!tR;5i%^@%?X79I($t>9XD8Th_N4hG!g`#>no+@21xaPz6&ZeJYD@<);T3K0RSaj BA=m%_ literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/dma/gbc_dma_cont/test.gb b/cinema/gb/samesuite/dma/gbc_dma_cont/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..15b9bc666e183082d1ad57c3967375510d258b92 GIT binary patch literal 32768 zcmeIxZ)h8390%|x&E6DwB%8|yh7kx2Y;puR})jzZ=>u8n4=kD6A^!4zK z-(PzV_xygp=TAN)gglzK@o2XBuXi~^uGYAp|16c}V&w7gn`DYaNsI`I)bx8KesgZD zvAB3+W_I?qSH|Lh%q`xW`E>T1XS7|HtOWBAA*E|S-CNNcm27lnxcPy+$=)ZazUs2% zdc}K*lZ04NE{1Yl-7$GH7`!luD9ZA~xs>F%;bE^|lCn}ZJDMFGHBCWa{c2G+4UR=nH}X202S<4Q zrpfjb1VJJaJ0sZN>-0MO`qq6+mE%;_FN%3l%x1G@KFc~-zrWY^7_8U*2-c4q`jOx? z{m8iCo#zz|!yEnk@0ja4A(mQt5SB_vUNZ8AA^BlhL7nHLQArvYcsTD*@_eb}^(T{R zQdP~TPo1)?Xq5G9<3-ElSp;?F!REmcUcY6HjIiyZNg>J3*gikFgv@{c{KGm+d!f%YNUUu|KoFurJwP+n4Pt z_HXtbd)fZoUa?p0yY`y>!@}*uy+jFdMx*_BUtf-PTeL?>a7HSX+R8{4?Nby#<0Zq# zH(T?6am%gwDSyF}7VX#0(Eas0>{9!eu3vH4r80Cc%k9&=HkPF#%Oz;9wnDq;6Piqu z%0R1{-im|UFK(4)++2N-i^&^q{rhnJmxxwaZn7ORv{lbV>aT{_r(~Zt_&shm=bHsN z&WGcXUZFph*>fN*wev%xg_nvajru2%3HH3jp10X!vZu_RU}aT59U{|-&m#)CV0gb) z@9)P%+GupLabibi!q0TvURe4rL$Z(E(?-~RRx^XOXIVixyOiE8wPgkyohnO&yUUGK zvq!Ei^pgH)-*vNjLH@Yhbma3c4QcPtww1Qpq`c`8r_JFU-VvM*C+fr<(dlw}oL)zA z_Bu(Y-yyp~A=4&(p-f*45uxgRFCy}WLL8GmU#3Sxge#{_mfeWR>s5M;9&>js#}on( zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z O1Rwwb2>dSv+b*0|T?Wr;B4q#hkY@9m|>(L>Lyj zzuETuaO^n`@hvveN~RuBbIms!efTTneqp`h^Ep9W+Cg5H&pY4d=D*B}UMCu_p}RBj zT}9jH_T7s6l6G&qle=B_de?c&l`trX;M9ey0BCe*VYtMa7doe-Lwun5MceV%pL#XS4FF zy}{}P%%`p2FModX$B*jGKVS2#TYdJ++qLaKwx#CP{9E_;w$$VJW5p_U6@RW*oH(`k z`^4LCrv>f0o2P$jzwzOZe;&J^Kfk|fjrG0U@A08+&wjnyzl;0#vyA=bIsUDWf66bL zJG*{urp|xUX)n&nzxcB67t=51gU3I|CwJbf3V0QK?fIO~>sNn?`1e<`@438v)w4QZ zuDg=O|JH{-R8Ri7w)tVtm4mO>m9E=-_298~gAn%o+Kzi&`Qj%p*toQ)%Uku_m$d(9 z`tsec7e}t&`(+hb~yxpd|!^ zcA}HXN@^z_1P@Xg1*Hd1qKgy}NtKO7Vc4u8ha3tGyac=0_=lvSDM@A5H#12aaxPx{ z{*w2Y_xt_ky|*8B33)VewPZOTjusNOA7#yX(1nDJ`xKHa=2!*z+XKZMZDC zRq`Gr5|c~Xl~AUmGpgT6LG{m+O<3gOBv3GuO3%|a5AKT!0gY_$l z&i?how(b>JzrWYs9K2ufBRJ2r&Wr}9of$PP?>w()S>Ej5f8V-LAf!3@@u}yZCL}S? zHPALd2BbHY7HPyNU0oG3tB2J4?xyh@JyFYt${LxGa>=OrPi-`$T?xmCT>CccKM2>q z3708PIofKJXvE-XbCb4~Y5O_iUb?XK{wEjjT|DZ%>b&LH&WFy7^M&)3bJh9Ix#r9{ zzdN^`HRlg!-Pv&NIGfJTOSevR6D`D<_14opJsH|*(=IK>nTbSVH>23JN7MX_mkgiY zX)gTDtu+^>{1=|GX|Hjf9;w}CmpZbtIOnoUrRb9^ci8aSSeD8x7o*+AI_;oO7%Gix zea&)mH;(N+xMiAhGqrv$s&2crpTf0j#K^BT*bXV$tYsp#*F)@6vQHcQ9(NiGjl3%H zVJXrr^hQ&MjwY2>eqcENN@2vTeHIyK;~h5MWy4})f{ozKa_(G+Ovk>AXymf#{aU@h zUt&qK-p=OneVK7T({^iV<;N6BKX%s`V)xld^;e%`1?|F0a<9~q>aVx!ED`RUs3#g- zYIUib^ol);R^zhz=|rQXUUF&3c#pQMw^S$99hX#EDqMxH2$i;qSdl8^KrCux+8CiP z8twF@5E07WS0SQqYouaS=nE`+Dnz)6q{Z^v5p_!{jjxL8ed%RmYIVsyuospPfB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb L2teTfD&YPL%T>cI literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/dma/gdma_addr_mask/test.sym b/cinema/gb/samesuite/dma/gdma_addr_mask/test.sym new file mode 100644 index 000000000..0e45f9371 --- /dev/null +++ b/cinema/gb/samesuite/dma/gdma_addr_mask/test.sym @@ -0,0 +1,48 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb RunTest +00:05db RunTest.initTestBuf +00:05f0 RunTest.initSrcBuf +00:05fc RunTest.initHRAM +01:4000 NopSlide +00:8800 vTestBuf +00:c000 SrcBuf diff --git a/cinema/gb/samesuite/dma/hdma_lcd_off/config.ini b/cinema/gb/samesuite/dma/hdma_lcd_off/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/dma/hdma_lcd_off/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/dma/hdma_lcd_off/test.gb b/cinema/gb/samesuite/dma/hdma_lcd_off/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..04db06c832e1ce0127bffd5f6b4c4af6c71b6128 GIT binary patch literal 32768 zcmeIxZ)h8390%|x$>n<1OL}R$dX?DRg)PJ&TZ=Eui{lnb>5A+{oC<<37I4O)qZEYg zs+Vh|b5~y|zL2phsC(fnksw1vHYM9|aHO#m>5IV%Pm2q#{-J+ZM>|P;?ylWRUk~5- z{k6}-J-^@Yp6AJjgpfxQHy_P5|Mf0s$n_fc%U{LfOoTihdYeoVkwl0POH6%0qPJ#7 z8w(3Jr!QZAS1vtY4C{l9W!T&1{-=uzqi^o!Ngs=Y{|Nn2|f` zpO!m1X1M3MMZ<7s@BX{ixf~&uR(ueaMo3mRvW6jhVOf5i=S5ML`}-fR`{F!bEV}*i zxE9wm^O;kpEK3wwzdly5OrC{bXC7?rAK~^}*6=XfPK*n2cE-;6{w=)v_I)g!=XKUE z%NqOF_FI};VEx`+JG1|O!3+O9!#pwSpLSx@Fx~UqqG`IbcmG}MLV=Lh#3#p|f0~fQ zVE17AAQ_ClDF>q`_41`9F|)K!x$ms&ztJQ0e4wI|>1Zw)QU0lq2Gon87?JAVg}evh z`nRD9ZTzp*db-`iL0 ztM>2q9edgS!(Oph?KOMd{(1iPkshK3IHS>aytg+)yDZwR#yBI9NNi_hi}tFjmvNJ! z<6EuSzq#es?4{2QEB+KpB-8Pn`63fMCkG?`X=@Ys_ z<7$7alH86%I}c8UrkqTDfQu-bPW@V_{%cszFE`l^DcY)M!u8h!>{GH&>;E3NnzPNk z66HhDaF5UzN$oqBl-u~hk^C!#lScjX@HiXqu<MAu7 z&2FVO-$VMu-Z`^*LHVrI{8BmZ(189P4Xy-h6UvrDs=+E(<*P!qy((6tRkA07Wj`^e zk|~qESfVclh){9A5MgCgB~_EYP@=~IgexUYmfZ|18`1LklBnE|zN}9!smjz^va+<6 zoOkwYj3oph009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< W0uX=z1Rwwb2tWV=5cnSnIR65*XUFmY literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/dma/hdma_lcd_off/test.sym b/cinema/gb/samesuite/dma/hdma_lcd_off/test.sym new file mode 100644 index 000000000..6e3b35efb --- /dev/null +++ b/cinema/gb/samesuite/dma/hdma_lcd_off/test.sym @@ -0,0 +1,48 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05d3 RunTest +00:05e1 RunTest.initTestBuf +00:05f4 RunTest.initSrcBuf +00:0600 RunTest.initHRAM +01:4000 NopSlide +00:8800 vTestBuf +00:c000 SrcBuf diff --git a/cinema/gb/samesuite/dma/hdma_lcd_off/xbaseline_0000.png b/cinema/gb/samesuite/dma/hdma_lcd_off/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b4ff643c16b771b1acbb8e52667a5198bee15c GIT binary patch literal 1229 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|UzxPZ!6KiaBp*A1qs~AmY04 zb#0>2o9_>G?w^ppu&F~l?*mikym_{p8r(~`1t;&4Nai>w+9HtDBYZkFchw}->sj+X zR09pR+dr$>{`yhZ+n7zarvU}!lX(>H3DzU zzn8W3^F811{r_bMD{o4V#+UwaxdX zBFleop!14vKlh%$+r&Kn=ZQZjeumxF|5>2){NZWK?YXn{Z*0@OdRA-t)|Fn<&g9Pj z(EIZB-@lf(?%5}wIj?MS-t6-BX#S6zQu2QP*!^vKc2ED8^d)2xETx02d`_pfTF+1+7S(YA|^Z&Ni_a5E(uMp4^7dN&MXTSYwx6n9 zeS2-x-oL*;2Pc+V&AnG&z0dK(JA=7RUngH-{jxnjc8crIQ;x?!pU&2HugS05VrO#F zZ;GnBe^E?BkezFTj{o8E*ne|gCrcc>E|im9>2Y8tYkacoon11v*5B4Rx_?^y>!QJo z`}cX*p8K|{Nc>XP{_J4B?>qf>8pTgLb5?)#6I03a^NVVyt#1zBe?-x0+WY3ytBkz= z+uf+mn;T{O`SbeCQ!O7m)alF9KOewDtQM?qpxtwP`b zUw34}`BDR`k16|KXjoq>c9%czc#+V~u)uRLHKe z`5Nkc%09LE+QQX8r&pYcz5B0(`NfM}KXd-tOD`Apc~;b0e(?woYqRsg2LT2aB0PMf dOr&u5!@lH&TH+pm^8=t_%G1@)Wt~$(69DokQ8oYo literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/dma/hdma_mode0/config.ini b/cinema/gb/samesuite/dma/hdma_mode0/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/dma/hdma_mode0/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/dma/hdma_mode0/test.gb b/cinema/gb/samesuite/dma/hdma_mode0/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..cb7df3705a9e242609dc6ab9850a391b5ac4afe0 GIT binary patch literal 32768 zcmeIyZ)h8390%|x$t6AOCB3v=y-IBE!WLqXt;HAS#c{ip(iPc@I28n6EZ~eoM=1#1 zRWH{_XRp2xd?901Q1`-DB0+|TbV_DX2x+WE`eLxc)8c}wf9N09(N+?lyKA?y*TWa` z{k6}-J-^@Yp6AJjri474xbbkd`LB1mKxV7l&wu6fb7Asm;7u|?1QI5EG(PnniQJqU zt}iX!n4Xz=?UmukpL0t$r$3$f_G#^bOBTJgkC6N?lXuqidNC!e4KzNGci8hd)z>R5 zxm9!?A|xsnl`FnCI+EH%yZdr_OOaFN(5!e=Ws0ZeYOam!y=GN)4rkhD?*^S-+aoO@m|M)s2kK*4`0L zziG1lc%GMt#Ln>ccRHO8x4w5DQ{_07^^0Og6jP~`nMtt@*6;4MKYQ=%Zg}sH82Tyi zH2u_w;hg6b4a1q;`yW{AIw6*tzZaHDNJcU;h9S9OSzbL95(G)=?Y+P5iG@P>ywe|x zsWDYGpE`fuvIK$kYa=jz=Z1HlVV)iKPCGknn9g}l(KMaez5juAE=Ndn{KM1FK1oQt zzq7x!pY%swm;8})TJh?NkX|_??^ZUo-{{F&)>l%@|Dc-mo|A9~W<(>>`SfGwLm8y1Ub~!=jx^lr!S-_+Cb`Xt$!c87CPy zv(udan_F$pPq;5UVbLD#0zFc@%`SChdEt76T`EZ*XSu_g)5fw?WVtBq($;7@eN2;S zOzCZw5_@rM|DjT%$x6D`$A#tXO6`Y0?bo1|U2U)(lC)V%2WzkT*r#Nl*84v0H0B#w zIT8v)f?a%1ICiql^O&IkyHjf?1jJcWCTZ_xzCrRp&JK7+-&w8@2`V1>57nc+JC4aK7-lnodprcTa zH#+6&Vi)NVx);pGW%=Vm<1_hEh5EF2sDI609hY}1r0g$q;M1& literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/dma/hdma_mode0/test.sym b/cinema/gb/samesuite/dma/hdma_mode0/test.sym new file mode 100644 index 000000000..6e3b35efb --- /dev/null +++ b/cinema/gb/samesuite/dma/hdma_mode0/test.sym @@ -0,0 +1,48 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05d3 RunTest +00:05e1 RunTest.initTestBuf +00:05f4 RunTest.initSrcBuf +00:0600 RunTest.initHRAM +01:4000 NopSlide +00:8800 vTestBuf +00:c000 SrcBuf diff --git a/cinema/gb/samesuite/dma/hdma_mode0/xbaseline_0000.png b/cinema/gb/samesuite/dma/hdma_mode0/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b4ff643c16b771b1acbb8e52667a5198bee15c GIT binary patch literal 1229 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|UzxPZ!6KiaBp*A1qs~AmY04 zb#0>2o9_>G?w^ppu&F~l?*mikym_{p8r(~`1t;&4Nai>w+9HtDBYZkFchw}->sj+X zR09pR+dr$>{`yhZ+n7zarvU}!lX(>H3DzU zzn8W3^F811{r_bMD{o4V#+UwaxdX zBFleop!14vKlh%$+r&Kn=ZQZjeumxF|5>2){NZWK?YXn{Z*0@OdRA-t)|Fn<&g9Pj z(EIZB-@lf(?%5}wIj?MS-t6-BX#S6zQu2QP*!^vKc2ED8^d)2xETx02d`_pfTF+1+7S(YA|^Z&Ni_a5E(uMp4^7dN&MXTSYwx6n9 zeS2-x-oL*;2Pc+V&AnG&z0dK(JA=7RUngH-{jxnjc8crIQ;x?!pU&2HugS05VrO#F zZ;GnBe^E?BkezFTj{o8E*ne|gCrcc>E|im9>2Y8tYkacoon11v*5B4Rx_?^y>!QJo z`}cX*p8K|{Nc>XP{_J4B?>qf>8pTgLb5?)#6I03a^NVVyt#1zBe?-x0+WY3ytBkz= z+uf+mn;T{O`SbeCQ!O7m)alF9KOewDtQM?qpxtwP`b zUw34}`BDR`k16|KXjoq>c9%czc#+V~u)uRLHKe z`5Nkc%09LE+QQX8r&pYcz5B0(`NfM}KXd-tOD`Apc~;b0e(?woYqRsg2LT2aB0PMf dOr&u5!@lH&TH+pm^8=t_%G1@)Wt~$(69DokQ8oYo literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/interrupt/ei_delay_halt/config.ini b/cinema/gb/samesuite/interrupt/ei_delay_halt/config.ini new file mode 100644 index 000000000..7ddee425b --- /dev/null +++ b/cinema/gb/samesuite/interrupt/ei_delay_halt/config.ini @@ -0,0 +1,2 @@ +[testinfo] +fail=1 diff --git a/cinema/gb/samesuite/interrupt/ei_delay_halt/test.gb b/cinema/gb/samesuite/interrupt/ei_delay_halt/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..22d67738c90a9a70c4abb55e6cff601180b0e8e1 GIT binary patch literal 32768 zcmeIyZ)h8390%|x&E;~=B)zm4NM<@Ri_;1)O!$Q3^tL z)$29VxziVdFJ!C=%3k9E07=hBsKtdqp&xog)VdpGcn z-zUB2?)m+G&!2pfl#s`3%NyP1N^RvDyXUv=1%7|LRsXZur^uCx@XM{y(SDuhv+#9crCH`Dkx<32G-1jdSk3L<9kov7(HyUQWl!-Nl zn;)y2?0K4+YaR>UE%Ap0Ny;Vdd??$|8CN%ho)0UBDu;OJu0~4PgB_j5%tiH{A^)J> z@$B62!)E6Q8IZ>Z3I*A3woM4n3xXucva0Tkm6RY15A%9O$tamjK9kSewj{B7y=dB& zz*>;EawZ!GTkv|@X6s3kq!5Me5vHkPY`IuUO0hk*_YY3t z=eN$|7@}yfdPULMpT5u0d4kpZYi;+z{G#82{Ve;~Sg_l%G0W!r@uY3@-ar4Yaj{59 zYx{TCl>&9>NaJ3LBYh*TI_Q%z~t79SU zd^kzu>bGJ4LAvryxJ*SV(5O+O5ksJ@bs8uDN&Ib@!**%HeLJg#@b}J=)WgrJWA#(vpJJ*Vnfd zQ5@Q%X?}zU!$&t;i+>5Lt;HFC!ZQx-HBQm})tl^4`r80{p zX}8g!9rP(fr73NoRqo$v2e%)*GEIBg>Yxx;?|aoB!_`W}D6BTw3TfJ^W+TKjVplM;Y)*v8 zrQ}x;jhwUiua&=kPWD^%cGgesicI>EJu9{4`83Hqv0;p`^Q@%@D=)Hyc6zygJJpsR zthehd5bm6+_cgoJO0App#(J*W&2#E!Q_Yfk)}tZgJ=)f2t4yn#-tGCFS0UUeM8w94 zMqc2($$S1CU>|XWitGc9O6sLS^^$gbe&t_{Mc0ieZ5d(Oo@|_`tv#4{c7p|%?|YB_ z$A%~bAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz T00bZa0SG_<0ucB=33&eiK<@9U literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/interrupt/ei_delay_halt/test.sym b/cinema/gb/samesuite/interrupt/ei_delay_halt/test.sym new file mode 100644 index 000000000..57b57266c --- /dev/null +++ b/cinema/gb/samesuite/interrupt/ei_delay_halt/test.sym @@ -0,0 +1,47 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05cb RunTest +00:0604 RunTest.halt +01:4000 NopSlide +00:c000 RESULTS_START +00:c020 RESULTS_START.end +00:c020 wSPSave diff --git a/cinema/gb/samesuite/interrupt/ei_delay_halt/xbaseline_0000.png b/cinema/gb/samesuite/interrupt/ei_delay_halt/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..e8ff40eb16536ec175901f316ba0ba9703d55194 GIT binary patch literal 1193 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|QHer;B4q#hkaZVka$85MV1! z^1m@Jc>M{x4X49`10LOX`z}7ypKprlgsz11Q-Y$dml~~kJu7I}MjPY3mvvqqeID}o z;}iXl#a@~7o=^JN`S^^@`B3E=&-G^V{l_Qo|FHU(^$Cvq9=bmQKPB7FynSN2$>Y;c z>?QpF3H^^}?cb9*YisH!$sYCkhs%Fe&wE}Z-oRjg`9Axe6}snt$3AVnX>e(WP|orN z3d}!i+cM^|ajASenE3C(m%D5taqF)y{2~2$GylDl_OnYfO^bg`ip%x1lc-Ow`*!fr zmDMk_d-OLoO-kDn?{efL|I_cAQ}h3=$(o*ODN>*Ouc~X^FMC7R`kx|a?IL8p9c2IX z+ce9^pw-OSX5#$X4}ACS=KuA%yd`(`-s0`Kr%U%1MW+^*}UXCgYM}~((&&e z1!a2|wZ+w}%RTm8ZsnJK@7J6Cy&Cy*hh)50-1=}!?f2Qao>N!NJUi`=^=hl)Cp%`Y z5YJcsE8$!FXXoyZl`%~`kAMDc@OwXZtyfL1oW^g?MUwK{m%j>p-}Pxy#M`>jUKbAIkLnAv-wQ+WCJz3!ox zdbW3W#O=}be8`r(Wa78lC;Ec-vu5VrUiCab_WGoQ>m8a;`yRI4^!T%Tu+={PZ(AMr z$WB?+S-AM`&d0ZEYHGeNxW+&8?R$^4_A9v7Z%;4#{iA5jW`4QKRrAgT1hRd;GvVIl zc_n|YFHD;hS0gIC$8476Tj>+&8;-0F*dHa?vtBAkGSc<7@cK22YO5cGmYn?m!|sRo z^X5a#d(U6|X0wm~oo&Hx|AzZLM?boMzP-8WPxJ3*C->fclksHX2G!8($8O(0bAR`v z`7YnQl#jQ6JGku{|GR{@!XIB6e_QGQ{rkt-4^#O>PQCt9)n0o*^kD1d-&Zcbm6w@s z+*Gal`2Qy38;!3j_8eCJ`T6l|J&twjER=p6`^NulfAELAKY7BBZ@psUdc^I-Mw|WameAqFU~Fc8)N1E2z>nVW6n?88|&`8`S|Yr zLD8R=V~??$XE*;?{PXW)(c}83gZxguPLCIgw>|g&!jBKtANW2W{(WV+;|7cJf8nY% z3LIkW2OlX!$gp%bClm_k@HHI;N{tG_1LR!(AHU}-?%qGc2r7a+UHx3vIVCg!0Q&<- A4gdfE literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/ppu/blocking_bgpi_increase/baseline_0000.png b/cinema/gb/samesuite/ppu/blocking_bgpi_increase/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..86ad2e3f74c405e1cfabe7e2752b0f9295d7e5cd GIT binary patch literal 577 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|OI>r;B4q#hka-0<#_)h&Tl9 z_MWYJMsBa)+4hwNVY69o85CGPKkf0z@|l(5ZHdPgeQzIG^cf!0U$=hu^|i&RI@dmL z|LK2zw*9didCK<+ZNsmf?*A{W1O){kpjPe@WimI{&=+Ikx-P&G=vPZ}ECd t#_#hpl34nLE&Lu>G(H|>5EBSH>Wi2jpStvx`vxd!c)I$ztaD0e0sv622EqUU literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/ppu/blocking_bgpi_increase/test.gb b/cinema/gb/samesuite/ppu/blocking_bgpi_increase/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..862260c534ae81983a0148a8734410e36b22b3bb GIT binary patch literal 32768 zcmeIyPiP!f90%~X+1brlcQ><18Yi-5XO?yu7ikkbxQB5%hL8s7VewS(&;{EyY6$_M zo#mCcg@WWa+a`qP1wj-gNm1_4<&+={4Dfnc)?`f^(uRg?TNGKnUNmh>U@gd7d6Uh9 zBY3@Sv;9O-l!?sF2=?cdyu#1#+{e}hL1*=nl$Rt;)9k#)Dp%B+b)(8Q|yf0^MhOX`JMYXMl@=$ zdRf-lpMJp6d4kpZd+m0^DO)1NO0Q85zFT1@uY3@(ZBzmd9g@HbK-*+o_~^% zbbn|6zJAi5cvWsm3>)Q{l~`_Nzq0LZ8b8ycwL++(lIet*i7S8AMndYvaFR&1FT?(W zIQK=kLZeimtwxzf41qQ`X={bHogv=&sl~THJa_lpA@@c1HP><9bEn-;-Ot?__bd03 zd&T|5z2&aDzq)Jgy1U_Sx>px(9_=D(NU-XyC%U_Hw8NpDYErP$>GV!Sc4)V%`Vk%s zpV(?H{2{D17bg7$PdK#4I7<)KZm~-pT)uY2W0%U($64%v!OK{bN-UP7UB()1r;iy5 zO{u-jN@k}W-hJ>YH0$MReL`IM)2n?KuFXV@!fJ!b%cVsFXbHuybmH5M8L zB@qoLB3)unJiGr;MsAJv4;79VhppPjkulcaVEs+jZPv$G4^~#pGa+(0`B_9I7cBm3 z<)0st8LQsL#<4w-F+Z~J=Hl|VS)x61+Zbf`SOCzLJk`>Vl6C6^P!75bdf!d{HMp&_#8 zsg;dPWt+BXjg5>UJs42_HNd_DM(eZ6-`jlQT!H-)LxTVWAOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z x1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0{?3P?;pp2+?xOZ literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/ppu/blocking_bgpi_increase/test.sym b/cinema/gb/samesuite/ppu/blocking_bgpi_increase/test.sym new file mode 100644 index 000000000..d9a1dee8e --- /dev/null +++ b/cinema/gb/samesuite/ppu/blocking_bgpi_increase/test.sym @@ -0,0 +1,48 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05b3 RunTest +00:05d0 RunTest.waitWrite_u16402 +00:05e1 RunTest.waitWrite_u16403 +00:05f2 RunTest.waitWrite_u16404 +00:0605 RunTest.delay_u16405 +00:0609 RunTest.waitWrite_u16405 +01:4000 NopSlide diff --git a/cinema/gb/samesuite/sgb/command_mlt_req/baseline_0000.png b/cinema/gb/samesuite/sgb/command_mlt_req/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..602e3026a0093faa1e48ac2fa9ec21e6746bd88e GIT binary patch literal 608 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|S$~r;B4q#hka-9rKz3L>w+| zd&w245xs<2IN9XYdZ(kei`}vUS4{tY@O)~d-HTsUUl}*(Ha=$Q6SnYsU@`EF-}kE6 zKikO5`(G~kzJB}m`G{u@S2i#A|8@C5`{$C~J8O==w0~kF_tV6; zeR;O*{_GENGMCr=-nct@k-T-W{{HD}!@IBMmK;#4(B~4ashVH&Hbi#k`h7J|zsdgC zn*a8enez9~k5%*D|9#W7`yK0#%D#DNTbXl!Yzcv5QEpVoiVeBOR1-JYD@<);T3K0RZzg B76kwR literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/sgb/command_mlt_req/test.gb b/cinema/gb/samesuite/sgb/command_mlt_req/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..8d8b9514b66d23cb35a8178828753aac054e2e83 GIT binary patch literal 32768 zcmeIzZ)h8390%|x%_Ti&l3x1HtBcKD*@DEPLZhs_tVXRf$1Q5-1{aOBLNa5d^q~!9xTnx{XB8$ z(rd2_hJK%(yFT&BrEd=?TgALA2{7 z=S3p2J>2!}O1r|zZ=6R@2pkr-T7&!x$}qA^dWb*^r0cu z-p@{|s@*&1uNkM)gy^Y(`%O;~k`&dXs)|n2bvN(#2Lhtl*||AxkNEuq19p8Rl8U5K z+H)sP=z1W)>Xo6auK8JW^UQ;d-7V~TUGME>%LO8QgzZt?-#vws-#Cx1`27m27sV9& zPwmlDc7oMAYgK!9e%5L3eyVnC(B19WpsLyX*-1^ad*}Q$<7}3Y%IF6#zxWIx(eCE% zUEQQR^txCVIy;e!DIBe=()v7YI7!TNXNvE9c=qnueZ~>v4MR8HGbW5rjn9pX#y7@gW77E5 zxM3_AzZuKMigC+WHLevG`&xGh@z#r*zt`oT7WJ8|+Yf=VvEPcBmMAlEwBYb{UIOfyKhKRavHu^a(|x5xKLH z@7QSjt2btz#>|A(#Ra9mOzW!Gn(`@`r7~L~Mk`jrXT9oSPsyIveIM7#Gv$mF@_R$R zR=zzLYuVQ!*898rGl#RsRqJElFuUGj*J*ZX>>6R0J2Rg?=^E4}PIE3vM^^DH5sneV8k>SA4`h7=2Un?_2}aQUaNb<1^yQEAPrlq;;2*YB0>yY=;Tr(3Ut$(2R<1>Rby zpI;_coVTL9^SLNL>jeLm+zh_-s2NALCacRb*0|S$~r;B4q#hka-9rKz3L>w+| zd&w245xs<2IN9XYdZ(kei`}vUS4{tY@O)~d-HTsUUl}*(Ha=$Q6SnYsU@`EF-}kE6 zKikO5`(G~kzJB}m`G{u@S2i#A|8@C5`{$C~J8O==w0~kF_tV6; zeR;O*{_GENGMCr=-nct@k-T-W{{HD}!@IBMmK;#4(B~4ashVH&Hbi#k`h7J|zsdgC zn*a8enez9~k5%*D|9#W7`yK0#%D#DNTbXl!Yzcv5QEpVoiVeBOR1-JYD@<);T3K0RZzg B76kwR literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/sgb/command_mlt_req_1/test.gb b/cinema/gb/samesuite/sgb/command_mlt_req_1/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..3b4f846f17a0ed5c0dfe8e5a8d0c2c9885518f3c GIT binary patch literal 32768 zcmeIyZ)h8390%|x$>nmJNqXr&uP!#1y2dQXmNCS<2-i?bTVyYSuLizYz*&cmQV_PQ zyIv!mI|~ZFkh$s$8R$!iIz^;aR>y=RJxgEYg|NcYVS`pD*~&IsHSxK-X003kd9B}H zbC-L5zu)sGADR&Izm8Mn@@4Lu>mwrzA@YFlMKVQ#Bt(Qr?A2)!zPd14U0(inW_I?u zXGX(6Ei7N1d3W~nL(2VPK9=$vA|Lj>cB_`F7L&o+K>ZDQlRZz;+zpc@Zx`){Fo}r8 z_ytd@wJjuXx_5h6?ko4%soQZNzRJBs*)eACo219wBq5Rw+h()qmTgr*T< z*EvoQL{XNv$5NEz1_tbYNlHq|lek0C?=ChEt6y&tlwFyd3WdMoN(ulsky`MZn?u_s=c3G zR8{-#oPWnSmm@^aj@%7BOGrjiGpZ^%q3dp)=Yv5>N~gES-BF$&8L|7L(QGuE)gC)> zLf3;q)~}2ebd6`>)|m$zyIa`(x;{9_mJ3FODBGjCzk3R&zI7g5;dzDiOH!7-vU~Nc zU10srTFtvVzu<(spQ;@jb$2^9s%rLrc2U#pyL0{><3fRu#^jq%J-LsNSbux}?taoA zeqQp1k1NHC*Mg~Q9rCZ{y7Cg`w`;DiK7YyBa-Iy`nH$E^f8lM?+#=P;p@q@8u{AkpS8^%pz z-MCU&9qJ_U4WC*K9PR2#(Kem7$9HjREEe0!NILC`cR3k5={vgFSp1n=Yb;JV6CT!S zw{nX1TGUsfy(>%eCOcJvKE!f+6}ydPsmO8>+NsoND}7LrX*8a0lzO(}K=Xlptc01e z_HiM3!?eEgS)cfo{92u@kf06g5x@1UhkZ=;aoz9XW__`qm&3d-?C%u1Ly3<4JyL-0 zAI={s99ONk{NwC;iCw4JrLk**UGB_M?j-S$OOf~dadKX@zoz!z*O4Bz+QRPRJ2K-= zX7_4k<;w&~?z*K6vIE^n94tS<3h^^5JNXSSabYJjac4*wZS{@t8u@R z{8Mo|+52}h9>2fXT(b*0|VoEPZ!6KiaBqu1!grnh&Ti; zFZpj>*n64ZF(_Cick6}Imhpw3CN!=-sZ)HeGs{w8^<(bq%&*;<^zYM8!{;)| zZ-mQh?)4b*&8~>E{D18a|Fir2*VW6P*jusfyZS9kpTGa&=dPdG&;Ofz(Ecy;Z2jDN z>zIDSZ_67Rwx>pJyZnA$nLSVZ*19B{iqzfr=kC9K_xI1gf6t%GWRa;~)G27;_rRj@ hF-xEDD1(?luwz&wS;b$Z+`SbP!=A2wF6*2Ung9b)-PHg9 literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/test.gb b/cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..bd1aef6c9ddaba811b2a76f55915e12cce4cfd42 GIT binary patch literal 32768 zcmeIyZ)h8390%|x&E*pQHzLl%DOS(NYBz2c_FOublBjklXPXPR!MxGyJU-h-uuGu zlitJq{ycy3fs~N{^*BqemxS-`OiZkV$)o;P$s7rhFbPKEZ_bm*&6UZ@`ug_^OG_`k zFd6xIW&P&Dhf7}_(f%psXDQzi^6Bo_y=tyfNQJ7ywRe;~_C8B<+crzyFYuQLiAsgU zWna3pE3E8!GY?BgOGkO?eu5OzhdaBpxhu-9CVj2kwTA(wQ+d-6+3@PjgT>wvyx%lOM%Z?tSTM%UXrAxg!mT&%V``$Pv3^-r*`IpARC$5* zyL&ZfZ++e!-g&xla?(5P@m45(t4I0W-qC)bqt3Xmm>>(0+(20Q!E7r30qjlTbvVO9v z*0y!m+OckwH%EI(!YAmJ_7i=5Y1(Dd?nG43;tDA|pL`M}jG>H-|LrIl5(;`!933%mS z6MtF4gVsdxZ!s_OT&8hG>$`oU+$%K_=}2%?lS(d4k_MbCB_?G|x literal 0 HcmV?d00001 diff --git a/cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/test.sym b/cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/test.sym new file mode 100644 index 000000000..9d0a8fb79 --- /dev/null +++ b/cinema/gb/samesuite/sgb/command_mlt_req_1_incrementing/test.sym @@ -0,0 +1,52 @@ +; File generated by rgblink +00:00ff reboot +00:0100 Start +00:0150 LCDOff +00:0157 LCDOff.LCDOffLoop +00:0163 LCDOff.ret +00:0165 LCDOn +00:016e LoadFont +00:0176 LoadFont.loop +00:017c LoadFont.loop2 +00:0185 LoadFont.loop3 +00:0192 LoadFont.loop4 +00:01a1 HexDigits +00:03a1 Palette +00:03b1 LoadObjPalettes +00:03b5 LoadBGPalettes +00:03b7 LoadPalettes +00:03bc LoadPalettes.loop +00:03c2 CommonInit +00:03d0 CommonInit.clearLogoTilemap +00:03e9 ModemSleep +00:0401 ModemCh1Freqs +00:0411 ModemCh2Freqs +00:0421 ModemCh3Freqs +00:0431 ModemSendByte +00:0485 ModemStart +00:04bf ModemStop +00:04c3 ModemSendBuffer +00:04cb _Start +00:04e7 _Start.loop_u16400 +00:0502 _Start.failed +00:0509 _Start.sendSerial +00:0521 _Start.loop_u16401 +00:052a PrintResults +00:0533 PrintResults.yLoop +00:0557 PrintResults.xLoop +00:0569 PrintResults.correct +00:057d PrintResults.correct2 +00:059e SerialSendByte +00:05a4 SerialSendByte.loop +00:05ab CorrectResults +00:05b3 RunTest +00:063c SendSgbPacket +00:0647 SendSgbPacket.sgbByte +00:064b SendSgbPacket.sgbByteLoop +00:0653 SendSgbPacket.sgbBit +00:066b SgbWait +00:066f SgbWait.waitloop +00:0679 StoreResult +00:067c MLT_REQ_0 +00:068c MLT_REQ_1 +01:4000 NopSlide From a171c54b9ac6a6c25903ea9f8817416db1485786 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Dec 2023 02:11:53 -0800 Subject: [PATCH 023/336] CInema: Sprite priority has been fixed --- cinema/gb/mooneye-gb/manual-only/sprite_priority/config.ini | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 cinema/gb/mooneye-gb/manual-only/sprite_priority/config.ini diff --git a/cinema/gb/mooneye-gb/manual-only/sprite_priority/config.ini b/cinema/gb/mooneye-gb/manual-only/sprite_priority/config.ini deleted file mode 100644 index 7ddee425b..000000000 --- a/cinema/gb/mooneye-gb/manual-only/sprite_priority/config.ini +++ /dev/null @@ -1,2 +0,0 @@ -[testinfo] -fail=1 From 1f6337fc1f132b143e418560dbadfbafb83423f2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Dec 2023 02:12:12 -0800 Subject: [PATCH 024/336] CInema: Fix xbaseline differences being ignored with no baseline --- .../misc/boot_div-cgb0/xbaseline_0000.png | Bin 1444 -> 1438 bytes src/platform/test/cinema-main.c | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cinema/gb/mooneye-gb/misc/boot_div-cgb0/xbaseline_0000.png b/cinema/gb/mooneye-gb/misc/boot_div-cgb0/xbaseline_0000.png index b9d24cc3a6b7aa103cba20524a151a49314d4cec..767dc72dd2561e99aa924f87fdfa2b5052c4407a 100644 GIT binary patch delta 1324 zcmV+{1=ISZ3!V#*B!6W|L_t(|ob8?6ma8BPh4HMu|0{bgI>WG#guhV2?*4A3qc)~) zQ9`0z_k9O~%fHEQX;Cod;FqgpSjo>WmC?0rT=6aOIPoK=Az#q zGgXwk#+dzYX7+q%i*e4YzDWtTm{VZ;1BWA7;80+2C@?q_7#s==4h05>0)sO+&=Hb^ z(xeAPJ0=4u*?&0suql1q)OnI)T;O#)^Mk{ttd4s%mFafKcF-;ThqeFOryav1Rn1s5 z?rR`l?uXe+bdj##*`9D5pqlRNwc}Gog%N?R&fKD%EM@8WfTpgx^>fKRc>c!unQT?p zt)%FW|4I_4=N++vaWFW8_u%;1a~y1FCzSj&uP0x@;D0@MX(!04ll6hln*Yw=;3fL{ zrCRM=wG(^J>5{mCiMo=V89z^9NelK92kV^T=L|bLS+QB9jU#I%!-v(%j^yVlEUBt= z5(ii9%-=ZuSC=~N8W1ZO2ZQ4=4qlPRow1WzTjA$YJjTJn?qIDx=srbF*_>>UvN4|- z$@1gpI)9c3JRe_vrUm=)a~(TNc8;is2uwB>&0Y!8+A+(Mjukyo{P8?Gy}2%0il@C5vng@EXLZATCres8Q_Plr{TAM{WWs#W zUFdw((C3*Q$qFU0+x6I65pjy2GkEM|DFq&+mw)|3mG2LW>W%e$fXOBLy~^#0=+rG@ zg~v-YF@yqxLxI7ez~E3|a40Z16c`)|3=Rbb=TG4I{Hr8B&mw#2kMhewCrraOYpNcAL&a-1{U)yPvDs z`M&7*hN-wD)#JIa*M9L~7F$27U)-+oehT7M<`T@2huf{#nI z$2iy!t0#;lKm9+ay7OhEjn9Ibw7i)Xru(Vb_kfpqlNQC7x+n8~erXGC=al$zOg|5j zJB@>@U+hgb6pb6k>ux()`#m5_VH^z3U>s}}-c<9!leYk?>r*uj4imS4rFfj2(lAM2 zLQ5R%mYwq^wFJIPk2)aZV3GNBUiS4Z2gooEcFX2YR;-AKOR{W#@lvrX4({Er2l;mn zRZ8)tRUS9g`aw?e)=Sy%0a*&;lW+wYe}3j{c&_j~!qrmAHE9ioS5Qj>tA**sB!6p3L_t(|ob8?4maHHQMDeWt|6lezIK#M*gj;ArS^H&r)Q)LO zkdUayd7gpb@^7^RWG)mK9108$1qO!#gF}JAp}^pLLI}rk#Q#mg;^R0NUOVA){fT-c z+Vp9k-7=a=)@IL!j{QpZU(Ru!r*t%*V&Bh$Yhy{C8Wn>eq<_BO=&<4{iTt(TVoSO& zytd4)&5~86b-&NO$1h6u$tQlw9&7!0C9PlQsY-EUeO1;~HsyrR{hvf*srT+^F8T#B zQAN3G^x1ziqvtzYjB`HaO>(fs>;l^#IGo7>hXR8`fx)4`;80+2C@?q_7@W?Dj&MsT z4SFEi8MmLzlYe)c(&tT`Cpr2BHX)lDQkJ)3b=-@oOt(|Eoo?wrtn$}Z9<1(TSIk({ z`ypJyXY)_erGY=*=on9iV8i0tm{Wc>QllA_wPz+O3w#$3qPk^gX@2-Ug_~% zZcDwNQufS$C5hAXj#$As7@VFi+P02*UK||cuC?3Lcz;dtm+8C)Ta7BG#=*~e+ipK4 z{Ex0XyXfPWVzskwq&RZ!9;H7E`MUiKx4@x0WLU+N7VPs}e$wRUcG6y~9Ar(6gOk=a zB9B$vzl14Ol}_T|yBLFhO8BoXbviU4Rxl0*$738kBab^`=WcC=pHo>J2N&%-v9rql zIE#}F%6~-1^BV)?Qao*v4>m-J`#q~0#s^u_+L2@J=Ru4?BeGL9)AZ}Thtrx!uqMo>%*jaV?7^W(nVjZ z+@6R|-6B?a?4pSw6c`)|3=RbbhXR8`fx)4`;80+2C@?sG0*~ik&GF{Xj+E!3rD<3x z(-%LtR-`^LnMUFz(J zQ$Nj~LrwX7{p7pbFZ%f&e%@WE95|_TCc9iYj(1UQd>8Czm%p|t7p}og7vQt~eMiw+ z&Bh(}Uw#1&%m>56IFnohEq@dkoW;+JR;nbGU6?$2p$WwwrKrzCA=t|2MOQu>t9uvE zx?Nj8w_xRalcpZEnsU!^KM(isQ(FJtq-PiRwc|DD=Y6?byu9K)Vf;aBNlE=+57Bxj zN4=l3S^2!^_=Ksr} z+2!L|8hwtp-o9at{-$Wj1|`w0-x=JR0n{bTo^~A-9f|*yzU@x!TUQcJ^?gdMEllq@ zM#$QclJ<}k1XiRnx$_`status == CI_ERROR) { break; } - bool failed = false; + bool failed = true; if (baselineFound) { int max = 0; failed = !_compareImages(test, &image, &expected, &max, diffs ? &diff : NULL); From c8f4d4aad9c6d5f65589ff6c22592dee471a8ac4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Dec 2023 02:18:19 -0800 Subject: [PATCH 025/336] GB Audio: Fix restarting envelope when writing to register (fixes #3067) --- CHANGES | 1 + src/gb/audio.c | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index f4d714888..b5a6b9136 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ Emulation fixes: - ARM: Fake bpkt instruction should take no cycles (fixes mgba.io/i/2551) - GB Audio: Fix channels 1/2 staying muted if restarted after long silence - GB Audio: Fix channel 1 restarting if sweep applies after stop (fixes mgba.io/i/2965) + - GB Audio: Fix restarting envelope when writing to register (fixes mgba.io/i/3067) - GB I/O: Read back proper SVBK value after writing 0 (fixes mgba.io/i/2921) - GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501) - GB Serialize: Add missing Pocket Cam state to savestates diff --git a/src/gb/audio.c b/src/gb/audio.c index e9c014d05..8a778b2ed 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -880,9 +880,6 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { bool _resetEnvelope(struct GBAudioEnvelope* envelope) { envelope->currentVolume = envelope->initialVolume; _updateEnvelopeDead(envelope); - if (!envelope->dead) { - envelope->nextStep = envelope->stepTime; - } return envelope->initialVolume || envelope->direction; } @@ -967,6 +964,7 @@ static void _updateEnvelopeDead(struct GBAudioEnvelope* envelope) { envelope->dead = 1; } else { envelope->dead = 0; + envelope->nextStep = envelope->stepTime; } } From 36a9602e62ebf06e34c67a87fe778872aa599599 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Dec 2023 02:31:37 -0800 Subject: [PATCH 026/336] CInema: Update SameSuite results --- .../nrx2_speed_change/xbaseline_0000.png | Bin 1402 -> 1373 bytes .../nrx2_speed_change/xbaseline_0000.png | Bin 1420 -> 1393 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png index 76f5c4ff013cfcaba2fe1c9f8caba89031ff3504..eae5b521f447cc874255031a4ebfedd8714272bb 100644 GIT binary patch delta 1159 zcmV;21bF-U3f&5jB!47HL_t(|ob8;!nxh~PgmJ%pLf_Hc<{8<8vmHW12e6G;ssBXU zvPBCVdNc_!#%T@DYwO6%nN;$p@s|8)+|Hj}tGE46^)3B($^SRtqKB+ac8$7r>^heA!%iMT zc;0dwl7|o;kH_!sz%y94?fkkuL;m*bljhfN_D^@zw=I#Z ztt07~=ytJAHT1P?Ui!UD#oKi)zp)s$`_rqh8mx!FJO^I=y2HJ;>omV8VxYcrKsPhZ*TsVh#ogx1Ap}8qocvK_O%8N42ZXp%z&v3 zUe`69?%;KB?5R6zL&4rfo8g#$fS;eA{HS+XMHg={j{31xbf`FY;i^8B-M$VcZy1}A z#V2t^y?k^Tp{#=qeSGEFKiyHgof@e#X6;m&wQE~zde*@s{m+bfYgl&FPa15Wc6&BQ zz0sv&|9^$4>)@7%-H9=SYs$BpMg!9Re{~&vFM|gLL}P!7r+G&HM*R-!U`srZUz_2W ze*lL%SSK~~^6~hpwRnSZ)UysA0qK5lNB)Em9*@V8An$9{;_0R|m!S_Ajp(krxmSO7 z|9$i^St&HOud0K4^}TiTY<0GeJ~QU6VcC&pHh);}<*To4ol2jtqFbm9^L=K^ty`Cp zAEx)u|L}4l_N>)=_50P%{@!)y2WD_fBuidwpFM+X%6sWsA{{drtPVb#v*&JaXUfsL z)WNgW&1dUft`F;AbmC-hbWrcB&%bhrIUW?71~Xvidt)WL$Drerq8 z4S%M)w_vairn|Qxo?HjdwyOL#{dDg|6K4iya93PD&hmWp+w|hWzQMgM9n$UER_Yz~ ztb@Vvtb=EJ9!x@jejZGHU>%H4#C;x2ec)_AmB^XMy>gDq;b#Lnfghh$51x_i z)|!&Wdo@||V*3`ixV!6F2cr|YiiXy+4hCoNce29&8+Gd6Y`>E=n_hxNCnkCx9AYa! zl~vU11BF{HQXKU@&v$$E+C1AZoq`5;>Dvu+(T~)@`@NTCZZAI1cYE~%Gq|>+p((cK zoMGqbYsypgYc4;9Sjb?01nQfZx@pJli&n|lOF{} Z6(9IWYe_{5DtrI{002ovPDHLkV1g^nYSsV% delta 1204 zcmV;l1WWtf3i=9=B!59kL_t(|ob8;!mhvhPgmKRQgn7qgH_ymjaBhn0M;s z^R<4TRdjMN+vz{EiuSMTuf7i~*^VFQ+;v@#i0isSpH*Dr z^Xr$?^-rD5V1Jq2=52l6ko{(Rt@Nwa!9G`~*7NH#bK`iPT|Q@qyliWOD~H{c%}`%+ zA~$|PJKdV%vYk$1Zr6acb_}$cRR#q?K7Jct{ z^cnR7?+@!>bo|gSQ`rh6tC!7q84^kb9f`^I$|6N`KmWjZWc=yH7wcdCk?J2c6&BM zePu}5@qY{2>HB&?eojfp+Gub~q&|o-gG}lFFw8%|@9%HA*WOjMPFm5+=KWP`_5@?7 zA6rGcf^%P7)yJ~wbuiNTU`Ix-2ghA;uKM-h&wtm!v-PuQq>bK3D}~1PE_Lv1eed|c zqfd-^Ygn?UPa3RW^<90bcPV|kif*CwF|S{2xKHob`E0%5JJ;&odwq+~Ed9U?Ziytx zv+dp)TvG0(Z;4Et!C-apYknx6MXqcbpryW+CB z$S*s8PA?vW4)eAQNViM9)Enwq2ZLi-2hYA9Oh!mftub+2YwD3CdA7a9DQtJ;J zKG%b(AJFr9FggP>n04@H^b&MATJ^FWq<`jZy(72PBIS#EoBO&GV`AcXuckDJI|uwX z_3Z{{_2bWrmM>S_r5~w-dGGX2c&?&X)%#b*^sIx?Da|~qxNNRJ zV=(pNLFh1V%Ybyd)Jwggp4WrHxpmuYa^08LgI6RuwZ_EpUQLob+uq_7x4WKoFn>Cp zt7vFF>tJvOpOfWsPez~poUGmT63jZW(Dh(ncvMzauXp6OTBI22ZLaV3>a}@w!*mK7 z+@)_f%tSv@2ZwVn%iLaUuJ88h2WD{Tg%wSc^jxB{Hs)m&T7iHAl~2 z*1>gs_T8JUXB`X<{{Rlot$!Di^^@@gR+BIV7n3jr7n3jr7n3jr7n3jr7!^PH>w%*v SFrKpj0000(QiZVvJI=ZJQjsZCkM>grK`HdQ9U>K%+-H+Su_= ziXY^d^!Tx5smaQ^COrXNF1G3kGI}gdkkO+ZZS43b#lOWEZ-2L2*8J0!)W1@eXn(!l ze)`R7D3;9ecZF4{gX9X~$u z_V|Sm-dI^_?9$S{0tgLHd z$sjz{-PNx7;H~^(E#VM-TF-S)BxdddaPd9_ubMD zG}yjHhem_-i8)W$X@DNNtv{A;Yy7nJsliQp-89|cT7UUWgF7yW&}hI?25;MzZpgJB zDi4k=d8chj?GQcn1LJq_{r&xX9Bb~P_3dQLuJV_@U35sCTVz*nL!_3eaturZjLetI5!-TMIsUm=A1{eDZ3H@Ir`X;T`@(1%m5=%&26 zRX=x*h=fSg?y>?p% zA(Ka!3W%shC8 zUIa#j9=#}zhT&!DUYBdFpQ)eqUUz0pN`G44s7<@4Yb$!@JFX??3E3tlW=;ud#xJ@a66B6rcydgj64bpB6P_2WJzT%@v;q zlkxBe;NZOU>q4?VG#DHj3=Rzjhm-0AjFVpl7n5HF7n5HF1{VAWpZse{jl^Tg00000 LNkvXXu0mjfP^^9R delta 1208 zcmV;p1V{Vv3XBVoB!5#$L_t(|ob8;^vZEjnM9HoFLjO_U?l-az)J~B>CIf1T+z4oXEl8ywHn78lxRj-YE-$bIXz$_ z!WDgMe^%4S825eOwk<#BrT!ITe7#;0F(c3HiWo$CM8 z_VM2_j(><=u+Q~HeY()oI2)@!j>98ccLdkAdX~QRc>Vfv;GXJ#%FxN1Z{UWp+Z4P> zA2PG7ZR4t|XuF^5>+e}b$80@ys&Bi5$>aD5Asol?$~cZAwT-GTTT@e6b44!#Bf`!7 z3GZKd{`hGVzkl9}FC#dgh{l%HOd{p7=8Ar`JUIID)VxN`!~XsldTp@U;6Vo4n$rVp zir=AEvXA{2lG8)p$gIo2rt;Xs* z`d=2t#<%s%gR5t`6nDgbeaurY#P{$MLP%4q^hRddQGfN)Dr>ydRMuS4=VwzoVCzNf z(YN-eoIl6Lcj}o3qZ7M+nJROVnqEGp6-Oc^4`q!)7Ads|rPv?8qdy^AE;YqZoA~vf z`0<^pUc%*}?Q(9U+DEC+m8x88RflIpPzT%;zg3^QlwY+U<11JE{b|)({a40(G)(Pj zp24=})PI1c_#JvB``CX$e(o5k7xJG|PV^lHdur@c;5VSdV5b3jZ{=AZL!X9kYy7;` zb3yy{Wz$y}+;KrT`%@m&3I=c6CSL@ndZ;`&{`=9!Dej10p8A3DJNW(m{oIe%RrG0) znqEG(u3F3KWURh#6&*6?7FpFB5yB05@N?$_41ap=2j@+BEc<@&>^yk3e)fo*rH|Q? z!C78251y@W?f)uzWz0vz)Sl)UY-{e<`?p<6uUF9?N}Ch*&4yN5zr1Jbh1j@Ok1^IB z=($7RF@ilcD)?#HbA`5!u+{W=>k=dQ(RuJ}TE}i{@G1KEt$FZl{UWPq=E3O1RsY#Q z{eKX>e&}vSIq{nO&>i)sdj0oN73CCL^ z*Qns9r@sGv(emZWe0K=5p6liaUPNEp>Y~0U59YJePa<*^y@o!% zGfK}q7@gY48&xkKR~s?kq8ATR!|<|ns4Ul7sUN84{a|n|JvOWE`|^J9im0hICx5SR z)u`a7ZD!ryZPj;-;M#_U=Cr)R2%D#` zZFRH0|2 Date: Wed, 20 Dec 2023 02:52:45 -0800 Subject: [PATCH 027/336] GB Audio: Improve "zombie mode" emulation in CGB mode (fixes #2029) --- CHANGES | 1 + .../channel_1/nrx2_glitch/xbaseline_0000.png | Bin 762 -> 747 bytes .../nrx2_speed_change/xbaseline_0000.png | Bin 1373 -> 1388 bytes .../apu/channel_1/volume/xbaseline_0000.png | Bin 2574 -> 2611 bytes .../channel_2/nrx2_glitch/xbaseline_0000.png | Bin 756 -> 724 bytes .../nrx2_speed_change/xbaseline_0000.png | Bin 1393 -> 1402 bytes .../apu/channel_2/volume/xbaseline_0000.png | Bin 569 -> 569 bytes src/gb/audio.c | 17 +++++++++++++++-- 8 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index b5a6b9136..e5f40a5ff 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,7 @@ Emulation fixes: - GB Audio: Fix channels 1/2 staying muted if restarted after long silence - GB Audio: Fix channel 1 restarting if sweep applies after stop (fixes mgba.io/i/2965) - GB Audio: Fix restarting envelope when writing to register (fixes mgba.io/i/3067) + - GB Audio: Improve "zombie mode" emulation in CGB mode (fixes mgba.io/i/2029) - GB I/O: Read back proper SVBK value after writing 0 (fixes mgba.io/i/2921) - GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501) - GB Serialize: Add missing Pocket Cam state to savestates diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/nrx2_glitch/xbaseline_0000.png index 8ba9bc9df354f87486a5abb7edccccfb8089c0a6..24c22936bbb1e3acb6060a8c2e318877a0ad4404 100644 GIT binary patch delta 433 zcmV;i0Z#t<1?vTnB!99=L_t(|obA|AZsQ;T08v=&3Av+lP5Kcnq6TN}#Kd?s@1t@Z z;^It*NJGwfS(Z>)mL=zW;`#Q`=R@t8oO3yoQYz0)DRs}(c8;HIKEubCd#LZ{+~aa) zb=;n*U(oh=>(N8wXPeLH@qb@DZM1Lxtv!y;C&oBvCMQ}4zJElFah}-EZ0$$l3pwX$ zV_zS5s=DFdI^G{_=DHz-KdawkjNhE@RCV9D@yY9k5JJ9g7v0XJJ~{s`I{)_Gd`6F- zXaPNqUJys`clHJPUnj2A?)mcT*88#h_V12Ax+2TT?mC-fg$*BH?zz7I6OYS;y2mM{ z?#Fd^eD?}_*A2e*M{ne# zwOcN6?JhcO)ct%H-QMZz`OLN}&cD5P{o&t({a$;m=?VVPp>v(Ni`Imb(E<~a0_2hc bG#2{-WO8kH=dqhN00000NkvXXu0mjfV;k#^ delta 446 zcmV;v0YU!j1^NY$B!9t4L_t(|obA_9a)TfM08!}lgx*oFNk5!YDw=47hVJb9vPcYc zYez#$X`bg$nCCgA)Ns5$yPm2?Qc8Jbnx_2OX_|INN+;)!ww~_u^B&6mv^~xvo8x+< z{Ds!XM`th1A8kFo=YKx2^F(doC>*3*0bKsV5; z_YHA%zoXxv&wPXsmSu^BWm(p9t;XxK>#2IAbpMXbgS+=xr}YdsKkvERf7|0cvN^6t z(!rZwI)2Z4aDV-rJniYUp5f;2#yB7E%<<7LbocDl4Ll9DyS0AnX*mDr?4|2(pQ7(r z@0k1?zIo<)pwqMT%hw$0**@HRR*(6^^_I%yIPOyk@71}UcdKx zvitLoW?s6!@4>%}ww^op?$0Iu^?UHu>-Szy!}*&9zZiD?vHoDg_4m%+>;LcX!NUbs oTP>fWH6W8A0<@D*0(Ta^07$WJUIU2OU;qFB07*qoM6N<$g10LG=l}o! diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png index eae5b521f447cc874255031a4ebfedd8714272bb..0032b919f1aaef5acc9573be68705c0633b9bf45 100644 GIT binary patch delta 1197 zcmV;e1XBCm3hWAyB!4qWL_t(|ob8>_daEE1gt1?r(04RbC`P0ml-1%G%0HkU2)hdY>M2D?<9TF|HKLOZ>jz~qq1`Sm7ceNBFUnyA2tOPM zz8RT(5|`A=OOq>22M(T`FJ5)yPTyIX#I=E;2kue_)i}re_!R5oQ z&t|AE41Xy(eqrc3xF%8_M4!Pq{Zc}4z8{SNEklDH$k zHp4J~2L^SpPFm2*%k!(&%w_LGK>AqMPdG zR{hoEx6%7xrBK;^st#_|x7N+0)!8=s$e53YMSpu5*=OzYc!_j19vtkqlf``M1(?;7+SGq@%aB~P}mp20cgT>6?w!wd$igRkc5x!XFJ zbaa+Fc(l6tYQ4$%VI7Q)zxWd!^78&Vm3rs8>folf-jTGgu2ZQ$=)59~w`y{O2;1S$ zntubJzC+(r2Mf8sJ8jyW`b+iw2A_17+(Ty_On0ZjKUW7Q-_EJG)w2#p$3IsG&+$BU zcD;D8cbK~ z`#hL>$2u6Fjv354_#V9kU5W{w2j_aJ-+$X6&x7j^_;2d#4NmI&zb{(eTv_j4gw69~ z&fsD7Ic1Z+rw-<4r)R=*6+NonAL-Mx4n`+8^Q_|Xa{L*CsTU9S4)eAQNVjvn)Enyg zJQ$o)ADfMy`|^44h(x#6kTBk=iIOMVQ{3Wa*Ru{r$8!}8t!Et!PUrVzx&Jrn(0{+t zz9(xmy#$j^4D>wMXTB;csnq^)}CUTlLz!vSB&}4Q|rc8)l;Kse|`>FU#Ck zp80#?jv1WWu%Jn{$DCo;>2u0U_5I(IB{Hs)hsO8*A0$14SqGQ($+LI0o^>!d!~J6{ zV#}$&E+peagTbM};Lu=jXfQZ57?aKfd6O^&7n3jr7n3jr6c)}uF*V1W(PxIk00000 LNkvXXu0mjf1d@V) delta 1187 zcmV;U1YG;<3f&5jB!47HL_t(|ob8;!nxh~PgmJ%pLf_Hc<{8<8vmHW12e6G;ssBXU zvPBCVdNc_!#%T@DYwO6%nN;$p@s|8)+|Hj}tGE46^)3B($^SRtqKB+ac8$7r>^heA!%iMT zc;0dwl7|o;kH_!sz%y94?fkkuL;m*bljhfN_D^@zw=I#Z ztt07~=ytJAHT1P?Ui!UD#oKi)zp)s$`_rqh8mx!FJO^I=y2HJ;>omV8VxYcrKsPhZ*TsVh#ogx1Ap}8qocvK_O%8N42ZXp%z&v3 zUe`69?%;KB?5R6zL&4rfo8g#$fS;eA{HS+XMHg={j{31xbf`FY;i^8B-M$VcZy1}A z#V2t^y?k^Tp{#=qeSGEFKiyHgof@e#X6;m&wQE~zde*@s{m+bfYgl&FPa15Wc6&BQ zz0sv&|9^$4>)@7%-H9=SYs$BpMg!9Re{~&vFM|gLL}P!7r+G&HM*R-!U`srZUz_2W ze*lL%SSK~~^6~hpwRnSZ)UysA0qK5lNB)Em9*@V8An$9{;_0R|m!S_Ajp(krxmSO7 z|9$i^St&HOud0K4^}TiTY<0GeJ~QU6VcC&pHh);}<*To4ol2jtqFbm9^L=K^ty`Cp zAEx)u|L}4l_N>)=_50P%{@!)y2WD_fBuidwpFM+X%6sWsA{{drtPVb#v*&JaXUfsL z)WNgW&1dUft`F;AbmC-hbWrcB&%bhrIUW?71~Xvidt)WL$Drerq8 z4S%M)w_vairn|Qxo?HjdwyOL#{dDg|6K4iya93PD&hmWp+w|hWzQMgM9n$UER_Yz~ ztb@Vvtb=EJ9!x@jejZGHU>%H4#C;x2ec)_AmB^XMy>gDq;b#Lnfghh$51x_i z)|!&Wdo@||V*3`ixV!6F2cr|YiiXy+4hCoNce29&8+Gd6Y`>E=n_hxNCnkCx9AYa! zl~vU11BF{HQXKU@&v$$E+C1AZoq`5;>Dvu+(T~)@`@NTCZZAI1cYE~%Gq|>+p((cK zoMGqbYsypgYc4;9Sjb?01nQfZx@pJlQ9J)lRpI) zlRpI)lRpI)lRpI)lRpI)lRpI)lRpI)84e8w=O6e;Ye_{5DtrI{002ovPDHLkV1lO2 Ba7+LI diff --git a/cinema/gb/samesuite/apu/channel_1/volume/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/volume/xbaseline_0000.png index 54a535e66235423006341ee9e309270765b7ad5f..e639befda77330efede3dff21af8e5b7b963afdb 100644 GIT binary patch delta 2602 zcmaKtc~sJg7RTL^>Ih6plQ=G!I%SJXW+^4Ms8~#q<+!9Gm6?^ciW|#MrJ3AGO>J6S zLvcw6OG^`_GBrxeHFO*>bJ#=>&`?~SZ_asty!Xeuf86`eJ@=k-&-Z@5*|2)p9UEZ& zi047S_=mF4BPr5qi0#$1Zbe;>3)gf`fBED(d_knyFEQQ*+2>tSOI}~6JyfyfRc&m! zn=pGZMr~5&?sh@MYXH}cHe|`{N>#=On-}zJuQe0fJ$wXJK#6gfH$y)1yG4J6JMG4^ zomrGL zj*5jsp|4;inMemPD5}-)sjp}WuHAzg7pP7{e0ks4iSY$}2Q$AR+e?$^lzj$){BW`1 zrsUjxj|n{U;hY|ft5f_u^LRCDTj=$wJkdM?Jzk z!}V@|Hl4LX?~wI6c3Dquz0_A!OJ*qWMISJ&{On2FyFEumbl?*GLCp+<@6}ghLv{d( zBhX_x_Bm7e>7&LqXV6JC(g=rEyS4(0*k_{$(|LFGfjYIJ3HZpo6uo=Ie{+YS(cJ9a zo=kf)+_%9~OUcnAqJa2~i@}nJ!j|(|j~KW%PNvmsf0HsKb@BN_s7jbD%6?bUj0*=s zxodqjG0(1Syw6XLIiaKs@Lq6bHLYbQn_FtVd_l!+(qf*PiuiKhDO8P7X2S1s;`7d5 zM41C2l|VWoFz(Kk2AG9-y%=jJ!Bq)aDqK0o7c@@TYpA&kTu;gg#>|1rAZ+6k`*)-w z?)4b{hC!7>8btEvdnE$X_(kUjOD^#J>a^@^_&BMo9Q|%9@ml=XPj%3q+y1I zSwBUURh88nn_b-R1@5(Ho0d8oU5Iw^1xa@9lXP1gmVL!>-?nLJ3F1Zh!geX{zY?I+fUneX$D)PPN++Zsy>AQW0d4S z4mTrr08NM&{m|z$-;Mkl42ryzwe}IXQdu+S3tHCAOhgt>=0xwqGKSdl@!9J}yZ#uS zc;zD>^IJU^m3F+rs3bi%#GZKy&*w214u|)70FN>Ompe#Z_ zZ#oXbc{$X-$#HW6#oMtuA*c4tOMZpedjTfo6ni}cIeYnT)|P7{n1>?fGKxV`vv!}s z?gTwEA*aTDU)B#o4tJ`IV^v%Jb^pDN*DuM?%x+wp4bXK`69v4B>9;ia84~w|!qt}U zk#)V^T+sD%is}ATzV9*&ueh)duQ*~(%uwNebNG);Pi74iCysn%K$zX7M9HQ>Qj_jv zq{EV~A1JQhLn5&I0k2>+M_ya4#5gR@Y?!FSGdI>h0b`dxQ~(nM*2(FzbD|)ndr*lL zsn{8iCD7$J4M~~v_46+RU@@pnRjqBZM zOD@#e9)X4oxVJa-X$h?3GiPjl$_Xk0t8TU9{vyoPE+t`A;0@YaUgE1Q=tAgxSgZxn zE2*mYrs2KnY8CVsvc=@gg+&4@Y0n7zDPX|jr_d>LFpr72Dr@oR2J%H~mxT%;2Mc(c z6P@G7XYhDtuC9+joW5&5ZQUNqDBkTo3B8a15;8@n?yi>RIk-WWF4uEh!6r?8F1mvs zBN*p*7OHjIo{203vxqNGFkVSCM7%n|F&C_ol-aM!*&Gp1Zdl@knHk&C3jO;5qnUcfM+!?yl{gzvlaU75zfcJG@<>7-hw4;4f zWh*Zu&*n)q5corKvY>ti9Z(*2E z@RO)|H%%QAx3oZzzjj*SF8by4d=NR4LX=nA7^|6YKNm)#gZCb2eM~y^%uGn~O5!z? z-FciC#->#Q-KFz!3y*cD{_=51hKb#*Eq z1Pl>ai1$OzY_9$NYWL9uMIpm-^z+!u$U83c-#O*QsR#6$8Cy3MWZiP2jLw&DZ;3vl z|9)lj*{~$W^1Yi*83aXoj784UTr$$WyspzAk_-l$ZBsh>uC(t9Jo+;HQA;6Q5e z)C~)xTjwer>EW*|u3He5&wG^OtX|+P{O6pYC6R%|L||Ki|K9+f9jnu6QIH2{&p0BSHF?s2AQ6F$fDOV z4gXxAWj^NHg)0{>-3|LlMQEV3P)cTE3s%dfj&wM6hF>aFZEgW>hgf~{>Y;34vpvy+ zya{WmM6)s{)M{{5G1w6Sos}>YEygL}^g>I#<2%>p?3uY#HNGZhh068iH>duG+OANn xS>GzxPa8G+T$v`D+cK>6Ub+6?V*Ot|OQ2ORh*f$jzW|+;IO28Ov+fWsh;kq7=>v}z2ujl)Ub#}B-kW-a| zKp+ZswpLh4&6bRZJEbKvWc14@1oGpsozyu#F2^DOk)n!DMAnPnSg0(g z4_g%USh^xr_ zhvzNJs(caxFW#UGDRs)AP_2rt)3fv1AuiY5`D;hgQ}f*0A!(un8~gdy(26vj#l#eb zYEz%zd9bX%4m(#CRu}Ip;PEv6T=}v*N#61cxP#hy&|8yVgYWU^`ZGiT3z5MIMT%Y9@?YqLGZ8$HegA7nb-TV(>~(b@;PGy-Hnm^2oxo0m02YM)K)@d2g)lrn2+p zDyE}-F@lTD4Lk(Q9R}4#H>l{s8`F*hiKzcrocoS&!|P{v;62AW=0mt#flnE_@ekr zdysaUx;Q84S(LdKRDDEbim&pPfzfYsES zk!IYracO_&by~?4zfla%U@)Q$k=|g815oca2Tjn`^UKCCM27u^Iv(TEEF*f;3^pOJ zee5o9ao}obY<5Y3-?+o{yIsz%kyJ$Q3JK^NeN2OD@3JkkKR5syHqA&)aI+3_u+|FZ z?cWsYd@4(a3aU>{y>b606MaYNj6ud%x(a33(8PLR|6xMf8>ydHpQJ-^Y=e!aM3z=Bkf zBOW<$e|(8UoMQ|Txyr52P)54_iQO|SHxo=Mw4R?cC&GP7LQ%ateU&kOPHE8kOASr8 zPX_mKa!AKn@|%Zk2Q6*#EnC{4&^<9TWY4d`q@W@gHE%>cycnIY{-nZk)QWii_?VW*=E(-7xeH6g~k!en5)(?;Zbmw zN?=udepLYzEZ7SB$WD^wF;@7ZKqDb(WsdAu>hmN-XY5A$%??;NKshEtJ+_OJ9)q)q zvf93>EkaU7zYEP*Ow(u$2b#u-1-nJ4&@tQz`JJZD;XvQzspsLa1Ue(q4&8$lE+y!( zV6rkXjdKj{n)8#9!#=wmeD|DE13C;@a1^Y0A04_p%cwVkxeKw6{=wsO$Ex&)J;lK_ z85?Y=5#tmm=wE7Rwp874T-H54!BR|zI!O(HY3wuYk=d)2L*?a~#8==2y?5iUzdMrR z=&t!S5Bhs5#c`jejNrvcjI?nn(H?Mukc?i?TrHK>d9HPfzHgvs=p*>m?&i+D@e1YWR;*2I zgj;0Mxy&rRPblG8boREfmqo^nNl$6E6LN*;yXs0w3rw~dD%KVa*(?Y*cnpoD+@k9P zpmO&pm(d${U;a~>rn&)k@XadoN9&03vKk~en1_1noG4*s;IM1Y_K87lD*OJ=$7g#G zEfe?HQue-@N19JmB?GP1!fnn-WG(+fcR}*Df3AmCW6rGszoRf94A4=?>+lf}&Lpz_ zc?&&H1m2sVO|lwDAGSdkn^;)s5rf+8ZN#xdX+Ia7^E_!s{zF9^QIUJf!>z~Tv#nf! z5HbMjiMBz*Vyi;$T#X)3$&AakDE}iK7yO&B0rhNna_sZxiyV%jVcQ)+lyGHe_JA@k z3wmIoT!zG91SKNsAq25a#E>A>O6)V{*pZn6_$sHdu1QKxD5WU2hjx_ zRmU%+ing@Jjq76ws^t8phOxP<4jl@z$c%3nZb`&)O|o#W?ri8h_cmu;{2nY*ShH!q zskvj!Rjs>DQ4=ci$ZA@__*l%8+`$KnQyb1&0gFslZpTr4TZq55>CX~|J)YymG@>-L zEjL`+FjB<kovb3SN`TmBDpU0$c_}(X8F!$ zNNtr&(o6OGYX#8}Idno2)MEh}3W%hP(4V%!1 zgl?imC@TP!GDth%qCcF|0`pc=GkA>5UGZO}W%*V*)-HGmIfUt;i!dgf4y}H$qiWSs zt$pIV5|jUSKg@cT>7OUQDQWWXlyHSV7R2G*`<=r29e%67L&E=gK@;Ak`5R5b8quaVIiW z)HapEoxjPF-n%Z~bn4+E)#_T884o%+Qr-svPUqDBT~^^#ji-0P;b8FFKhN%rqgB~y H!u|gMb80eD diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_glitch/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/nrx2_glitch/xbaseline_0000.png index 2cecec38f21d9e1405731f0756f9592498cc2234..eefe570bd37d0089822dd3b0b873b18100f7b8b5 100644 GIT binary patch delta 420 zcmV;V0bBm`1=IzQB!8PpL_t(|obA}rZo(h{Kv7ush5TdvP4-|$5L`1IbZ~ReQ-`(E z-e7Pc=X@MTs2sU?61lV&ni8~6e-#(#BU-?Q~!fG2X!8^yjl z@KSZd_d5Q4u)XSr5I&l}V~q1|V5z!q+~#(5LkJ;XwTnLg-1T?S`O&EP%szjiC3QD@ ziM)Eh`z_hVz?J%Ry#Kf|ICe#r37o9aJpUVFx%10C*Y`j0xS3O3J&*XE*XJxFPmf={ z{`TkhPpW<>;eYYD{4sDdkFkO4({>Epzjw&>+gOvK8D9j$Oegt9GLmd_KcBu7Bz8;QCol`iQL!Uc2R@SMH)iRd?(z`ux7u-$my~ zqpm;wcd)-}|JQQ==+IarchOpqf#D1cXJ9x3!x_`#ppzg1eidIQ8q#ve~%C1!xHaMO4MbTxk z6B|uKN@{&Xf+GKiYn}pP#Rxyq>n>JhK_s zGvzO|9zQ#J>ip66)BF6-osYHEZ{=&w?kC3BX(wH61HVCxaetiHYqt6i;Et5ijbgt$ z@KANb_kDak*uCn85I#0P#~Axvz)*EBT;}cSh7dw}*HiTV_m2M*oqlVzpWf#WbW5#z z-y&zP_kOqRZyzCqWm#fjS(f!!tNHrqdZ?Z$oxLOTEx2=!mUTPrXSnn8HJ8`lcARH6 z<9a4NdGkxp-+%M+3OVP_H@;y%!=3*y#_@PZ#t&C+^$R_+=4RY=KbOz1Kig#e?NjtC z)_W*Fhi{&_vQE#^m)9KX**>&>R*!kP`XbBuSH_z)^W?*EzP9o@*Ks{lf5o5c_ufx- z_WWm`dU5^#`yL#|+fUnj_h->tzXzXPzxRGFpI>j!_Y&X``u`8(?(f0F1y)-vpQ1G& ilfeQ0lVAcZ7QO)g0d8Jb7JIA!0000#cIzMvL`l#4LjR+)>o@WiZdHOn5d<7OnY*Ge z2+SB49j9rCG4A^w683$MF%GQPtw)oti7`sewr$dP+qPm&2tf~FjF`rkfX0Y+w6XJ_ z6hBCxwEx($)MRB{lU{%>7hClL86y@K$QaR%Hg^7#;@@J7w}0C$YyN3V>R%~Kw7*er zKjUUK((&kU&(c5rQ!TKw85?~U(YA3aJj{+ABjeQU#W!rpBP?$u$OqV4O_@#7`X7ISgy5>)gMzjZbavNGFSZbY1LcvFPgD}!SE*|cJCu2_p^uML^)WdzILoP#*%(@%DzkE}HM=|`LUzGT@muxb)AC^5tEg|DkWW)I zpecTbK7W%voxgCgJlIoXFM;2H4uhQrq_brnd>Ml~ZV2am^hK>;F!Nwb+!0?d{lNGg zOv!_bL27#WvGvrdA1BO%jmgyX)AQi#J`XVX3L)I@_gjK|f~!`aHl?u)eK_TgZpxcm z^|R+cOCOUXgR^{29^9&L&6`)tvuEiuW1bq8jeoR`!M5ggy}$2L`ur5_LEC(A>}+{- zXJ@Y2wEnX1J{-iBvwExkSX<+B&dvIc9qg&ef)~qUcd%!~_4R4%lpTEOJa{&<_ipQC zyt*~>;MMZx+4@QA!#o(BIQbJDY0cC;mHJ_Ma8p?iFEzC?^&|C}F)3+%tEM)j{{pBV zqJQtng9YOcAZy~*;MBjU?>D%~UGgqE^I*Dr8RA)au>R$JtvvOjdgj6C#Iy3?Ro;(& znqE9O8ito;Lb_aQrGB73{~9G7NaN9vMHra}zxRDGDU&@~Q_^~^v1_v6#quQ{aaY$f z4@M`Vybq?HdGJTlv4fch&(Mp&h|r@K#edN-yez}(a;^0<^&szq{TKY1dcVO=egF4G z%P&{vyF-}u{+K&>5q+)Ki~62Cn4g`#5|O9qHT3b3QF`XV=+t)JsCxNvwH@;*dhy_B z7+#hM>2j@=`hj}B4+iI@kIiQ9efd6kMY2b0N?PBl$$}Tlmw3coUC%rioyb!(w11v? zFgTsxlNEj+)Tw{({hqAV^dc}KoS_%R(cme^%2#C-^{Ff?*IF_3v)=Ev>a}^cVOdaJ zNrOF_)AT)g@bT8}gP`jgQFij)5YKNj;J#k(QiZVvJI=ZJQjsZCkM>grK`HdQ9U>K%+-H+Su_= ziXY^d^!Tx5smaQ^COrXNF1G3kGI}gdkkO+ZZS43b#lOWEZ-2L2*8J0!)W1@eXn(!l ze)`R7D3;9ecZF4{gX9X~$u z_V|Sm-dI^_?9$S{0tgLHd z$sjz{-PNx7;H~^(E#VM-TF-S)BxdddaPd9_ubMD zG}yjHhem_-i8)W$X@DNNtv{A;Yy7nJsliQp-89|cT7UUWgF7yW&}hI?25;MzZpgJB zDi4k=d8chj?GQcn1LJq_{r&xX9Bb~P_3dQLuJV_@U35sCTVz*nL!_3eaturZjLetI5!-TMIsUm=A1{eDZ3H@Ir`X;T`@(1%m5=%&26 zRX=x*h=fSg?y>?p% zA(Ka!3W%shC8 zUIa#j9=#}zhT&!DUYBdFpQ)eqUUz0pN`G44s7<@4Yb$!@JFX??3E3tlW=;ud#xJ@a66B6rcydgj64bpB6P_2WJzT%@v;q zlkxBe;NZOU>q4?VG#DHj3=Rzjhm)!Vx|1IT1{VAWpZse{jl^Tg00000NkvXXu0mjf DZE$<^ diff --git a/cinema/gb/samesuite/apu/channel_2/volume/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/volume/xbaseline_0000.png index c8e022e1856fb0b467006640e7d5cccdcd9eb1dc..cb59bd6b2e3d0c9c5a56d99851749aa80f5fc78d 100644 GIT binary patch literal 569 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|OI-r;B4q#hka-0`r<2L>vN_ zdoRgOnfs;rio{Vj>CC53=II|1PbfP4A~SMY+kLHp8mYPwx)XV<-Gh4S8r^5Rvz{Kt8`7wYrm~}Z|><|vp#SC`rzw$cDdvp z!?=GY^$B;^9FyRG*Y)1){~Gu8`!)VA$~Rw;eD?j8dmDG|+<(FGJM*!3ji2|=v5&kN mk`U8a$a+jvB7BrVI1u8SLoXG#t!jG$N)n!~elF{r5}E*p-SCY7 literal 569 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|OI-r;B4q#hka-qVr}uFgOIR z*yR+V{CZBEi|ZAYz>W>CV&;A}ZJSsbW0NM8oO9bu7Ko4S$o~DWFml?*>zj1m=UG-w z{P}y@direction; envelope->stepTime = GBAudioRegisterSweepGetStepTime(value); envelope->direction = GBAudioRegisterSweepGetDirection(value); envelope->initialVolume = GBAudioRegisterSweepGetInitialVolume(value); - if (style == GB_AUDIO_DMG && !envelope->stepTime) { + if (!envelope->stepTime) { // TODO: Improve "zombie" mode - ++envelope->currentVolume; + if (style == GB_AUDIO_DMG) { + ++envelope->currentVolume; + } else if (style == GB_AUDIO_CGB) { + if (envelope->direction == oldDirection) { + if (envelope->direction) { + ++envelope->currentVolume; + } else { + envelope->currentVolume += 2; + } + } else { + envelope->currentVolume = 0; + } + } envelope->currentVolume &= 0xF; } _updateEnvelopeDead(envelope); From 5bd5a8d998b4449bc85e606f48be3cc18d280ef1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Dec 2023 22:05:17 -0800 Subject: [PATCH 028/336] GBA I/O: Fix HALTCNT access behavior (fixes #2309) --- CHANGES | 3 ++- src/gba/io.c | 34 +++++++++++++++++----------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index e5f40a5ff..30d8b9dff 100644 --- a/CHANGES +++ b/CHANGES @@ -21,8 +21,9 @@ Emulation fixes: - GBA Audio: Fix sample timing drifting when changing sample interval - GBA Audio: Fix initial channel 3 wave RAM (fixes mgba.io/i/2947) - GBA Audio: Fix sample position issues when rate changes (fixes mgba.io/i/3006) - - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) - GBA BIOS: Fix clobbering registers with word-sized CpuSet + - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) + - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA SIO: Fix normal mode SI/SO semantics (fixes mgba.io/i/2925) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) Other fixes: diff --git a/src/gba/io.c b/src/gba/io.c index 10eb9fb4c..184146511 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -531,6 +531,21 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { case GBA_REG_MAX: // Some bad interrupt libraries will write to this break; + case GBA_REG_POSTFLG: + if (gba->memory.activeRegion == GBA_REGION_BIOS) { + if (gba->memory.io[address >> 1]) { + if (value & 0x8000) { + GBAStop(gba); + } else { + GBAHalt(gba); + } + } + value &= ~0x8000; + } else { + mLOG(GBA_IO, GAME_ERROR, "Write to BIOS-only I/O register: %03X", address); + return; + } + break; case GBA_REG_EXWAITCNT_HI: // This register sits outside of the normal I/O block, so we need to stash it somewhere unused address = GBA_REG_INTERNAL_EXWAITCNT_HI; @@ -563,19 +578,6 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { } void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) { - if (address == GBA_REG_HALTCNT) { - value &= 0x80; - if (!value) { - GBAHalt(gba); - } else { - GBAStop(gba); - } - return; - } - if (address == GBA_REG_POSTFLG) { - gba->memory.io[(address & (GBA_SIZE_IO - 1)) >> 1] = value; - return; - } if (address >= GBA_REG_DEBUG_STRING && address - GBA_REG_DEBUG_STRING < sizeof(gba->debugString)) { gba->debugString[address - GBA_REG_DEBUG_STRING] = value; return; @@ -806,10 +808,6 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { gba->memory.io[GBA_REG(JOYSTAT)] &= ~JOYSTAT_RECV; break; - case GBA_REG_POSTFLG: - mLOG(GBA_IO, STUB, "Stub I/O register read: %03x", address); - break; - // Wave RAM can be written and read even if the audio hardware is disabled. // However, it is not possible to switch between the two banks because it // isn't possible to write to register SOUND3CNT_LO. @@ -883,6 +881,7 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { case GBA_REG_IF: case GBA_REG_WAITCNT: case GBA_REG_IME: + case GBA_REG_POSTFLG: // Handled transparently by registers break; case 0x066: @@ -897,6 +896,7 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { case 0x142: case 0x15A: case 0x206: + case 0x302: mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address); return 0; // These registers sit outside of the normal I/O block, so we need to stash them somewhere unused From ffacbcfeea0cd7a35b8c9908976f95161f5bcb55 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Dec 2023 22:59:35 -0800 Subject: [PATCH 029/336] Qt: Make Gamepad be a shared_ptr --- src/platform/qt/InputController.cpp | 16 ++++++++-------- src/platform/qt/InputController.h | 4 ++-- src/platform/qt/input/InputDriver.cpp | 6 +++--- src/platform/qt/input/InputDriver.h | 6 ++++-- src/platform/qt/input/SDLInputDriver.cpp | 6 +++--- src/platform/qt/input/SDLInputDriver.h | 2 +- .../qt/scripting/ScriptingController.cpp | 2 +- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 5e8634497..212c55c09 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -345,7 +345,7 @@ void InputController::update() { int InputController::pollEvents() { int activeButtons = 0; for (auto& pad : gamepads()) { - InputMapper im(mapper(pad)); + InputMapper im(mapper(pad.get())); activeButtons |= im.mapKeys(pad->currentButtons()); activeButtons |= im.mapAxes(pad->currentAxes()); activeButtons |= im.mapHats(pad->currentHats()); @@ -358,7 +358,7 @@ int InputController::pollEvents() { return activeButtons; } -Gamepad* InputController::gamepad(uint32_t type) { +std::shared_ptr InputController::gamepad(uint32_t type) { auto driver = m_inputDrivers.value(type); if (!driver) { return nullptr; @@ -370,13 +370,13 @@ Gamepad* InputController::gamepad(uint32_t type) { return driver->activeGamepad(); } -QList InputController::gamepads() { - QList pads; +QList> InputController::gamepads() { + QList> pads; for (auto& driver : m_inputDrivers) { if (!driver->supportsGamepads()) { continue; } - Gamepad* pad = driver->activeGamepad(); + std::shared_ptr pad = driver->activeGamepad(); if (pad) { pads.append(pad); } @@ -386,7 +386,7 @@ QList InputController::gamepads() { QSet InputController::activeGamepadButtons(uint32_t type) { QSet activeButtons; - Gamepad* pad = gamepad(type); + std::shared_ptr pad = gamepad(type); if (!pad) { return {}; } @@ -401,7 +401,7 @@ QSet InputController::activeGamepadButtons(uint32_t type) { QSet> InputController::activeGamepadAxes(uint32_t type) { QSet> activeAxes; - Gamepad* pad = gamepad(type); + std::shared_ptr pad = gamepad(type); if (!pad) { return {}; } @@ -422,7 +422,7 @@ QSet> InputController::activeGamepadAxes QSet> InputController::activeGamepadHats(uint32_t type) { QSet> activeHats; - Gamepad* pad = gamepad(type); + std::shared_ptr pad = gamepad(type); if (!pad) { return {}; } diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index 6f2326cbd..06871ff1e 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -143,8 +143,8 @@ private: static int claimPlayer(); static void freePlayer(int); - Gamepad* gamepad(uint32_t type); - QList gamepads(); + std::shared_ptr gamepad(uint32_t type); + QList> gamepads(); QSet activeGamepadButtons(uint32_t type); QSet> activeGamepadAxes(uint32_t type); diff --git a/src/platform/qt/input/InputDriver.cpp b/src/platform/qt/input/InputDriver.cpp index f76649bd8..3f805f411 100644 --- a/src/platform/qt/input/InputDriver.cpp +++ b/src/platform/qt/input/InputDriver.cpp @@ -36,7 +36,7 @@ QList InputDriver::connectedKeySources() const { return {}; } -QList InputDriver::connectedGamepads() const { +QList> InputDriver::connectedGamepads() const { return {}; } @@ -57,8 +57,8 @@ KeySource* InputDriver::activeKeySource() { return ks[activeKeySource]; } -Gamepad* InputDriver::activeGamepad() { - QList pads(connectedGamepads()); +std::shared_ptr InputDriver::activeGamepad() { + QList> pads(connectedGamepads()); int activeGamepad = activeGamepadIndex(); if (activeGamepad < 0 || activeGamepad >= pads.count()) { return nullptr; diff --git a/src/platform/qt/input/InputDriver.h b/src/platform/qt/input/InputDriver.h index cc0a6e0cd..4b0513f2e 100644 --- a/src/platform/qt/input/InputDriver.h +++ b/src/platform/qt/input/InputDriver.h @@ -9,6 +9,8 @@ #include #include +#include + struct mRotationSource; struct mRumble; @@ -42,13 +44,13 @@ public: virtual bool update() = 0; virtual QList connectedKeySources() const; - virtual QList connectedGamepads() const; + virtual QList> connectedGamepads() const; virtual int activeKeySourceIndex() const; virtual int activeGamepadIndex() const; KeySource* activeKeySource(); - Gamepad* activeGamepad(); + std::shared_ptr activeGamepad(); virtual void setActiveKeySource(int); virtual void setActiveGamepad(int); diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index 5b68462d1..e3a77094f 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -139,10 +139,10 @@ bool SDLInputDriver::update() { return true; } -QList SDLInputDriver::connectedGamepads() const { - QList pads; +QList> SDLInputDriver::connectedGamepads() const { + QList> pads; for (auto& pad : m_gamepads) { - pads.append(pad.get()); + pads.append(pad); } return pads; } diff --git a/src/platform/qt/input/SDLInputDriver.h b/src/platform/qt/input/SDLInputDriver.h index 0ca2f4030..61f1e6238 100644 --- a/src/platform/qt/input/SDLInputDriver.h +++ b/src/platform/qt/input/SDLInputDriver.h @@ -44,7 +44,7 @@ public: bool update() override; - QList connectedGamepads() const override; + QList> connectedGamepads() const override; int activeGamepadIndex() const override; void setActiveGamepad(int) override; diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index f4c5092c1..95180d1de 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -264,7 +264,7 @@ void ScriptingController::updateGamepad() { detachGamepad(); return; } - Gamepad* gamepad = driver->activeGamepad(); + std::shared_ptr gamepad = driver->activeGamepad(); if (!gamepad) { detachGamepad(); return; From 45387aa6631171276e708dc2003333296dcb273a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 21 Dec 2023 00:24:16 -0800 Subject: [PATCH 030/336] Qt: Fix Action leak --- src/platform/qt/ActionMapper.cpp | 11 +++++++++-- src/platform/qt/ConfigController.cpp | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/ActionMapper.cpp b/src/platform/qt/ActionMapper.cpp index cb96ab6dc..890ea8893 100644 --- a/src/platform/qt/ActionMapper.cpp +++ b/src/platform/qt/ActionMapper.cpp @@ -93,7 +93,13 @@ void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, QWidget* conte qaction->setMenuRole(QAction::QuitRole); break; } - QObject::connect(qaction, &QAction::triggered, [qaction, action](bool enabled) { + + std::weak_ptr weakAction(action); + QObject::connect(qaction, &QAction::triggered, [qaction, weakAction](bool enabled) { + if (weakAction.expired()) { + return; + } + std::shared_ptr action(weakAction.lock()); if (qaction->isCheckable()) { action->trigger(enabled); } else { @@ -101,7 +107,8 @@ void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, QWidget* conte } }); QObject::connect(action.get(), &Action::enabled, qaction, &QAction::setEnabled); - QObject::connect(action.get(), &Action::activated, [qaction, action](bool active) { + QObject::connect(action.get(), &Action::activated, [qaction, weakAction](bool active) { + std::shared_ptr action(weakAction.lock()); if (qaction->isCheckable()) { qaction->setChecked(active); } else if (active) { diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 7a26ea844..8922830fc 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -49,7 +49,12 @@ std::shared_ptr ConfigOption::addValue(const QString& text, const QVaria action = std::make_shared(function, name, text, this); } action->setExclusive(); - QObject::connect(action.get(), &QObject::destroyed, this, [this, action, value]() { + std::weak_ptr weakAction(action); + QObject::connect(action.get(), &QObject::destroyed, this, [this, weakAction, value]() { + if (weakAction.expired()) { + return; + } + std::shared_ptr action(weakAction.lock()); m_actions.removeAll(std::make_pair(action, value)); }); m_actions.append(std::make_pair(action, value)); @@ -71,7 +76,12 @@ std::shared_ptr ConfigOption::addBoolean(const QString& text, ActionMapp action = std::make_shared(function, m_name, text, this); } - QObject::connect(action.get(), &QObject::destroyed, this, [this, action]() { + std::weak_ptr weakAction(action); + QObject::connect(action.get(), &QObject::destroyed, this, [this, weakAction]() { + if (weakAction.expired()) { + return; + } + std::shared_ptr action(weakAction.lock()); m_actions.removeAll(std::make_pair(action, QVariant(1))); }); m_actions.append(std::make_pair(action, QVariant(1))); From d83b2f99cd3d35509cf110bb47cbc72f569a31ed Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 21 Dec 2023 22:57:09 -0800 Subject: [PATCH 031/336] VFS: Use anonymousMemoryMap for large 7z allocations (fixes #3013) --- CHANGES | 1 + src/util/vfs/vfs-lzma.c | 68 ++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 30d8b9dff..65174a532 100644 --- a/CHANGES +++ b/CHANGES @@ -47,6 +47,7 @@ Misc: - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Scripting: Add `callbacks:oneshot` for single-call callbacks + - VFS: Use anonymousMemoryMap for large 7z allocations (fixes mgba.io/i/3013) 0.10.2: (2023-04-23) Emulation fixes: diff --git a/src/util/vfs/vfs-lzma.c b/src/util/vfs/vfs-lzma.c index a094c187a..0ded446bd 100644 --- a/src/util/vfs/vfs-lzma.c +++ b/src/util/vfs/vfs-lzma.c @@ -7,7 +7,9 @@ #ifdef USE_LZMA +#include #include +#include #include "third-party/lzma/7z.h" #include "third-party/lzma/7zAlloc.h" @@ -26,15 +28,19 @@ struct VDirEntry7z { char* utf8; }; +struct VDir7zAlloc { + ISzAlloc d; + struct Table allocs; +}; + struct VDir7z { struct VDir d; struct VDirEntry7z dirent; - // What is all this garbage? CFileInStream archiveStream; CLookToRead2 lookStream; CSzArEx db; - ISzAlloc allocImp; + struct VDir7zAlloc allocImp; ISzAlloc allocTempImp; }; @@ -70,6 +76,43 @@ static bool _vd7zDeleteFile(struct VDir* vd, const char* path); static const char* _vde7zName(struct VDirEntry* vde); static enum VFSType _vde7zType(struct VDirEntry* vde); +static void* _vd7zAlloc(ISzAllocPtr p, size_t size) { + struct VDir7zAlloc* alloc = (struct VDir7zAlloc*) p; + void* address; + if (size >= 0x10000) { + address = anonymousMemoryMap(size); + } else { + address = malloc(size); + } + if (address) { + TableInsert(&alloc->allocs, (uintptr_t) address >> 2, (void*) size); + } + return address; +} + +static void _vd7zFree(ISzAllocPtr p, void* address) { + struct VDir7zAlloc* alloc = (struct VDir7zAlloc*) p; + size_t size = (size_t) TableLookup(&alloc->allocs, (uintptr_t) address >> 2); + if (size) { + if (size >= 0x10000) { + mappedMemoryFree(address, size); + } else { + free(address); + } + TableRemove(&alloc->allocs, (uintptr_t) address >> 2); + } +} + +static void* _vd7zAllocTemp(ISzAllocPtr p, size_t size) { + UNUSED(p); + return malloc(size); +} + +static void _vd7zFreeTemp(ISzAllocPtr p, void* address) { + UNUSED(p); + free(address); +} + struct VDir* VDirOpen7z(const char* path, int flags) { if (flags & O_WRONLY || flags & O_CREAT) { return 0; @@ -83,11 +126,12 @@ struct VDir* VDirOpen7z(const char* path, int flags) { return 0; } - vd->allocImp.Alloc = SzAlloc; - vd->allocImp.Free = SzFree; + vd->allocImp.d.Alloc = _vd7zAlloc; + vd->allocImp.d.Free = _vd7zFree; + TableInit(&vd->allocImp.allocs, 0, NULL); - vd->allocTempImp.Alloc = SzAllocTemp; - vd->allocTempImp.Free = SzFreeTemp; + vd->allocTempImp.Alloc = _vd7zAllocTemp; + vd->allocTempImp.Free = _vd7zFreeTemp; FileInStream_CreateVTable(&vd->archiveStream); LookToRead2_CreateVTable(&vd->lookStream, False); @@ -101,11 +145,12 @@ struct VDir* VDirOpen7z(const char* path, int flags) { CrcGenerateTable(); SzArEx_Init(&vd->db); - SRes res = SzArEx_Open(&vd->db, &vd->lookStream.vt, &vd->allocImp, &vd->allocTempImp); + SRes res = SzArEx_Open(&vd->db, &vd->lookStream.vt, &vd->allocImp.d, &vd->allocTempImp); if (res != SZ_OK) { - SzArEx_Free(&vd->db, &vd->allocImp); + SzArEx_Free(&vd->db, &vd->allocImp.d); File_Close(&vd->archiveStream.file); free(vd->lookStream.buf); + TableDeinit(&vd->allocImp.allocs); free(vd); return 0; } @@ -128,7 +173,7 @@ struct VDir* VDirOpen7z(const char* path, int flags) { bool _vf7zClose(struct VFile* vf) { struct VFile7z* vf7z = (struct VFile7z*) vf; - IAlloc_Free(&vf7z->vd->allocImp, vf7z->outBuffer); + IAlloc_Free(&vf7z->vd->allocImp.d, vf7z->outBuffer); free(vf7z); return true; } @@ -215,12 +260,13 @@ ssize_t _vf7zSize(struct VFile* vf) { bool _vd7zClose(struct VDir* vd) { struct VDir7z* vd7z = (struct VDir7z*) vd; - SzArEx_Free(&vd7z->db, &vd7z->allocImp); + SzArEx_Free(&vd7z->db, &vd7z->allocImp.d); File_Close(&vd7z->archiveStream.file); free(vd7z->lookStream.buf); free(vd7z->dirent.utf8); vd7z->dirent.utf8 = 0; + TableDeinit(&vd7z->allocImp.allocs); free(vd7z); return true; @@ -292,7 +338,7 @@ struct VFile* _vd7zOpenFile(struct VDir* vd, const char* path, int mode) { SRes res = SzArEx_Extract(&vd7z->db, &vd7z->lookStream.vt, i, &blockIndex, &vf->outBuffer, &outBufferSize, &vf->bufferOffset, &vf->size, - &vd7z->allocImp, &vd7z->allocTempImp); + &vd7z->allocImp.d, &vd7z->allocTempImp); if (res != SZ_OK) { free(vf); From 48253afc54336de9d6c1c6346739a443132ed16e Mon Sep 17 00:00:00 2001 From: luc-git <102831178+luc-git@users.noreply.github.com> Date: Sun, 7 Jan 2024 07:47:11 +0100 Subject: [PATCH 032/336] Qt: Fix shaders not applying when display is loaded (#3100) Co-authored-by: Vicki Pfau --- src/platform/qt/Display.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp index b9bb77c1f..8bec92f28 100644 --- a/src/platform/qt/Display.cpp +++ b/src/platform/qt/Display.cpp @@ -116,7 +116,10 @@ void QGBA::Display::configure(ConfigController* config) { config->updateOption("videoSync"); #if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(BUILD_GLES3) if (opts->shader && supportsShaders()) { - struct VDir* shader = VDirOpen(opts->shader); + struct VDir* shader = VDirOpenArchive(opts->shader); + if (!shader) { + shader = VDirOpen(opts->shader); + } if (shader) { setShaders(shader); shader->close(shader); From 3becd63ef5ef623957cae822c67c9a694aeda7a6 Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Sun, 7 Jan 2024 08:54:01 +0200 Subject: [PATCH 033/336] Res: Add gbc-lcd shader, imitates GBC LCD subpixel arrangement with an optional backlight effect (#3097) --- res/shaders/gbc-lcd.shader/gbc-lcd-light.fs | 119 ++++++ res/shaders/gbc-lcd.shader/gbc-lcd.fs | 421 ++++++++++++++++++++ res/shaders/gbc-lcd.shader/license.txt | 24 ++ res/shaders/gbc-lcd.shader/manifest.ini | 129 ++++++ 4 files changed, 693 insertions(+) create mode 100644 res/shaders/gbc-lcd.shader/gbc-lcd-light.fs create mode 100644 res/shaders/gbc-lcd.shader/gbc-lcd.fs create mode 100644 res/shaders/gbc-lcd.shader/license.txt create mode 100644 res/shaders/gbc-lcd.shader/manifest.ini diff --git a/res/shaders/gbc-lcd.shader/gbc-lcd-light.fs b/res/shaders/gbc-lcd.shader/gbc-lcd-light.fs new file mode 100644 index 000000000..cb583f4da --- /dev/null +++ b/res/shaders/gbc-lcd.shader/gbc-lcd-light.fs @@ -0,0 +1,119 @@ +/** + * This shader creates a backlight bleeding effect, + * and an internal reflection or ghosting effect. + */ + +varying vec2 texCoord; +uniform sampler2D tex; + +/** + * Determines the color of the backlight bleed. + * Lower values produce less, dimmer light. + * Higher values produce brighter or more colorful light. + * You'll normally want each of these numbers to be close + * to 1, and not normally lower than 0. + */ +uniform vec3 LightColor; + +/** + * Affects the shape of the backlight bleed glow. + * Lower values cause the light bleed to fade out quickly + * from the edges. + * Higher values cause the light bleed to fade out more + * softly and gradually toward the center. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float LightSoftness; + +/** + * Lower values result in a less visible or intense + * backlight bleed. + * Higher values make the backlight bleed more pronounced. + * You'll normally want this to be a number close to 0, + * and not normally higher than 1. + */ +uniform float LightIntensity; + +/** + * Lower values cause the internal reflection or ghosting + * effect to be less visible. + * Higher values cause the effect to be brighter and more + * visible. + * You'll normally want this to be a number close to 0, + * and not normally higher than 1. + */ +uniform float ReflectionBrightness; + +/** + * Lower values have the internal reflection or ghosting + * effect appear offset by a lesser distance. + * Higher values have the effect offset by a greater + * distance. + * You'll normally want each of these numbers to be close + * to 0, and not normally higher than 1. + */ +uniform vec2 ReflectionDistance; + +#define M_PI 3.1415926535897932384626433832795 + +/** + * Helper to compute backlight bleed intensity + * for a texCoord input. + */ +float getLightIntensity(vec2 coord) { + vec2 coordCentered = coord - vec2(0.5, 0.5); + float coordDistCenter = ( + length(coordCentered) / sqrt(0.5) + ); + vec2 coordQuadrant = vec2( + 1.0 - (1.5 * min(coord.x, 1.0 - coord.x)), + 1.0 - (1.5 * min(coord.y, 1.0 - coord.y)) + ); + float lightIntensityEdges = ( + pow(coordQuadrant.x, 5.0) + + pow(coordQuadrant.y, 5.0) + ); + float lightIntensity = ( + (1.0 - LightSoftness) * lightIntensityEdges + + LightSoftness * coordDistCenter + ); + return clamp(lightIntensity, 0.0, 1.0); +} + +/** + * Helper to convert an intensity value into a white + * gray color with that intensity. A radial distortion + * effect with subtle chromatic abberation is applied that + * makes it look a little more like a real old or cheap + * backlight, and also helps to reduce color banding. + */ +vec3 getWhiteVector(float intensity) { + const float DeformAmount = 0.0025; + vec2 texCoordCentered = texCoord - vec2(0.5, 0.5); + float radians = atan(texCoordCentered.y, texCoordCentered.x); + float rot = pow(2.0, 4.0 + floor(6.0 * length(texCoordCentered))); + float deformRed = cos(rot * radians + (2.0 / 3.0 * M_PI)); + float deformGreen = cos(rot * radians); + float deformBlue = cos(rot * radians + (4.0 / 3.0 * M_PI)); + return clamp(vec3( + intensity + (deformRed * DeformAmount), + intensity + (deformGreen * DeformAmount), + intensity + (deformBlue * DeformAmount) + ), 0.0, 1.0); +} + +void main() { + vec3 colorSource = texture2D(tex, texCoord).rgb; + vec3 lightWhiteVector = getWhiteVector(getLightIntensity(texCoord)); + vec3 colorLight = LightColor * lightWhiteVector; + vec3 colorReflection = texture2D(tex, texCoord - ReflectionDistance).rgb; + vec3 colorResult = ( + colorSource + + (colorLight * LightIntensity) + + (colorReflection * ReflectionBrightness) + ); + gl_FragColor = vec4( + colorResult, + 1.0 + ); +} diff --git a/res/shaders/gbc-lcd.shader/gbc-lcd.fs b/res/shaders/gbc-lcd.shader/gbc-lcd.fs new file mode 100644 index 000000000..4b88ad3aa --- /dev/null +++ b/res/shaders/gbc-lcd.shader/gbc-lcd.fs @@ -0,0 +1,421 @@ +/** + * This shader imitates the GameBoy Color subpixel + * arrangement. + */ + +varying vec2 texCoord; +uniform sampler2D tex; +uniform vec2 texSize; + +/** + * Adds a base color to everything. + * Lower values make black colors darker. + * Higher values make black colors lighter. + * You'll normally want each of these numbers to be close + * to 0, and not normally higher than 1. + */ +uniform vec3 BaseColor; + +/** + * Modifies the contrast or saturation of the image. + * Lower values make the image more gray and higher values + * make it more colorful. + * A value of 1 represents a normal, baseline level of + * contrast. + * You'll normally want this to be somewhere around 1. + */ +uniform float SourceContrast; + +/** + * Modifies the luminosity of the image. + * Lower values make the image darker and higher values make + * it lighter. + * A value of 1 represents normal, baseline luminosity. + * You'll normally want this to be somewhere around 1. + */ +uniform float SourceLuminosity; + +/** + * Lower values look more like a sharp, unshaded image. + * Higher values look more like an LCD display with subpixels. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelBlendAmount; + +/** + * Lower values make subpixels darker. + * Higher values make them lighter and over-bright. + * A value of 1 represents a normal, baseline gamma value. + * You'll normally want this to be somewhere around 1. + */ +uniform float SubpixelGamma; + +/** + * Higher values allow subpixels to be more blended-together + * and brighter. + * Lower values keep subpixel colors more separated. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelColorBleed; + +/** + * Determines the distance between subpixels. + * Lower values put the red, green, and blue subpixels + * within a single pixel closer together. + * Higher values put them farther apart. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelSpread; + +/** + * Determines the vertical offset of subpixels within + * a pixel. + * Lower values put the red, green, and blue subpixels + * within a single pixel higher up. + * Higher values put them further down. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelVerticalOffset; + +/** + * Lower values make the subpixels horizontally thinner, + * and higher values make them thicker. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelLightWidth; + +/** + * Lower values make the subpixels vertically taller, + * and higher values make them shorter. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelLightHeight; + +/** + * Lower values make the subpixels sharper and more + * individually distinct. + * Higher values add an increasingly intense glowing + * effect around each subpixel. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelLightGlow; + +/** + * Scale the size of pixels up or down. + * Useful for looking at larger than 8x8 subpixel sizes. + * You'll normally want this number to be exactly 1, + * meaning that every group of 3 subpixels corresponds + * to one pixel in the display. + */ +uniform float SubpixelScale; + +/** + * GBC subpixels are roughly rectangular shaped, but + * with a rectangular gap in the lower-right corner. + * Lower values make the lower-right gap in each GBC + * subpixel less distinct. A value of 0 results in no + * gap being shown at all. + * Higher values make the gap more distinct. + * You'll normally want this to be a number from 0 to 1. + */ +uniform float SubpixelTabHeight; + +/** + * The following three uniforms decide the base colors + * of each of the subpixels. + * + * Default subpixel colors are based on this resource: + * https://gbcc.dev/technology/ + * R: #FF7145 (1.00, 0.44, 0.27) + * G: #C1D650 (0.75, 0.84, 0.31) + * B: #3BCEFF (0.23, 0.81, 1.00) + */ +uniform vec3 SubpixelColorRed; // vec3(1.00, 0.38, 0.22); +uniform vec3 SubpixelColorGreen; // vec3(0.60, 0.88, 0.30); +uniform vec3 SubpixelColorBlue; // vec3(0.23, 0.65, 1.00); + +/** + * Helper to get luminosity of an RGB color. + * Used with HCL color space related code. + */ +float getColorLumosity(in vec3 rgb) { + return ( + (rgb.r * (5.0 / 16.0)) + + (rgb.g * (9.0 / 16.0)) + + (rgb.b * (2.0 / 16.0)) + ); +} + +/** + * Helper to convert RGB color to HCL. (Hue, Chroma, Luma) + */ +vec3 convertRgbToHcl(in vec3 rgb) { + float xMin = min(rgb.r, min(rgb.g, rgb.b)); + float xMax = max(rgb.r, max(rgb.g, rgb.b)); + float c = xMax - xMin; + float l = getColorLumosity(rgb); + float h = mod(( + c == 0 ? 0.0 : + xMax == rgb.r ? ((rgb.g - rgb.b) / c) : + xMax == rgb.g ? ((rgb.b - rgb.r) / c) + 2.0 : + xMax == rgb.b ? ((rgb.r - rgb.g) / c) + 4.0 : + 0.0 + ), 6.0); + return vec3(h, c, l); +} + +/** + * Helper to convert HCL color to RGB. (Hue, Chroma, Luma) + */ +vec3 convertHclToRgb(in vec3 hcl) { + vec3 rgb; + float h = mod(hcl.x, 6.0); + float c = hcl.y; + float l = hcl.z; + float x = c * (1.0 - abs(mod(h, 2.0) - 1.0)); + if(h <= 1.0) { + rgb = vec3(c, x, 0.0); + } + else if(h <= 2.0) { + rgb = vec3(x, c, 0.0); + } + else if(h <= 3.0) { + rgb = vec3(0.0, c, x); + } + else if(h <= 4.0) { + rgb = vec3(0.0, x, c); + } + else if(h <= 5.0) { + rgb = vec3(x, 0.0, c); + } + else { + rgb = vec3(c, 0.0, x); + } + float lRgb = getColorLumosity(rgb); + float m = l - lRgb; + return clamp(vec3(m, m, m) + rgb, 0.0, 1.0); +} + +/** + * Helper to check if a point is contained within + * a rectangular area. + */ +bool getPointInRect( + vec2 point, + vec2 rectTopLeft, + vec2 rectBottomRight +) { + return ( + point.x >= rectTopLeft.x && + point.y >= rectTopLeft.y && + point.x <= rectBottomRight.x && + point.y <= rectBottomRight.y + ); +} + +/** + * Helper to get the nearest offset vector from a + * point to a line segment. + * (The length of this offset vector is the nearest + * distance from the point to the line segment.) + * Thank you to https://stackoverflow.com/a/1501725 + */ +vec2 getPointLineDistance( + vec2 point, + vec2 line0, + vec2 line1 +) { + vec2 lineDelta = line0 - line1; + float lineLengthSq = dot(lineDelta, lineDelta); + if(lineLengthSq <= 0) { + return line0 - point; + } + float t = ( + dot(point - line0, line1 - line0) / lineLengthSq + ); + vec2 projection = ( + line0 + clamp(t, 0.0, 1.0) * (line1 - line0) + ); + return projection - point; +} + +/** + * Helper to get the nearest offset vector from a + * point to a rectangle. + * Returns (0, 0) for points within the rectangle. + */ +vec2 getPointRectDistance( + vec2 point, + vec2 rectTopLeft, + vec2 rectBottomRight +) { + if(getPointInRect(point, rectTopLeft, rectBottomRight)) { + return vec2(0.0, 0.0); + } + vec2 rectTopRight = vec2(rectBottomRight.x, rectTopLeft.y); + vec2 rectBottomLeft = vec2(rectTopLeft.x, rectBottomRight.y); + vec2 v0 = getPointLineDistance(point, rectTopLeft, rectTopRight); + vec2 v1 = getPointLineDistance(point, rectBottomLeft, rectBottomRight); + vec2 v2 = getPointLineDistance(point, rectTopLeft, rectBottomLeft); + vec2 v3 = getPointLineDistance(point, rectTopRight, rectBottomRight); + float v0LengthSq = dot(v0, v0); + float v1LengthSq = dot(v1, v1); + float v2LengthSq = dot(v2, v2); + float v3LengthSq = dot(v3, v3); + float minLengthSq = min( + min(v0LengthSq, v1LengthSq), + min(v2LengthSq, v3LengthSq) + ); + if(minLengthSq == v0LengthSq) { + return v0; + } + else if(minLengthSq == v1LengthSq) { + return v1; + } + else if(minLengthSq == v2LengthSq) { + return v2; + } + else { + return v3; + } +} + +/** + * Helper to get the nearest offset vector from a + * point to a subpixel. + * GBC subpixels are roughly rectangular in shape, + * but have a rectangular gap in their bottom-left + * corner. + * Returns (0, 0) for points within the subpixel. + */ +vec2 getPointSubpixelDistance( + vec2 point, + vec2 subpixelCenter, + vec2 subpixelSizeHalf +) { + float rectLeft = subpixelCenter.x - subpixelSizeHalf.x; + float rectRight = subpixelCenter.x + subpixelSizeHalf.x; + float rectTop = subpixelCenter.y - subpixelSizeHalf.y; + float rectBottom = subpixelCenter.y + subpixelSizeHalf.y; + vec2 offsetLeft = getPointRectDistance( + point, + vec2(rectLeft, rectTop + SubpixelTabHeight), + vec2(subpixelCenter.x, rectBottom) + ); + vec2 offsetRight = getPointRectDistance( + point, + vec2(subpixelCenter.x, rectTop), + vec2(rectRight, rectBottom) + ); + float offsetLeftLengthSq = dot(offsetLeft, offsetLeft); + float offsetRightLengthSq = dot(offsetRight, offsetRight); + if(offsetLeftLengthSq <= offsetRightLengthSq) { + return offsetLeft; + } + else { + return offsetRight; + } +} + +/** + * Helper to get the intensity of light from a + * subpixel. + * The pixelPosition argument represents a + * fragment's position within a pixel. + * Spread represents the subpixel's horizontal + * position within the pixel. + */ +float getSubpixelIntensity( + vec2 pixelPosition, + float spread +) { + vec2 subpixelCenter = vec2( + 0.5 + (spread * SubpixelSpread), + 1.0 - SubpixelVerticalOffset + ); + vec2 subpixelSizeHalf = 0.5 * vec2( + SubpixelLightWidth, + SubpixelLightHeight + ); + vec2 offset = getPointSubpixelDistance( + pixelPosition, + subpixelCenter, + subpixelSizeHalf + ); + if(SubpixelLightGlow <= 0) { + return dot(offset, offset) <= 0.0 ? 1.0 : 0.0; + } + else { + float dist = length(offset); + float glow = max(0.0, + 1.0 - (dist / SubpixelLightGlow) + ); + return glow; + } +} + +/** + * Helper to apply SubpixelColorBleed to the intensity + * value computed for a fragment and subpixel. + * Subpixel color bleed allows subpixel colors to be + * more strongly coerced to more accurately represent + * the underlying pixel color. + */ +float applySubpixelBleed( + float subpixelIntensity, + float colorSourceChannel +) { + return subpixelIntensity * ( + SubpixelColorBleed + + ((1.0 - SubpixelColorBleed) * colorSourceChannel) + ); +} + +void main() { + // Get base color of the pixel, adjust based on + // contrast and luminosity settings. + vec3 colorSource = texture2D(tex, texCoord).rgb; + vec3 colorSourceHcl = convertRgbToHcl(colorSource); + vec3 colorSourceAdjusted = convertHclToRgb(vec3( + colorSourceHcl.x, + colorSourceHcl.y * SourceContrast, + colorSourceHcl.z * SourceLuminosity + )); + // Determine how much each subpixel's light should + // affect this fragment. + vec2 pixelPosition = ( + mod(texCoord * texSize * SubpixelScale, 1.0) + ); + float subpixelIntensityRed = applySubpixelBleed( + getSubpixelIntensity(pixelPosition, -1.0), + colorSourceAdjusted.r + ); + float subpixelIntensityGreen = applySubpixelBleed( + getSubpixelIntensity(pixelPosition, +0.0), + colorSourceAdjusted.g + ); + float subpixelIntensityBlue = applySubpixelBleed( + getSubpixelIntensity(pixelPosition, +1.0), + colorSourceAdjusted.b + ); + vec3 subpixelLightColor = SubpixelGamma * ( + (subpixelIntensityRed * SubpixelColorRed) + + (subpixelIntensityGreen * SubpixelColorGreen) + + (subpixelIntensityBlue * SubpixelColorBlue) + ); + // Compute final color + vec3 colorResult = clamp( + subpixelLightColor * colorSourceAdjusted, 0.0, 1.0 + ); + vec3 colorResultBlended = ( + ((1.0 - SubpixelBlendAmount) * colorSourceAdjusted) + + (SubpixelBlendAmount * colorResult) + ); + colorResultBlended = BaseColor + ( + (colorResultBlended * (vec3(1.0, 1.0, 1.0) - BaseColor)) + ); + gl_FragColor = vec4( + colorResultBlended, + 1.0 + ); +} diff --git a/res/shaders/gbc-lcd.shader/license.txt b/res/shaders/gbc-lcd.shader/license.txt new file mode 100644 index 000000000..68a49daad --- /dev/null +++ b/res/shaders/gbc-lcd.shader/license.txt @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/res/shaders/gbc-lcd.shader/manifest.ini b/res/shaders/gbc-lcd.shader/manifest.ini new file mode 100644 index 000000000..3af7e9e2f --- /dev/null +++ b/res/shaders/gbc-lcd.shader/manifest.ini @@ -0,0 +1,129 @@ +[shader] +name=gbc-lcd +author=Sophie Kirschner +description=Imitates the GameBoy Color LCD screen subpixel arrangement, with an optional backlight effect. +passes=2 + +[pass.0] +integerScaling=1 +fragmentShader=gbc-lcd.fs +blend=1 + +[pass.1] +fragmentShader=gbc-lcd-light.fs + +[pass.0.uniform.BaseColor] +type=float3 +default[0]=0.130 +default[1]=0.128 +default[2]=0.101 +readableName=Screen base color + +[pass.0.uniform.SubpixelColorRed] +type=float3 +default[0]=1.00 +default[1]=0.38 +default[2]=0.22 +readableName=Red subpixel color + +[pass.0.uniform.SubpixelColorGreen] +type=float3 +default[0]=0.60 +default[1]=0.88 +default[2]=0.30 +readableName=Green subpixel color + +[pass.0.uniform.SubpixelColorBlue] +type=float3 +default[0]=0.23 +default[1]=0.65 +default[2]=1.00 +readableName=Blue subpixel color + +[pass.0.uniform.SourceContrast] +type=float +default=0.85 +readableName=Screen contrast + +[pass.0.uniform.SourceLuminosity] +type=float +default=0.88 +readableName=Screen luminosity + +[pass.0.uniform.SubpixelBlendAmount] +type=float +default=1.0 +readableName=Subpixel effect amount + +[pass.0.uniform.SubpixelColorBleed] +type=float +default=0.31 +readableName=Subpixel color bleeding + +[pass.0.uniform.SubpixelSpread] +type=float +default=0.333 +readableName=Subpixel spread X + +[pass.0.uniform.SubpixelVerticalOffset] +type=float +default=0.48 +readableName=Subpixel offset Y + +[pass.0.uniform.SubpixelGamma] +type=float +default=1.040 +readableName=Subpixel brightness + +[pass.0.uniform.SubpixelLightWidth] +type=float +default=0.220 +readableName=Subpixel width + +[pass.0.uniform.SubpixelLightHeight] +type=float +default=0.850 +readableName=Subpixel height + +[pass.0.uniform.SubpixelLightGlow] +type=float +default=0.195 +readableName=Subpixel glow size + +[pass.0.uniform.SubpixelTabHeight] +type=float +default=0.175 +readableName=Subpixel tab shaping + +[pass.0.uniform.SubpixelScale] +type=float +default=1.0 +readableName=Subpixel scale + +[pass.1.uniform.LightColor] +type=float3 +default[0]=1.000 +default[1]=0.968 +default[2]=0.882 +readableName=Backlight color + +[pass.1.uniform.LightIntensity] +type=float +default=0.06 +readableName=Backlight intensity + +[pass.1.uniform.LightSoftness] +type=float +default=0.67 +readableName=Backlight softness + +[pass.1.uniform.ReflectionDistance] +type=float2 +default[0]=0 +default[1]=0.025 +readableName=Internal reflection distance + +[pass.1.uniform.ReflectionBrightness] +type=float +default=0.032 +readableName=Internal reflection brightness From 2e3ad7ed161097d95fec17b86694977c040aaaf9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Dec 2023 19:58:12 -0800 Subject: [PATCH 034/336] CMake: Clean up with PROJECT_SOURCE_DIR --- src/platform/3ds/CMakeLists.txt | 10 ++++----- src/platform/psp2/CMakeLists.txt | 2 +- src/platform/qt/CMakeLists.txt | 34 +++++++++++++++--------------- src/platform/sdl/CMakeLists.txt | 26 +++++++++++------------ src/platform/switch/CMakeLists.txt | 6 +++--- src/platform/test/CMakeLists.txt | 4 ++-- src/platform/wii/CMakeLists.txt | 10 ++++----- 7 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index 893af0317..54787189f 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -27,7 +27,7 @@ source_group("3DS-specific code" FILES ${OS_SRC}) if(USE_VFS_3DS) list(APPEND OS_DEFINES USE_VFS_3DS) else() - list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) + list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) endif() set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) @@ -54,8 +54,8 @@ set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DE target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${OS_LIB}) add_custom_command(OUTPUT ${BINARY_NAME}.smdh - COMMAND ${BANNERTOOL} makesmdh -s "${PROJECT_NAME}" -l "${SUMMARY}" -p "endrift" -i ${CMAKE_SOURCE_DIR}/res/mgba-48.png -o ${BINARY_NAME}.smdh - DEPENDS ${CMAKE_SOURCE_DIR}/res/mgba-48.png) + COMMAND ${BANNERTOOL} makesmdh -s "${PROJECT_NAME}" -l "${SUMMARY}" -p "endrift" -i ${PROJECT_SOURCE_DIR}/res/mgba-48.png -o ${BINARY_NAME}.smdh + DEPENDS ${PROJECT_SOURCE_DIR}/res/mgba-48.png) add_custom_command(OUTPUT ${BINARY_NAME}.xml COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/hbl.xml ${BINARY_NAME}.xml @@ -67,8 +67,8 @@ add_custom_command(OUTPUT ${BINARY_NAME}.bnr # tex3ds binaries as of 2.0.1-3 crash if you try to do this #add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.t3x -# COMMAND ${TEX3DS} -f rgb5551 -o icons.t3x ${CMAKE_SOURCE_DIR}/res/icons.png -# MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/res/icons.png +# COMMAND ${TEX3DS} -f rgb5551 -o icons.t3x ${PROJECT_SOURCE_DIR}/res/icons.png +# MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/res/icons.png # WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.c diff --git a/src/platform/psp2/CMakeLists.txt b/src/platform/psp2/CMakeLists.txt index 3e638aa64..c42f5355b 100644 --- a/src/platform/psp2/CMakeLists.txt +++ b/src/platform/psp2/CMakeLists.txt @@ -47,7 +47,7 @@ target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${OS_LIB}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.o COMMAND ${OBJCOPY_CMD} icons2x.png ${CMAKE_CURRENT_BINARY_DIR}/icons.o - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/res) + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/res) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/backdrop.o COMMAND ${OBJCOPY_CMD} backdrop.png ${CMAKE_CURRENT_BINARY_DIR}/backdrop.o diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 6cac77e4f..610fa362d 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -12,8 +12,8 @@ if(BUILD_SDL) link_directories(${SDL2_LIBDIR}) endif() list(APPEND PLATFORM_LIBRARY ${SDL_LIBRARY}) - list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-events.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-audio.c) - include_directories(${SDL_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/src/platform/sdl) + list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${PROJECT_SOURCE_DIR}/src/platform/sdl/sdl-events.c ${PROJECT_SOURCE_DIR}/src/platform/sdl/sdl-audio.c) + include_directories(${SDL_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/src/platform/sdl) endif() if(POLICY CMP0071) @@ -309,7 +309,7 @@ if(APPLE) set(MACOSX_BUNDLE_BUNDLE_VERSION ${LIB_VERSION_STRING}) set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) set(MACOSX_BUNDLE_GUI_IDENTIFIER com.endrift.${BINARY_NAME}-qt) - set_source_files_properties(${CMAKE_SOURCE_DIR}/res/mgba.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + set_source_files_properties(${PROJECT_SOURCE_DIR}/res/mgba.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) if(DISTBUILD) set(APPDIR ".") else() @@ -317,9 +317,9 @@ if(APPLE) endif() endif() if(WIN32) - configure_file(${CMAKE_SOURCE_DIR}/res/mgba.rc.in ${CMAKE_BINARY_DIR}/res/mgba.rc) + configure_file(${PROJECT_SOURCE_DIR}/res/mgba.rc.in ${CMAKE_BINARY_DIR}/res/mgba.rc) list(APPEND RESOURCES ${CMAKE_BINARY_DIR}/res/mgba.rc) - set_source_files_properties(${CMAKE_BINARY_DIR}/res/mgba.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/res/mgba.ico) + set_source_files_properties(${CMAKE_BINARY_DIR}/res/mgba.rc PROPERTIES OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/res/mgba.ico) endif() if(NOT DEFINED DATADIR) if(APPLE) @@ -332,9 +332,9 @@ if(NOT DEFINED DATADIR) endif() if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY) if(NOT USE_LIBZIP AND NOT USE_MINIZIP) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/res/shaders DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) + install(DIRECTORY ${PROJECT_SOURCE_DIR}/res/shaders DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) else() - file(GLOB SHADERS ${CMAKE_SOURCE_DIR}/res/shaders/*.shader) + file(GLOB SHADERS ${PROJECT_SOURCE_DIR}/res/shaders/*.shader) message(STATUS ${SHADERS}) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shaders) foreach(SHADER_DIR ${SHADERS}) @@ -346,9 +346,9 @@ if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY) endif() endif() if(ENABLE_SCRIPTING AND USE_LUA) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/res/scripts DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) + install(DIRECTORY ${PROJECT_SOURCE_DIR}/res/scripts DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) endif() -install(FILES ${CMAKE_SOURCE_DIR}/res/nointro.dat DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) +install(FILES ${PROJECT_SOURCE_DIR}/res/nointro.dat DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) if(NOT WIN32 AND NOT APPLE) if(DATADIR MATCHES "^\\.[.\\]") list(APPEND QT_DEFINES DATADIR="${DATADIR}") @@ -414,8 +414,8 @@ else() qt5_wrap_ui(UI_SRC ${UI_FILES}) endif() -add_executable(${BINARY_NAME}-qt WIN32 MACOSX_BUNDLE main.cpp ${CMAKE_SOURCE_DIR}/res/mgba.icns ${SOURCE_FILES} ${PLATFORM_SRC} ${UI_SRC} ${AUDIO_SRC} ${RESOURCES}) -set_target_properties(${BINARY_NAME}-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/res/info.plist.in COMPILE_DEFINITIONS "${FEATURE_DEFINES};${FUNCTION_DEFINES};${OS_DEFINES};${QT_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") +add_executable(${BINARY_NAME}-qt WIN32 MACOSX_BUNDLE main.cpp ${PROJECT_SOURCE_DIR}/res/mgba.icns ${SOURCE_FILES} ${PLATFORM_SRC} ${UI_SRC} ${AUDIO_SRC} ${RESOURCES}) +set_target_properties(${BINARY_NAME}-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/res/info.plist.in COMPILE_DEFINITIONS "${FEATURE_DEFINES};${FUNCTION_DEFINES};${OS_DEFINES};${QT_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") if(WIN32) set_target_properties(${BINARY_NAME}-qt PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") @@ -458,10 +458,10 @@ target_link_libraries(${BINARY_NAME}-qt ${PLATFORM_LIBRARY} ${BINARY_NAME} ${QT_ set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE) if(UNIX AND NOT APPLE) - install(FILES ${CMAKE_SOURCE_DIR}/res/mgba-qt.desktop DESTINATION share/applications RENAME io.mgba.${PROJECT_NAME}.desktop COMPONENT ${BINARY_NAME}-qt) + install(FILES ${PROJECT_SOURCE_DIR}/res/mgba-qt.desktop DESTINATION share/applications RENAME io.mgba.${PROJECT_NAME}.desktop COMPONENT ${BINARY_NAME}-qt) endif() if(UNIX AND NOT (APPLE AND DISTBUILD)) - install(FILES ${CMAKE_SOURCE_DIR}/doc/mgba-qt.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-qt) + install(FILES ${PROJECT_SOURCE_DIR}/doc/mgba-qt.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-qt) endif() if(APPLE OR WIN32) set_target_properties(${BINARY_NAME}-qt PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) @@ -483,7 +483,7 @@ if(APPLE) fixup_bundle(\"${BUNDLE_PATH}\" \"${PLUGINS}\" \"\") " COMPONENT ${BINARY_NAME}-qt) if(CODESIGN_IDENTITY) - install(CODE "execute_process(COMMAND codesign -s \"${CODESIGN_IDENTITY}\" -vf -o runtime --timestamp --entitlements \"${CMAKE_SOURCE_DIR}/res/entitlements.plist\" \"${BUNDLE_PATH}\")" + install(CODE "execute_process(COMMAND codesign -s \"${CODESIGN_IDENTITY}\" -vf -o runtime --timestamp --entitlements \"${PROJECT_SOURCE_DIR}/res/entitlements.plist\" \"${BUNDLE_PATH}\")" COMPONENT ${BINARY_NAME}-qt) endif() else() @@ -498,9 +498,9 @@ if(APPLE) set(DEPLOY_OPTIONS ${DEPLOY_OPTIONS} -R "${CROSS_ROOT}") endif() if($ENV{CODESIGN_IDENTITY}) - set(DEPLOY_OPTIONS ${DEPLOY_OPTIONS} -s "$ENV{CODESIGN_IDENTITY}" -E "${CMAKE_SOURCE_DIR}/res/entitlements.xml") + set(DEPLOY_OPTIONS ${DEPLOY_OPTIONS} -s "$ENV{CODESIGN_IDENTITY}" -E "${PROJECT_SOURCE_DIR}/res/entitlements.xml") endif() - install(CODE "execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/tools/deploy-mac.py\" -v ${DEPLOY_OPTIONS} \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${APPDIR}/${PROJECT_NAME}.app\")") + install(CODE "execute_process(COMMAND \"${PROJECT_SOURCE_DIR}/tools/deploy-mac.py\" -v ${DEPLOY_OPTIONS} \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${APPDIR}/${PROJECT_NAME}.app\")") endif() elseif(WIN32) if(CMAKE_MAJOR_VERSION EQUAL 3 AND CMAKE_MINOR_VERSION EQUAL 8) @@ -509,7 +509,7 @@ elseif(WIN32) endif() if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") find_program(BASH bash) - install(CODE "execute_process(COMMAND \"${BASH}\" \"${CMAKE_SOURCE_DIR}/tools/deploy-win.sh\" \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.exe\" \"\${CMAKE_INSTALL_PREFIX}\" \"\$ENV{PWD}\" WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")" COMPONENT ${BINARY_NAME}-qt) + install(CODE "execute_process(COMMAND \"${BASH}\" \"${PROJECT_SOURCE_DIR}/tools/deploy-win.sh\" \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.exe\" \"\${CMAKE_INSTALL_PREFIX}\" \"\$ENV{PWD}\" WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")" COMPONENT ${BINARY_NAME}-qt) endif() if(DISTBUILD) file(WRITE "${CMAKE_BINARY_DIR}/portable.ini" "") diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 987bd160f..ca1919da9 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -70,20 +70,20 @@ endif() set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libsdl${SDL_VERSION_DEBIAN}" PARENT_SCOPE) -file(GLOB PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-*.c) +file(GLOB PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sdl-*.c) set(PLATFORM_LIBRARY ${SDL_LIBRARY} ${SDLMAIN_LIBRARY} ${SDL_LIBRARY} ${PIXMAN-1_LIBRARIES}) -include_directories(${CMAKE_SOURCE_DIR}/src/platform/sdl ${PIXMAN-1_INCLUDE_DIRS} ${SDL_INCLUDE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${PIXMAN-1_INCLUDE_DIRS} ${SDL_INCLUDE_DIR}) set(SDL_INCLUDE_DIR "${SDL_INCLUDE_DIR}" PARENT_SCOPE) set(SDL_LIBRARY "${SDL_LIBRARY}" PARENT_SCOPE) set(SDLMAIN_LIBRARY "${SDLMAIN_LIBRARY}" PARENT_SCOPE) -set(MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/main.c) +set(MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/main.c) if(BUILD_RASPI) add_definitions(-DBUILD_RASPI) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/rpi-common.c) - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gles2-sdl.c) + list(APPEND PLATFORM_SRC ${PROJECT_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c ${CMAKE_CURRENT_SOURCE_DIR}/rpi-common.c) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) set(OPENGLES2_LIBRARY "-lEGL -lGLESv2 -lbcm_host") set(BUILD_GLES2 ON CACHE BOOL "Using OpenGL|ES 2" FORCE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fgnu89-inline") @@ -95,21 +95,21 @@ if(BUILD_RASPI) endif() if(BUILD_PANDORA) - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/pandora-sdl.c) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pandora-sdl.c) else() if(BUILD_GL) - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) endif() if(BUILD_GLES2) - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gles2-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) include_directories(${OPENGLES2_INCLUDE_DIR}) endif() if(SDL_VERSION EQUAL "2") - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl2.c) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl2.c) else() - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl1.c) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl1.c) endif() endif() @@ -129,7 +129,7 @@ else() endif() install(TARGETS ${BINARY_NAME}-sdl DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-sdl) if(UNIX) - install(FILES ${CMAKE_SOURCE_DIR}/doc/mgba.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-sdl) + install(FILES ${PROJECT_SOURCE_DIR}/doc/mgba.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-sdl) endif() if(DISTBUILD AND CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index a12473b4c..716b33449 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -5,7 +5,7 @@ find_library(GLAPI_LIBRARY glapi REQUIRED) find_library(EGL_LIBRARY EGL REQUIRED) set(OS_DEFINES _GNU_SOURCE IOAPI_NO_64) -list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) +list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) include_directories(AFTER ${OPENGLES3_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIR}) @@ -39,11 +39,11 @@ add_custom_command(OUTPUT control.nacp add_custom_command(OUTPUT romfs.bin COMMAND ${CMAKE_COMMAND} -E make_directory romfs - COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/res/font-new.png" romfs/ + COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/res/font-new.png" romfs/ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/fileassoc.cfg.in" romfs/ COMMAND ${BUILD_ROMFS} romfs romfs.bin COMMAND ${CMAKE_COMMAND} -E remove_directory romfs - DEPENDS "${CMAKE_SOURCE_DIR}/res/font-new.png" "${CMAKE_CURRENT_SOURCE_DIR}/fileassoc.cfg.in") + DEPENDS "${PROJECT_SOURCE_DIR}/res/font-new.png" "${CMAKE_CURRENT_SOURCE_DIR}/fileassoc.cfg.in") add_custom_target(${BINARY_NAME}.nro ALL ${ELF2NRO} ${BINARY_NAME}.elf ${BINARY_NAME}.nro --romfs=romfs.bin --nacp=control.nacp --icon="${CMAKE_CURRENT_SOURCE_DIR}/icon.jpg" diff --git a/src/platform/test/CMakeLists.txt b/src/platform/test/CMakeLists.txt index 5e20cb41e..3172c6c88 100644 --- a/src/platform/test/CMakeLists.txt +++ b/src/platform/test/CMakeLists.txt @@ -8,7 +8,7 @@ if(BUILD_PERF) target_link_libraries(${BINARY_NAME}-perf ${BINARY_NAME} ${PERF_LIB} ${OS_LIB}) set_target_properties(${BINARY_NAME}-perf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") install(TARGETS ${BINARY_NAME}-perf DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-perf) - install(FILES "${CMAKE_SOURCE_DIR}/tools/perf.py" DESTINATION "${LIBDIR}/${BINARY_NAME}" COMPONENT ${BINARY_NAME}-perf) + install(FILES "${PROJECT_SOURCE_DIR}/tools/perf.py" DESTINATION "${LIBDIR}/${BINARY_NAME}" COMPONENT ${BINARY_NAME}-perf) endif() if(BUILD_TEST) @@ -27,7 +27,7 @@ if(BUILD_SUITE) link_directories(${CMOCKA_LIBRARY_DIRS}) foreach(TEST IN LISTS TEST_SRC) - string(REPLACE "${CMAKE_SOURCE_DIR}/src/" "" TEST_NAME "${TEST}") + string(REPLACE "${PROJECT_SOURCE_DIR}/src/" "" TEST_NAME "${TEST}") string(REPLACE "/" "-" TEST_NAME "${TEST_NAME}") string(REPLACE "-test" "" TEST_NAME "${TEST_NAME}") string(REPLACE ".c" "" TEST_NAME "${TEST_NAME}") diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index 3fead14c8..569408523 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -9,7 +9,7 @@ if(WIIDRC_LIBRARY) endif() set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64 FIXED_ROM_BUFFER) -list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) +list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) include_directories(${CMAKE_CURRENT_BINARY_DIR}) @@ -30,8 +30,8 @@ if(WIIDRC_LIBRARY) endif() add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.tpl - COMMAND ${GXTEXCONV} -i ${CMAKE_SOURCE_DIR}/res/font2x.png -o font.tpl colfmt=5 mipmap=no - MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/res/font2x.png + COMMAND ${GXTEXCONV} -i ${PROJECT_SOURCE_DIR}/res/font2x.png -o font.tpl colfmt=5 mipmap=no + MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/res/font2x.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.c @@ -40,8 +40,8 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.c WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.tpl - COMMAND ${GXTEXCONV} -i ${CMAKE_SOURCE_DIR}/res/icons2x.png -o icons.tpl colfmt=5 mipmap=no - MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/res/icons2x.png + COMMAND ${GXTEXCONV} -i ${PROJECT_SOURCE_DIR}/res/icons2x.png -o icons.tpl colfmt=5 mipmap=no + MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/res/icons2x.png WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.c From e01fc0f2b7dcfc36c3a7cdbeabdf8c5935ecc0d3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Dec 2023 20:43:22 -0800 Subject: [PATCH 035/336] 3DS: Remove fancy memory mapping --- src/platform/3ds/3ds-memory.c | 17 ----------------- src/platform/3ds/CMakeLists.txt | 8 ++++++-- src/platform/3ds/ctru-heap.c | 3 --- 3 files changed, 6 insertions(+), 22 deletions(-) delete mode 100644 src/platform/3ds/3ds-memory.c diff --git a/src/platform/3ds/3ds-memory.c b/src/platform/3ds/3ds-memory.c deleted file mode 100644 index c37e4637b..000000000 --- a/src/platform/3ds/3ds-memory.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 2013-2014 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include - -#include <3ds.h> - -void* anonymousMemoryMap(size_t size) { - return linearAlloc(size); -} - -void mappedMemoryFree(void* memory, size_t size) { - UNUSED(size); - linearFree(memory); -} diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index 54787189f..ef70eed51 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -19,8 +19,12 @@ if(${CMAKE_BUILD_TYPE} STREQUAL Debug OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDeb else() list(APPEND OS_LIB citro3d ctru) endif() -file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/3ds-*.c ${CMAKE_CURRENT_SOURCE_DIR}/ctru-heap.c ${CMAKE_CURRENT_SOURCE_DIR}/socket.c) -set(OS_SRC ${OS_SRC} PARENT_SCOPE) +set(OS_SRC + ${PROJECT_SOURCE_DIR}/src/util/memory.c + ${CMAKE_CURRENT_SOURCE_DIR}/3ds-vfs.c + ${CMAKE_CURRENT_SOURCE_DIR}/ctru-heap.c + ${CMAKE_CURRENT_SOURCE_DIR}/socket.c + PARENT_SCOPE) set(OS_LIB ${OS_LIB} PARENT_SCOPE) source_group("3DS-specific code" FILES ${OS_SRC}) diff --git a/src/platform/3ds/ctru-heap.c b/src/platform/3ds/ctru-heap.c index 25e606c1d..ea2f4d450 100644 --- a/src/platform/3ds/ctru-heap.c +++ b/src/platform/3ds/ctru-heap.c @@ -7,9 +7,6 @@ #include -u32 __ctru_heap_size = 0x02400000; -u32 __ctru_linear_heap_size = 0x01400000; - uint32_t* romBuffer = NULL; size_t romBufferSize; From feb7b5a116f777b5b0018c81d20643a184df327d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Dec 2023 20:43:39 -0800 Subject: [PATCH 036/336] Config: Fix warning --- src/core/config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/config.c b/src/core/config.c index 78a527332..d0cd4603c 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -290,6 +290,7 @@ void mCoreConfigPortablePath(char* out, size_t outLength) { WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0); StringCchCatA(out, outLength, PATH_SEP "portable.ini"); #elif defined(PSP2) || defined(GEKKO) || defined(__SWITCH__) || defined(__3DS__) + UNUSED(outLength); out[0] = '\0'; #else getcwd(out, outLength); From 16c777cdd956b89d1bf887ea0889545a13d8350d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jan 2024 16:57:15 -0800 Subject: [PATCH 037/336] Qt: Fix screen freezing on macOS after closing save state window (fixes #2885) --- CHANGES | 1 + src/platform/qt/Window.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index 65174a532..e6567d3e9 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Other fixes: - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Re-enable sync for multiplayer windows that aren't connected (fixes mgba.io/i/2974) - Qt: Fix mute settings not being loaded on setting screen (fixes mgba.io/i/2990) + - Qt: Fix screen freezing on macOS after closing save state window (fixes mgba.io/i/2885) - Vita: Fix camera setting not appearing (fixes mgba.io/i/3012) Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 746f44aff..800453489 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1931,8 +1931,15 @@ void Window::setupOptions() { } void Window::attachWidget(QWidget* widget) { + // Fix https://mgba.io/i/2885 -- seems like a Qt bug + if (m_display && widget != m_display.get()) { + m_display->hide(); + } takeCentralWidget(); setCentralWidget(widget); + if (m_display && widget == m_display.get()) { + m_display->show(); + } } void Window::detachWidget() { From 70689e111247addb89384aec84fc5dccba9861fa Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jan 2024 19:13:02 -0800 Subject: [PATCH 038/336] Res: Update nointro.dat --- res/nointro.dat | 4686 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 3531 insertions(+), 1155 deletions(-) diff --git a/res/nointro.dat b/res/nointro.dat index cb73775b6..d63e3f818 100644 --- a/res/nointro.dat +++ b/res/nointro.dat @@ -1,8 +1,8 @@ clrmamepro ( name "Nintendo - Game Boy Advance" description "Nintendo - Game Boy Advance" - version 20230422-084331 - author "aci68, Arctic Circle System, Aringon, Bent, BigFred, bikerspade, C. V. Reynolds, chillerecke, DeadSkullzJr, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, Flashfire42, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, InternalLoss, Jack, jimmsu, kazumi213, Larsenv, Lesserkuma, Madeline, MeguCocoa, Money_114, NESBrew12, niemand, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, rarenight, relax, RetroGamer, Rifu, sCZther, SonGoku, Tauwasser, Tescu, togemet2, ufocrossing, Vallaine01, Whovian9369, xprism, xuom2, zg" + version 20240104-012251 + author "aci68, Arctic Circle System, Aringon, Bent, BigFred, bikerspade, C. V. Reynolds, chillerecke, DeadSkullzJr, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, FakeShemp, Flashfire42, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, Larsenv, Lesserkuma, Madeline, MeguCocoa, Money_114, NESBrew12, niemand, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Prominos, Psychofox11, psykopat, rarenight, relax, RetroGamer, Rifu, sCZther, SonGoku, Tauwasser, Tescu, togemet2, ufocrossing, Vallaine01, Whovian9369, xprism, xuom2, zg" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -19,9 +19,9 @@ game ( ) game ( - name "[BIOS] Game Boy Advance (Japan) (Debug Version)" - description "[BIOS] Game Boy Advance (Japan) (Debug Version)" - rom ( name "[BIOS] Game Boy Advance (Japan) (Debug Version).bin" size 16384 crc 15e1f676 sha1 aa98a2ad32b86106340665d1222d7d973a1361c7 ) + name "[BIOS] Game Boy Advance (World) (Beta)" + description "[BIOS] Game Boy Advance (World) (Beta)" + rom ( name "[BIOS] Game Boy Advance (World) (Beta).bin" size 16384 crc 15e1f676 sha1 aa98a2ad32b86106340665d1222d7d973a1361c7 ) ) game ( @@ -30,6 +30,12 @@ game ( rom ( name "[BIOS] Game Boy Advance (World).bin" size 16384 crc 81977335 sha1 300c20df6731a33952ded8c436f7f186d25d3492 flags verified ) ) +game ( + name "[BIOS] Game Boy Advance (GBC Mode) (World)" + description "[BIOS] Game Boy Advance (GBC Mode) (World)" + rom ( name "[BIOS] Game Boy Advance (GBC Mode) (World).gbc" size 2304 crc ffd6b0f1 sha1 fa5287e24b0fa533b3b5ef2b28a81245346c1a0f ) +) + game ( name "007 - Everything or Nothing (USA, Europe) (En,Fr,De)" description "007 - Everything or Nothing (USA, Europe) (En,Fr,De)" @@ -423,7 +429,7 @@ game ( game ( name "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It)" description "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc a50de233 sha1 df086e816109a18d0f037e8c0aa7a2ae40677c14 ) + rom ( name "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc a50de233 sha1 df086e816109a18d0f037e8c0aa7a2ae40677c14 flags verified ) ) game ( @@ -483,7 +489,7 @@ game ( game ( name "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl)" description "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl)" - rom ( name "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl).gba" size 16777216 crc a04cebfe sha1 0286e31772601f7c7420722e8fbf8a210d562a06 ) + rom ( name "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl).gba" size 16777216 crc a04cebfe sha1 0286e31772601f7c7420722e8fbf8a210d562a06 flags verified ) ) game ( @@ -561,7 +567,7 @@ game ( game ( name "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It)" description "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It)" - rom ( name "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5813810f sha1 f116cc8e6a7f6dba49564031a2ac63d837d4f11b ) + rom ( name "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5813810f sha1 f116cc8e6a7f6dba49564031a2ac63d837d4f11b flags verified ) ) game ( @@ -585,7 +591,7 @@ game ( game ( name "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It)" description "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It)" - rom ( name "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It).gba" size 33554432 crc d732e52d sha1 5bf33c1f0fd50f268ed5941d3246cfad1893ef89 ) + rom ( name "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It).gba" size 33554432 crc e76db6ef sha1 287071f81572a95cf3a3b35fab93862733864c3e ) ) game ( @@ -630,6 +636,12 @@ game ( rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (Europe).gba" size 16777216 crc 3535b2bf sha1 be51cfa607d461efd1dab640a5b4f5b037c060df ) ) +game ( + name "2004Mbit Competition (World) (Unl)" + description "2004Mbit Competition (World) (Unl)" + rom ( name "2004Mbit Competition (World) (Unl).gba" size 4194304 crc 107de6b7 sha1 0cf3dec1b8ff2372e4fbe339c0b338d590b39256 ) +) + game ( name "2006 FIFA World Cup - Germany 2006 (USA, Europe) (En,Fr,De,Es,It)" description "2006 FIFA World Cup - Germany 2006 (USA, Europe) (En,Fr,De,Es,It)" @@ -637,9 +649,9 @@ game ( ) game ( - name "2K Sports - Major League Baseball 2K7 (USA)" - description "2K Sports - Major League Baseball 2K7 (USA)" - rom ( name "2K Sports - Major League Baseball 2K7 (USA).gba" size 8388608 crc 8f3ff0e4 sha1 07390bc2bd53cd9ee5c6d2805ad374c59c195d9f ) + name "2048 Pool (World) (Aftermarket) (Unl)" + description "2048 Pool (World) (Aftermarket) (Unl)" + rom ( name "2048 Pool (World) (Aftermarket) (Unl).gba" size 203440 crc 9df6ae4f sha1 c93a9cf3502237b474e70de8dee274901ee7ecb2 ) ) game ( @@ -648,6 +660,12 @@ game ( rom ( name "2K Sports - Major League Baseball 2K7 (USA) (Beta).gba" size 8388608 crc ea51532d sha1 776e084ac31336114f23230bde4adfc1f231934b ) ) +game ( + name "2K Sports - Major League Baseball 2K7 (USA)" + description "2K Sports - Major League Baseball 2K7 (USA)" + rom ( name "2K Sports - Major League Baseball 2K7 (USA).gba" size 8388608 crc 8f3ff0e4 sha1 07390bc2bd53cd9ee5c6d2805ad374c59c195d9f ) +) + game ( name "3 Game Pack! - Candy Land + Chutes and Ladders + Original Memory Game (USA)" description "3 Game Pack! - Candy Land + Chutes and Ladders + Original Memory Game (USA)" @@ -741,7 +759,7 @@ game ( game ( name "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It)" description "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It)" - rom ( name "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It).gba" size 33554432 crc 04a40017 sha1 a99bbc7ec018af85260669917939004baabf4ac1 ) + rom ( name "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It).gba" size 33554432 crc 04a40017 sha1 a99bbc7ec018af85260669917939004baabf4ac1 flags verified ) ) game ( @@ -756,18 +774,18 @@ game ( rom ( name "Ab durch die Hecke (Germany).gba" size 8388608 crc 31e57a19 sha1 05fc0931ecbdfaed18ffd59df86fa36a7ed6da9d ) ) -game ( - name "Ace Combat Advance (Europe) (En,Fr,De,Es,It) (Beta)" - description "Ace Combat Advance (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Ace Combat Advance (Europe) (En,Fr,De,Es,It) (Beta).gba" size 4194304 crc 76da5c78 sha1 6e5c57049866596db0e977b80e499b868e0394c2 ) -) - game ( name "Ace Combat Advance (USA, Europe)" description "Ace Combat Advance (USA, Europe)" rom ( name "Ace Combat Advance (USA, Europe).gba" size 4194304 crc 43f5e157 sha1 856a08e8f60f817b96add5bf2f6db186bea832ef flags verified ) ) +game ( + name "Ace Combat Advance (Europe) (En,Fr,De,Es,It) (Beta)" + description "Ace Combat Advance (Europe) (En,Fr,De,Es,It) (Beta)" + rom ( name "Ace Combat Advance (Europe) (En,Fr,De,Es,It) (Beta).gba" size 4194304 crc 76da5c78 sha1 6e5c57049866596db0e977b80e499b868e0394c2 ) +) + game ( name "Ace Lightning (Europe)" description "Ace Lightning (Europe)" @@ -997,9 +1015,15 @@ game ( ) game ( - name "Aero the Acro-Bat - Rascal Rival Revenge (Europe)" - description "Aero the Acro-Bat - Rascal Rival Revenge (Europe)" - rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (Europe).gba" size 4194304 crc a7e98ebe sha1 11050975c211550a8bea751212ceb8856daea759 flags verified ) + name "Aero the Acro-Bat (Europe)" + description "Aero the Acro-Bat (Europe)" + rom ( name "Aero the Acro-Bat (Europe).gba" size 4194304 crc a7e98ebe sha1 11050975c211550a8bea751212ceb8856daea759 flags verified ) +) + +game ( + name "Aero the Acro-Bat (USA)" + description "Aero the Acro-Bat (USA)" + rom ( name "Aero the Acro-Bat (USA).gba" size 4194304 crc b47ac020 sha1 cdbc609df128127d05c435f59b781958c0e751fd ) ) game ( @@ -1008,12 +1032,6 @@ game ( rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (USA) (Beta 2) (2002-03-27).gba" size 4194304 crc 6f3ea564 sha1 3f88084c501fb15820f6ad9a9c87ac21af3b59eb ) ) -game ( - name "Aero the Acro-Bat - Rascal Rival Revenge (USA)" - description "Aero the Acro-Bat - Rascal Rival Revenge (USA)" - rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (USA).gba" size 4194304 crc b47ac020 sha1 cdbc609df128127d05c435f59b781958c0e751fd ) -) - game ( name "Agassi Tennis Generation (Europe) (En,Fr,De,Es,It)" description "Agassi Tennis Generation (Europe) (En,Fr,De,Es,It)" @@ -1029,7 +1047,7 @@ game ( game ( name "AGB Aging Cartridge (World) (v1.0) (Test Program)" description "AGB Aging Cartridge (World) (v1.0) (Test Program)" - rom ( name "AGB Aging Cartridge (World) (v1.0) (Test Program).gba" size 2097152 crc bf553530 sha1 2445bf11a5f905695b00011d77d18c99e754b633 ) + rom ( name "AGB Aging Cartridge (World) (v1.0) (Test Program).gba" size 4194304 crc d2e80e33 sha1 30b3ea4b0c2611a7d8aaf1cacbe8c3b79eb2ab78 ) ) game ( @@ -1057,9 +1075,9 @@ game ( ) game ( - name "AGS Aging Cartridge (World) (Rev 1, v7.0) (Test Program)" - description "AGS Aging Cartridge (World) (Rev 1, v7.0) (Test Program)" - rom ( name "AGS Aging Cartridge (World) (Rev 1, v7.0) (Test Program).gba" size 2097152 crc bbb6a960 sha1 c67e0a5e26ea5eba2bc11c99d003027a96e44060 flags verified ) + name "Agoria - Ode to Fate (World) (Aftermarket) (Unl)" + description "Agoria - Ode to Fate (World) (Aftermarket) (Unl)" + rom ( name "Agoria - Ode to Fate (World) (Aftermarket) (Unl).gba" size 2725504 crc 67d3361f sha1 cb0b83b85a290c223cd3249b37ae7207d3efde06 ) ) game ( @@ -1075,9 +1093,15 @@ game ( ) game ( - name "AGS Aging Cartridge (World) (Rev 3, v9.0) (Test Program)" - description "AGS Aging Cartridge (World) (Rev 3, v9.0) (Test Program)" - rom ( name "AGS Aging Cartridge (World) (Rev 3, v9.0) (Test Program).gba" size 2097152 crc 2e69686d sha1 03d3a486482b61128872519fd755d0c072c12d93 flags verified ) + name "AGS Aging Cartridge (World) (Rev 3) (v9.0) (Test Program)" + description "AGS Aging Cartridge (World) (Rev 3) (v9.0) (Test Program)" + rom ( name "AGS Aging Cartridge (World) (Rev 3) (v9.0) (Test Program).gba" size 4194304 crc 584bbdc7 sha1 4a21b60c23014750250e56a8a22b886032f0d33d ) +) + +game ( + name "AGS Aging Cartridge (World) (Rev 1) (v7.0) (Test Program)" + description "AGS Aging Cartridge (World) (Rev 1) (v7.0) (Test Program)" + rom ( name "AGS Aging Cartridge (World) (Rev 1) (v7.0) (Test Program).gba" size 4194304 crc e16e1360 sha1 5c73fb4074b19c5a1a9bb60fd359b528d2ed99a6 ) ) game ( @@ -1098,18 +1122,18 @@ game ( rom ( name "AirForce Delta Storm (USA) (En,Ja,Fr,De).gba" size 4194304 crc ebf757b8 sha1 7bc53480a43ada2aad32d798ab00b6e761726728 flags verified ) ) -game ( - name "Aka-chan Doubutsuen (Japan) (Rev 1)" - description "Aka-chan Doubutsuen (Japan) (Rev 1)" - rom ( name "Aka-chan Doubutsuen (Japan) (Rev 1).gba" size 4194304 crc c1072e26 sha1 634624c77c90a8ff40bec9046133c50041efc49b ) -) - game ( name "Aka-chan Doubutsuen (Japan)" description "Aka-chan Doubutsuen (Japan)" rom ( name "Aka-chan Doubutsuen (Japan).gba" size 4194304 crc b50cd166 sha1 9a0623a8680c4cf9b745f940b99da0a192764828 ) ) +game ( + name "Aka-chan Doubutsuen (Japan) (Rev 1)" + description "Aka-chan Doubutsuen (Japan) (Rev 1)" + rom ( name "Aka-chan Doubutsuen (Japan) (Rev 1).gba" size 4194304 crc c1072e26 sha1 634624c77c90a8ff40bec9046133c50041efc49b ) +) + game ( name "Akumajou Dracula - Circle of the Moon (Japan) (Virtual Console)" description "Akumajou Dracula - Circle of the Moon (Japan) (Virtual Console)" @@ -1297,9 +1321,9 @@ game ( ) game ( - name "Anguna - Warriors of Virtue (Unknown) (Retro-Bit Generations) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (Unknown) (Retro-Bit Generations) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (Unknown) (Retro-Bit Generations) (Aftermarket) (Unl).gba" size 1775660 crc a234813c sha1 ad904624bf198a164ba580eea326cd30fffebac8 ) + name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl).gba" size 1775660 crc a234813c sha1 ad904624bf198a164ba580eea326cd30fffebac8 ) ) game ( @@ -1404,18 +1428,18 @@ game ( rom ( name "Ant Bully, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 52dc386b sha1 a735364887c31a19fa7d250ec830d02220d6a6cd ) ) -game ( - name "Antz - Extreme Racing (USA)" - description "Antz - Extreme Racing (USA)" - rom ( name "Antz - Extreme Racing (USA).gba" size 4194304 crc f4efc5ed sha1 ad6ded0f643457d652292bb97e30b1ad442e41da ) -) - game ( name "Antz - Extreme Racing (Europe) (En,Fr,De,Es,It,Nl)" description "Antz - Extreme Racing (Europe) (En,Fr,De,Es,It,Nl)" rom ( name "Antz - Extreme Racing (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 367927ed sha1 68fca49cba74dc108f50ec762ab91b6dff5a92b8 ) ) +game ( + name "Antz - Extreme Racing (USA)" + description "Antz - Extreme Racing (USA)" + rom ( name "Antz - Extreme Racing (USA).gba" size 4194304 crc f4efc5ed sha1 ad6ded0f643457d652292bb97e30b1ad442e41da ) +) + game ( name "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan)" description "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan)" @@ -1521,7 +1545,7 @@ game ( game ( name "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It)" description "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 1e2e8937 sha1 9a4fc3533bbdb28fd5945bd1ee7d84d992eee12f ) + rom ( name "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 1e2e8937 sha1 9a4fc3533bbdb28fd5945bd1ee7d84d992eee12f flags verified ) ) game ( @@ -1929,7 +1953,7 @@ game ( game ( name "Barbie Software - Groovy Games (Europe) (En,Fr,De,Es,It)" description "Barbie Software - Groovy Games (Europe) (En,Fr,De,Es,It)" - rom ( name "Barbie Software - Groovy Games (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 749339b2 sha1 e41751c52d5cd84b204ac4d73eefc5b360f56f1d ) + rom ( name "Barbie Software - Groovy Games (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 749339b2 sha1 e41751c52d5cd84b204ac4d73eefc5b360f56f1d flags verified ) ) game ( @@ -2070,6 +2094,12 @@ game ( rom ( name "Battle Network - Rockman EXE 3 - Black (Japan) (Rev 1).gba" size 8388608 crc fd57493b sha1 e089a2254496a4791666c8122585cb785e3012fc ) ) +game ( + name "Battle Picross (World) (Unl)" + description "Battle Picross (World) (Unl)" + rom ( name "Battle Picross (World) (Unl).gba" size 194784 crc 7f36d6f0 sha1 7431f36c68bba7ad42301b395e1237445f059a9e ) +) + game ( name "Battle X Battle - Kyodai Gyo Densetsu (Japan)" description "Battle X Battle - Kyodai Gyo Densetsu (Japan)" @@ -2118,6 +2148,12 @@ game ( rom ( name "Bee Game, The (USA).gba" size 4194304 crc da747c99 sha1 3a073625e7d0f844b940d0d8a71216cdce335a47 ) ) +game ( + name "Bengt Swinger of Longarm (World) (Unl)" + description "Bengt Swinger of Longarm (World) (Unl)" + rom ( name "Bengt Swinger of Longarm (World) (Unl).gba" size 434844 crc e514de30 sha1 5ce8574548fe0ebd587eddf974f837b44a2d3c6c ) +) + game ( name "Berenstain Bears and the Spooky Old Tree, The (USA)" description "Berenstain Bears and the Spooky Old Tree, The (USA)" @@ -2226,12 +2262,6 @@ game ( rom ( name "Bionicle - Matoran Adventures (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc daec2264 sha1 a478f5880c484a70a5fdefc42f73aae2eb948168 flags verified ) ) -game ( - name "Bionicle - Maze of Shadows (Europe) (En,De)" - description "Bionicle - Maze of Shadows (Europe) (En,De)" - rom ( name "Bionicle - Maze of Shadows (Europe) (En,De).gba" size 8388608 crc bce2d68e sha1 7ff9811e2bd40b24da02be194213d41a0885aa34 ) -) - game ( name "Bionicle - Maze of Shadows (USA)" description "Bionicle - Maze of Shadows (USA)" @@ -2244,6 +2274,12 @@ game ( rom ( name "Bionicle - Maze of Shadows (Europe) (En,De) (Rev 1).gba" size 8388608 crc 9d66ec5e sha1 430c7dac6f7dd989294a8ac1cfdabd9e74b3e682 ) ) +game ( + name "Bionicle - Maze of Shadows (Europe) (En,De)" + description "Bionicle - Maze of Shadows (Europe) (En,De)" + rom ( name "Bionicle - Maze of Shadows (Europe) (En,De).gba" size 8388608 crc bce2d68e sha1 7ff9811e2bd40b24da02be194213d41a0885aa34 ) +) + game ( name "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" description "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" @@ -2575,9 +2611,9 @@ game ( ) game ( - name "Bounty Hunter X (Europe) (Unl)" - description "Bounty Hunter X (Europe) (Unl)" - rom ( name "Bounty Hunter X (Europe) (Unl).gba" size 304344 crc 91344285 sha1 6e39d034ccf318a17a8bd044dd58bc31f4ba2ab9 ) + name "Bounty Hunter X (World) (Unl)" + description "Bounty Hunter X (World) (Unl)" + rom ( name "Bounty Hunter X (World) (Unl).gba" size 304344 crc 91344285 sha1 6e39d034ccf318a17a8bd044dd58bc31f4ba2ab9 flags verified ) ) game ( @@ -2685,7 +2721,7 @@ game ( game ( name "Breath of Fire (USA)" description "Breath of Fire (USA)" - rom ( name "Breath of Fire (USA).gba" size 4194304 crc f06422a8 sha1 b30533f68037b47d5439bab0182169e4a643a38d ) + rom ( name "Breath of Fire (USA).gba" size 4194304 crc f06422a8 sha1 b30533f68037b47d5439bab0182169e4a643a38d flags verified ) ) game ( @@ -2745,7 +2781,7 @@ game ( game ( name "Broken Circle (Europe) (En,It) (Proto)" description "Broken Circle (Europe) (En,It) (Proto)" - rom ( name "Broken Circle (Europe) (En,It) (Proto).gba" size 8388608 crc 1e8f8ae0 sha1 fec9fda1c776ac9bb87a609d0be1effe7ea158b6 ) + rom ( name "Broken Circle (Europe) (En,It) (Proto).gba" size 8409344 crc e78bc690 sha1 d015a5039ff5d08eeba3ddb16470eaab259631d0 ) ) game ( @@ -2931,7 +2967,7 @@ game ( game ( name "Card e-Reader+ (Japan)" description "Card e-Reader+ (Japan)" - rom ( name "Card e-Reader+ (Japan).gba" size 8388608 crc 4139e7c3 sha1 2af41785dd72c664e8a1c0f1e1ce0edcd105dd5e ) + rom ( name "Card e-Reader+ (Japan).gba" size 8388608 crc 4139e7c3 sha1 2af41785dd72c664e8a1c0f1e1ce0edcd105dd5e flags verified ) ) game ( @@ -3210,6 +3246,12 @@ game ( rom ( name "Cat in the Hat, The (USA).gba" size 4194304 crc 13c2249e sha1 9340482db02bf5263429a15798d06c509017aa93 ) ) +game ( + name "Cat's Curse (World) (Aftermarket) (Unl)" + description "Cat's Curse (World) (Aftermarket) (Unl)" + rom ( name "Cat's Curse (World) (Aftermarket) (Unl).gba" size 353052 crc a35d87de sha1 4a149baad17840948c2d4ffdf068bfaf1116a024 ) +) + game ( name "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" @@ -3385,9 +3427,9 @@ game ( ) game ( - name "Chopper 2 The Return (Europe) (Unl)" - description "Chopper 2 The Return (Europe) (Unl)" - rom ( name "Chopper 2 The Return (Europe) (Unl).gba" size 861720 crc f33aac43 sha1 50c0eb0f3832a068bb9591d4dfaa8e1389bb87db ) + name "Chopper 2 - The Return (World) (Unl)" + description "Chopper 2 - The Return (World) (Unl)" + rom ( name "Chopper 2 - The Return (World) (Unl).gba" size 861720 crc f33aac43 sha1 50c0eb0f3832a068bb9591d4dfaa8e1389bb87db ) ) game ( @@ -3693,7 +3735,7 @@ game ( game ( name "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl)" description "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc d8382427 sha1 4e184f8f52e5a6b79a272f7674178d3d3ccc3386 ) + rom ( name "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc d8382427 sha1 4e184f8f52e5a6b79a272f7674178d3d3ccc3386 flags verified ) ) game ( @@ -3705,7 +3747,7 @@ game ( game ( name "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It)" description "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It)" - rom ( name "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 0510b70f sha1 bf33976d1a26e336416e0fd28b2b8da65450737d ) + rom ( name "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc c7269e6a sha1 ec25e705d5129a97b405b6b15197cbb9141e135f flags verified ) ) game ( @@ -4233,7 +4275,7 @@ game ( game ( name "DemiKids - Dark Version (USA)" description "DemiKids - Dark Version (USA)" - rom ( name "DemiKids - Dark Version (USA).gba" size 8388608 crc 1bab58bd sha1 f3dbc8c6d58c33b88c28306f54ff742da1c8d6c9 ) + rom ( name "DemiKids - Dark Version (USA).gba" size 8388608 crc 1bab58bd sha1 f3dbc8c6d58c33b88c28306f54ff742da1c8d6c9 flags verified ) ) game ( @@ -4389,7 +4431,7 @@ game ( game ( name "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It)" description "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It)" - rom ( name "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc ea5fc3da sha1 ecf0e597839905c9f23c6d568c79fc00c2719f49 ) + rom ( name "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc ea5fc3da sha1 ecf0e597839905c9f23c6d568c79fc00c2719f49 flags verified ) ) game ( @@ -5025,7 +5067,7 @@ game ( game ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It)" description "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It)" - rom ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 6c135820 sha1 e49ae836b14f84dc8cd817bf912fcdce82d8a587 ) + rom ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 6c135820 sha1 e49ae836b14f84dc8cd817bf912fcdce82d8a587 flags verified ) ) game ( @@ -5157,7 +5199,7 @@ game ( game ( name "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan)" description "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan)" - rom ( name "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan).gba" size 16777216 crc c891b2a0 sha1 f306ce96404cff93caee78c86696a69b431b289a ) + rom ( name "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan).gba" size 16777216 crc c891b2a0 sha1 f306ce96404cff93caee78c86696a69b431b289a flags verified ) ) game ( @@ -5556,6 +5598,12 @@ game ( rom ( name "Elf Bowling 1 & 2 (USA).gba" size 4194304 crc 68feff40 sha1 013f128c8d67f1165196b4f29297bcd4616c5033 ) ) +game ( + name "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl)" + description "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl)" + rom ( name "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl).gba" size 4016344 crc e3128bcb sha1 67617136f205fa071d9fc239df09471e603c675c ) +) + game ( name "Enchanted - Once Upon Andalasia (USA) (En,Fr)" description "Enchanted - Once Upon Andalasia (USA) (En,Fr)" @@ -5821,9 +5869,81 @@ game ( ) game ( - name "F-Zero - Maximum Velocity (USA, Europe) (Virtual Console)" - description "F-Zero - Maximum Velocity (USA, Europe) (Virtual Console)" - rom ( name "F-Zero - Maximum Velocity (USA, Europe) (Virtual Console).gba" size 4194304 crc 4b5f1cdd sha1 bd08e426c743c7429efd576ce0ef00a70cffd72a flags verified ) + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-29) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-29) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-29) (Netcard).gba" size 16777216 crc d329df50 sha1 71b626b355813e80f9cc3d6ae3765552b5e09009 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-26) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-26) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-26) (Netcard).gba" size 16777216 crc c77188b6 sha1 377f0f17ce3cea637dfdf9021f04aa56971db6a6 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-24) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-24) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-24) (Netcard).gba" size 16777216 crc 77c0c615 sha1 bfe6b7f099998edf6e35bc47dfd86c1e88152cb4 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-23) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-23) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-23) (Netcard).gba" size 16777216 crc 4d224e17 sha1 685753aa1bff5ed077eaa01ab058fa800b9c50c7 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-18 23.00.14) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-18 23.00.14) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-18 23.00.14) (Netcard).gba" size 16777216 crc 6f7486d7 sha1 3633a74b5fbed1a129f2ff37f7fd000c70b23a4d ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-18 02.40.54) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-18 02.40.54) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-18 02.40.54) (Netcard).gba" size 16777216 crc 27c8a067 sha1 54fa13e875c899dab0de270f334c283d3f5bb05c ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-17) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-17) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-17) (Netcard).gba" size 16777216 crc e73c5f4a sha1 8397fb78936dd667d0ef45b055613795df4a1c0e ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-16) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-16) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-16) (Netcard).gba" size 16777216 crc aa522f27 sha1 d8d9035e5672cb95fcd49499d5e4e7b6d6daad67 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-15) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-15) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-15) (Netcard).gba" size 16777216 crc 7ec47244 sha1 c8ca3281e9b329d967e96516f98744226f18974a ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-11) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-11) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-11) (Netcard).gba" size 16777216 crc debc0acb sha1 2d46237c002846b3a5cd1ed3daa173ebcf8e35f2 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-09) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-08-09) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-08-09) (Netcard).gba" size 16777216 crc c46fd22a sha1 2319499d453179763fc607ffbfe2d24a272237f3 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-09-02 00.17.57) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-09-02 00.17.57) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-09-02 00.17.57) (Netcard).gba" size 16777216 crc 61f9dc0e sha1 a9c26c71373bfa19c578591fd774f66644c0bdf2 ) +) + +game ( + name "F-Zero - GP Legend (Unknown) (Proto) (2005-09-02 01.21.24) (Netcard)" + description "F-Zero - GP Legend (Unknown) (Proto) (2005-09-02 01.21.24) (Netcard)" + rom ( name "F-Zero - GP Legend (Unknown) (Proto) (2005-09-02 01.21.24) (Netcard).gba" size 16777216 crc 26358b01 sha1 32d0b25c339f814c2840e289b232f38678b88193 ) ) game ( @@ -5833,9 +5953,9 @@ game ( ) game ( - name "F-Zero for Game Boy Advance (Japan)" - description "F-Zero for Game Boy Advance (Japan)" - rom ( name "F-Zero for Game Boy Advance (Japan).gba" size 4194304 crc 25e3fc9a sha1 cd8648b7158cf7c979cc05dea4c1aa927496e8b7 ) + name "F-Zero - Maximum Velocity (USA, Europe) (Virtual Console)" + description "F-Zero - Maximum Velocity (USA, Europe) (Virtual Console)" + rom ( name "F-Zero - Maximum Velocity (USA, Europe) (Virtual Console).gba" size 4194304 crc 4b5f1cdd sha1 bd08e426c743c7429efd576ce0ef00a70cffd72a flags verified ) ) game ( @@ -5845,9 +5965,9 @@ game ( ) game ( - name "F1 2002 (Europe) (En,Fr,De,Es,It)" - description "F1 2002 (Europe) (En,Fr,De,Es,It)" - rom ( name "F1 2002 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc aac551fd sha1 ae8c986de946e7fde8249e958c6743816fb05784 ) + name "F-Zero for Game Boy Advance (Japan)" + description "F-Zero for Game Boy Advance (Japan)" + rom ( name "F-Zero for Game Boy Advance (Japan).gba" size 4194304 crc 25e3fc9a sha1 cd8648b7158cf7c979cc05dea4c1aa927496e8b7 ) ) game ( @@ -5856,6 +5976,12 @@ game ( rom ( name "F1 2002 (USA, Europe).gba" size 4194304 crc 7dd20f33 sha1 c5b3860403425da6f062dd5b6d433781051e1a85 ) ) +game ( + name "F1 2002 (Europe) (En,Fr,De,Es,It)" + description "F1 2002 (Europe) (En,Fr,De,Es,It)" + rom ( name "F1 2002 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc aac551fd sha1 ae8c986de946e7fde8249e958c6743816fb05784 ) +) + game ( name "F24 Stealth Fighter (USA)" description "F24 Stealth Fighter (USA)" @@ -6138,6 +6264,12 @@ game ( rom ( name "Fanqiejiang Wangguo Da Maoxian (China) (Proto).gba" size 8388608 crc 5116a665 sha1 51ab57e6b414bae66f3e3ef4335dc0d68df2ed5e ) ) +game ( + name "Fantastic 4 (Europe)" + description "Fantastic 4 (Europe)" + rom ( name "Fantastic 4 (Europe).gba" size 16777216 crc b30ae33d sha1 758b2afaf4dcd96baab60e04d64eb22718efcecf ) +) + game ( name "Fantastic 4 (USA)" description "Fantastic 4 (USA)" @@ -6150,12 +6282,6 @@ game ( rom ( name "Fantastic 4 (Europe) (Fr,De,Es,Nl).gba" size 16777216 crc 88643de0 sha1 1e6ef7a4c941ea074ed88010f5cd7bab7c807d0d flags verified ) ) -game ( - name "Fantastic 4 (Europe)" - description "Fantastic 4 (Europe)" - rom ( name "Fantastic 4 (Europe).gba" size 16777216 crc b30ae33d sha1 758b2afaf4dcd96baab60e04d64eb22718efcecf ) -) - game ( name "Fantastic 4 - Flame On (USA)" description "Fantastic 4 - Flame On (USA)" @@ -6432,6 +6558,12 @@ game ( rom ( name "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan).gba" size 16777216 crc a0093822 sha1 4894c960c64b4f2d250e054ffd5d6971940c3b17 ) ) +game ( + name "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan) (Rev 1)" + description "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan) (Rev 1)" + rom ( name "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan) (Rev 1).gba" size 16777216 crc 3f98600b sha1 2fbb9ef803a07c23139709179e6af25f141abe51 ) +) + game ( name "Findet Nemo (Germany) (Beta)" description "Findet Nemo (Germany) (Beta)" @@ -6453,7 +6585,7 @@ game ( game ( name "Finding Nemo (Japan)" description "Finding Nemo (Japan)" - rom ( name "Finding Nemo (Japan).gba" size 8388608 crc f895ba2d sha1 cab85c042c168e46ec42547a87af1b036e45c2a4 ) + rom ( name "Finding Nemo (Japan).gba" size 8388608 crc f895ba2d sha1 cab85c042c168e46ec42547a87af1b036e45c2a4 flags verified ) ) game ( @@ -6543,7 +6675,7 @@ game ( game ( name "Fire Emblem - Fuuin no Tsurugi (Japan)" description "Fire Emblem - Fuuin no Tsurugi (Japan)" - rom ( name "Fire Emblem - Fuuin no Tsurugi (Japan).gba" size 8388608 crc d38763e1 sha1 a57095da867de4d585c33d4394712986245fe6ca ) + rom ( name "Fire Emblem - Fuuin no Tsurugi (Japan).gba" size 8388608 crc d38763e1 sha1 a57095da867de4d585c33d4394712986245fe6ca flags verified ) ) game ( @@ -6579,7 +6711,7 @@ game ( game ( name "Fire Emblem - Seima no Kouseki (Japan)" description "Fire Emblem - Seima no Kouseki (Japan)" - rom ( name "Fire Emblem - Seima no Kouseki (Japan).gba" size 16777216 crc 9d76826f sha1 7da0456035366aa18414faa79d8fe7649f03c1ed ) + rom ( name "Fire Emblem - Seima no Kouseki (Japan).gba" size 16777216 crc 9d76826f sha1 7da0456035366aa18414faa79d8fe7649f03c1ed flags verified ) ) game ( @@ -7080,6 +7212,18 @@ game ( rom ( name "Gauntlet - Dark Legacy (USA).gba" size 8388608 crc e99de964 sha1 3ea608f4ea2235886fa1d7256f6a9ae88c2c0e28 ) ) +game ( + name "GB-A TV Tuner PAL (China) (v1.3) (Unl)" + description "GB-A TV Tuner PAL (China) (v1.3) (Unl)" + rom ( name "GB-A TV Tuner PAL (China) (v1.3) (Unl).gba" size 524288 crc 63524b0f sha1 256f5510a2051ae0512c4e1e90b9a572b1d859b6 ) +) + +game ( + name "GB-A TV Tuner PAL (China) (v2.0) (Unl)" + description "GB-A TV Tuner PAL (China) (v2.0) (Unl)" + rom ( name "GB-A TV Tuner PAL (China) (v2.0) (Unl).gba" size 524288 crc 0abecb5b sha1 96425bba00c21cd5c1970d6d80de547a1e226338 ) +) + game ( name "GBA AV Adapter (China) (Unl)" description "GBA AV Adapter (China) (Unl)" @@ -7104,18 +7248,6 @@ game ( rom ( name "GBA Personal Organizer (USA) (Unl).gba" size 1048576 crc 424f71e5 sha1 26e7a5435372c46628985cba57f12a322b59537b ) ) -game ( - name "GBA TV Tuner PAL (China) (v1.3) (Unl)" - description "GBA TV Tuner PAL (China) (v1.3) (Unl)" - rom ( name "GBA TV Tuner PAL (China) (v1.3) (Unl).gba" size 1048576 crc af124f8c sha1 e0899f4097054862d33c03e21e9d4a5eef790402 ) -) - -game ( - name "GBA TV Tuner PAL (China) (v2.0) (Unl)" - description "GBA TV Tuner PAL (China) (v2.0) (Unl)" - rom ( name "GBA TV Tuner PAL (China) (v2.0) (Unl).gba" size 8388608 crc b511df64 sha1 5a62463cbaaa0c4586e227ad6ca6a5d54485d955 ) -) - game ( name "Gegege no Kitarou - Kikiippatsu! Youkai Rettou (Japan)" description "Gegege no Kitarou - Kikiippatsu! Youkai Rettou (Japan)" @@ -7236,6 +7368,12 @@ game ( rom ( name "Global Star - Sudoku Fever (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 383cf600 sha1 8a6ab9e999cb9618bf169f70a9423abdc0de6a92 ) ) +game ( + name "Glucoboy (Australia)" + description "Glucoboy (Australia)" + rom ( name "Glucoboy (Australia).gba" size 16777216 crc 6e2d7eff sha1 4e9e198aef017bfe49802824e436ce47f2e807bb ) +) + game ( name "Go! Go! Beckham! - Adventure on Soccer Island (Europe) (En,Fr,De,Es,It)" description "Go! Go! Beckham! - Adventure on Soccer Island (Europe) (En,Fr,De,Es,It)" @@ -7339,45 +7477,93 @@ game ( ) game ( - name "Goodboy Galaxy (World) (En) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy (World) (En) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy (World) (En) (Demo) (Aftermarket) (Unl).gba" size 13224124 crc 19ba7d80 sha1 1bf95f8730ecdfa6665b85bea8764f42a88e8e3d ) + name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13224124 crc 19ba7d80 sha1 1bf95f8730ecdfa6665b85bea8764f42a88e8e3d ) ) game ( - name "Goodboy Galaxy (World) (Ja) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy (World) (Ja) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy (World) (Ja) (Demo) (Aftermarket) (Unl).gba" size 13219728 crc d4621e3e sha1 5bd59fac58c5f9a375216e9d1cf85fa5262f21f7 ) + name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13219728 crc d4621e3e sha1 5bd59fac58c5f9a375216e9d1cf85fa5262f21f7 ) ) game ( - name "Goodboy Galaxy (World) (Fr) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy (World) (Fr) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy (World) (Fr) (Demo) (Aftermarket) (Unl).gba" size 13225068 crc 21512022 sha1 8832d38f787f3e1da620fcae7514d7387445ccf2 ) + name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13225068 crc 21512022 sha1 8832d38f787f3e1da620fcae7514d7387445ccf2 ) ) game ( - name "Goodboy Galaxy (World) (Es) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy (World) (Es) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy (World) (Es) (Demo) (Aftermarket) (Unl).gba" size 13223944 crc c1811c9b sha1 9d413bce82708df137215a2968306a5196b1638b ) + name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223944 crc c1811c9b sha1 9d413bce82708df137215a2968306a5196b1638b ) ) game ( - name "Goodboy Galaxy (World) (Zh) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy (World) (Zh) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy (World) (Zh) (Demo) (Aftermarket) (Unl).gba" size 13269108 crc 3360e114 sha1 50186922ff77714b9ac638948b464cdbf80ab5fb ) + name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13269108 crc 3360e114 sha1 50186922ff77714b9ac638948b464cdbf80ab5fb ) ) game ( - name "Goodboy Galaxy (World) (Pt) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy (World) (Pt) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy (World) (Pt) (Demo) (Aftermarket) (Unl).gba" size 13223696 crc 3477ef15 sha1 4b447de09a23fbfdaa6d640824f8ceb5bbe56fab ) + name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223696 crc 3477ef15 sha1 4b447de09a23fbfdaa6d640824f8ceb5bbe56fab ) ) game ( - name "Goodboy Galaxy (World) (Ar) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy (World) (Ar) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy (World) (Ar) (Demo) (Aftermarket) (Unl).gba" size 13250016 crc a4054c2b sha1 c3cd833b9bdf87a8481c9b05251bba782bc3527e ) + name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13250016 crc a4054c2b sha1 c3cd833b9bdf87a8481c9b05251bba782bc3527e ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220676 crc ab179d6e sha1 2ad1c4840f2f6c2138ed44b1a7aa36071c227a0a ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221620 crc 3aa591f1 sha1 2548615eeaecd7498e32d02b5c758b713ada27f4 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221368 crc d02cdb6a sha1 1e579e15bdc8dc1def99bcb3c30acfc185e0476b ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220496 crc 906717a5 sha1 31857a9ab4daa537322f80faa77482a4b8120483 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220252 crc d12372bd sha1 89ea5ea41133419c317fd28e7c7f172f5bb53ec3 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13216280 crc d3c8dffd sha1 c41c0596a4c52b0e26bb9ffe5c9f7f1c064e0be6 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13265660 crc 119f9ddc sha1 d6c23ff47b21a7bf2f8238ac916aeea3866042b5 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13246576 crc b14cd1b4 sha1 0d15bd0584148b1658f7d47a2dda604a936ea166 ) ) game ( @@ -7428,6 +7614,18 @@ game ( rom ( name "Green Eggs and Ham by Dr. Seuss (USA).gba" size 4194304 crc e4ae2cd1 sha1 be062fa28db26ec37ec96e5a7e6dc77cf4ad6907 ) ) +game ( + name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl).gba" size 6639328 crc 78b81bbc sha1 fb090890bd767a22afe07b3323dd0992d698c906 ) +) + +game ( + name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl).gba" size 6937384 crc 9fa9f00f sha1 005f4dc0d615d36d32bbe36e9cc9007b22be2ecd ) +) + game ( name "Greg Hastings' Tournament Paintball Max'd (USA)" description "Greg Hastings' Tournament Paintball Max'd (USA)" @@ -7758,6 +7956,12 @@ game ( rom ( name "Hamtaro - Rainbow Rescue (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 5d051081 sha1 b6446397744c10eb08f112f005e995dd9954a675 ) ) +game ( + name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29)" + description "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29)" + rom ( name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29).gba" size 16777216 crc fd630f6c sha1 14cf38e86f019572393f0109680ff2db345f9f50 ) +) + game ( name "Hanabi Hyakkei Advance (Japan)" description "Hanabi Hyakkei Advance (Japan)" @@ -8077,9 +8281,9 @@ game ( ) game ( - name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan)" - description "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan)" - rom ( name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan).gba" size 8388608 crc 8ea9afcc sha1 fefc7a73ddceaf28ebb95b88f5f39a5489024d4e ) + name "Hikaru no Go 3 - Senyou Joy Carry Cartridge (Japan) (Rewritable Cartridge)" + description "Hikaru no Go 3 - Senyou Joy Carry Cartridge (Japan) (Rewritable Cartridge)" + rom ( name "Hikaru no Go 3 - Senyou Joy Carry Cartridge (Japan) (Rewritable Cartridge).gba" size 33554432 crc 5bfbc276 sha1 e064ceecae66f7eb0b6ba4f19424a52e504f4bf2 ) ) game ( @@ -8088,6 +8292,12 @@ game ( rom ( name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan) (Rev 1).gba" size 8388608 crc 526fdfff sha1 93b98fcf585483722240e56c01826ae5c31930e4 ) ) +game ( + name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan)" + description "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan)" + rom ( name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan).gba" size 8388608 crc 8ea9afcc sha1 fefc7a73ddceaf28ebb95b88f5f39a5489024d4e ) +) + game ( name "Hime Kishi Monogatari - Princess Blue (Japan)" description "Hime Kishi Monogatari - Princess Blue (Japan)" @@ -8118,6 +8328,12 @@ game ( rom ( name "Hobbit, The - The Prelude to the Lord of the Rings (USA).gba" size 8388608 crc d3f654b3 sha1 70d04d6d3ab8a1bfc4fa1a26d55cd4f73f84d479 ) ) +game ( + name "Holy Bible, The - World English Bible (USA) (Proto)" + description "Holy Bible, The - World English Bible (USA) (Proto)" + rom ( name "Holy Bible, The - World English Bible (USA) (Proto).gba" size 4194304 crc 0152a619 sha1 807d0b3dcf5ea7e972a0ecf0cecb03a040befb91 ) +) + game ( name "Home on the Range (USA) (En,Fr)" description "Home on the Range (USA) (En,Fr)" @@ -8436,12 +8652,30 @@ game ( rom ( name "Increibles, Los (Spain).gba" size 8388608 crc fc6ccadb sha1 c87047934ae328f52ef6b01083a57c65cbbab514 ) ) +game ( + name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" + description "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl).gba" size 10592124 crc a9014760 sha1 2430c6c0784912ad2f0b51e633bf577f087f189f ) +) + +game ( + name "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl)" + description "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl)" + rom ( name "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl).gba" size 25516708 crc 965a1a75 sha1 ae23cfba1f53a9bbde025490f3d7bdf52c3970e4 ) +) + game ( name "Initial D - Another Stage (Japan)" description "Initial D - Another Stage (Japan)" rom ( name "Initial D - Another Stage (Japan).gba" size 8388608 crc 23110a94 sha1 abc8a136e00e38132bf07d38cf28e52a2719fab9 ) ) +game ( + name "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl)" + description "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl).gba" size 3145728 crc 7ee7ae7f sha1 73d870fad3caa86b6f659e13b57eddac80db2f37 ) +) + game ( name "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl)" description "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl)" @@ -8535,7 +8769,7 @@ game ( game ( name "Iridion II (Europe) (En,Fr,De)" description "Iridion II (Europe) (En,Fr,De)" - rom ( name "Iridion II (Europe) (En,Fr,De).gba" size 8388608 crc 57930c6a sha1 661442c24404cc0727e4343f9ce570c87c797661 ) + rom ( name "Iridion II (Europe) (En,Fr,De).gba" size 8388608 crc 57930c6a sha1 661442c24404cc0727e4343f9ce570c87c797661 flags verified ) ) game ( @@ -8574,18 +8808,18 @@ game ( rom ( name "It's Mr. Pants (USA, Europe).gba" size 4194304 crc 757a4efb sha1 c49742f964a698ccce0520e24368a9d425a29b4d flags verified ) ) -game ( - name "J.League Pocket (Japan)" - description "J.League Pocket (Japan)" - rom ( name "J.League Pocket (Japan).gba" size 8388608 crc 51be73b8 sha1 b4cd024b10d740f3525dddfbcc613c04a8d4c166 ) -) - game ( name "J.League Pocket (Japan) (Rev 1)" description "J.League Pocket (Japan) (Rev 1)" rom ( name "J.League Pocket (Japan) (Rev 1).gba" size 8388608 crc 0524e9ef sha1 64c6b3f0113d91daf41e63b2755d26b9ed0cea3a ) ) +game ( + name "J.League Pocket (Japan)" + description "J.League Pocket (Japan)" + rom ( name "J.League Pocket (Japan).gba" size 8388608 crc 51be73b8 sha1 b4cd024b10d740f3525dddfbcc613c04a8d4c166 ) +) + game ( name "J.League Pocket 2 (Japan)" description "J.League Pocket 2 (Japan)" @@ -8826,18 +9060,18 @@ game ( rom ( name "Justice League - Injustice for All (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc d71c4382 sha1 7385169111585230ba62007397802a7197653447 ) ) -game ( - name "Justice League - Injustice for All (USA) (Beta)" - description "Justice League - Injustice for All (USA) (Beta)" - rom ( name "Justice League - Injustice for All (USA) (Beta).gba" size 8388608 crc c41081cf sha1 e3302c2aa5cd14bf5546a3069bc6757363ee38b4 ) -) - game ( name "Justice League - Injustice for All (USA)" description "Justice League - Injustice for All (USA)" rom ( name "Justice League - Injustice for All (USA).gba" size 8388608 crc b2477b72 sha1 f7d774f3d1f1436c18b044c65e574dc327ad6437 ) ) +game ( + name "Justice League - Injustice for All (USA) (Beta)" + description "Justice League - Injustice for All (USA) (Beta)" + rom ( name "Justice League - Injustice for All (USA) (Beta).gba" size 8388608 crc c41081cf sha1 e3302c2aa5cd14bf5546a3069bc6757363ee38b4 ) +) + game ( name "Justice League Heroes - The Flash (USA)" description "Justice League Heroes - The Flash (USA)" @@ -9126,18 +9360,18 @@ game ( rom ( name "Kim Possible - Revenge of Monkey Fist (USA).gba" size 8388608 crc 1a56efbd sha1 64ef958beae876d3a6c295d0351d671b6991774b ) ) -game ( - name "Kim Possible 2 - Drakken's Demise (USA) (En,Fr)" - description "Kim Possible 2 - Drakken's Demise (USA) (En,Fr)" - rom ( name "Kim Possible 2 - Drakken's Demise (USA) (En,Fr).gba" size 8388608 crc fa946fc6 sha1 d2baaec3c20b48bebe79ebe27761cd107fd067bf flags verified ) -) - game ( name "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es)" description "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es)" rom ( name "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es).gba" size 8388608 crc 71c505c8 sha1 eb4099911dbd28073c554f4d4fa35cbeed82bc6b ) ) +game ( + name "Kim Possible 2 - Drakken's Demise (USA) (En,Fr)" + description "Kim Possible 2 - Drakken's Demise (USA) (En,Fr)" + rom ( name "Kim Possible 2 - Drakken's Demise (USA) (En,Fr).gba" size 8388608 crc fa946fc6 sha1 d2baaec3c20b48bebe79ebe27761cd107fd067bf flags verified ) +) + game ( name "Kim Possible 3 - Team Possible (USA) (En,Fr)" description "Kim Possible 3 - Team Possible (USA) (En,Fr)" @@ -9162,12 +9396,6 @@ game ( rom ( name "King of Fighters EX 2, The - Howling Blood (USA) (Beta) (2003-04-03).gba" size 8388608 crc 7704ff39 sha1 b859122c1813a5ec9fb565dcca815a9f0a52bf18 ) ) -game ( - name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" - description "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" - rom ( name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1).gba" size 8388608 crc dc5beacd sha1 2b7ec55de56d7f7f0932a53a0d3fcc3f36a0af8e ) -) - game ( name "King of Fighters EX 2, The - Howling Blood (Europe)" description "King of Fighters EX 2, The - Howling Blood (Europe)" @@ -9181,15 +9409,9 @@ game ( ) game ( - name "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" - description "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" - rom ( name "King of Fighters EX, The - NeoBlood (USA) (Rev 1).gba" size 8388608 crc 0f960e70 sha1 3031264c4b27cac55c2df38ab5f2bfcafa7c301d ) -) - -game ( - name "King of Fighters EX, The - NeoBlood (Japan) (Beta)" - description "King of Fighters EX, The - NeoBlood (Japan) (Beta)" - rom ( name "King of Fighters EX, The - NeoBlood (Japan) (Beta).gba" size 8388608 crc 811ffcfa sha1 cde8454951d3509f0b2bf9de98221eef248f5f8d ) + name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" + description "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" + rom ( name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1).gba" size 8388608 crc dc5beacd sha1 2b7ec55de56d7f7f0932a53a0d3fcc3f36a0af8e ) ) game ( @@ -9210,6 +9432,18 @@ game ( rom ( name "King of Fighters EX, The - NeoBlood (Europe).gba" size 8388608 crc 17e66b52 sha1 48c85734164d4d83a232b5aca6bb9a2c5b7f5317 ) ) +game ( + name "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" + description "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" + rom ( name "King of Fighters EX, The - NeoBlood (USA) (Rev 1).gba" size 8388608 crc 0f960e70 sha1 3031264c4b27cac55c2df38ab5f2bfcafa7c301d ) +) + +game ( + name "King of Fighters EX, The - NeoBlood (Japan) (Beta)" + description "King of Fighters EX, The - NeoBlood (Japan) (Beta)" + rom ( name "King of Fighters EX, The - NeoBlood (Japan) (Beta).gba" size 8388608 crc 811ffcfa sha1 cde8454951d3509f0b2bf9de98221eef248f5f8d ) +) + game ( name "Kingdom Hearts - Chain of Memories (Japan)" description "Kingdom Hearts - Chain of Memories (Japan)" @@ -9253,9 +9487,9 @@ game ( ) game ( - name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" - description "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" - rom ( name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 3b7a7477 sha1 39b00beee4558e6738859cfa250e4e0fcaae626e flags verified ) + name "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" + description "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" + rom ( name "Kirby - Nightmare in Dream Land (USA) (Virtual Console).gba" size 8388608 crc 1af07ac8 sha1 3d142008d50a64c315fd2d7cbd86ba94dffa2e12 ) ) game ( @@ -9265,15 +9499,9 @@ game ( ) game ( - name "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" - description "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" - rom ( name "Kirby - Nightmare in Dream Land (USA) (Virtual Console).gba" size 8388608 crc 1af07ac8 sha1 3d142008d50a64c315fd2d7cbd86ba94dffa2e12 ) -) - -game ( - name "Kirby & The Amazing Mirror (USA) (Virtual Console)" - description "Kirby & The Amazing Mirror (USA) (Virtual Console)" - rom ( name "Kirby & The Amazing Mirror (USA) (Virtual Console).gba" size 16777216 crc f70ebb99 sha1 a7b758c2abf4f0ef722922eab4d394a1579b52e8 ) + name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" + description "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" + rom ( name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 3b7a7477 sha1 39b00beee4558e6738859cfa250e4e0fcaae626e flags verified ) ) game ( @@ -9288,6 +9516,12 @@ game ( rom ( name "Kirby & The Amazing Mirror (USA).gba" size 16777216 crc 9f2a3048 sha1 274b102b6d940f46861a92b4e65f89a51815c12c flags verified ) ) +game ( + name "Kirby & The Amazing Mirror (USA) (Virtual Console)" + description "Kirby & The Amazing Mirror (USA) (Virtual Console)" + rom ( name "Kirby & The Amazing Mirror (USA) (Virtual Console).gba" size 16777216 crc f70ebb99 sha1 a7b758c2abf4f0ef722922eab4d394a1579b52e8 ) +) + game ( name "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It) (Virtual Console)" description "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It) (Virtual Console)" @@ -9324,18 +9558,18 @@ game ( rom ( name "Klonoa - Empire of Dreams (Europe).gba" size 4194304 crc 69492530 sha1 e4a81713b134e0b7409708843dad2a4948b903ef ) ) -game ( - name "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console)" - description "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console)" - rom ( name "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console).gba" size 4194304 crc 766c7f9a sha1 455c6f19a703b2bd54a9a3a9588964239965e6db ) -) - game ( name "Klonoa 2 - Dream Champ Tournament (USA)" description "Klonoa 2 - Dream Champ Tournament (USA)" rom ( name "Klonoa 2 - Dream Champ Tournament (USA).gba" size 4194304 crc 8bd23a7f sha1 35c05676e65fd4c92220861662cd3709342f36e2 ) ) +game ( + name "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console)" + description "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console)" + rom ( name "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console).gba" size 4194304 crc 766c7f9a sha1 455c6f19a703b2bd54a9a3a9588964239965e6db ) +) + game ( name "Klonoa Heroes - Densetsu no Star Medal (Japan)" description "Klonoa Heroes - Densetsu no Star Medal (Japan)" @@ -9414,6 +9648,12 @@ game ( rom ( name "Konami Krazy Racers (Europe).gba" size 4194304 crc cfec0650 sha1 90a0035818ba0ab2a0c6ea45dc7eff2eb7296970 flags verified ) ) +game ( + name "Konami Krazy Racers (USA) (Beta)" + description "Konami Krazy Racers (USA) (Beta)" + rom ( name "Konami Krazy Racers (USA) (Beta).gba" size 4194304 crc 5f2ae8fe sha1 329b82282d633d1162f9afb3334c035b10b91e72 ) +) + game ( name "Konami Krazy Racers (USA) (Virtual Console)" description "Konami Krazy Racers (USA) (Virtual Console)" @@ -9427,9 +9667,9 @@ game ( ) game ( - name "Konami Krazy Racers (USA) (Beta)" - description "Konami Krazy Racers (USA) (Beta)" - rom ( name "Konami Krazy Racers (USA) (Beta).gba" size 4194304 crc 5f2ae8fe sha1 329b82282d633d1162f9afb3334c035b10b91e72 ) + name "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" + description "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" + rom ( name "Konami Wai Wai Racing Advance (Japan) (Virtual Console).gba" size 4194304 crc f424858f sha1 29f850ea1a9900446a0e1ce8ef1c2fd85341f242 ) ) game ( @@ -9438,12 +9678,6 @@ game ( rom ( name "Konami Wai Wai Racing Advance (Japan).gba" size 4194304 crc aa039a8a sha1 e3549b9b7d7208b88e368e7b7a59e31eec8b1da6 ) ) -game ( - name "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" - description "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" - rom ( name "Konami Wai Wai Racing Advance (Japan) (Virtual Console).gba" size 4194304 crc f424858f sha1 29f850ea1a9900446a0e1ce8ef1c2fd85341f242 ) -) - game ( name "Konchuu Monster - Battle Master (Japan)" description "Konchuu Monster - Battle Master (Japan)" @@ -10134,6 +10368,12 @@ game ( rom ( name "Lufia - The Ruins of Lore (USA).gba" size 8388608 crc de5ffcbc sha1 a2b7e80a6c7d586ebeec77c8a2c2545fe27e0592 ) ) +game ( + name "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" + description "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" + rom ( name "Luggage Retrieval Officer (World) (Aftermarket) (Unl).gba" size 3336260 crc 5aa30d90 sha1 84c9b2d50c8af74b8b04f88af367d9fac1a24ef6 ) +) + game ( name "Lunar Legend (Japan)" description "Lunar Legend (Japan)" @@ -10470,6 +10710,12 @@ game ( rom ( name "Marie, Elie & Anis no Atelier - Soyokaze kara no Dengon (Japan).gba" size 8388608 crc 1b70a454 sha1 0dbde8bcaa9e4bdc201674a0d66c6ce64242eb4b ) ) +game ( + name "Mario & Luigi (USA) (Demo) (Kiosk, E3 2003)" + description "Mario & Luigi (USA) (Demo) (Kiosk, E3 2003)" + rom ( name "Mario & Luigi (USA) (Demo) (Kiosk, E3 2003).gba" size 8388608 crc 2d01a8df sha1 4265af33441ad7b16566ea6c6a2803dc8e9cdf9b ) +) + game ( name "Mario & Luigi - Superstar Saga (USA) (Demo) (Kiosk)" description "Mario & Luigi - Superstar Saga (USA) (Demo) (Kiosk)" @@ -11253,7 +11499,7 @@ game ( game ( name "Megaman - Battle Network 4 - Blue Moon (Europe)" description "Megaman - Battle Network 4 - Blue Moon (Europe)" - rom ( name "Megaman - Battle Network 4 - Blue Moon (Europe).gba" size 8388608 crc 48758316 sha1 a05e8dce26b5134001337e193d49958be2081598 ) + rom ( name "Megaman - Battle Network 4 - Blue Moon (Europe).gba" size 8388608 crc 48758316 sha1 a05e8dce26b5134001337e193d49958be2081598 flags verified ) ) game ( @@ -11580,6 +11826,12 @@ game ( rom ( name "Metal Slug Advance (Europe).gba" size 8388608 crc 3806f4ae sha1 0719aee29b0da365e7ad52bb0ae9545bcd377152 flags verified ) ) +game ( + name "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl)" + description "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl).gba" size 524288 crc 7ec3485e sha1 729592141bc160ead0af51d4322c7f9f17da0b82 ) +) + game ( name "Metalgun Slinger (Japan)" description "Metalgun Slinger (Japan)" @@ -11587,21 +11839,9 @@ game ( ) game ( - name "Metroid - Zero Mission (USA)" - description "Metroid - Zero Mission (USA)" - rom ( name "Metroid - Zero Mission (USA).gba" size 8388608 crc 5c61a844 sha1 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8 flags verified ) -) - -game ( - name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" - description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" - rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f1d92e63 sha1 0fd107445a42e6f3a3e5ce8c865f412583179903 flags verified ) -) - -game ( - name "Metroid - Zero Mission (Japan)" - description "Metroid - Zero Mission (Japan)" - rom ( name "Metroid - Zero Mission (Japan).gba" size 8388608 crc 44b79e2b sha1 096f07685a3dc9286e71aa0b761f233b5efa2fcd ) + name "Metroid - Zero Mission (Japan) (Virtual Console)" + description "Metroid - Zero Mission (Japan) (Virtual Console)" + rom ( name "Metroid - Zero Mission (Japan) (Virtual Console).gba" size 8388608 crc 220b68f5 sha1 24d99f32875464dbcef5ca8ec231ec42073ff1e8 ) ) game ( @@ -11629,9 +11869,21 @@ game ( ) game ( - name "Metroid - Zero Mission (Japan) (Virtual Console)" - description "Metroid - Zero Mission (Japan) (Virtual Console)" - rom ( name "Metroid - Zero Mission (Japan) (Virtual Console).gba" size 8388608 crc 220b68f5 sha1 24d99f32875464dbcef5ca8ec231ec42073ff1e8 ) + name "Metroid - Zero Mission (USA)" + description "Metroid - Zero Mission (USA)" + rom ( name "Metroid - Zero Mission (USA).gba" size 8388608 crc 5c61a844 sha1 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8 flags verified ) +) + +game ( + name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" + description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" + rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f1d92e63 sha1 0fd107445a42e6f3a3e5ce8c865f412583179903 flags verified ) +) + +game ( + name "Metroid - Zero Mission (Japan)" + description "Metroid - Zero Mission (Japan)" + rom ( name "Metroid - Zero Mission (Japan).gba" size 8388608 crc 44b79e2b sha1 096f07685a3dc9286e71aa0b761f233b5efa2fcd ) ) game ( @@ -11785,9 +12037,21 @@ game ( ) game ( - name "Minicraft (World) (Aftermarket) (Unl)" - description "Minicraft (World) (Aftermarket) (Unl)" - rom ( name "Minicraft (World) (Aftermarket) (Unl).gba" size 131072 crc e852c9e9 sha1 06faa5be11978666db6995d8fce40ce2c3641ce8 ) + name "Minicraft (World) (v1.0) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.0) (Aftermarket) (Unl).gba" size 131072 crc e852c9e9 sha1 06faa5be11978666db6995d8fce40ce2c3641ce8 ) +) + +game ( + name "Minicraft (World) (v1.1) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.1) (Aftermarket) (Unl).gba" size 131072 crc 07595773 sha1 fee5cfa5b9e1f3383780432772f29764ac0fc443 ) +) + +game ( + name "Minicraft (World) (v1.2) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.2) (Aftermarket) (Unl).gba" size 131072 crc 37e7ee7d sha1 dc7faa4952986d5c5f0e3b32203936cd717f97eb ) ) game ( @@ -12240,6 +12504,18 @@ game ( rom ( name "Mother 3 (Japan) (Virtual Console).gba" size 33554432 crc c704a567 sha1 a9fb9c36df3b0fb24b266826f5853c56122f9d36 ) ) +game ( + name "Moto Racer Advance (USA) (En,Fr,De,Es,It)" + description "Moto Racer Advance (USA) (En,Fr,De,Es,It)" + rom ( name "Moto Racer Advance (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 2fdbe7a8 sha1 351414650e6969c270b1339ada7b3565ce80374c ) +) + +game ( + name "Moto Racer Advance (Europe) (En,Fr,De,Es,It)" + description "Moto Racer Advance (Europe) (En,Fr,De,Es,It)" + rom ( name "Moto Racer Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8cb19da0 sha1 b91bad8ee04652d71e0610f8d1a5deaebd4c1fd0 flags verified ) +) + game ( name "Motocross Challenge (USA) (Proto)" description "Motocross Challenge (USA) (Proto)" @@ -12282,18 +12558,6 @@ game ( rom ( name "MotoGP (Europe) (Beta).gba" size 4194304 crc 508bf8dc sha1 25554ecf8c3b534e0a70c6d4e402fa8f721da7d8 ) ) -game ( - name "Motoracer Advance (USA) (En,Fr,De,Es,It)" - description "Motoracer Advance (USA) (En,Fr,De,Es,It)" - rom ( name "Motoracer Advance (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 2fdbe7a8 sha1 351414650e6969c270b1339ada7b3565ce80374c ) -) - -game ( - name "Motoracer Advance (Europe) (En,Fr,De,Es,It)" - description "Motoracer Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Motoracer Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8cb19da0 sha1 b91bad8ee04652d71e0610f8d1a5deaebd4c1fd0 flags verified ) -) - game ( name "Mr Nutz (Europe) (En,Fr,De,Es,It)" description "Mr Nutz (Europe) (En,Fr,De,Es,It)" @@ -12312,12 +12576,6 @@ game ( rom ( name "Mr. Driller 2 (USA).gba" size 4194304 crc 02f51696 sha1 e7009dd8418303343c4aac2558538b8caa28b694 ) ) -game ( - name "Mr. Driller 2 (Japan)" - description "Mr. Driller 2 (Japan)" - rom ( name "Mr. Driller 2 (Japan).gba" size 4194304 crc 5264c730 sha1 0373318ef431b1d02708941af261c91de1677d9d ) -) - game ( name "Mr. Driller 2 (USA) (Virtual Console)" description "Mr. Driller 2 (USA) (Virtual Console)" @@ -12337,9 +12595,9 @@ game ( ) game ( - name "Mr. Driller A - Fushigi na Pacteria (Japan) (Virtual Console)" - description "Mr. Driller A - Fushigi na Pacteria (Japan) (Virtual Console)" - rom ( name "Mr. Driller A - Fushigi na Pacteria (Japan) (Virtual Console).gba" size 8388608 crc 5f595157 sha1 d51a4ef35205cb61a242db65be6a7807d49dec5c ) + name "Mr. Driller 2 (Japan)" + description "Mr. Driller 2 (Japan)" + rom ( name "Mr. Driller 2 (Japan).gba" size 4194304 crc 5264c730 sha1 0373318ef431b1d02708941af261c91de1677d9d ) ) game ( @@ -12348,6 +12606,12 @@ game ( rom ( name "Mr. Driller A - Fushigi na Pacteria (Japan).gba" size 8388608 crc 529f06a4 sha1 ccfb5f3051b4d3bdec38f0085f2a585ecf249f20 ) ) +game ( + name "Mr. Driller A - Fushigi na Pacteria (Japan) (Virtual Console)" + description "Mr. Driller A - Fushigi na Pacteria (Japan) (Virtual Console)" + rom ( name "Mr. Driller A - Fushigi na Pacteria (Japan) (Virtual Console).gba" size 8388608 crc 5f595157 sha1 d51a4ef35205cb61a242db65be6a7807d49dec5c ) +) + game ( name "Mr. Incredible (Japan)" description "Mr. Incredible (Japan)" @@ -12396,18 +12660,18 @@ game ( rom ( name "Mummy, The (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 55bf350b sha1 cc833b1398a6ea87d31712806757c2fe52fadd31 ) ) -game ( - name "Muppet Pinball Mayhem (Europe)" - description "Muppet Pinball Mayhem (Europe)" - rom ( name "Muppet Pinball Mayhem (Europe).gba" size 4194304 crc 8d5034d7 sha1 1c45790873605defc999b45ee145013e7e406a5d ) -) - game ( name "Muppet Pinball Mayhem (USA)" description "Muppet Pinball Mayhem (USA)" rom ( name "Muppet Pinball Mayhem (USA).gba" size 4194304 crc 58575f65 sha1 cbf381536ab8d8ea02814a77f46db13cb625c72f ) ) +game ( + name "Muppet Pinball Mayhem (Europe)" + description "Muppet Pinball Mayhem (Europe)" + rom ( name "Muppet Pinball Mayhem (Europe).gba" size 4194304 crc 8d5034d7 sha1 1c45790873605defc999b45ee145013e7e406a5d ) +) + game ( name "Muppets, The - On with the Show! (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Muppets, The - On with the Show! (USA, Europe) (En,Fr,De,Es,It,Nl)" @@ -13410,6 +13674,12 @@ game ( rom ( name "Pinball Tycoon (USA).gba" size 4194304 crc 1c4d3fdf sha1 fac76a646d112a775f9877b53f1386716d968a79 ) ) +game ( + name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" + description "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" + rom ( name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl).gba" size 1048576 crc 9ec140d3 sha1 9e19e8f97e8619a4755c3ceb482fa3e2ad5a4529 ) +) + game ( name "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" description "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" @@ -13560,6 +13830,12 @@ game ( rom ( name "Pocket Dogs (USA).gba" size 8388608 crc beddc67f sha1 79a90b119ea84c5812575d20ba6107be7edbfee7 ) ) +game ( + name "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" + description "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Pocket Meat (World) (Proto) (Aftermarket) (Unl).gba" size 861952 crc 0b029da3 sha1 9958d9a66742cc00e234a96c311b2acec40f69d1 ) +) + game ( name "Pocket Monsters - Emerald (Japan)" description "Pocket Monsters - Emerald (Japan)" @@ -13626,6 +13902,12 @@ game ( rom ( name "Pocket Monsters - Sapphire (Japan) (Rev 1).gba" size 8388608 crc 01bd60e3 sha1 01f509671445965236ac4c6b5a354fe2f1e69f13 flags verified ) ) +game ( + name "Pocket Monsters Diamond - Pocket Monsters Pearl - Manaphy Present Campaign Senyou Cartridge (Japan) (En)" + description "Pocket Monsters Diamond - Pocket Monsters Pearl - Manaphy Present Campaign Senyou Cartridge (Japan) (En)" + rom ( name "Pocket Monsters Diamond - Pocket Monsters Pearl - Manaphy Present Campaign Senyou Cartridge (Japan) (En).gba" size 2097152 crc e31566cf sha1 3fbbd166bacdc668844e38b0ca35d6e29d11da7a ) +) + game ( name "Pocket Monsters Diamond - Tomodachi to Issho ni! - Present Campaign Senyou Cartridge (Japan) [b]" description "Pocket Monsters Diamond - Tomodachi to Issho ni! - Present Campaign Senyou Cartridge (Japan) [b]" @@ -13902,12 +14184,6 @@ game ( rom ( name "Pokemon - Sapphire Version - Gotta Catch 'em All! (USA) (Unl).gba" size 33554432 crc 86a602ab sha1 14051d159d7a1266b5bfecbfd52722fd3e0711bf ) ) -game ( - name "Pokemon - Slot 2 Distribution (Japan) (En) (B5DJ)" - description "Pokemon - Slot 2 Distribution (Japan) (En) (B5DJ)" - rom ( name "Pokemon - Slot 2 Distribution (Japan) (En) (B5DJ).gba" size 2097152 crc e31566cf sha1 3fbbd166bacdc668844e38b0ca35d6e29d11da7a ) -) - game ( name "Pokemon - Slot 2 Distribution (Japan) (Proto)" description "Pokemon - Slot 2 Distribution (Japan) (Proto)" @@ -13947,7 +14223,7 @@ game ( game ( name "Pokemon - Version Saphir (France)" description "Pokemon - Version Saphir (France)" - rom ( name "Pokemon - Version Saphir (France).gba" size 16777216 crc 3581a05f sha1 c269b5692b2d0e5800ba1ddf117fda95ac648634 ) + rom ( name "Pokemon - Version Saphir (France).gba" size 16777216 crc 3581a05f sha1 c269b5692b2d0e5800ba1ddf117fda95ac648634 flags verified ) ) game ( @@ -14535,7 +14811,7 @@ game ( game ( name "Racing Gears Advance (USA) (Beta)" description "Racing Gears Advance (USA) (Beta)" - rom ( name "Racing Gears Advance (USA) (Beta).gba" size 16777216 crc 86a05f93 sha1 d258526ce1dcfbed51b745a762f148c9bea01154 ) + rom ( name "Racing Gears Advance (USA) (Beta).gba" size 8388608 crc 7a3820b3 sha1 ff18dfe7d75a8154c0dcc3970e5d0d4cb75c3568 ) ) game ( @@ -14587,9 +14863,9 @@ game ( ) game ( - name "Ratatouille (Greece) (En)" - description "Ratatouille (Greece) (En)" - rom ( name "Ratatouille (Greece) (En).gba" size 8388608 crc 3e1711c7 sha1 58f2fa1d7e531c7345b11db268e1bbc10372bebc ) + name "Ratatouille (Australia, Greece) (En)" + description "Ratatouille (Australia, Greece) (En)" + rom ( name "Ratatouille (Australia, Greece) (En).gba" size 8388608 crc 3e1711c7 sha1 58f2fa1d7e531c7345b11db268e1bbc10372bebc flags verified ) ) game ( @@ -14667,7 +14943,7 @@ game ( game ( name "Rayman Advance (Europe) (En,Fr,De,Es,It)" description "Rayman Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Rayman Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b43783b4 sha1 6a32d270848ae302a3e4fb873e53b663c2db4811 ) + rom ( name "Rayman Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b43783b4 sha1 6a32d270848ae302a3e4fb873e53b663c2db4811 flags verified ) ) game ( @@ -14772,12 +15048,6 @@ game ( rom ( name "Relaxuma na Mainichi (Japan).gba" size 4194304 crc 9f333017 sha1 e6e649605603dc84b20934ac00f99a13dc8ff8cc ) ) -game ( - name "Remute - Unity (World) (Aftermarket) (Unl)" - description "Remute - Unity (World) (Aftermarket) (Unl)" - rom ( name "Remute - Unity (World) (Aftermarket) (Unl).gba" size 33554432 crc 6cd42a32 sha1 d8001b07885557ee32608c661e202a257d3e8c3d ) -) - game ( name "Renzhe Shen Gui 2 (Taiwan) (Unl)" description "Renzhe Shen Gui 2 (Taiwan) (Unl)" @@ -15048,6 +15318,12 @@ game ( rom ( name "Rockman EXE 4 - Tournament Blue Moon (Japan) (Rev 1) (Virtual Console).gba" size 8388608 crc 0a27789e sha1 bfded71514df71d0449f9c972a4f6356970796a1 ) ) +game ( + name "Rockman EXE 4 - Tournament Blue Moon (Japan) (Rev 1)" + description "Rockman EXE 4 - Tournament Blue Moon (Japan) (Rev 1)" + rom ( name "Rockman EXE 4 - Tournament Blue Moon (Japan) (Rev 1).gba" size 8388608 crc 709bbf07 sha1 c46305f0398f75230b7f6f62d39167dfcc7b1778 ) +) + game ( name "Rockman EXE 4 - Tournament Blue Moon (Japan)" description "Rockman EXE 4 - Tournament Blue Moon (Japan)" @@ -15222,6 +15498,30 @@ game ( rom ( name "Rugrats - Travesuras en el Castillo (Spain).gba" size 4194304 crc 0bcab7d0 sha1 89448f91091a46deaebaddbaaada43522f387465 ) ) +game ( + name "S World 3 (World) (Beta 4) (Unl)" + description "S World 3 (World) (Beta 4) (Unl)" + rom ( name "S World 3 (World) (Beta 4) (Unl).gba" size 265800 crc 9d5e128c sha1 243555734e942b3ddba2d7834805e56eb72403c4 ) +) + +game ( + name "S World 3 (World) (Beta 3) (Unl)" + description "S World 3 (World) (Beta 3) (Unl)" + rom ( name "S World 3 (World) (Beta 3) (Unl).gba" size 43296 crc 3bc15e46 sha1 830f34779783f645dc88c4b00f8d85ca5f87f904 ) +) + +game ( + name "S World 3 (World) (Beta 2) (Unl)" + description "S World 3 (World) (Beta 2) (Unl)" + rom ( name "S World 3 (World) (Beta 2) (Unl).gba" size 12844 crc 34ad13fe sha1 5de0d42c33c616d8b27bb32050b10853cdea232d ) +) + +game ( + name "S World 3 (World) (Beta 1) (Unl)" + description "S World 3 (World) (Beta 1) (Unl)" + rom ( name "S World 3 (World) (Beta 1) (Unl).gba" size 10144 crc 6b1a6173 sha1 201d6c313fed6b263ba31872be7032cfe874c50b ) +) + game ( name "Sabre Wulf (Europe) (En,Fr,De)" description "Sabre Wulf (Europe) (En,Fr,De)" @@ -16218,6 +16518,12 @@ game ( rom ( name "Sims, The - Bustin' Out (USA) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 16777216 crc d1183501 sha1 7038fa0e4cb8aeac9e48a0b45574db66cba39e73 flags verified ) ) +game ( + name "Sips (World) (Aftermarket) (Unl)" + description "Sips (World) (Aftermarket) (Unl)" + rom ( name "Sips (World) (Aftermarket) (Unl).gba" size 6235380 crc 5c1fb22d sha1 bb725df7226307d55df04365f85e5698b199c3c9 ) +) + game ( name "Sister Princess - RePure (Japan)" description "Sister Princess - RePure (Japan)" @@ -16266,6 +16572,30 @@ game ( rom ( name "Sky Dancers - They Magically Fly! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3af1063b sha1 df749ac7e33a1c7ede3faadb6648a8e53fa77048 ) ) +game ( + name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl).gba" size 15887876 crc c798529d sha1 ea4a6494bcec25757f657c69550c91190e46cebd ) +) + +game ( + name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl).gba" size 15894868 crc af572de8 sha1 997bf192369d48433a7c35187c7e1d0b5fcc16e0 ) +) + +game ( + name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl).gba" size 15900084 crc df05edff sha1 1328d17668480b4e9bea338662532ace332c74a9 ) +) + +game ( + name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl).gba" size 16075456 crc d271c516 sha1 0dbdf16b23afb70229eff2de269fd5d73659d745 ) +) + game ( name "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" description "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" @@ -16305,7 +16635,7 @@ game ( game ( name "Smuggler's Run (Europe) (En,Fr,De,Es,It)" description "Smuggler's Run (Europe) (En,Fr,De,Es,It)" - rom ( name "Smuggler's Run (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3ae0afc8 sha1 e87067719da93f0d7c8136cdf5717612a6c15034 ) + rom ( name "Smuggler's Run (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3ae0afc8 sha1 e87067719da93f0d7c8136cdf5717612a6c15034 flags verified ) ) game ( @@ -16398,6 +16728,18 @@ game ( rom ( name "Sonic Advance (Japan) (En,Ja) (Rev 1).gba" size 8388608 crc 85957a24 sha1 f43faca5d8df354a63471aebfea3be125e797e51 ) ) +game ( + name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" + description "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" + rom ( name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console).gba" size 16777216 crc 6c6c65a3 sha1 2aa6ee2cf2b0ebfafbea6d6d24165b252a7e329e ) +) + +game ( + name "Sonic Advance 2 (USA) (Beta) (2002-10-25)" + description "Sonic Advance 2 (USA) (Beta) (2002-10-25)" + rom ( name "Sonic Advance 2 (USA) (Beta) (2002-10-25).gba" size 16777216 crc 95ab3867 sha1 3368642fc4157824af63367e2a685b7d6ee9b09d ) +) + game ( name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It)" description "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It)" @@ -16416,30 +16758,6 @@ game ( rom ( name "Sonic Advance 2 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 89509891 sha1 b0f64bdca097f2de8f05ac4c8caea2b80c5faeb1 flags verified ) ) -game ( - name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" - description "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" - rom ( name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console).gba" size 16777216 crc 6c6c65a3 sha1 2aa6ee2cf2b0ebfafbea6d6d24165b252a7e329e ) -) - -game ( - name "Sonic Advance 2 (USA) (Beta) (2002-10-25)" - description "Sonic Advance 2 (USA) (Beta) (2002-10-25)" - rom ( name "Sonic Advance 2 (USA) (Beta) (2002-10-25).gba" size 16777216 crc 95ab3867 sha1 3368642fc4157824af63367e2a685b7d6ee9b09d ) -) - -game ( - name "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" - description "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" - rom ( name "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console).gba" size 16777216 crc 1f36892f sha1 9fc8e926fc5472a1e34e3251c5d316526dc7a7a9 ) -) - -game ( - name "Sonic Advance 3 (Japan) (Demo) (Kiosk, GameCube)" - description "Sonic Advance 3 (Japan) (Demo) (Kiosk, GameCube)" - rom ( name "Sonic Advance 3 (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 0594d496 sha1 9c3f18112c126ca08403408a844a3a83967eb4dc flags verified ) -) - game ( name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta)" description "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta)" @@ -16464,6 +16782,18 @@ game ( rom ( name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 5bf83456 sha1 685af3a2dc0f1b3f8922e73ec42c1dc92e210e39 flags verified ) ) +game ( + name "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" + description "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console)" + rom ( name "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It) (Virtual Console).gba" size 16777216 crc 1f36892f sha1 9fc8e926fc5472a1e34e3251c5d316526dc7a7a9 ) +) + +game ( + name "Sonic Advance 3 (Japan) (Demo) (Kiosk, GameCube)" + description "Sonic Advance 3 (Japan) (Demo) (Kiosk, GameCube)" + rom ( name "Sonic Advance 3 (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 0594d496 sha1 9c3f18112c126ca08403408a844a3a83967eb4dc flags verified ) +) + game ( name "Sonic Battle (Japan) (En,Ja)" description "Sonic Battle (Japan) (En,Ja)" @@ -16473,7 +16803,7 @@ game ( game ( name "Sonic Battle (USA) (En,Ja,Fr,De,Es,It)" description "Sonic Battle (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Battle (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 9ec9d86f sha1 8cf4fbbe73f6b1907ab9997caab4c4e7d9708937 ) + rom ( name "Sonic Battle (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 9ec9d86f sha1 8cf4fbbe73f6b1907ab9997caab4c4e7d9708937 flags verified ) ) game ( @@ -16662,18 +16992,18 @@ game ( rom ( name "Spider-Man 3 (USA) (Unl).gba" size 33554432 crc 3e1b693a sha1 54d22c0fe81e78380fc2d839aa800f36fc1ef311 ) ) -game ( - name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" - description "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" - rom ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta).gba" size 4183576 crc caaaefb6 sha1 53c4bb950d9b92918f26aeb7b0105604d0263ba1 ) -) - game ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany)" description "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany)" rom ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany).gba" size 4194304 crc 4785eee0 sha1 ce8f271e143456616a9649fee7d47ef1602ee497 ) ) +game ( + name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" + description "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" + rom ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta).gba" size 4183576 crc caaaefb6 sha1 53c4bb950d9b92918f26aeb7b0105604d0263ba1 ) +) + game ( name "Spirit - L'Etalon des Plaines - A la Recherche de la Terre Natale (France)" description "Spirit - L'Etalon des Plaines - A la Recherche de la Terre Natale (France)" @@ -17220,6 +17550,12 @@ game ( rom ( name "Street Racing Syndicate (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc ac24888b sha1 0536c9d6b0732337eaa6764d918f3b314b96c063 ) ) +game ( + name "Strike Force Hydra (Europe)" + description "Strike Force Hydra (Europe)" + rom ( name "Strike Force Hydra (Europe).gba" size 4194304 crc 277d2c89 sha1 4203315be9e7ce1801cddf294cd18e98c9c9e8b0 ) +) + game ( name "Strike Force Hydra (USA)" description "Strike Force Hydra (USA)" @@ -17227,9 +17563,9 @@ game ( ) game ( - name "Strike Force Hydra (Europe)" - description "Strike Force Hydra (Europe)" - rom ( name "Strike Force Hydra (Europe).gba" size 4194304 crc 277d2c89 sha1 4203315be9e7ce1801cddf294cd18e98c9c9e8b0 ) + name "Stuart Little 2 (Europe) (Rev 1)" + description "Stuart Little 2 (Europe) (Rev 1)" + rom ( name "Stuart Little 2 (Europe) (Rev 1).gba" size 8388608 crc 34e4f8c5 sha1 1435574b92777a633cec0722300601dcbb5f84ce ) ) game ( @@ -17244,12 +17580,6 @@ game ( rom ( name "Stuart Little 2 (France).gba" size 8388608 crc 0827d896 sha1 59ab956ef920bdf2a75b36448f557df8538d558a ) ) -game ( - name "Stuart Little 2 (Europe) (Rev 1)" - description "Stuart Little 2 (Europe) (Rev 1)" - rom ( name "Stuart Little 2 (Europe) (Rev 1).gba" size 8388608 crc 34e4f8c5 sha1 1435574b92777a633cec0722300601dcbb5f84ce ) -) - game ( name "Stuntman (Europe) (En,Fr,De,Es,It)" description "Stuntman (Europe) (En,Fr,De,Es,It)" @@ -17814,6 +18144,12 @@ game ( rom ( name "Superman Returns - Fortress of Solitude (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 68215047 sha1 1ff9d19032466227ae7aaebb0161c531aaf60428 ) ) +game ( + name "Superman Returns - Fortress of Solitude (USA, Europe) (Beta)" + description "Superman Returns - Fortress of Solitude (USA, Europe) (Beta)" + rom ( name "Superman Returns - Fortress of Solitude (USA, Europe) (Beta).gba" size 16777216 crc a0fb8e93 sha1 fd4585fc39ef54e1eb901e463d8e6d45ab40fccf ) +) + game ( name "Surf's Up (USA) (En,Fr,Es)" description "Surf's Up (USA) (En,Fr,Es)" @@ -17832,6 +18168,12 @@ game ( rom ( name "Surf's Up (Europe) (En,Fr,Es).gba" size 8388608 crc 317326b0 sha1 b0a2ba2a7d042cc9426ec1abdbd912613c4ae191 ) ) +game ( + name "Sushi the Cat (World) (Aftermarket) (Unl)" + description "Sushi the Cat (World) (Aftermarket) (Unl)" + rom ( name "Sushi the Cat (World) (Aftermarket) (Unl).gba" size 540296 crc 6f019a88 sha1 f6d523a073c21639e15d615947167bba3871c67a ) +) + game ( name "Sutakomi - Star Communicator (Japan)" description "Sutakomi - Star Communicator (Japan)" @@ -17844,12 +18186,6 @@ game ( rom ( name "Sweet Cookie Pie (Japan).gba" size 4194304 crc 63f45849 sha1 96610003fdb49a14b35aeedf0c8cebf5f80d8e4a ) ) -game ( - name "Sword of Mana (Europe)" - description "Sword of Mana (Europe)" - rom ( name "Sword of Mana (Europe).gba" size 16777216 crc 88e64a8a sha1 129712ce98646c89136cee01902dd20ef6541978 flags verified ) -) - game ( name "Sword of Mana (USA, Australia)" description "Sword of Mana (USA, Australia)" @@ -17868,6 +18204,12 @@ game ( rom ( name "Sword of Mana (Europe) (Es,It).gba" size 16777216 crc 11a0af49 sha1 390dff3ec37d24a5d00165deb17eb64c0ace32b1 ) ) +game ( + name "Sword of Mana (Europe)" + description "Sword of Mana (Europe)" + rom ( name "Sword of Mana (Europe).gba" size 16777216 crc 88e64a8a sha1 129712ce98646c89136cee01902dd20ef6541978 flags verified ) +) + game ( name "Sylvanian Families - Fashion Designer ni Naritai! - Kurumi-risu no Onnanoko (Japan)" description "Sylvanian Families - Fashion Designer ni Naritai! - Kurumi-risu no Onnanoko (Japan)" @@ -18096,12 +18438,6 @@ game ( rom ( name "Teenage Mutant Ninja Turtles Double Pack (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 176a42e5 sha1 15cbff45ce0cb35f3e6a6059ada2710f0cec05c3 ) ) -game ( - name "Tekken Advance (Europe)" - description "Tekken Advance (Europe)" - rom ( name "Tekken Advance (Europe).gba" size 8388608 crc 4628c1b8 sha1 0a8665fe4e1f33427f710793db2937485a1c9418 flags verified ) -) - game ( name "Tekken Advance (Japan)" description "Tekken Advance (Japan)" @@ -18114,6 +18450,12 @@ game ( rom ( name "Tekken Advance (USA).gba" size 8388608 crc c59ea73b sha1 8b21cd57cacf172f963dfc7ead4fa127a8a63870 ) ) +game ( + name "Tekken Advance (Europe)" + description "Tekken Advance (Europe)" + rom ( name "Tekken Advance (Europe).gba" size 8388608 crc 4628c1b8 sha1 0a8665fe4e1f33427f710793db2937485a1c9418 flags verified ) +) + game ( name "Ten Pin Alley 2 (USA)" description "Ten Pin Alley 2 (USA)" @@ -18180,6 +18522,12 @@ game ( rom ( name "Tetris Worlds (Europe) (En,Es,It).gba" size 4194304 crc 4a834fc2 sha1 2de4d4c3d239b2e56ad4cc3000bb1ad2fdddd987 ) ) +game ( + name "Tetris Worlds (Japan) (Rev 1)" + description "Tetris Worlds (Japan) (Rev 1)" + rom ( name "Tetris Worlds (Japan) (Rev 1).gba" size 4194304 crc fcf2d471 sha1 be44036e39f95fb9feb93630720d46570ba1a42f ) +) + game ( name "Tetris Worlds (USA)" description "Tetris Worlds (USA)" @@ -18199,9 +18547,9 @@ game ( ) game ( - name "Tetris Worlds (Japan) (Rev 1)" - description "Tetris Worlds (Japan) (Rev 1)" - rom ( name "Tetris Worlds (Japan) (Rev 1).gba" size 4194304 crc fcf2d471 sha1 be44036e39f95fb9feb93630720d46570ba1a42f ) + name "Texas Hold 'em Poker (USA)" + description "Texas Hold 'em Poker (USA)" + rom ( name "Texas Hold 'em Poker (USA).gba" size 4194304 crc 78b59aac sha1 5fcc9958210d8bde94a429516b15ca669427fe6d ) ) game ( @@ -18210,12 +18558,6 @@ game ( rom ( name "Texas Hold 'em Poker (Europe) (Rev 1).gba" size 4194304 crc 1a13df6b sha1 f6d018d9174bf04fd8c90b3173570391f2d11b19 ) ) -game ( - name "Texas Hold 'em Poker (USA)" - description "Texas Hold 'em Poker (USA)" - rom ( name "Texas Hold 'em Poker (USA).gba" size 4194304 crc 78b59aac sha1 5fcc9958210d8bde94a429516b15ca669427fe6d ) -) - game ( name "TG Rally (Europe)" description "TG Rally (Europe)" @@ -18324,36 +18666,36 @@ game ( rom ( name "Tiny Toon Adventures - Scary Dreams (USA).gba" size 4194304 crc fcd7a7c0 sha1 305c6cf66e47508deee4b9fc12c8917302f2ed39 ) ) -game ( - name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" - description "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" - rom ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4ac770b6 sha1 cd9d810b29070d9f37df219bfd7e52ce9d52d2b0 ) -) - game ( name "Tiny Toon Adventures - Wacky Stackers (USA)" description "Tiny Toon Adventures - Wacky Stackers (USA)" rom ( name "Tiny Toon Adventures - Wacky Stackers (USA).gba" size 4194304 crc e03c633e sha1 fd9d10006bd29945ac16c6f88608a27e15f8f7da ) ) +game ( + name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" + description "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" + rom ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4ac770b6 sha1 cd9d810b29070d9f37df219bfd7e52ce9d52d2b0 ) +) + game ( name "Tir et But - Edition Champions du Monde (France)" description "Tir et But - Edition Champions du Monde (France)" rom ( name "Tir et But - Edition Champions du Monde (France).gba" size 4194304 crc 7782a204 sha1 e097aa37ab67146d544ae1438a19f8cd9e3a8f7c ) ) -game ( - name "Titeuf - Mega Compet (France)" - description "Titeuf - Mega Compet (France)" - rom ( name "Titeuf - Mega Compet (France).gba" size 4194304 crc ffd0a045 sha1 ff59a9810adc3270295763282c9d86d549f58a6f ) -) - game ( name "Titeuf - Mega Compet (France) (Beta)" description "Titeuf - Mega Compet (France) (Beta)" rom ( name "Titeuf - Mega Compet (France) (Beta).gba" size 4194304 crc c9be7fcf sha1 1ed43c7419b22b1147bd7e3198de52f4c8d3003d ) ) +game ( + name "Titeuf - Mega Compet (France)" + description "Titeuf - Mega Compet (France)" + rom ( name "Titeuf - Mega Compet (France).gba" size 4194304 crc ffd0a045 sha1 ff59a9810adc3270295763282c9d86d549f58a6f ) +) + game ( name "Titeuf - Ze Gag Machine (France)" description "Titeuf - Ze Gag Machine (France)" @@ -18462,18 +18804,18 @@ game ( rom ( name "Tom Clancy's Splinter Cell (USA) (En,Fr,Es).gba" size 8388608 crc 308ba69c sha1 dbd089cbdd79c26b2f0b651f74df59b6cbfafbcb ) ) -game ( - name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl)" - description "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7ecd29ce sha1 d623cbd1019665eee78846a2a60d17adaf8ec0fe flags verified ) -) - game ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl) (Beta)" description "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl) (Beta)" rom ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 16777216 crc e07ba799 sha1 3a55f6ed66a3ec7c019221fa2660e2f85954ebae ) ) +game ( + name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl)" + description "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7ecd29ce sha1 d623cbd1019665eee78846a2a60d17adaf8ec0fe flags verified ) +) + game ( name "Tom Clancy's Splinter Cell - Pandora Tomorrow (Europe) (En,Fr,De,Es,It,Nl)" description "Tom Clancy's Splinter Cell - Pandora Tomorrow (Europe) (En,Fr,De,Es,It,Nl)" @@ -18567,7 +18909,7 @@ game ( game ( name "Tony Hawk's Pro Skater 3 (France)" description "Tony Hawk's Pro Skater 3 (France)" - rom ( name "Tony Hawk's Pro Skater 3 (France).gba" size 8388608 crc 8d132067 sha1 62ba6f28f5bbd8fe42ecabecdcff4d6b96ae4f21 ) + rom ( name "Tony Hawk's Pro Skater 3 (France).gba" size 8388608 crc 8d132067 sha1 62ba6f28f5bbd8fe42ecabecdcff4d6b96ae4f21 flags verified ) ) game ( @@ -18708,6 +19050,12 @@ game ( rom ( name "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 7cd6839c sha1 ace1d3587636d17fd9ebfe7a7cfd3ee36bc51b43 flags verified ) ) +game ( + name "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan) (Beta) (2002-05-29)" + description "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan) (Beta) (2002-05-29)" + rom ( name "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan) (Beta) (2002-05-29).gba" size 8388608 crc 782e25ae sha1 3f1a1448db7a48fe99428bb94b7b04382fd67aad ) +) + game ( name "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan)" description "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan)" @@ -18756,6 +19104,12 @@ game ( rom ( name "Travis Pastrana's Pro MotoX (USA) (Proto) (2002-12-12).gba" size 4194304 crc ecfe5f96 sha1 64e356f495fd58a862f272124798ecf61e20cfb7 ) ) +game ( + name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" + description "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" + rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc 794b2602 sha1 c703edaee8a2bad09c2298e2c92a14d459fe664a ) +) + game ( name "Treasure Planet (USA)" description "Treasure Planet (USA)" @@ -18769,33 +19123,33 @@ game ( ) game ( - name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" - description "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" - rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc 794b2602 sha1 c703edaee8a2bad09c2298e2c92a14d459fe664a ) + name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl).gba" size 16239516 crc ce85ba07 sha1 b09b600bfc222c2d92829d8883feab700b013953 ) ) game ( - name "Tremblay Island (World) (En) (v.1.10) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v.1.10) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v.1.10) (Aftermarket) (Unl).gba" size 16239516 crc ce85ba07 sha1 b09b600bfc222c2d92829d8883feab700b013953 ) + name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16229600 crc bd57344d sha1 a2fcfe94c9b8b0feff31c1245c8b033222c9f668 ) ) game ( - name "Tremblay Island (World) (En) (v.1.10) (Solid State Version) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v.1.10) (Solid State Version) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v.1.10) (Solid State Version) (Aftermarket) (Unl).gba" size 16229600 crc bd57344d sha1 a2fcfe94c9b8b0feff31c1245c8b033222c9f668 ) + name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + description "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16204024 crc fa43669e sha1 a57392fa7cee61913b20a840fe8b2ee27f11d808 ) ) game ( - name "Tremblay Island (World) (Fr) (v.1.10) (Solid State Version) (Aftermarket) (Unl)" - description "Tremblay Island (World) (Fr) (v.1.10) (Solid State Version) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (Fr) (v.1.10) (Solid State Version) (Aftermarket) (Unl).gba" size 16204024 crc fa43669e sha1 a57392fa7cee61913b20a840fe8b2ee27f11d808 ) + name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl).gba" size 16777216 crc ff5d64ab sha1 645ab8d4dacb6666d8eb549d491f77d8cd63ce97 ) ) game ( - name "Tremblay Island (World) (En) (Kickstarter Edition) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (Kickstarter Edition) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (Kickstarter Edition) (Aftermarket) (Unl).gba" size 16777216 crc ff5d64ab sha1 645ab8d4dacb6666d8eb549d491f77d8cd63ce97 ) + name "Tremblay Island (World) (Aftermarket) (Unl)" + description "Tremblay Island (World) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (Aftermarket) (Unl).gba" size 16225608 crc 95503690 sha1 634ea6be3df5ebd85c9c60871e34fc3c72ae5140 ) ) game ( @@ -19302,6 +19656,12 @@ game ( rom ( name "Wagamama Fairy Mirumo de Pon! - Yume no Kakera (Japan).gba" size 8388608 crc a606c803 sha1 0429693de0ff6e020b01807047dbb07b70b42529 ) ) +game ( + name "Waimanu - Grinding Blocks Adventure (World) (Homebrew)" + description "Waimanu - Grinding Blocks Adventure (World) (Homebrew)" + rom ( name "Waimanu - Grinding Blocks Adventure (World) (Homebrew).gba" size 1739504 crc 0fe153c5 sha1 c4ce156b04fb257875bc5f539f3d64accbc08451 ) +) + game ( name "Wakeboarding Unleashed Featuring Shaun Murray (Europe)" description "Wakeboarding Unleashed Featuring Shaun Murray (Europe)" @@ -19356,12 +19716,6 @@ game ( rom ( name "Wanwan Meitantei (Japan).gba" size 8388608 crc 5f41c9fe sha1 d438e3b030a814818ed7e96777ac3e46043922f9 ) ) -game ( - name "Wario Land 4 (USA, Europe) (Virtual Console)" - description "Wario Land 4 (USA, Europe) (Virtual Console)" - rom ( name "Wario Land 4 (USA, Europe) (Virtual Console).gba" size 8388608 crc 8bb73d8a sha1 ed643151b8cc9749a490cab6bae26104e1652089 flags verified ) -) - game ( name "Wario Land 4 (USA, Europe)" description "Wario Land 4 (USA, Europe)" @@ -19369,9 +19723,9 @@ game ( ) game ( - name "Wario Land Advance - Youki no Otakara (Japan)" - description "Wario Land Advance - Youki no Otakara (Japan)" - rom ( name "Wario Land Advance - Youki no Otakara (Japan).gba" size 8388608 crc f56ebb7a sha1 a01de1f2e69ec8aa9715ed0d0fbb263372b71e12 flags verified ) + name "Wario Land 4 (USA, Europe) (Virtual Console)" + description "Wario Land 4 (USA, Europe) (Virtual Console)" + rom ( name "Wario Land 4 (USA, Europe) (Virtual Console).gba" size 8388608 crc 8bb73d8a sha1 ed643151b8cc9749a490cab6bae26104e1652089 flags verified ) ) game ( @@ -19380,12 +19734,24 @@ game ( rom ( name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console).gba" size 8388608 crc a8cd90f9 sha1 2d3e6b124c84877520b482ba1016b8e3c36bab14 ) ) +game ( + name "Wario Land Advance - Youki no Otakara (Japan)" + description "Wario Land Advance - Youki no Otakara (Japan)" + rom ( name "Wario Land Advance - Youki no Otakara (Japan).gba" size 8388608 crc f56ebb7a sha1 a01de1f2e69ec8aa9715ed0d0fbb263372b71e12 flags verified ) +) + game ( name "WarioWare - Twisted! (USA, Australia)" description "WarioWare - Twisted! (USA, Australia)" rom ( name "WarioWare - Twisted! (USA, Australia).gba" size 16777216 crc cb4e844b sha1 f0102d0d6f7596fe853d5d0a94682718278e083a flags verified ) ) +game ( + name "WarioWare, Inc. - Mega Microgame$! (USA)" + description "WarioWare, Inc. - Mega Microgame$! (USA)" + rom ( name "WarioWare, Inc. - Mega Microgame$! (USA).gba" size 8388608 crc 785d8b8c sha1 3f556448d290fa5406d6ed367fee16cc02387ad3 flags verified ) +) + game ( name "WarioWare, Inc. - Mega Microgame$! (USA) (Beta)" description "WarioWare, Inc. - Mega Microgame$! (USA) (Beta)" @@ -19399,9 +19765,9 @@ game ( ) game ( - name "WarioWare, Inc. - Mega Microgame$! (USA)" - description "WarioWare, Inc. - Mega Microgame$! (USA)" - rom ( name "WarioWare, Inc. - Mega Microgame$! (USA).gba" size 8388608 crc 785d8b8c sha1 3f556448d290fa5406d6ed367fee16cc02387ad3 flags verified ) + name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" + description "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" + rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc 1fe34e43 sha1 dca921c60b3686be6b3a5feeec7a4f37a921aee3 ) ) game ( @@ -19410,12 +19776,6 @@ game ( rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 500ca178 sha1 aad81e722aa88f98913c0354e559f845c4689cce flags verified ) ) -game ( - name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" - description "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" - rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc 1fe34e43 sha1 dca921c60b3686be6b3a5feeec7a4f37a921aee3 ) -) - game ( name "Weekend Miljonairs (Netherlands)" description "Weekend Miljonairs (Netherlands)" @@ -19548,18 +19908,18 @@ game ( rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 2).gba" size 4194304 crc 9fb4af0a sha1 9151cf54475c4f773bdd9ab86a42d3e1ba462afa ) ) -game ( - name "Winning Post for Game Boy Advance (Japan) (Rev 1)" - description "Winning Post for Game Boy Advance (Japan) (Rev 1)" - rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 1).gba" size 4194304 crc f6180af5 sha1 0f395a384b9db2415196edc2f911ccc67eb5e038 ) -) - game ( name "Winning Post for Game Boy Advance (Japan)" description "Winning Post for Game Boy Advance (Japan)" rom ( name "Winning Post for Game Boy Advance (Japan).gba" size 4194304 crc 5ada60f6 sha1 cc7e9c2a9e1df985aed3dc4a018c93140d7a1b2c ) ) +game ( + name "Winning Post for Game Boy Advance (Japan) (Rev 1)" + description "Winning Post for Game Boy Advance (Japan) (Rev 1)" + rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 1).gba" size 4194304 crc f6180af5 sha1 0f395a384b9db2415196edc2f911ccc67eb5e038 ) +) + game ( name "Winter Sports (Europe) (En,Fr,De,Es,It)" description "Winter Sports (Europe) (En,Fr,De,Es,It)" @@ -19591,9 +19951,15 @@ game ( ) game ( - name "Wizardry Summoner (Japan)" - description "Wizardry Summoner (Japan)" - rom ( name "Wizardry Summoner (Japan).gba" size 4194304 crc 71695a71 sha1 c9ba4742d494d61a215f6e8068fdaeed12d19cdc ) + name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" + description "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" + rom ( name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl).gba" size 1449956 crc 4ffa611d sha1 89bbeb3fbce1533acf2f2113642ebe2a4f9f79a8 ) +) + +game ( + name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" + description "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" + rom ( name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl).gba" size 1449956 crc 27055186 sha1 b9ce91d55870e07434509f6e2e91c2f90b4afc97 ) ) game ( @@ -19602,6 +19968,12 @@ game ( rom ( name "Wizardry Summoner (Japan) (Rev 1).gba" size 4194304 crc b3c77a61 sha1 c4ddb35319b8ed0f2e3d281ad93e42a0db757cd5 flags verified ) ) +game ( + name "Wizardry Summoner (Japan)" + description "Wizardry Summoner (Japan)" + rom ( name "Wizardry Summoner (Japan).gba" size 4194304 crc 71695a71 sha1 c9ba4742d494d61a215f6e8068fdaeed12d19cdc ) +) + game ( name "Wolfenstein 3D (USA, Europe)" description "Wolfenstein 3D (USA, Europe)" @@ -19674,12 +20046,6 @@ game ( rom ( name "World Reborn (USA) (Aftermarket) (Unl).gba" size 4194304 crc eefb32ff sha1 c7ec2f8d7d3dec40a893cdfe2a41a8ed43ed71c4 ) ) -game ( - name "World Tennis Stars (Europe)" - description "World Tennis Stars (Europe)" - rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc b5830f5f sha1 2a93449943e85b7c5d75d0d7a9e1d8ad67c7a706 ) -) - game ( name "World Tennis Stars (USA)" description "World Tennis Stars (USA)" @@ -19687,9 +20053,9 @@ game ( ) game ( - name "Worms - World Party (USA) (En,Fr,De,Es,It)" - description "Worms - World Party (USA) (En,Fr,De,Es,It)" - rom ( name "Worms - World Party (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e8789c18 sha1 7b078976d9056aba7f81bb1ff33e5a36357f5f0b ) + name "World Tennis Stars (Europe)" + description "World Tennis Stars (Europe)" + rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc b5830f5f sha1 2a93449943e85b7c5d75d0d7a9e1d8ad67c7a706 ) ) game ( @@ -19698,6 +20064,12 @@ game ( rom ( name "Worms - World Party (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8ee32cbe sha1 5e0abe3d94d1489fadebe897df1ed5a5c0212901 ) ) +game ( + name "Worms - World Party (USA) (En,Fr,De,Es,It)" + description "Worms - World Party (USA) (En,Fr,De,Es,It)" + rom ( name "Worms - World Party (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e8789c18 sha1 7b078976d9056aba7f81bb1ff33e5a36357f5f0b ) +) + game ( name "Worms Blast (Europe) (En,Fr,De,Es,It)" description "Worms Blast (Europe) (En,Fr,De,Es,It)" @@ -19728,36 +20100,36 @@ game ( rom ( name "WWE - Survivor Series (USA, Europe).gba" size 4194304 crc 6694f94d sha1 bb61e289f2a09e7ce0e193267430dbc6f5583a49 flags verified ) ) -game ( - name "WWF - Road to WrestleMania (USA, Europe) (Beta)" - description "WWF - Road to WrestleMania (USA, Europe) (Beta)" - rom ( name "WWF - Road to WrestleMania (USA, Europe) (Beta).gba" size 4194304 crc 8314421b sha1 13c1965b62849873738417830e142182782430fe ) -) - game ( name "WWF - Road to WrestleMania (USA, Europe)" description "WWF - Road to WrestleMania (USA, Europe)" rom ( name "WWF - Road to WrestleMania (USA, Europe).gba" size 4194304 crc 8d3b116e sha1 e9334fd4b7a8acf2256a8e2e97f0ab3dd91d6abb ) ) +game ( + name "WWF - Road to WrestleMania (USA, Europe) (Beta)" + description "WWF - Road to WrestleMania (USA, Europe) (Beta)" + rom ( name "WWF - Road to WrestleMania (USA, Europe) (Beta).gba" size 4194304 crc 8314421b sha1 13c1965b62849873738417830e142182782430fe ) +) + game ( name "X Zhan Jing (Taiwan) (Unl)" description "X Zhan Jing (Taiwan) (Unl)" rom ( name "X Zhan Jing (Taiwan) (Unl).gba" size 33554432 crc 652a2ebe sha1 a35c891af070819fd14e0704984197c8e04ae127 ) ) -game ( - name "X-Bladez - Inline Skater (Europe)" - description "X-Bladez - Inline Skater (Europe)" - rom ( name "X-Bladez - Inline Skater (Europe).gba" size 4194304 crc c05f9907 sha1 8a5dc506fd6e000116be2ca923a056bc15d5b553 ) -) - game ( name "X-Bladez - Inline Skater (USA)" description "X-Bladez - Inline Skater (USA)" rom ( name "X-Bladez - Inline Skater (USA).gba" size 4194304 crc 09fdd665 sha1 a8354a51738c6b28660ab74acc7f8445a9a570a1 ) ) +game ( + name "X-Bladez - Inline Skater (Europe)" + description "X-Bladez - Inline Skater (Europe)" + rom ( name "X-Bladez - Inline Skater (Europe).gba" size 4194304 crc c05f9907 sha1 8a5dc506fd6e000116be2ca923a056bc15d5b553 ) +) + game ( name "X-Man - Armour of Might (Russia) (Unl)" description "X-Man - Armour of Might (Russia) (Unl)" @@ -19944,6 +20316,12 @@ game ( rom ( name "Yu-Gi-Oh! - Destiny Board Traveler (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ae1a8e9d sha1 96fd0e583ab49258b194f578e29e9a5d55122b50 ) ) +game ( + name "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It)" + description "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It)" + rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ee317f69 sha1 3ded1227698fbdb2ba47f03025cd1934fc184b99 flags verified ) +) + game ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Japan)" description "Yu-Gi-Oh! - Dungeon Dice Monsters (Japan)" @@ -19956,12 +20334,6 @@ game ( rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (USA) (En,Es).gba" size 8388608 crc 8b5e0a27 sha1 fdd69455a072b2f74e6c5c50b96daa0438156b27 flags verified ) ) -game ( - name "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It)" - description "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ee317f69 sha1 3ded1227698fbdb2ba47f03025cd1934fc184b99 flags verified ) -) - game ( name "Yu-Gi-Oh! - Reshef of Destruction (USA)" description "Yu-Gi-Oh! - Reshef of Destruction (USA)" @@ -20115,7 +20487,7 @@ game ( game ( name "Yu-Gi-Oh! GX - Duel Academy (USA)" description "Yu-Gi-Oh! GX - Duel Academy (USA)" - rom ( name "Yu-Gi-Oh! GX - Duel Academy (USA).gba" size 33554432 crc 3b8a00fe sha1 57d6bb789833b62b360072902982d5f1011b3640 ) + rom ( name "Yu-Gi-Oh! GX - Duel Academy (USA).gba" size 33554432 crc 3b8a00fe sha1 57d6bb789833b62b360072902982d5f1011b3640 flags verified ) ) game ( @@ -20292,18 +20664,18 @@ game ( rom ( name "Zoids Saga II (Japan).gba" size 8388608 crc 0c039503 sha1 6014ca7c7af931d62634be4baa992a2fe187413f ) ) -game ( - name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)" - description "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)" - rom ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan).gba" size 16777216 crc 2804e589 sha1 54a4dcdeca2ee9a22559eb104b88586386639097 ) -) - game ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan) (Rev 1)" description "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan) (Rev 1)" rom ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan) (Rev 1).gba" size 16777216 crc 71e2cd01 sha1 1a81843c3070decea4cbca20c4563541400b2437 ) ) +game ( + name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)" + description "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)" + rom ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan).gba" size 16777216 crc 2804e589 sha1 54a4dcdeca2ee9a22559eb104b88586386639097 ) +) + game ( name "Zone of the Enders - The Fist of Mars (USA)" description "Zone of the Enders - The Fist of Mars (USA)" @@ -20939,7 +21311,7 @@ game ( clrmamepro ( name "Nintendo - Game Boy Advance (Video)" description "Nintendo - Game Boy Advance (Video)" - version 20230301-094141 + version 20230804-201325 author "BigFred, C. V. Reynolds, DeadSkullzJr, Hiccup, kazumi213, omonim2007, relax, SonGoku, xuom2" homepage No-Intro url "https://www.no-intro.org" @@ -20992,6 +21364,12 @@ game ( rom ( name "Game Boy Advance Video - Cartoon Network Collection - Premium Edition (USA, Europe).gba" size 33554432 crc f2825729 sha1 d0fe380fcdf5b1bb99188ed95c8c3272cbb65ce8 flags verified ) ) +game ( + name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" + description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5).gba" size 33554432 crc 1baf372d sha1 86f257c7b8d8feaee0a7e7dd5f5ba48053fd633e flags verified ) +) + game ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe)" @@ -21055,7 +21433,7 @@ game ( game ( name "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA)" description "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA)" - rom ( name "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA).gba" size 33554432 crc 65deeeb6 sha1 03a767124f034b1eea51ab84ba6e80ec76f7f50c ) + rom ( name "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA).gba" size 33554432 crc 65deeeb6 sha1 03a767124f034b1eea51ab84ba6e80ec76f7f50c flags verified ) ) game ( @@ -21082,18 +21460,18 @@ game ( rom ( name "Game Boy Advance Video - Pokemon - Volume 4 (USA).gba" size 33554432 crc be468496 sha1 fd79b821ff601e0091f19ab9c86b08f1c39ea2f3 ) ) -game ( - name "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" - description "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" - rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 6).gba" size 67108864 crc d2cf417a sha1 9bc5b60793b8a6de3b80eb2c213cd125e1fa468e flags verified ) -) - game ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" description "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 5).gba" size 67108864 crc 01468820 sha1 6128a476edb10e6839ac5bd2697e83b9b7a9b234 ) ) +game ( + name "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" + description "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" + rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 6).gba" size 67108864 crc d2cf417a sha1 9bc5b60793b8a6de3b80eb2c213cd125e1fa468e flags verified ) +) + game ( name "Game Boy Advance Video - Shrek (USA) (Rev 5)" description "Game Boy Advance Video - Shrek (USA) (Rev 5)" @@ -21112,18 +21490,18 @@ game ( rom ( name "Game Boy Advance Video - Shrek + Shark Tale (USA) (Rev 5).gba" size 67108864 crc aadb3e3d sha1 f23390b7a62c605fbce6730addc29d381488e076 flags verified ) ) -game ( - name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" - description "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" - rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5).gba" size 67108864 crc 0d353654 sha1 5cd627e205020297b25d707131883be5850515fe flags verified ) -) - game ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" description "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6).gba" size 67108864 crc 925b6c02 sha1 3bcb4acc5da539bc1b91c9537bf7ffa081ded1d4 ) ) +game ( + name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" + description "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5).gba" size 67108864 crc 0d353654 sha1 5cd627e205020297b25d707131883be5850515fe flags verified ) +) + game ( name "Game Boy Advance Video - Sonic X - Volume 1 (USA)" description "Game Boy Advance Video - Sonic X - Volume 1 (USA)" @@ -21211,8 +21589,8 @@ game ( clrmamepro ( name "Nintendo - Game Boy" description "Nintendo - Game Boy" - version 20230422-225330 - author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, jimmsu, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xuom2" + version 20240106-192522 + author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Psychofox11, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xprism, xuom2" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -21253,21 +21631,9 @@ game ( ) game ( - name "2097 ROM Pack II (USA) (Test Program)" - description "2097 ROM Pack II (USA) (Test Program)" - rom ( name "2097 ROM Pack II (USA) (Test Program).gb" size 32768 crc 0a9ab6e7 sha1 68968d1b1fc84b2381159c0938675d2048c57ee2 ) -) - -game ( - name "2420 ROM Pack V (USA) (Test Program)" - description "2420 ROM Pack V (USA) (Test Program)" - rom ( name "2420 ROM Pack V (USA) (Test Program).gb" size 32768 crc 97561d80 sha1 a55a5fd97ca1be3fa129f744f81fc972e29418ac ) -) - -game ( - name "2440 ROM Pack (USA) (Test Program)" - description "2440 ROM Pack (USA) (Test Program)" - rom ( name "2440 ROM Pack (USA) (Test Program).gb" size 32768 crc 7a9359ea sha1 c15325e2e0ad2c8bd4323ef2390df28e578dcdb8 ) + name "14 Juillet (World) (Fr) (Aftermarket) (Unl)" + description "14 Juillet (World) (Fr) (Aftermarket) (Unl)" + rom ( name "14 Juillet (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 7b66bee4 sha1 02f387457a779cbd2f493e52743cd32c169c098e ) ) game ( @@ -21405,13 +21771,7 @@ game ( game ( name "Adulting! (World) (v2.0) (Aftermarket) (Unl)" description "Adulting! (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Adulting! (World) (v2.0) (Aftermarket) (Unl).gb" size 524288 crc e56d1244 sha1 d107bd8bf32d0d94a988466885fe1a44aae32c9a ) -) - -game ( - name "Adulting! Soundtrack (World) (Aftermarket) (Unl)" - description "Adulting! Soundtrack (World) (Aftermarket) (Unl)" - rom ( name "Adulting! Soundtrack (World) (Aftermarket) (Unl).gb" size 131072 crc 1b5b9e64 sha1 c5dad32be800c36814a0f9b940e99b5eada34150 ) + rom ( name "Adulting! (World) (v2.0) (Aftermarket) (Unl).gb" size 524288 crc e56d1244 sha1 d107bd8bf32d0d94a988466885fe1a44aae32c9a flags verified ) ) game ( @@ -21576,12 +21936,6 @@ game ( rom ( name "Alien vs Predator - The Last of His Clan (USA).gb" size 131072 crc 4bbcf652 sha1 c0d39ee87b908cdbd68c59f73e5dc2a7a6ccbedc ) ) -game ( - name "All Humans Must Die! (World) (Aftermarket) (Unl)" - description "All Humans Must Die! (World) (Aftermarket) (Unl)" - rom ( name "All Humans Must Die! (World) (Aftermarket) (Unl).gb" size 524288 crc b4d50eed sha1 f4513fc525cbcfa4a2804b55ce20c809e01d1c87 ) -) - game ( name "All-Star Baseball 99 (USA)" description "All-Star Baseball 99 (USA)" @@ -21690,12 +22044,6 @@ game ( rom ( name "Animaniacs (USA) (SGB Enhanced).gb" size 262144 crc 673c815d sha1 a0732f81e0c4f1bba592563bdc0eaae9d759ef28 flags verified ) ) -game ( - name "Another Adventure (World) (En,Es) (Aftermarket) (Unl)" - description "Another Adventure (World) (En,Es) (Aftermarket) (Unl)" - rom ( name "Another Adventure (World) (En,Es) (Aftermarket) (Unl).gb" size 1048576 crc dfcd02ef sha1 041473b2381dd9e11b3cbda5858f9841324327af ) -) - game ( name "Another Bible (Japan) (SGB Enhanced)" description "Another Bible (Japan) (SGB Enhanced)" @@ -21769,27 +22117,27 @@ game ( ) game ( - name "Art School Pocket (World) (Aftermarket) (Unl)" - description "Art School Pocket (World) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (Aftermarket) (Unl).gb" size 1048576 crc b4eab528 sha1 c482cfc6ec40b1f33c4ba48ecdc45fef4730b653 ) + name "Art School Pocket (World) (En) (Aftermarket) (Unl)" + description "Art School Pocket (World) (En) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (En) (Aftermarket) (Unl).gb" size 1048576 crc b4eab528 sha1 c482cfc6ec40b1f33c4ba48ecdc45fef4730b653 ) ) game ( - name "Art School Pocket (Spain) (Aftermarket) (Unl)" - description "Art School Pocket (Spain) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (Spain) (Aftermarket) (Unl).gb" size 1048576 crc 240067df sha1 c8a75895c87b11f9493f629c19c54d0c607505bd ) + name "Art School Pocket (World) (Es) (Aftermarket) (Unl)" + description "Art School Pocket (World) (Es) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (Es) (Aftermarket) (Unl).gb" size 1048576 crc 240067df sha1 c8a75895c87b11f9493f629c19c54d0c607505bd ) ) game ( - name "Art School Pocket (France) (Aftermarket) (Unl)" - description "Art School Pocket (France) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (France) (Aftermarket) (Unl).gb" size 1048576 crc 49a5b74d sha1 73ecffaee185eb2caf1db385d04b863676c777fb ) + name "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" + description "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 49a5b74d sha1 73ecffaee185eb2caf1db385d04b863676c777fb ) ) game ( - name "Art School Pocket (Germany) (Aftermarket) (Unl)" - description "Art School Pocket (Germany) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (Germany) (Aftermarket) (Unl).gb" size 1048576 crc 82b73e5b sha1 7772e2b9d5e722e54d19fc6283ccb1fa5d19b641 ) + name "Art School Pocket (World) (De) (Aftermarket) (Unl)" + description "Art School Pocket (World) (De) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (De) (Aftermarket) (Unl).gb" size 1048576 crc 82b73e5b sha1 7772e2b9d5e722e54d19fc6283ccb1fa5d19b641 ) ) game ( @@ -21852,6 +22200,12 @@ game ( rom ( name "Asteroids (USA, Europe) (Beta).gb" size 32768 crc eb31e472 sha1 28f4e2a076bfe5f7a77f695332705ea0085fccfb ) ) +game ( + name "Asteroids Chasers (World) (Aftermarket) (Unl)" + description "Asteroids Chasers (World) (Aftermarket) (Unl)" + rom ( name "Asteroids Chasers (World) (Aftermarket) (Unl).gb" size 131072 crc 58d8b1b8 sha1 f93a4e6788eaf0231a6ca269cca297f0d45ec830 flags verified ) +) + game ( name "Astro Rabby (Japan)" description "Astro Rabby (Japan)" @@ -21865,9 +22219,9 @@ game ( ) game ( - name "Astro-Jump - The Sequel (World) (Aftermarket) (Unl)" - description "Astro-Jump - The Sequel (World) (Aftermarket) (Unl)" - rom ( name "Astro-Jump - The Sequel (World) (Aftermarket) (Unl).gb" size 131072 crc e6a96130 sha1 2cd0ef086c4b89497d9497a17d871a6568a9e2d3 ) + name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc afc128f2 sha1 956be9371990b18e351f2e10848b2ea8bb70c2b7 ) ) game ( @@ -21894,12 +22248,6 @@ game ( rom ( name "Auto Zone (World) (Aftermarket) (Unl).gb" size 524288 crc cee73c14 sha1 3070ec215014633dac5dbbb487aade2e2993c049 ) ) -game ( - name "Autumn With You, An (World) (Aftermarket) (Unl)" - description "Autumn With You, An (World) (Aftermarket) (Unl)" - rom ( name "Autumn With You, An (World) (Aftermarket) (Unl).gb" size 262144 crc eac459fa sha1 68a5520be76c52a4936ad1756ea274667f2ac0e3 ) -) - game ( name "Avenging Spirit (USA, Europe)" description "Avenging Spirit (USA, Europe)" @@ -22029,7 +22377,7 @@ game ( game ( name "Bases Loaded (USA)" description "Bases Loaded (USA)" - rom ( name "Bases Loaded (USA).gb" size 131072 crc d37a2fdf sha1 5220db2e87622648caeacdfb8d4f564c9bf479fc ) + rom ( name "Bases Loaded (USA).gb" size 131072 crc d37a2fdf sha1 5220db2e87622648caeacdfb8d4f564c9bf479fc flags verified ) ) game ( @@ -22212,12 +22560,6 @@ game ( rom ( name "Battletoads-Double Dragon (USA).gb" size 262144 crc a727f9cd sha1 ce68df4dc2d604625164430266017b237b72303d ) ) -game ( - name "Batty Zabella (World) (Aftermarket) (Unl)" - description "Batty Zabella (World) (Aftermarket) (Unl)" - rom ( name "Batty Zabella (World) (Aftermarket) (Unl).gb" size 1048576 crc dfa3c64c sha1 2361d5f87bd525964e61bd39765a6fa843fa4c43 ) -) - game ( name "Beavis and Butt-head (USA, Europe)" description "Beavis and Butt-head (USA, Europe)" @@ -22267,9 +22609,9 @@ game ( ) game ( - name "Bill & Ted's Excellent Portable Adventure - A Bogus Journey! (World) (Aftermarket) (Unl)" - description "Bill & Ted's Excellent Portable Adventure - A Bogus Journey! (World) (Aftermarket) (Unl)" - rom ( name "Bill & Ted's Excellent Portable Adventure - A Bogus Journey! (World) (Aftermarket) (Unl).gb" size 131072 crc 7b5e19ca sha1 c6e606cb5e17f7530a529387ad2fb703a94b205a ) + name "Bill & Ted's Excellent Portable Adventure - A Bogus Journey! (World) (Retro Collection)" + description "Bill & Ted's Excellent Portable Adventure - A Bogus Journey! (World) (Retro Collection)" + rom ( name "Bill & Ted's Excellent Portable Adventure - A Bogus Journey! (World) (Retro Collection).gb" size 131072 crc 7b5e19ca sha1 c6e606cb5e17f7530a529387ad2fb703a94b205a flags verified ) ) game ( @@ -22278,6 +22620,12 @@ game ( rom ( name "Bill Elliott's NASCAR Fast Tracks (USA).gb" size 131072 crc 71cf43ce sha1 ebc2ca8b4503f0b05e00749d693462a54f2f95eb ) ) +game ( + name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" + description "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" + rom ( name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl).gb" size 32768 crc bf922249 sha1 187782720d4f7c0986a0d916b0c7efa2c488612e ) +) + game ( name "Bionic Battler (USA)" description "Bionic Battler (USA)" @@ -22302,6 +22650,12 @@ game ( rom ( name "Bionic Commando (USA).gb" size 262144 crc 41dbb5fb sha1 e0ef47568a017ccdd3dbe0db5d7654822b4e5ce1 ) ) +game ( + name "Birdie Bartender (World) (Aftermarket) (Unl)" + description "Birdie Bartender (World) (Aftermarket) (Unl)" + rom ( name "Birdie Bartender (World) (Aftermarket) (Unl).gb" size 262144 crc 0bf2a1c8 sha1 aa1325fc7160b84745b076de9b976a1b368da50e ) +) + game ( name "Bishoujo Senshi Sailor Moon (Japan)" description "Bishoujo Senshi Sailor Moon (Japan)" @@ -22321,15 +22675,9 @@ game ( ) game ( - name "Black Castle GB (World) (Aftermarket) (Unl)" - description "Black Castle GB (World) (Aftermarket) (Unl)" - rom ( name "Black Castle GB (World) (Aftermarket) (Unl).gb" size 65536 crc 10f577c7 sha1 45d979be572bb820835d2ecd4e990cd1eadbf5a6 ) -) - -game ( - name "Black Tape (World) (Aftermarket) (Unl)" - description "Black Tape (World) (Aftermarket) (Unl)" - rom ( name "Black Tape (World) (Aftermarket) (Unl).gb" size 524288 crc 45c5f990 sha1 ec8c467e955d69b2084805f11a954e0d90855461 ) + name "Black Castle (World) (Aftermarket) (Unl)" + description "Black Castle (World) (Aftermarket) (Unl)" + rom ( name "Black Castle (World) (Aftermarket) (Unl).gb" size 65536 crc 10f577c7 sha1 45d979be572bb820835d2ecd4e990cd1eadbf5a6 ) ) game ( @@ -22434,18 +22782,6 @@ game ( rom ( name "Boggle Plus (USA).gb" size 131072 crc 70c8c799 sha1 d6cf512f7301ccdc2d802f34fbbde2d0ba2cf3cd ) ) -game ( - name "BOING! (World) (Aftermarket) (Unl)" - description "BOING! (World) (Aftermarket) (Unl)" - rom ( name "BOING! (World) (Aftermarket) (Unl).gb" size 2097152 crc 91961796 sha1 09fde4065941784bab4cf8f624a0398049ed4add ) -) - -game ( - name "Bokujou Monogatari GB (Japan) (SGB Enhanced) (NP)" - description "Bokujou Monogatari GB (Japan) (SGB Enhanced) (NP)" - rom ( name "Bokujou Monogatari GB (Japan) (SGB Enhanced) (NP).gb" size 524288 crc 0424df85 sha1 551df2021d0e433e7f07cf881c7b1d534f54f6ad ) -) - game ( name "Bokujou Monogatari GB (Japan) (SGB Enhanced)" description "Bokujou Monogatari GB (Japan) (SGB Enhanced)" @@ -22459,9 +22795,9 @@ game ( ) game ( - name "Bomb Jack (Europe)" - description "Bomb Jack (Europe)" - rom ( name "Bomb Jack (Europe).gb" size 32768 crc 9bd8815e sha1 a2b2799e867777a5a19155ed1f2245630fc03560 ) + name "Bokujou Monogatari GB (Japan) (SGB Enhanced) (NP)" + description "Bokujou Monogatari GB (Japan) (SGB Enhanced) (NP)" + rom ( name "Bokujou Monogatari GB (Japan) (SGB Enhanced) (NP).gb" size 524288 crc 0424df85 sha1 551df2021d0e433e7f07cf881c7b1d534f54f6ad ) ) game ( @@ -22476,6 +22812,12 @@ game ( rom ( name "Bomb Jack (Europe) (Beta 2).gb" size 32768 crc 7ca8e543 sha1 6fc3794149f5e75ad82b4a7d47ad5497e1ee4e6a ) ) +game ( + name "Bomb Jack (Europe)" + description "Bomb Jack (Europe)" + rom ( name "Bomb Jack (Europe).gb" size 32768 crc 9bd8815e sha1 a2b2799e867777a5a19155ed1f2245630fc03560 ) +) + game ( name "Bomber Boy (Japan)" description "Bomber Boy (Japan)" @@ -22549,9 +22891,15 @@ game ( ) game ( - name "Borbo's Quest (World) (Aftermarket) (Unl)" - description "Borbo's Quest (World) (Aftermarket) (Unl)" - rom ( name "Borbo's Quest (World) (Aftermarket) (Unl).gb" size 1048576 crc e92ce3d4 sha1 1ddf864188dfd741ccda0b0715e75e162d212605 ) + name "Bork Paw Kisses (World) (Aftermarket) (Unl)" + description "Bork Paw Kisses (World) (Aftermarket) (Unl)" + rom ( name "Bork Paw Kisses (World) (Aftermarket) (Unl).gb" size 262144 crc c29f0d35 sha1 8f1efe6982d2b4ebc1fbeb3ade68dd9b9aabb7a6 ) +) + +game ( + name "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" + description "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" + rom ( name "Borruga - Neo Pinball (World) (Aftermarket) (Unl).gb" size 32768 crc 2bb55ca5 sha1 269f12091d5ab87362a2cb2cf5484f14bfcbd537 flags verified ) ) game ( @@ -22584,6 +22932,12 @@ game ( rom ( name "Bouncing Ball, The (World) (Aftermarket).gb" size 65536 crc 42ddf53e sha1 5d331f2e66d7d3f4b4b0fcbaf6ab4b1a0147db3e ) ) +game ( + name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" + description "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" + rom ( name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl).gb" size 262144 crc 98222a4a sha1 0bdb8ad04469a329c8cee2fb0c55da35f7752042 ) +) + game ( name "Boxing (Japan)" description "Boxing (Japan)" @@ -22704,6 +23058,12 @@ game ( rom ( name "Bubsy II (USA).gb" size 262144 crc 600a6ad5 sha1 1ac9bf5043caf428994bca3e80158ca697e94c58 ) ) +game ( + name "Bug Bites! (World) (Aftermarket) (Unl)" + description "Bug Bites! (World) (Aftermarket) (Unl)" + rom ( name "Bug Bites! (World) (Aftermarket) (Unl).gb" size 262144 crc bb473d7a sha1 8d601612ac262e4548d8b8f6ac19a04cb92ecfb7 ) +) + game ( name "Bugs Bunny Collection (Japan) (SGB Enhanced)" description "Bugs Bunny Collection (Japan) (SGB Enhanced)" @@ -22821,7 +23181,7 @@ game ( game ( name "Caesars Palace (USA) (Rev 1)" description "Caesars Palace (USA) (Rev 1)" - rom ( name "Caesars Palace (USA) (Rev 1).gb" size 131072 crc 87a9d605 sha1 126e9ef9e975bbbc6303d5d62a379d4dbd404cf0 ) + rom ( name "Caesars Palace (USA) (Rev 1).gb" size 131072 crc 87a9d605 sha1 126e9ef9e975bbbc6303d5d62a379d4dbd404cf0 flags verified ) ) game ( @@ -22926,6 +23286,12 @@ game ( rom ( name "Castle Quest (Europe) (Beta).gb" size 131072 crc 8a5636ea sha1 356c8510b0647e56a558aba9d5dc4cc9d3ccd94c ) ) +game ( + name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 3c492b31 sha1 0861af0039dab4b4f5bce747c6fcd586eced401a ) +) + game ( name "Castlevania - The Adventure (USA) (Castlevania Anniversary Collection)" description "Castlevania - The Adventure (USA) (Castlevania Anniversary Collection)" @@ -22962,12 +23328,6 @@ game ( rom ( name "Castlevania Legends (USA, Europe) (SGB Enhanced).gb" size 262144 crc ad9c17fb sha1 91a8e49bf6eac5fe62ec2cc5e6decbd08ce9b515 flags verified ) ) -game ( - name "Cat Boy's Stellar Journey (World) (Aftermarket) (Unl)" - description "Cat Boy's Stellar Journey (World) (Aftermarket) (Unl)" - rom ( name "Cat Boy's Stellar Journey (World) (Aftermarket) (Unl).gb" size 262144 crc 280937cc sha1 9ec53942f0136076b6468671562764e1ab9dee3b ) -) - game ( name "Catrap (USA)" description "Catrap (USA)" @@ -23034,6 +23394,12 @@ game ( rom ( name "Chase H.Q. (USA, Europe).gb" size 131072 crc 67a45d19 sha1 cbcd6254b1b0227ba6aa8d95c979abb7fe8e4d38 flags verified ) ) +game ( + name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" + description "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 3e20c1a8 sha1 f76645a2830fcc733b7392a52112df628f0b7a4a ) +) + game ( name "Cherry Rescue! (World) (Aftermarket) (Unl)" description "Cherry Rescue! (World) (Aftermarket) (Unl)" @@ -23191,9 +23557,9 @@ game ( ) game ( - name "Ciao Nonna (World) (v1.0) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (v1.0) (Aftermarket) (Unl).gb" size 1048576 crc dd7576d6 sha1 0556eb6160fdca6e7959bba1a619b8e34d974375 ) + name "Ciao Nonna (World) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (Aftermarket) (Unl).gb" size 1048576 crc dd7576d6 sha1 0556eb6160fdca6e7959bba1a619b8e34d974375 ) ) game ( @@ -23202,12 +23568,6 @@ game ( rom ( name "Cliffhanger (USA, Europe).gb" size 131072 crc aa133439 sha1 c74f85035842f8a2d9560066d7065ff86d9107e2 flags verified ) ) -game ( - name "Clockmaker's Tale, A (World) (Aftermarket) (Unl)" - description "Clockmaker's Tale, A (World) (Aftermarket) (Unl)" - rom ( name "Clockmaker's Tale, A (World) (Aftermarket) (Unl).gb" size 1048576 crc c4b00adb sha1 07e4254c7f74b9d4caa6a1231558b2430dff163a ) -) - game ( name "Collection Pocket (Japan) (SGB Enhanced)" description "Collection Pocket (Japan) (SGB Enhanced)" @@ -23250,12 +23610,6 @@ game ( rom ( name "Contra Spirits (Japan) (SGB Enhanced).gb" size 131072 crc 7fc22df5 sha1 72213c5d8af05cad5f17a42566f7383066612eee ) ) -game ( - name "Cookie's Bakery (World) (v1.0.3) (Aftermarket) (Unl)" - description "Cookie's Bakery (World) (v1.0.3) (Aftermarket) (Unl)" - rom ( name "Cookie's Bakery (World) (v1.0.3) (Aftermarket) (Unl).gb" size 524288 crc c53ace00 sha1 02fdc52bc934b80aa41520d92cf0340753d8f668 ) -) - game ( name "Cool Ball (USA)" description "Cool Ball (USA)" @@ -23292,12 +23646,6 @@ game ( rom ( name "Cool World (USA, Europe).gb" size 131072 crc a193c0d0 sha1 1919495cc83c4126c90d6cfa2e14427b6364da3a flags verified ) ) -game ( - name "Coria and the Sunken City (World) (Demo) (Aftermarket) (Unl)" - description "Coria and the Sunken City (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Coria and the Sunken City (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc fe1bdae6 sha1 00d86bbdbc228ff3ea0684984a261cadbed5fb0a ) -) - game ( name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" description "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" @@ -23406,6 +23754,12 @@ game ( rom ( name "CutThroat Island (USA, Europe).gb" size 262144 crc eebdd360 sha1 5e99ea51b383cdcd53874eb027ebd59d2a3156b9 flags verified ) ) +game ( + name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" + description "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" + rom ( name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl).gb" size 1048576 crc e3a78253 sha1 45c9c6a7a4ec985146a4a616a49dba45decc6d3e ) +) + game ( name "Cyraid (USA)" description "Cyraid (USA)" @@ -23461,21 +23815,15 @@ game ( ) game ( - name "Dangan (World) (v1.1) (Aftermarket) (Unl)" - description "Dangan (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Dangan (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 5359d6db sha1 10029774046dabec2d8c0533caf94091f6e19071 ) + name "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" + description "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Dangan GB (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 5359d6db sha1 10029774046dabec2d8c0533caf94091f6e19071 ) ) game ( - name "Dangan (World) (v1.0) (Aftermarket) (Unl)" - description "Dangan (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Dangan (World) (v1.0) (Aftermarket) (Unl).gb" size 262144 crc daa59c9c sha1 8375d845fcfe4c236cd68f3d56a290f8c7b76c06 ) -) - -game ( - name "Dark Winter Wander, A (World) (Aftermarket) (Unl)" - description "Dark Winter Wander, A (World) (Aftermarket) (Unl)" - rom ( name "Dark Winter Wander, A (World) (Aftermarket) (Unl).gb" size 1048576 crc df19aa9f sha1 412f18ba08f2f2a2afbf3bfb5281e360d7aba31d ) + name "Dangan GB (World) (Aftermarket) (Unl)" + description "Dangan GB (World) (Aftermarket) (Unl)" + rom ( name "Dangan GB (World) (Aftermarket) (Unl).gb" size 262144 crc daa59c9c sha1 8375d845fcfe4c236cd68f3d56a290f8c7b76c06 ) ) game ( @@ -23496,12 +23844,6 @@ game ( rom ( name "Darkwing Duck (USA).gb" size 131072 crc 238b9646 sha1 cc1f12f3ec3852657a14d11c13d1ef91fbdda5bb ) ) -game ( - name "Darkwing Duck (USA) (Beta)" - description "Darkwing Duck (USA) (Beta)" - rom ( name "Darkwing Duck (USA) (Beta).gb" size 131072 crc 311ade03 sha1 2883b8854529369cce4d473e71fa0193c7df02b6 ) -) - game ( name "Darkwing Duck (Germany)" description "Darkwing Duck (Germany)" @@ -23514,6 +23856,12 @@ game ( rom ( name "Darkwing Duck (Spain).gb" size 131072 crc a1d4c544 sha1 3d4b301aab995bdf19b15ed5040df7426a2e8057 ) ) +game ( + name "Darkwing Duck (USA) (Beta)" + description "Darkwing Duck (USA) (Beta)" + rom ( name "Darkwing Duck (USA) (Beta).gb" size 131072 crc 311ade03 sha1 2883b8854529369cce4d473e71fa0193c7df02b6 ) +) + game ( name "Dash (World) (Aftermarket) (Unl)" description "Dash (World) (Aftermarket) (Unl)" @@ -23532,12 +23880,6 @@ game ( rom ( name "David Crane's The Rescue of Princess Blobette (USA).gb" size 65536 crc 8210a03f sha1 0a45d1b98646fd7832b5119b04bc8d6d6d0f657a ) ) -game ( - name "Dawn Will Come (World) (Aftermarket) (Unl)" - description "Dawn Will Come (World) (Aftermarket) (Unl)" - rom ( name "Dawn Will Come (World) (Aftermarket) (Unl).gb" size 2097152 crc bb64f51c sha1 1611ddfdb9af72f20ddeca4133d8eebd0f14e424 ) -) - game ( name "Days of Thunder (USA, Europe)" description "Days of Thunder (USA, Europe)" @@ -23568,6 +23910,12 @@ game ( rom ( name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl).gb" size 1048576 crc 9e2bf649 sha1 3feeba5c438880f70cdfdc4ea7e29f77e645e9be flags verified ) ) +game ( + name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" + description "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" + rom ( name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl).gb" size 1048576 crc 818a7db7 sha1 43a93dc6f7bef002271e583edaeaf2e7162b8af4 ) +) + game ( name "Death Track (Europe) (Proto)" description "Death Track (Europe) (Proto)" @@ -23580,18 +23928,18 @@ game ( rom ( name "Deep Forest (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 3ddf177d sha1 517302d20cb5140975e6cd1b3c495786b6390aaf ) ) -game ( - name "Dennis (Europe)" - description "Dennis (Europe)" - rom ( name "Dennis (Europe).gb" size 131072 crc 896a30a8 sha1 9b5c289f25829534020951f84732177036837aea ) -) - game ( name "Dennis (Europe) (Beta) (1993-09-13)" description "Dennis (Europe) (Beta) (1993-09-13)" rom ( name "Dennis (Europe) (Beta) (1993-09-13).gb" size 131072 crc 807d34a4 sha1 fab382a28f9d7fefae7dc9a16bf86f309d89e037 ) ) +game ( + name "Dennis (Europe)" + description "Dennis (Europe)" + rom ( name "Dennis (Europe).gb" size 131072 crc 896a30a8 sha1 9b5c289f25829534020951f84732177036837aea ) +) + game ( name "Dennis the Menace (USA)" description "Dennis the Menace (USA)" @@ -23646,6 +23994,12 @@ game ( rom ( name "Dig Dug (USA).gb" size 131072 crc 6c742478 sha1 951753904389332412d4b0a80b48d7ac61a494fc ) ) +game ( + name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" + description "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" + rom ( name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc b230b782 sha1 f1796dcbfb6f0f5e01c60222c376cc1c46945806 ) +) + game ( name "Dino Breeder (Japan) (SGB Enhanced)" description "Dino Breeder (Japan) (SGB Enhanced)" @@ -23682,34 +24036,28 @@ game ( rom ( name "Dirty Racing (Japan).gb" size 131072 crc 43af45b1 sha1 5b58b4d02987ce3a16774bc4a6707d12ac404c1c ) ) -game ( - name "Disco Elysium - Game Boy Edition (World) (Aftermarket) (Unl)" - description "Disco Elysium - Game Boy Edition (World) (Aftermarket) (Unl)" - rom ( name "Disco Elysium - Game Boy Edition (World) (Aftermarket) (Unl).gb" size 1048576 crc ef349515 sha1 06fe25086432c82f1e4b4c44473dd5b487a8af05 ) -) - game ( name "DMG Deals Damage (World) (Aftermarket) (Unl)" description "DMG Deals Damage (World) (Aftermarket) (Unl)" - rom ( name "DMG Deals Damage (World) (Aftermarket) (Unl).gb" size 32768 crc 250e0cbd sha1 a15539199e4b6bd2a71d1ac0e7c61ae4f19a65e7 ) + rom ( name "DMG Deals Damage (World) (Aftermarket) (Unl).gb" size 32768 crc 250e0cbd sha1 a15539199e4b6bd2a71d1ac0e7c61ae4f19a65e7 flags verified ) ) game ( - name "Do I Pass (World) (Demo) (Aftermarket) (Unl)" - description "Do I Pass (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc f339fa82 sha1 bdbc082017bdf2e4caa84e7d00dad9707727e9d4 ) + name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc f339fa82 sha1 bdbc082017bdf2e4caa84e7d00dad9707727e9d4 ) ) game ( - name "Do I Pass (World) (v1.4) (Aftermarket) (Unl)" - description "Do I Pass (World) (v1.4) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (v1.4) (Aftermarket) (Unl).gb" size 1048576 crc cfb44d68 sha1 6dde71bbec8b807af5132d1ef2e99c6bb6af3a1c ) + name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl).gb" size 1048576 crc cfb44d68 sha1 6dde71bbec8b807af5132d1ef2e99c6bb6af3a1c ) ) game ( - name "Do I Pass (World) (v1.4) (Web) (Aftermarket) (Unl)" - description "Do I Pass (World) (v1.4) (Web) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (v1.4) (Web) (Aftermarket) (Unl).gb" size 1048576 crc 62e0c3a2 sha1 e1b516e472e0c681b4ad1c7f4aeda55c91e7f340 ) + name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl).gb" size 1048576 crc 62e0c3a2 sha1 e1b516e472e0c681b4ad1c7f4aeda55c91e7f340 ) ) game ( @@ -23719,9 +24067,9 @@ game ( ) game ( - name "Do I Pass (World) (v1.5) (Aftermarket) (Unl)" - description "Do I Pass (World) (v1.5) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (v1.5) (Aftermarket) (Unl).gb" size 1048576 crc 3890e0a4 sha1 6998e1bbf2ccb9db3d661ddac2d7edf7571d0af7 ) + name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl).gb" size 1048576 crc 3890e0a4 sha1 6998e1bbf2ccb9db3d661ddac2d7edf7571d0af7 ) ) game ( @@ -23761,21 +24109,9 @@ game ( ) game ( - name "Don't Forget About Me (World) (v1.0) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (v1.0) (Aftermarket) (Unl).gb" size 524288 crc 52cf7153 sha1 74e6246405dd52d4c5c2eabc417946550c637164 ) -) - -game ( - name "Don't Forget About Me (World) (v1.2) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (v1.2) (Aftermarket) (Unl).gb" size 1048576 crc 3d87efd8 sha1 83201c43e9fc89f4393678ade8c6107b4cfdb628 ) -) - -game ( - name "Don't Forget About Me (World) (v1.1) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 8ca9dbe0 sha1 cf6eaac37c4ae1b3cfc4ed8d2ce73a143635b525 ) + name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" + description "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 83247308 sha1 4579eaa45e2bf8f17f4dc99bdfb0b98270b871f5 ) ) game ( @@ -24048,6 +24384,12 @@ game ( rom ( name "Dragon Ball Z 3 (USA) (SGB Enhanced) (Unl).gb" size 1048576 crc 71b8ea17 sha1 c43eb3906f77dda5fee94a0fce0b6d783461238c ) ) +game ( + name "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" + description "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Dragon Battle (World) (Demo) (Aftermarket) (Unl).gb" size 4194304 crc c1e1e52c sha1 c5ac56e266c421a1c5b82de46859a44f75d03359 ) +) + game ( name "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" description "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" @@ -24204,6 +24546,12 @@ game ( rom ( name "Earthworm Jim (USA).gb" size 262144 crc 259ff267 sha1 f5d3085de17a5181c07739e49be7637faa5ff932 ) ) +game ( + name "Eclipse (Europe) (Proto)" + description "Eclipse (Europe) (Proto)" + rom ( name "Eclipse (Europe) (Proto).gb" size 65536 crc 6b507efd sha1 de02a34675a57d450284103681951436a4c830cd ) +) + game ( name "Edd the Duck (Europe) (Proto)" description "Edd the Duck (Europe) (Proto)" @@ -24216,6 +24564,12 @@ game ( rom ( name "Eddie's Puzzle Time (USA) (Proto).gb" size 65536 crc f2600f02 sha1 cd2695295831737d0f8a7eb825bbfe870b9c0bfd ) ) +game ( + name "Elden Ring GB (World) (Aftermarket) (Unl)" + description "Elden Ring GB (World) (Aftermarket) (Unl)" + rom ( name "Elden Ring GB (World) (Aftermarket) (Unl).gb" size 524288 crc e7a420f3 sha1 2e0bec6acf1a94ae3f2f6cf2040323862933d95a ) +) + game ( name "Elevator Action (Japan)" description "Elevator Action (Japan)" @@ -24234,12 +24588,6 @@ game ( rom ( name "Elite Soccer (USA) (SGB Enhanced).gb" size 131072 crc f54158a6 sha1 4576881ea25e29ebba91c49c89f8e70e105fbc60 ) ) -game ( - name "Empire of Dreams, The (World) (Aftermarket) (Unl)" - description "Empire of Dreams, The (World) (Aftermarket) (Unl)" - rom ( name "Empire of Dreams, The (World) (Aftermarket) (Unl).gb" size 524288 crc d87e5e68 sha1 92b2da6bd10337950ddcb8bb372cabccdce4f6bd ) -) - game ( name "Exodus - Journey to the Promised Land (USA) (Unl)" description "Exodus - Journey to the Promised Land (USA) (Unl)" @@ -24312,6 +24660,12 @@ game ( rom ( name "Faceball 2000 (USA).gb" size 131072 crc 7d890cd0 sha1 b0bd15bace04e0a3eb89773f231ac3a532181a0a flags verified ) ) +game ( + name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" + description "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" + rom ( name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 4f04cdfc sha1 591980cb5e17104d826c2a915f53bfc8a21affca ) +) + game ( name "Family Jockey (Japan)" description "Family Jockey (Japan)" @@ -24480,6 +24834,12 @@ game ( rom ( name "Final Fantasy Legend, The (USA).gb" size 131072 crc 8046148f sha1 901dfc83c72e172d35a376835807fc788444a9bb flags verified ) ) +game ( + name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" + description "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" + rom ( name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc 6cfb4669 sha1 339fd673509a5ac8f25426af25b4ccc96e8d2880 ) +) + game ( name "Final Reverse (Japan)" description "Final Reverse (Japan)" @@ -24511,9 +24871,9 @@ game ( ) game ( - name "Fix My Heart (World) (Aftermarket) (Unl)" - description "Fix My Heart (World) (Aftermarket) (Unl)" - rom ( name "Fix My Heart (World) (Aftermarket) (Unl).gb" size 524288 crc 507f9ea2 sha1 28ad64e379dc60d6e1c2617e073f6361c0feb475 ) + name "Flappy Special (Japan)" + description "Flappy Special (Japan)" + rom ( name "Flappy Special (Japan).gb" size 32768 crc 3b6cdda4 sha1 6517aee7caa2fa60750005ef1dacaeaecee7c2f6 ) ) game ( @@ -24522,24 +24882,12 @@ game ( rom ( name "Flappy Special (USA) (Proto).gb" size 32768 crc 617d0d9f sha1 75347d9f708da85487b779ed79b9c1e84954020d ) ) -game ( - name "Flappy Special (Japan)" - description "Flappy Special (Japan)" - rom ( name "Flappy Special (Japan).gb" size 32768 crc 3b6cdda4 sha1 6517aee7caa2fa60750005ef1dacaeaecee7c2f6 ) -) - game ( name "Flash, The (USA, Europe)" description "Flash, The (USA, Europe)" rom ( name "Flash, The (USA, Europe).gb" size 131072 crc 6deb1f06 sha1 f7e5701e6fa8fe4440988d1207517668c35088c6 ) ) -game ( - name "Flashin' (World) (v3.0) (Aftermarket) (Unl)" - description "Flashin' (World) (v3.0) (Aftermarket) (Unl)" - rom ( name "Flashin' (World) (v3.0) (Aftermarket) (Unl).gb" size 1048576 crc fcc05ec4 sha1 64d31f34e189b3af08bf0c659a93f71dbf83ef71 ) -) - game ( name "Fleet Commander VS. (Japan)" description "Fleet Commander VS. (Japan)" @@ -24577,9 +24925,9 @@ game ( ) game ( - name "Flooder (World) (Aftermarket) (Unl)" - description "Flooder (World) (Aftermarket) (Unl)" - rom ( name "Flooder (World) (Aftermarket) (Unl).gb" size 32768 crc 253dcbe0 sha1 8fdcd8b02604ac5259fb6aa80e5ba67a03c861fb ) + name "Fly O'Clock (World) (Aftermarket) (Unl)" + description "Fly O'Clock (World) (Aftermarket) (Unl)" + rom ( name "Fly O'Clock (World) (Aftermarket) (Unl).gb" size 32768 crc 93df7f55 sha1 83dc8498bdbabc14a8f81a715c9da19970c1f0b9 ) ) game ( @@ -24600,18 +24948,6 @@ game ( rom ( name "Foreman for Real (USA, Europe).gb" size 262144 crc 77083ae0 sha1 7b088c7b3a0ad275d340ca27f64a99c1bd6c34e6 ) ) -game ( - name "Forest of Fallen Knights (World) (Aftermarket) (Unl)" - description "Forest of Fallen Knights (World) (Aftermarket) (Unl)" - rom ( name "Forest of Fallen Knights (World) (Aftermarket) (Unl).gb" size 524288 crc fa2d92a1 sha1 24f02d116aafb7b55d6cfd6d263b7595986af843 ) -) - -game ( - name "Forest of Fallen Knights (World) (Beta) (Aftermarket) (Unl)" - description "Forest of Fallen Knights (World) (Beta) (Aftermarket) (Unl)" - rom ( name "Forest of Fallen Knights (World) (Beta) (Aftermarket) (Unl).gb" size 524288 crc 4c21e563 sha1 f6f84f1a44d41fa7d26a9195ddf791fae53dfcdf ) -) - game ( name "Fortified Zone (USA, Europe)" description "Fortified Zone (USA, Europe)" @@ -24630,12 +24966,6 @@ game ( rom ( name "Franky, Joe & Dirk - On the Tiles (Europe) (En,Fr,De,Es,It,Nl).gb" size 131072 crc caf5b372 sha1 b7e292cfd34d64546f158e548afa92efaf8c2acd ) ) -game ( - name "Friday the 13th - The GB Game (World) (Aftermarket) (Unl)" - description "Friday the 13th - The GB Game (World) (Aftermarket) (Unl)" - rom ( name "Friday the 13th - The GB Game (World) (Aftermarket) (Unl).gb" size 1048576 crc 7543586a sha1 397821751ac6464582f61566f3a7c731a46b24ba ) -) - game ( name "Frisky Tom (Japan) (SGB Enhanced)" description "Frisky Tom (Japan) (SGB Enhanced)" @@ -24684,6 +25014,12 @@ game ( rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB - Tsukikage Mura no Kaibutsu (Japan) (SGB Enhanced).gb" size 524288 crc 2962afb4 sha1 920ef94c05ac741047a266cb1668c881eab2937c flags verified ) ) +game ( + name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" + description "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" + rom ( name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl).gb" size 32768 crc 36e2ca02 sha1 fd985703b296dd0bf74225c72155ea9e51dd6853 ) +) + game ( name "G Arms - Operation Gundam (Japan)" description "G Arms - Operation Gundam (Japan)" @@ -24738,12 +25074,6 @@ game ( rom ( name "Game Boy Camera (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 4640909f sha1 461c3c37ed270681e3e94053efb21504b600aef5 flags verified ) ) -game ( - name "Game Boy Camera Gallery 2022, The (World) (Aftermarket) (Unl)" - description "Game Boy Camera Gallery 2022, The (World) (Aftermarket) (Unl)" - rom ( name "Game Boy Camera Gallery 2022, The (World) (Aftermarket) (Unl).gb" size 524288 crc f1948966 sha1 14849ab5831c71949ec3a1fe7657050057d2cf29 ) -) - game ( name "Game Boy Camera Gold (USA) (SGB Enhanced)" description "Game Boy Camera Gold (USA) (SGB Enhanced)" @@ -24852,6 +25182,12 @@ game ( rom ( name "Game of Harmony, The (USA).gb" size 32768 crc b0074acb sha1 b0bc752e3ad25fcb83d8ca04a82a0f5e35381db2 ) ) +game ( + name "GameBoy WORDLE (World) (Aftermarket) (Unl)" + description "GameBoy WORDLE (World) (Aftermarket) (Unl)" + rom ( name "GameBoy WORDLE (World) (Aftermarket) (Unl).gb" size 32768 crc cc971c0f sha1 ba93939b93ab3f3aa5f7aa451d50d9b89220adbc ) +) + game ( name "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" description "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" @@ -24936,12 +25272,6 @@ game ( rom ( name "GB Basketball (Japan).gb" size 131072 crc d9b24d21 sha1 65f73db2942d400a4c555fbcfd6313f07303d4e4 ) ) -game ( - name "GB Corp. (World) (Aftermarket) (Unl)" - description "GB Corp. (World) (Aftermarket) (Unl)" - rom ( name "GB Corp. (World) (Aftermarket) (Unl).gb" size 32768 crc fd2e40f4 sha1 e442316132506ff223a9e5f33d874b71ec09d71a ) -) - game ( name "GB Genjin (Japan)" description "GB Genjin (Japan)" @@ -24966,66 +25296,6 @@ game ( rom ( name "GB Pachi-Slot Hisshouhou! Jr. (Japan).gb" size 131072 crc a2e210e9 sha1 7636799f5a57d22cf579bb687be5bb9fedddd0ca ) ) -game ( - name "GB-Wordyl (World) (Pt-BR) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Pt-BR) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Pt-BR) (Aftermarket) (Unl).gb" size 32768 crc f20c0097 sha1 691af25434a09931a302ced52c757d28b9b06619 ) -) - -game ( - name "GB-Wordyl (World) (Ca) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Ca) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Ca) (Aftermarket) (Unl).gb" size 32768 crc 164999eb sha1 197d3d194d4cb6cae9a358f7fb53d6de649e7c5f ) -) - -game ( - name "GB-Wordyl (World) (De) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (De) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (De) (Aftermarket) (Unl).gb" size 32768 crc 60b075d1 sha1 0a66254b2327b48657de64d6102ac05f1e8700e7 ) -) - -game ( - name "GB-Wordyl (World) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Aftermarket) (Unl).gb" size 32768 crc 8780e125 sha1 7163bfbaa2cae2f9d41c472128f69a4fa5879180 ) -) - -game ( - name "GB-Wordyl (World) (Es) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Es) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Es) (Aftermarket) (Unl).gb" size 32768 crc 1a169897 sha1 0636b968e8e24fe7c1910f61db6e94fa84824494 ) -) - -game ( - name "GB-Wordyl (World) (Fr) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Fr) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Fr) (Aftermarket) (Unl).gb" size 32768 crc 593965ff sha1 75d566045a680aaed4d40b83b6418cbfab5b4422 ) -) - -game ( - name "GB-Wordyl (World) (It) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (It) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (It) (Aftermarket) (Unl).gb" size 32768 crc d81ab567 sha1 1dfd3c4508ffb6598662bcf1b16ec109a9282dd5 ) -) - -game ( - name "GB-Wordyl (World) (Kw) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Kw) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Kw) (Aftermarket) (Unl).gb" size 32768 crc f795689c sha1 9a332127182e8155d1a3dc53e1382a6c9dde6aeb ) -) - -game ( - name "GB-Wordyl (World) (Es-XL) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Es-XL) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Es-XL) (Aftermarket) (Unl).gb" size 32768 crc 660ed37b sha1 0792fbef010cac21c12cbcb8b3c85b3af30faec4 ) -) - -game ( - name "GB-Wordyl (World) (Nl) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Nl) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Nl) (Aftermarket) (Unl).gb" size 32768 crc 6dc4faaa sha1 7617083f9b13b2f95bdf1b0b327ffb4f8ccbe3c9 ) -) - game ( name "GBKiss Mini Games (Japan)" description "GBKiss Mini Games (Japan)" @@ -25062,6 +25332,12 @@ game ( rom ( name "Genesis (World) (Aftermarket) (Unl).gb" size 65536 crc 74b3ec78 sha1 ca43f82d73ba0b3e43ec17f6bc6761c09ca23626 ) ) +game ( + name "Genesis II (World) (Demo) (Aftermarket) (Unl)" + description "Genesis II (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Genesis II (World) (Demo) (Aftermarket) (Unl).gb" size 262144 crc d7aec1cc sha1 9700ea1278850df004ded7553253cfdd354f4ada ) +) + game ( name "Genjin Collection (Japan) (SGB Enhanced)" description "Genjin Collection (Japan) (SGB Enhanced)" @@ -25134,6 +25410,18 @@ game ( rom ( name "Ginga - Card & Puzzle Collection (Japan) (En,Ja).gb" size 65536 crc 87d0637b sha1 14f4f14caee081dceadb9d31ae26fd8968c432ea ) ) +game ( + name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" + description "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 4b19366d sha1 77f3b561bf28a81f38dbedc351752e10ff4c23dc ) +) + +game ( + name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" + description "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" + rom ( name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 3f34ff66 sha1 a0bff49b6917186d27dc24773da0674a18a6212c ) +) + game ( name "Gluecksrad (Germany)" description "Gluecksrad (Germany)" @@ -25219,9 +25507,9 @@ game ( ) game ( - name "Gorf the Ghost Saves Halloween (World) (Aftermarket) (Unl)" - description "Gorf the Ghost Saves Halloween (World) (Aftermarket) (Unl)" - rom ( name "Gorf the Ghost Saves Halloween (World) (Aftermarket) (Unl).gb" size 262144 crc ab10cec6 sha1 9dcaa6824fab806683737bdf1c76609c68c451a5 ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer).gb" size 1048576 crc 5d43a385 sha1 d367f2dab5eacb10e785a13a2550ca7cc3e54177 ) ) game ( @@ -25231,9 +25519,9 @@ game ( ) game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer).gb" size 1048576 crc 5d43a385 sha1 d367f2dab5eacb10e785a13a2550ca7cc3e54177 ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute).gb" size 1048576 crc 180d54a7 sha1 7dce0adcbac61f0caae33646847fd06ced8c8b67 ) ) game ( @@ -25243,9 +25531,9 @@ game ( ) game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute).gb" size 1048576 crc 180d54a7 sha1 7dce0adcbac61f0caae33646847fd06ced8c8b67 ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer).gb" size 1048576 crc 71acbb67 sha1 e2ac91493248869aba6b7d26a36e5ff6bd6d6f5a flags verified ) ) game ( @@ -25255,9 +25543,9 @@ game ( ) game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer).gb" size 1048576 crc 71acbb67 sha1 e2ac91493248869aba6b7d26a36e5ff6bd6d6f5a flags verified ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan) (Proto) (IE Institute)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan) (Proto) (IE Institute)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan) (Proto) (IE Institute).gb" size 1048576 crc 91ab959f sha1 2e1797646b2d3aa6fc9b2f5eaa248751133a0518 ) ) game ( @@ -25266,12 +25554,6 @@ game ( rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan) (Imagineer).gb" size 1048576 crc 3c907f2c sha1 fa7a40acd835676fbcae9507a8aaaf1191f9b1cd ) ) -game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan) (Proto) (IE Institute)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan) (Proto) (IE Institute)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan) (Proto) (IE Institute).gb" size 1048576 crc 91ab959f sha1 2e1797646b2d3aa6fc9b2f5eaa248751133a0518 ) -) - game ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Zukei no Tatsujin (Japan)" description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Zukei no Tatsujin (Japan)" @@ -25513,15 +25795,15 @@ game ( ) game ( - name "Gunman Clive (World) (Aftermarket) (Unl)" - description "Gunman Clive (World) (Aftermarket) (Unl)" - rom ( name "Gunman Clive (World) (Aftermarket) (Unl).gb" size 65536 crc 11f5fded sha1 ec03763db2c0d754e2eb7e98384ed92fc8aeeb1d ) + name "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" + description "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Gunman Clive (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc 11f5fded sha1 ec03763db2c0d754e2eb7e98384ed92fc8aeeb1d ) ) game ( - name "Gunship (USA) (Aftermarket) (Unl)" - description "Gunship (USA) (Aftermarket) (Unl)" - rom ( name "Gunship (USA) (Aftermarket) (Unl).gb" size 131072 crc bd31eef8 sha1 a801977c3746799cfb4d8bdfd679e45cccd3b719 ) + name "Gunship (World) (Aftermarket) (Unl)" + description "Gunship (World) (Aftermarket) (Unl)" + rom ( name "Gunship (World) (Aftermarket) (Unl).gb" size 131072 crc bd31eef8 sha1 a801977c3746799cfb4d8bdfd679e45cccd3b719 ) ) game ( @@ -25566,12 +25848,6 @@ game ( rom ( name "Hatris (Japan, USA) (En).gb" size 65536 crc 7635f28b sha1 e8002f226e90ed52e1675c003d3c8ce804b56b0e ) ) -game ( - name "Hauntsfield (World) (Aftermarket) (Unl)" - description "Hauntsfield (World) (Aftermarket) (Unl)" - rom ( name "Hauntsfield (World) (Aftermarket) (Unl).gb" size 1048576 crc 287afc75 sha1 42ccc76883c041bc5c6c25a2e61ccc939c14811f ) -) - game ( name "Hayaoshi Quiz - Ouza Ketteisen (Japan) (SGB Enhanced)" description "Hayaoshi Quiz - Ouza Ketteisen (Japan) (SGB Enhanced)" @@ -25632,6 +25908,12 @@ game ( rom ( name "Hercules (USA, Europe) (SGB Enhanced).gb" size 524288 crc 00a9001e sha1 215cceaccd4a33a2da6205f33a2803ff4004e2b1 flags verified ) ) +game ( + name "Hermano (World) (v1.1) (Aftermarket) (Unl)" + description "Hermano (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Hermano (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 74a0419b sha1 c42cfe91a1ec593a76291e031c47137bd794ffda ) +) + game ( name "Hero Shuugou!! Pinball Party (Japan)" description "Hero Shuugou!! Pinball Party (Japan)" @@ -25800,18 +26082,18 @@ game ( rom ( name "Hudson Hawk (Europe) (Proto).gb" size 131072 crc d4cd525d sha1 07c6a49f7c340d3cc78ca688eb1591853255a6c6 ) ) -game ( - name "Hugo (Europe) (SGB Enhanced)" - description "Hugo (Europe) (SGB Enhanced)" - rom ( name "Hugo (Europe) (SGB Enhanced).gb" size 131072 crc 74aa5e0f sha1 d314dffcf5fb441d5d6d6419e01dc825e90cf0fc flags verified ) -) - game ( name "Hugo (World) (Aftermarket) (Unl)" description "Hugo (World) (Aftermarket) (Unl)" rom ( name "Hugo (World) (Aftermarket) (Unl).gb" size 262144 crc 8cc87f60 sha1 53fac2774b29a32501788e1eac65db23bf5c7b8f ) ) +game ( + name "Hugo (Europe) (SGB Enhanced)" + description "Hugo (Europe) (SGB Enhanced)" + rom ( name "Hugo (Europe) (SGB Enhanced).gb" size 131072 crc 74aa5e0f sha1 d314dffcf5fb441d5d6d6419e01dc825e90cf0fc flags verified ) +) + game ( name "Hugo 2 (Germany)" description "Hugo 2 (Germany)" @@ -25830,6 +26112,12 @@ game ( rom ( name "Humans, The (USA).gb" size 262144 crc 1df2e81d sha1 39b7f8f6abb213bb5727379b864106ca2947fe6f ) ) +game ( + name "Humans, The (USA) (QUByte Classics)" + description "Humans, The (USA) (QUByte Classics)" + rom ( name "Humans, The (USA) (QUByte Classics).gb" size 262144 crc 4580ec88 sha1 669f4645b426400a4853793c7070c53642f71556 ) +) + game ( name "Hunchback of Notre Dame, The - 5 Foolishly Fun Topsy Turvy Games (USA, Europe) (SGB Enhanced)" description "Hunchback of Notre Dame, The - 5 Foolishly Fun Topsy Turvy Games (USA, Europe) (SGB Enhanced)" @@ -25891,9 +26179,9 @@ game ( ) game ( - name "In the Dark (World) (Aftermarket) (Unl)" - description "In the Dark (World) (Aftermarket) (Unl)" - rom ( name "In the Dark (World) (Aftermarket) (Unl).gb" size 1048576 crc 89ac8948 sha1 dfed92c906d9fd4e4ee405453ee391e0e9b174bf ) + name "Impossible Gameboy (World) (Aftermarket) (Unl)" + description "Impossible Gameboy (World) (Aftermarket) (Unl)" + rom ( name "Impossible Gameboy (World) (Aftermarket) (Unl).gb" size 131072 crc ab65b738 sha1 d31cedd6227b23cf3d8ef81c73f133ab0b57e4f4 ) ) game ( @@ -25908,12 +26196,6 @@ game ( rom ( name "Incredible Crash Dummies, The (USA, Europe).gb" size 131072 crc d81c08fa sha1 f62d369b576cfd2882f8e03a5a32238eb1599477 ) ) -game ( - name "IndestructoTank! (World) (Aftermarket) (Unl)" - description "IndestructoTank! (World) (Aftermarket) (Unl)" - rom ( name "IndestructoTank! (World) (Aftermarket) (Unl).gb" size 32768 crc aa176926 sha1 e70992f8598c489bd34c30bd3a4c3789dddb8057 ) -) - game ( name "Indiana Jones - Saigo no Seisen (Japan)" description "Indiana Jones - Saigo no Seisen (Japan)" @@ -25998,6 +26280,12 @@ game ( rom ( name "International Superstar Soccer (USA, Europe) (SGB Enhanced).gb" size 262144 crc 94757be8 sha1 13f2fc0945fb7a90f4d87d8c4e310dec9af6b792 ) ) +game ( + name "Into the Blue (World) (Aftermarket) (Unl)" + description "Into the Blue (World) (Aftermarket) (Unl)" + rom ( name "Into the Blue (World) (Aftermarket) (Unl).gb" size 131072 crc 7714e96e sha1 5ac7a349bb37c8767c9db264ed8ae7b7647fa8ea ) +) + game ( name "Ippatsu Gyakuten! DX Bakenou (Japan)" description "Ippatsu Gyakuten! DX Bakenou (Japan)" @@ -26191,9 +26479,9 @@ game ( ) game ( - name "Jetsons, The - Robot Panic (USA) (Rev 1) (Possible Proto)" - description "Jetsons, The - Robot Panic (USA) (Rev 1) (Possible Proto)" - rom ( name "Jetsons, The - Robot Panic (USA) (Rev 1) (Possible Proto).gb" size 131072 crc cc38cf0d sha1 38b5ec2c74316696b7731cd88e56be4519084168 ) + name "Jetsons, The - Robot Panic (USA, Europe) (Rev 1)" + description "Jetsons, The - Robot Panic (USA, Europe) (Rev 1)" + rom ( name "Jetsons, The - Robot Panic (USA, Europe) (Rev 1).gb" size 131072 crc cc38cf0d sha1 38b5ec2c74316696b7731cd88e56be4519084168 ) ) game ( @@ -26226,6 +26514,12 @@ game ( rom ( name "Jimmy Connors Tennis (USA, Europe) (Beta).gb" size 131072 crc eb50caf2 sha1 4ca04a3270e217d54d8c5fa7a254fdbcb48c5b87 ) ) +game ( + name "Jimmy Connors Tennis (USA, Europe) (1993-03-19) (Beta)" + description "Jimmy Connors Tennis (USA, Europe) (1993-03-19) (Beta)" + rom ( name "Jimmy Connors Tennis (USA, Europe) (1993-03-19) (Beta).gb" size 65536 crc 4ee3e02e sha1 06c9018f7943362f8b9571486b6412de11672718 ) +) + game ( name "Jinsei Game (Japan) (SGB Enhanced)" description "Jinsei Game (Japan) (SGB Enhanced)" @@ -26784,6 +27078,12 @@ game ( rom ( name "Krusty's Fun House (USA, Europe).gb" size 131072 crc 1cedb141 sha1 e61039c52c053a8ae1bdfffa3f694934569bb570 flags verified ) ) +game ( + name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" + description "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" + rom ( name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 0610049a sha1 a6fbe1a524547bebabc5e6b3baff1dff8f13dbd0 ) +) + game ( name "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced)" description "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced)" @@ -26850,6 +27150,18 @@ game ( rom ( name "Last Action Hero (USA, Europe).gb" size 131072 crc 10499af6 sha1 010eb2cbab987ec242cd0792c789a07c00106f48 ) ) +game ( + name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 2c430576 sha1 0e290b387a45b6ea85c6d49bf18bce3ce94951b7 ) +) + +game ( + name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 5cf1a6f9 sha1 9fac1324e863f719674219eb41e45f1f745c67a9 ) +) + game ( name "Lawn Mower Land (World) (Aftermarket) (Unl)" description "Lawn Mower Land (World) (Aftermarket) (Unl)" @@ -26953,9 +27265,21 @@ game ( ) game ( - name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16)" - description "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16).gb" size 524288 crc f7c59f5c sha1 d1a10a3f129bf060f16d1fb5f991ef6e2f28b97c ) + name "Legend of Zelda, The - Link's Awakening DX (France) (Proto) (1998-11-17)" + description "Legend of Zelda, The - Link's Awakening DX (France) (Proto) (1998-11-17)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Proto) (1998-11-17).gb" size 524288 crc bfa800c0 sha1 3d48bcec56bf202d3362ba3e5e20233f996492c5 ) +) + +game ( + name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Proto) (1998-11-08)" + description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Proto) (1998-11-08)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Proto) (1998-11-08).gb" size 524288 crc d8ba6631 sha1 9d6da903a5481aadfb20d75954bd01917497a38d ) +) + +game ( + name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17)" + description "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17).gb" size 524288 crc f7c59f5c sha1 d1a10a3f129bf060f16d1fb5f991ef6e2f28b97c ) ) game ( @@ -26991,7 +27315,7 @@ game ( game ( name "Lemmings 2 - The Tribes (Europe)" description "Lemmings 2 - The Tribes (Europe)" - rom ( name "Lemmings 2 - The Tribes (Europe).gb" size 524288 crc 9800bd49 sha1 76ccf9ac82faebc7f9c4a4c8b5cd47ddea46c486 ) + rom ( name "Lemmings 2 - The Tribes (Europe).gb" size 524288 crc 9800bd49 sha1 76ccf9ac82faebc7f9c4a4c8b5cd47ddea46c486 flags verified ) ) game ( @@ -27006,6 +27330,18 @@ game ( rom ( name "Lethal Weapon (USA, Europe) (Beta).gb" size 131072 crc d585ab23 sha1 2221ba322acffc9d7ae5400752e16d0455fda3ef ) ) +game ( + name "Life's Too Short (World) (Aftermarket) (Unl)" + description "Life's Too Short (World) (Aftermarket) (Unl)" + rom ( name "Life's Too Short (World) (Aftermarket) (Unl).gb" size 262144 crc 458174cc sha1 7b704cd999cbeeb9991d675e2b1e67a906fa766d ) +) + +game ( + name "Linea, La (World) (Aftermarket) (Unl)" + description "Linea, La (World) (Aftermarket) (Unl)" + rom ( name "Linea, La (World) (Aftermarket) (Unl).gb" size 262144 crc c8750c01 sha1 00348fec54b5d3ebb762484bdcc015881bb9e95b ) +) + game ( name "Lingo (Europe) (En,Fr,De,Nl)" description "Lingo (Europe) (En,Fr,De,Nl)" @@ -27066,6 +27402,54 @@ game ( rom ( name "Little Mermaid, The (Spain) (Proto).gb" size 131072 crc d19cf413 sha1 463036660b2739e450a7bdea68772c6738e04a53 ) ) +game ( + name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc 9c4f03fd sha1 288cb53b4782df4409ee683e9aa11b4dd2a3a53e ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc e5988949 sha1 08d033c7ef20fd4d24d1f07b3ebb177fb9b78673 ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc 59568248 sha1 6571db155f6f25eeeec86d28b105bf8fef156322 ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc a26345b8 sha1 641110cb187657fd15ea254440e1c74ab4a88856 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc d70f1d25 sha1 02e2fb6cbc5cff05ed775c9e1cd9acc07fa2e036 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc ae07c093 sha1 9f40b8719b3fdd2f7e6c59a4f616e9eb712d538d ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc 34671dc6 sha1 377d22d54e6e1fa4fcd4b4576d5886774f9f6c97 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc a8fb0d7a sha1 26803ba3413c7c52a8a58393f63472bc87ec3c6b ) +) + game ( name "Lock n' Chase ~ Lock 'n' Chase (World)" description "Lock n' Chase ~ Lock 'n' Chase (World)" @@ -27180,6 +27564,12 @@ game ( rom ( name "Machine, The (World) (Aftermarket) (Unl).gb" size 2097152 crc b06036a9 sha1 50c5d1eb7c8946ac2d7e2c566b1ea4a9b0d58e90 ) ) +game ( + name "Mad Monster (World) (Aftermarket) (Unl)" + description "Mad Monster (World) (Aftermarket) (Unl)" + rom ( name "Mad Monster (World) (Aftermarket) (Unl).gb" size 524288 crc c3fd371c sha1 9f4bea7ca7d26080110f54392314c60761236638 ) +) + game ( name "Madden 95 (USA, Europe) (SGB Enhanced)" description "Madden 95 (USA, Europe) (SGB Enhanced)" @@ -27360,6 +27750,18 @@ game ( rom ( name "Maru's Mission (USA).gb" size 131072 crc 6e4f1eb3 sha1 91446b1cc6dbf3b98b81f13e35ffe7bfaaa027aa flags verified ) ) +game ( + name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" + description "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl).gb" size 262144 crc dccaeb60 sha1 1e4fc83bfe9c9063975a3862770e4afee3f947a4 ) +) + +game ( + name "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" + description "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" + rom ( name "Marzipan Beef Reverser (World) (Aftermarket) (Unl).gb" size 131072 crc 4c3e0d15 sha1 6cbfb0390ee555718b5b0c3a5437b7d3d4ee0008 ) +) + game ( name "Masakari Densetsu - Kintarou Action Hen (Japan)" description "Masakari Densetsu - Kintarou Action Hen (Japan)" @@ -27558,12 +27960,6 @@ game ( rom ( name "Meitantei Conan - Giwaku no Gouka Ressha (Japan) (SGB Enhanced).gb" size 262144 crc 1dc5c31a sha1 125db863bad5d48033d0bf94ed808b2b8d34ca2f ) ) -game ( - name "Melanie and the Magic Forest (World) (Aftermarket) (Unl)" - description "Melanie and the Magic Forest (World) (Aftermarket) (Unl)" - rom ( name "Melanie and the Magic Forest (World) (Aftermarket) (Unl).gb" size 262144 crc f614bdff sha1 7e46c193f6566f620acf20ead3a1fca1d677c221 ) -) - game ( name "Mercenary Force (USA, Europe)" description "Mercenary Force (USA, Europe)" @@ -27709,9 +28105,9 @@ game ( ) game ( - name "Midterm Moments (World) (Aftermarket) (Unl)" - description "Midterm Moments (World) (Aftermarket) (Unl)" - rom ( name "Midterm Moments (World) (Aftermarket) (Unl).gb" size 262144 crc f9a5ed4e sha1 8b3e18287d5adf3b5a711e28a896f843927f22a2 ) + name "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced)" + description "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced)" + rom ( name "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced).gb" size 262144 crc c60d032a sha1 ef88476d9a1a26b67f3535ae7afcf5156578e38c flags verified ) ) game ( @@ -27720,12 +28116,6 @@ game ( rom ( name "Mighty Morphin Power Rangers (USA, Europe) (Beta) (SGB Enhanced).gb" size 262144 crc caab9ac9 sha1 be42f45d8038ce28461ed36ba9164854632aebe0 ) ) -game ( - name "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced)" - description "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced)" - rom ( name "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced).gb" size 262144 crc c60d032a sha1 ef88476d9a1a26b67f3535ae7afcf5156578e38c flags verified ) -) - game ( name "Mighty Morphin Power Rangers - The Movie (USA, Europe) (SGB Enhanced)" description "Mighty Morphin Power Rangers - The Movie (USA, Europe) (SGB Enhanced)" @@ -27816,6 +28206,138 @@ game ( rom ( name "Mini-Putt (Japan).gb" size 65536 crc 33cd7550 sha1 e2a75fc09d8f9e56325449ca91cda9a68d058c1f ) ) +game ( + name "Minolta 2085 Adj. Program (USA) (Unl)" + description "Minolta 2085 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2085 Adj. Program (USA) (Unl).gb" size 32768 crc de660a82 sha1 d0e586988108b7238bebcac055cb7c6982abf81c ) +) + +game ( + name "Minolta 2097 Adj. Program (USA) (Unl)" + description "Minolta 2097 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2097 Adj. Program (USA) (Unl).gb" size 32768 crc 0a9ab6e7 sha1 68968d1b1fc84b2381159c0938675d2048c57ee2 flags verified ) +) + +game ( + name "Minolta 2098 Adj. Program (USA) (Unl)" + description "Minolta 2098 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2098 Adj. Program (USA) (Unl).gb" size 32768 crc 1b7eb836 sha1 dc0f429cc1eac8dd9009a9b30dab0803099be646 ) +) + +game ( + name "Minolta 2156 Adj. Program (USA) (Unl)" + description "Minolta 2156 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2156 Adj. Program (USA) (Unl).gb" size 32768 crc 3af37d46 sha1 c4b46446553bf6c25e3b3c1d5cd450a205ff6692 ) +) + +game ( + name "Minolta 2162 Adj. Program (USA) (Unl)" + description "Minolta 2162 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2162 Adj. Program (USA) (Unl).gb" size 32768 crc 54a6aec4 sha1 58202d2f8f823c52c09275df3fa63b4b2a630bdc ) +) + +game ( + name "Minolta 2162 Adj. Program (USA) (Unl) (Alt)" + description "Minolta 2162 Adj. Program (USA) (Unl) (Alt)" + rom ( name "Minolta 2162 Adj. Program (USA) (Unl) (Alt).gb" size 32768 crc 74ecd4bf sha1 6e0121c4cb9cb82ca7ee1004f90f9954f062d927 ) +) + +game ( + name "Minolta 2166 Adj. Program (USA) (Unl)" + description "Minolta 2166 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2166 Adj. Program (USA) (Unl).gb" size 32768 crc 711179d9 sha1 dd48d1cb7218bda09d59247f4b0eb6832a611e51 ) +) + +game ( + name "Minolta 2181 Adj. Program (USA) (Unl)" + description "Minolta 2181 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2181 Adj. Program (USA) (Unl).gb" size 32768 crc ac64f965 sha1 14d85a2943a2caedb559ccd48f3c3536b7c54a18 ) +) + +game ( + name "Minolta 2205 Adj. Program (USA) (Unl)" + description "Minolta 2205 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2205 Adj. Program (USA) (Unl).gb" size 32768 crc d70cc276 sha1 48a417f53bb7852d7278f37b4a75c8da695db5d6 ) +) + +game ( + name "Minolta 2419 Adj. Program (USA) (Unl)" + description "Minolta 2419 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2419 Adj. Program (USA) (Unl).gb" size 32768 crc f9373901 sha1 c4fdbdc3a2b7cdd4b494ece7f81d88f5d7564c3d ) +) + +game ( + name "Minolta 2420 Adj. Program (USA) (Unl)" + description "Minolta 2420 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2420 Adj. Program (USA) (Unl).gb" size 32768 crc 5bd13f4f sha1 b5994db5e190bef18bb7f3d1c25f8b14ef4b9b22 ) +) + +game ( + name "Minolta 2420 Adj. Program2 (USA) (Unl)" + description "Minolta 2420 Adj. Program2 (USA) (Unl)" + rom ( name "Minolta 2420 Adj. Program2 (USA) (Unl).gb" size 32768 crc 97561d80 sha1 a55a5fd97ca1be3fa129f744f81fc972e29418ac ) +) + +game ( + name "Minolta 2428 Adj. Program (USA) (Unl)" + description "Minolta 2428 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2428 Adj. Program (USA) (Unl).gb" size 32768 crc 4abf7bd2 sha1 6192d29c564441ca2b42a06ef15cc6f56e90f90f ) +) + +game ( + name "Minolta 2429 Adj. Program (USA) (Unl)" + description "Minolta 2429 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2429 Adj. Program (USA) (Unl).gb" size 32768 crc e0dc1323 sha1 f3a394cee80a1de435fd3c90e3ca31b0672665f9 ) +) + +game ( + name "Minolta 2440 Adj. Program (USA) (Unl) (Alt)" + description "Minolta 2440 Adj. Program (USA) (Unl) (Alt)" + rom ( name "Minolta 2440 Adj. Program (USA) (Unl) (Alt).gb" size 32768 crc 37c305dc sha1 494b8392c67a6e91ccf198b82b8f9e515dd7e02a ) +) + +game ( + name "Minolta 2440 Adj. Program (USA) (Unl)" + description "Minolta 2440 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2440 Adj. Program (USA) (Unl).gb" size 32768 crc 7a9359ea sha1 c15325e2e0ad2c8bd4323ef2390df28e578dcdb8 ) +) + +game ( + name "Minolta 2463 Adj. Program (USA) (Unl)" + description "Minolta 2463 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2463 Adj. Program (USA) (Unl).gb" size 32768 crc 7e5429d3 sha1 828f068b0fe5d8c88862f505e982e2cb1568689b ) +) + +game ( + name "Minolta 2468 Adj. Program (USA) (Unl)" + description "Minolta 2468 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2468 Adj. Program (USA) (Unl).gb" size 32768 crc cd622b15 sha1 51480e67f459b966bf2e18ec5092c135557c12d7 ) +) + +game ( + name "Minolta 2472-73 Adj. Program (USA) (Unl)" + description "Minolta 2472-73 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2472-73 Adj. Program (USA) (Unl).gb" size 32768 crc 15493e75 sha1 b242bcf33d46b5642392e526d7466e63f0b6a718 ) +) + +game ( + name "Minolta 2476 Adj. Program (USA) (Unl)" + description "Minolta 2476 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2476 Adj. Program (USA) (Unl).gb" size 32768 crc 6c3501df sha1 2ac3148a2593e062ffd8ed116da4eb749277c434 ) +) + +game ( + name "Minolta 2481 Adj. Program (USA) (Unl)" + description "Minolta 2481 Adj. Program (USA) (Unl)" + rom ( name "Minolta 2481 Adj. Program (USA) (Unl).gb" size 32768 crc 67e5a203 sha1 4d1a3176e4232984a14580382152ce5313a620e6 ) +) + +game ( + name "Minolta SLR Data Copy (USA) (Unl)" + description "Minolta SLR Data Copy (USA) (Unl)" + rom ( name "Minolta SLR Data Copy (USA) (Unl).gb" size 32768 crc 76f0ff74 sha1 a0ada0dd3cdfd1e0908e90cd512fa094f5396e1e ) +) + game ( name "Miracle Adventure of Esparks - Ushinawareta Seiseki Perivron (Japan)" description "Miracle Adventure of Esparks - Ushinawareta Seiseki Perivron (Japan)" @@ -27829,15 +28351,21 @@ game ( ) game ( - name "Mission to Mars (World) (Aftermarket) (Unl)" - description "Mission to Mars (World) (Aftermarket) (Unl)" - rom ( name "Mission to Mars (World) (Aftermarket) (Unl).gb" size 262144 crc cb3a9ab8 sha1 31625a90b61d28ac782909ed8b00b3a48df7742e ) + name "Mission Mars (World) (Aftermarket) (Unl)" + description "Mission Mars (World) (Aftermarket) (Unl)" + rom ( name "Mission Mars (World) (Aftermarket) (Unl).gb" size 262144 crc cb3a9ab8 sha1 31625a90b61d28ac782909ed8b00b3a48df7742e ) ) game ( - name "Mofa Qiu (Taiwan) (Unl)" - description "Mofa Qiu (Taiwan) (Unl)" - rom ( name "Mofa Qiu (Taiwan) (Unl).gb" size 131072 crc e2cb3b91 sha1 88ac96eb953d1c273896893c7d8e1597524da4a4 ) + name "Mofa Qiu - Magic Ball (Taiwan) (Multicart Rip) (Unl)" + description "Mofa Qiu - Magic Ball (Taiwan) (Multicart Rip) (Unl)" + rom ( name "Mofa Qiu - Magic Ball (Taiwan) (Multicart Rip) (Unl).gb" size 131072 crc e2cb3b91 sha1 88ac96eb953d1c273896893c7d8e1597524da4a4 ) +) + +game ( + name "Mofa Qiu - Magic Ball (Taiwan) (Unl)" + description "Mofa Qiu - Magic Ball (Taiwan) (Unl)" + rom ( name "Mofa Qiu - Magic Ball (Taiwan) (Unl).gb" size 65536 crc 38465864 sha1 50c0450b540bb338a71bf626f93005e991929f6e ) ) game ( @@ -28086,12 +28614,6 @@ game ( rom ( name "Motocross Maniacs (Europe) (Rev 1).gb" size 32768 crc f867ee3b sha1 d21f2a4ddb69c408a370b6768f83914c11012c71 ) ) -game ( - name "Mountain Climber (World) (En,Es) (Aftermarket) (Unl)" - description "Mountain Climber (World) (En,Es) (Aftermarket) (Unl)" - rom ( name "Mountain Climber (World) (En,Es) (Aftermarket) (Unl).gb" size 262144 crc 362a84ba sha1 b4b3afa2379a07acab6965ae8fcf6d2ba82d6d7e ) -) - game ( name "Mouse Trap Hotel (USA)" description "Mouse Trap Hotel (USA)" @@ -28140,12 +28662,6 @@ game ( rom ( name "Ms. Pac-Man (USA).gb" size 65536 crc 0e5bb1c4 sha1 fcc05f0625d52ace28d21fd8270e71246229cbad ) ) -game ( - name "Mud Warriors (World) (Aftermarket) (Unl)" - description "Mud Warriors (World) (Aftermarket) (Unl)" - rom ( name "Mud Warriors (World) (Aftermarket) (Unl).gb" size 524288 crc 846afc79 sha1 dae84fbc60839da29878714cd845c3704b915323 ) -) - game ( name "Muhammad Ali Heavyweight Boxing (USA, Europe)" description "Muhammad Ali Heavyweight Boxing (USA, Europe)" @@ -28164,6 +28680,12 @@ game ( rom ( name "Mulan (USA) (SGB Enhanced).gb" size 524288 crc bfcf71a1 sha1 7832fcc373ff752e757550079519b39583665c82 ) ) +game ( + name "Muncher (World) (Aftermarket) (Unl)" + description "Muncher (World) (Aftermarket) (Unl)" + rom ( name "Muncher (World) (Aftermarket) (Unl).gb" size 262144 crc 444d3d5e sha1 c3e09aff66c7e395bf95a1864963fbe979d5cb9b ) +) + game ( name "MVP Baseball (Japan)" description "MVP Baseball (Japan)" @@ -28392,12 +28914,24 @@ game ( rom ( name "Nekketsu! Beach Volley Da yo Kunio-kun (Japan) (SGB Enhanced).gb" size 262144 crc abfb84df sha1 d3ad43c40c21d9825b4879dbf28ca58835da658a ) ) +game ( + name "Neko Can Dream (World) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (Aftermarket) (Unl).gb" size 2097152 crc 6e76ef25 sha1 55686fde78d17d00adfc831eca2c699274a82273 ) +) + game ( name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" description "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" rom ( name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc a0ad7a18 sha1 5fb1a09e04cf1704b059468de8855dfa7e23043b ) ) +game ( + name "Neko Can Dream (World) (Demo) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc dc011d07 sha1 43312b149355d20944e8a366584c69e5cb3be868 ) +) + game ( name "Nekojara Monogatari (Japan)" description "Nekojara Monogatari (Japan)" @@ -28728,6 +29262,18 @@ game ( rom ( name "Noobow (Japan).gb" size 262144 crc 8bbcc8bb sha1 b571d9051e3a9f1a55533b4f43941cae907aedff ) ) +game ( + name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" + description "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl).gb" size 262144 crc d6166c62 sha1 fa2198c5308a15195adbda004f09646589860d11 ) +) + +game ( + name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc 42b47080 sha1 08484b0f98e72d6577d9b7cde8c49908012d1fc5 ) +) + game ( name "Oblique Strategies (World) (Aftermarket) (Unl)" description "Oblique Strategies (World) (Aftermarket) (Unl)" @@ -28741,9 +29287,21 @@ game ( ) game ( - name "Office Combat (World) (Aftermarket) (Unl)" - description "Office Combat (World) (Aftermarket) (Unl)" - rom ( name "Office Combat (World) (Aftermarket) (Unl).gb" size 262144 crc 9742276d sha1 cd8f18d6e5fabaa130a42e5618e29c5ff26f6a93 ) + name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl).gb" size 524288 crc d3eba01d sha1 8cf234bbcb68ca2b676a4ccec89814b0cbce1c07 ) +) + +game ( + name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 71f34822 sha1 f24da97f44d280f27f8ebe3acdc33fea758d2255 ) +) + +game ( + name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 76baab68 sha1 cd76da35541535dd244ad60d10eb998f7692f07a ) ) game ( @@ -29232,12 +29790,6 @@ game ( rom ( name "Phantom Air Mission (Europe).gb" size 131072 crc 8aced4a6 sha1 2a270597d7b814a1c8819a5698ab922200569206 flags verified ) ) -game ( - name "Phantom Fright (World) (Aftermarket) (Unl)" - description "Phantom Fright (World) (Aftermarket) (Unl)" - rom ( name "Phantom Fright (World) (Aftermarket) (Unl).gb" size 524288 crc 154cb547 sha1 3b217c595e6a5b115dc7130123a321049cf01d22 ) -) - game ( name "Philip & Marlowe in Bloomland (USA) (Proto)" description "Philip & Marlowe in Bloomland (USA) (Proto)" @@ -29316,6 +29868,12 @@ game ( rom ( name "Pineapple Kid (World) (Aftermarket) (Unl).gb" size 131072 crc 9541488b sha1 fd574b5d407f3654db3227900a8ed7eff4fe48ae ) ) +game ( + name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" + description "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 9d9102d9 sha1 105e78f740d6bc517ef0079f867e9fdce8d012d2 ) +) + game ( name "Pingu - Sekai de 1ban Genki na Penguin (Japan)" description "Pingu - Sekai de 1ban Genki na Penguin (Japan)" @@ -29337,7 +29895,7 @@ game ( game ( name "Pipe Dream (Japan)" description "Pipe Dream (Japan)" - rom ( name "Pipe Dream (Japan).gb" size 32768 crc d8b4aea4 sha1 64a58aafecb0aceed2dde843a19a28b2bb000b2f ) + rom ( name "Pipe Dream (Japan).gb" size 32768 crc d8b4aea4 sha1 64a58aafecb0aceed2dde843a19a28b2bb000b2f flags verified ) ) game ( @@ -29359,9 +29917,9 @@ game ( ) game ( - name "Pixel Who - The Lost Legions (World) (v1.0) (Aftermarket) (Unl)" - description "Pixel Who - The Lost Legions (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Pixel Who - The Lost Legions (World) (v1.0) (Aftermarket) (Unl).gb" size 1048576 crc f41cf2a7 sha1 c07378c774602060f1f93f18fbfd3f0d552fe2d2 ) + name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" + description "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" + rom ( name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl).gb" size 1048576 crc f41cf2a7 sha1 c07378c774602060f1f93f18fbfd3f0d552fe2d2 ) ) game ( @@ -29418,6 +29976,12 @@ game ( rom ( name "Pocket Camera (Japan) (Rev 1) (SGB Enhanced).gb" size 1048576 crc 73e8ef96 sha1 912205ea22e1dd735ed4f41d247039eebf39dddc flags verified ) ) +game ( + name "Pocket Camera - Debug Game Tester - Second Impact (Japan) (Test Program) (v10.24) (SGB Enhanced)" + description "Pocket Camera - Debug Game Tester - Second Impact (Japan) (Test Program) (v10.24) (SGB Enhanced)" + rom ( name "Pocket Camera - Debug Game Tester - Second Impact (Japan) (Test Program) (v10.24) (SGB Enhanced).gb" size 1048576 crc 15726d8c sha1 5ffcda6fa1a3d87c5cbb8ddf743ddbc18242443b ) +) + game ( name "Pocket Densha (Japan) (SGB Enhanced)" description "Pocket Densha (Japan) (SGB Enhanced)" @@ -29484,6 +30048,12 @@ game ( rom ( name "Pocket Monsters - Ao (Japan) (SGB Enhanced).gb" size 524288 crc e4468d14 sha1 0da501e3e5c51ab8fef55b092dcdd7e6b050e424 flags verified ) ) +game ( + name "Pocket Monsters - Green Version - English Edition (Taiwan) (En) (Pirate)" + description "Pocket Monsters - Green Version - English Edition (Taiwan) (En) (Pirate)" + rom ( name "Pocket Monsters - Green Version - English Edition (Taiwan) (En) (Pirate).gb" size 786432 crc 742357fc sha1 b8d1b89a82fbad0352f4a15dd1bcc91868717578 ) +) + game ( name "Pocket Monsters - Midori (Japan) (SGB Enhanced)" description "Pocket Monsters - Midori (Japan) (SGB Enhanced)" @@ -29688,6 +30258,60 @@ game ( rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (CGB+SGB Enhanced).gb" size 1048576 crc 7d527d62 sha1 cc7d03262ebfaf2f06772c1a480c7d9d5f4a38e1 flags verified ) ) +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-22) (Beta) (CGB+SGB Enhanced) (Alt)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-22) (Beta) (CGB+SGB Enhanced) (Alt)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-22) (Beta) (CGB+SGB Enhanced) (Alt).gb" size 1048576 crc dbd0b8dc sha1 ad2ec0171cc731747adbe51b852a0bc6acd9471a ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-03) (Beta) (CGB+SGB Enhanced)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-03) (Beta) (CGB+SGB Enhanced)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-03) (Beta) (CGB+SGB Enhanced).gb" size 1048576 crc d0b1e29b sha1 7c4ef696e2d0d965d5c6f33e745bbacc1715bba1 ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-03) (Beta) (CGB+SGB Enhanced) (Alt)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-03) (Beta) (CGB+SGB Enhanced) (Alt)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-03) (Beta) (CGB+SGB Enhanced) (Alt).gb" size 1048576 crc 1116ae9f sha1 bfac8de19d04e859f64aaa52ffb1f3d5094417ff ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-18) (Beta) (CGB+SGB Enhanced)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-18) (Beta) (CGB+SGB Enhanced)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-18) (Beta) (CGB+SGB Enhanced).gb" size 1048576 crc b539a028 sha1 53dcd8b02c7ad002a7c40edf758b19d3b393a9c4 ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-15) (Beta) (CGB+SGB Enhanced)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-15) (Beta) (CGB+SGB Enhanced)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-15) (Beta) (CGB+SGB Enhanced).gb" size 1048576 crc 00787832 sha1 13ef81f63904d496c6d6acf6685750ecdb35357b ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-16) (Beta) (CGB+SGB Enhanced)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-16) (Beta) (CGB+SGB Enhanced)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-16) (Beta) (CGB+SGB Enhanced).gb" size 1048576 crc 42c5430a sha1 d8a7d2ec6a8dd9f8e97cf02a27882a750650aa6c ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-22) (Beta) (CGB+SGB Enhanced)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-22) (Beta) (CGB+SGB Enhanced)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-22) (Beta) (CGB+SGB Enhanced).gb" size 1048576 crc c83df319 sha1 490a925fe4e30dc0217c4a23ed9b4f41538277db ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-17) (Beta) (CGB+SGB Enhanced)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-17) (Beta) (CGB+SGB Enhanced)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-17) (Beta) (CGB+SGB Enhanced).gb" size 1048576 crc 0dee0d87 sha1 bde79c92c801cc0c0e73a022bdf23f086b4da4c5 ) +) + +game ( + name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-10) (Beta) (CGB+SGB Enhanced)" + description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-10) (Beta) (CGB+SGB Enhanced)" + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (1999-02-10) (Beta) (CGB+SGB Enhanced).gb" size 1048576 crc 2e63bc59 sha1 834e933256855403da07d88d375cdbe88d628f01 ) +) + game ( name "Pokonyan! - Yume no Daibouken (Japan) (SGB Enhanced)" description "Pokonyan! - Yume no Daibouken (Japan) (SGB Enhanced)" @@ -29713,9 +30337,9 @@ game ( ) game ( - name "Popcorn Caravan (World) (Aftermarket) (Unl)" - description "Popcorn Caravan (World) (Aftermarket) (Unl)" - rom ( name "Popcorn Caravan (World) (Aftermarket) (Unl).gb" size 65536 crc ead528f9 sha1 909d3421747d211a2dc70918d2c952db953e49b2 ) + name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" + description "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc ead528f9 sha1 909d3421747d211a2dc70918d2c952db953e49b2 ) ) game ( @@ -29779,9 +30403,15 @@ game ( ) game ( - name "Porklike (World) (v1.0.9) (Aftermarket) (Unl)" - description "Porklike (World) (v1.0.9) (Aftermarket) (Unl)" - rom ( name "Porklike (World) (v1.0.9) (Aftermarket) (Unl).gb" size 65536 crc 7aaa853a sha1 0868bffd52b2bdc5601ab6cf1e25f40924ca643d ) + name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" + description "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 7aaa853a sha1 0868bffd52b2bdc5601ab6cf1e25f40924ca643d ) +) + +game ( + name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" + description "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 801f097b sha1 5da110a88799765707e027bcedec0875a637509b ) ) game ( @@ -29907,7 +30537,7 @@ game ( game ( name "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced)" description "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced)" - rom ( name "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced).gb" size 131072 crc 6f5b6748 sha1 dc6b304ac4e9b679272f843411ba964b438a69b6 ) + rom ( name "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced).gb" size 131072 crc 6f5b6748 sha1 dc6b304ac4e9b679272f843411ba964b438a69b6 flags verified ) ) game ( @@ -30090,12 +30720,6 @@ game ( rom ( name "QIX (World).gb" size 65536 crc 9185e89e sha1 fb9935ca821562966eafa8f60ec2f489ad33940a flags verified ) ) -game ( - name "Quartet (World) (Aftermarket) (Unl)" - description "Quartet (World) (Aftermarket) (Unl)" - rom ( name "Quartet (World) (Aftermarket) (Unl).gb" size 32768 crc 46743216 sha1 bf866b438a602af386f8fad02727b4084edf6047 ) -) - game ( name "Quarth (Japan)" description "Quarth (Japan)" @@ -30108,12 +30732,6 @@ game ( rom ( name "Quarth (USA, Europe).gb" size 65536 crc bfb112ad sha1 89448b17700a6016a3f81de09a15e097c060d103 flags verified ) ) -game ( - name "Quest Arrest (World) (v1.1) (Aftermarket) (Unl)" - description "Quest Arrest (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Quest Arrest (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 9ac546d5 sha1 25b3a21135bfc7587c096b10f4a20d8b3095d721 ) -) - game ( name "Quick Draw (World) (Aftermarket) (Unl)" description "Quick Draw (World) (Aftermarket) (Unl)" @@ -30279,7 +30897,7 @@ game ( game ( name "Remute - Living Electronics (World) (Aftermarket) (Unl)" description "Remute - Living Electronics (World) (Aftermarket) (Unl)" - rom ( name "Remute - Living Electronics (World) (Aftermarket) (Unl).gb" size 2097152 crc 1ced0a62 sha1 bc4bf12344d3b9d028a7013c84b94aea515be196 ) + rom ( name "Remute - Living Electronics (World) (Aftermarket) (Unl).gb" size 2097152 crc 1ced0a62 sha1 bc4bf12344d3b9d028a7013c84b94aea515be196 flags verified ) ) game ( @@ -30312,6 +30930,12 @@ game ( rom ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 2d33e175 sha1 08dad9ac1f045d1c9e403c4ea1368aee991e0094 ) ) +game ( + name "Retroid (World) (Aftermarket) (Unl)" + description "Retroid (World) (Aftermarket) (Unl)" + rom ( name "Retroid (World) (Aftermarket) (Unl).gb" size 262144 crc 9f759f25 sha1 4c7323d6a10852fe416c7bd581d6ffdd2d473bb5 ) +) + game ( name "Rewind Time (World) (Aftermarket) (Unl)" description "Rewind Time (World) (Aftermarket) (Unl)" @@ -30319,9 +30943,9 @@ game ( ) game ( - name "Rhythm Land (World) (v1.0.0) (Aftermarket) (Unl)" - description "Rhythm Land (World) (v1.0.0) (Aftermarket) (Unl)" - rom ( name "Rhythm Land (World) (v1.0.0) (Aftermarket) (Unl).gb" size 131072 crc 4312c7ff sha1 c79f26ce187edea18cf92be8340ec0a0c8beec87 ) + name "Rhythm Land (World) (Aftermarket) (Unl)" + description "Rhythm Land (World) (Aftermarket) (Unl)" + rom ( name "Rhythm Land (World) (Aftermarket) (Unl).gb" size 131072 crc 4312c7ff sha1 c79f26ce187edea18cf92be8340ec0a0c8beec87 ) ) game ( @@ -30546,6 +31170,18 @@ game ( rom ( name "Rolan's Curse II (USA).gb" size 131072 crc 2754f360 sha1 7632e23853dd2579012489f75bd370473f0f2c46 flags verified ) ) +game ( + name "Roommate Simulator (World) (Aftermarket) (Unl)" + description "Roommate Simulator (World) (Aftermarket) (Unl)" + rom ( name "Roommate Simulator (World) (Aftermarket) (Unl).gb" size 131072 crc 3c95b1aa sha1 d5c99106c3bd4d46aeb75f513fd4314c19c734b2 ) +) + +game ( + name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" + description "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" + rom ( name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 51d09337 sha1 9e935cca00cb4c3aad7b1dfce9fe59f5d913bdff ) +) + game ( name "Rubble Saver (Japan)" description "Rubble Saver (Japan)" @@ -30594,6 +31230,24 @@ game ( rom ( name "Sa-Ga 3 - Jikuu no Hasha (World) (Ja) (Collection of SaGa).gb" size 262144 crc dc4f4e34 sha1 8125677ee63e9abb4b956ed0bee18fae3e04193b ) ) +game ( + name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" + description "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl).gb" size 2097152 crc 6669f0be sha1 25bcf936e8dadb10d288473989891e4f2ec6c605 ) +) + +game ( + name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" + description "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl).gb" size 2097152 crc 1c4b7eb0 sha1 5cd15f4629fdbcfd6f752d89be755d5ac02b9435 ) +) + +game ( + name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" + description "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 03f2dd1a sha1 78fe9c7cd6d0d7f1157c8c7716642d17c4b80303 ) +) + game ( name "Sagaia (Japan)" description "Sagaia (Japan)" @@ -30619,9 +31273,9 @@ game ( ) game ( - name "Sam Mallard - The Case of the Missing Swan (World) (Aftermarket) (Unl)" - description "Sam Mallard - The Case of the Missing Swan (World) (Aftermarket) (Unl)" - rom ( name "Sam Mallard - The Case of the Missing Swan (World) (Aftermarket) (Unl).gb" size 1048576 crc 994a2edd sha1 0132f0311d8478d4f45b3b8e2728698570091d69 ) + name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" + description "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 1048576 crc 994a2edd sha1 0132f0311d8478d4f45b3b8e2728698570091d69 ) ) game ( @@ -30672,12 +31326,6 @@ game ( rom ( name "Sanrio Uranai Party (Japan) (Rev 1).gb" size 262144 crc d0687d9f sha1 72dfcc83dbd78ad2b5b43014fc9adf05431e230c flags verified ) ) -game ( - name "Sapphire & Shiny Kidnap the Crows (World) (v2) (Aftermarket) (Unl)" - description "Sapphire & Shiny Kidnap the Crows (World) (v2) (Aftermarket) (Unl)" - rom ( name "Sapphire & Shiny Kidnap the Crows (World) (v2) (Aftermarket) (Unl).gb" size 1048576 crc edb63c15 sha1 4617b71836c3ddabcfef46b33aa8a83803eaea90 ) -) - game ( name "Sarakon (Europe) (Proto)" description "Sarakon (Europe) (Proto)" @@ -30853,16 +31501,9 @@ game ( ) game ( - name "Shapeshifter 2, The (World) (Aftermarket)" - description "Shapeshifter 2, The (World) (Aftermarket)" - rom ( name "Shapeshifter 2, The (World) (Aftermarket) (Cartridge 1).gb" size 2097152 crc 276125f1 sha1 b181b58984cb44c950fc56f88a4fb8112da8fcff ) - rom ( name "Shapeshifter 2, The (World) (Aftermarket) (Cartridge 2).gb" size 2097152 crc 5b45bce2 sha1 79d16ef5383ddc7ae299f825cd03268d00887500 ) -) - -game ( - name "Shapeshifter, The (World) (Aftermarket)" - description "Shapeshifter, The (World) (Aftermarket)" - rom ( name "Shapeshifter, The (World) (Aftermarket).gb" size 1048576 crc ef735794 sha1 179e69199f19b403b4c1a9675a3ee431ee570797 ) + name "Shapeshifter, The (World) (Aftermarket) (Unl)" + description "Shapeshifter, The (World) (Aftermarket) (Unl)" + rom ( name "Shapeshifter, The (World) (Aftermarket) (Unl).gb" size 1048576 crc ef735794 sha1 179e69199f19b403b4c1a9675a3ee431ee570797 ) ) game ( @@ -30877,6 +31518,12 @@ game ( rom ( name "Shark Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 3032025a sha1 6cc65bb719af53128bb04c9ee7c6abbf4ff1c3cf ) ) +game ( + name "Sheep it Up (World) (Digital) (Aftermarket) (Unl)" + description "Sheep it Up (World) (Digital) (Aftermarket) (Unl)" + rom ( name "Sheep it Up (World) (Digital) (Aftermarket) (Unl).gb" size 32768 crc fa6de2e4 sha1 9ad365ed7d4e07041c0147831a9bb1c496ea0bc8 ) +) + game ( name "Shikinjou (Japan)" description "Shikinjou (Japan)" @@ -31051,12 +31698,6 @@ game ( rom ( name "Sloth Story (World) (Aftermarket) (Unl).gb" size 262144 crc c873f232 sha1 369d2afec4ffb59d4f3a59ee684c5bfec0b34ff8 ) ) -game ( - name "Sludge & Sorcery (World) (Aftermarket) (Unl)" - description "Sludge & Sorcery (World) (Aftermarket) (Unl)" - rom ( name "Sludge & Sorcery (World) (Aftermarket) (Unl).gb" size 1048576 crc c906c5af sha1 0e0d472b282e3ea590e0f126baf633ef0d9298fa ) -) - game ( name "Small Soldiers (USA, Europe) (SGB Enhanced)" description "Small Soldiers (USA, Europe) (SGB Enhanced)" @@ -31093,12 +31734,6 @@ game ( rom ( name "Smurfs, The (USA, Europe) (En,Fr,De) (Rev 1) (SGB Enhanced).gb" size 131072 crc 8b5bcde7 sha1 a0d6a85331fb034f68f05629a5ff85e13adab205 flags verified ) ) -game ( - name "Snail DX, The (World) (Aftermarket) (Unl)" - description "Snail DX, The (World) (Aftermarket) (Unl)" - rom ( name "Snail DX, The (World) (Aftermarket) (Unl).gb" size 262144 crc 1aecd096 sha1 8ce256d963a55badf71fd45047c173a74d76a92c ) -) - game ( name "Snail, The (World) (v1.3) (Aftermarket) (Unl)" description "Snail, The (World) (v1.3) (Aftermarket) (Unl)" @@ -31111,6 +31746,12 @@ game ( rom ( name "Snakebird (World) (Aftermarket) (Unl).gb" size 131072 crc 4627f98e sha1 99cc82279d65b86b4366bf61db9bf67a78e051dc ) ) +game ( + name "Snaky Pocket (World) (Aftermarket) (Unl)" + description "Snaky Pocket (World) (Aftermarket) (Unl)" + rom ( name "Snaky Pocket (World) (Aftermarket) (Unl).gb" size 32768 crc 7209370d sha1 f5eab31a499f33b3ae1f7b5b006dcca1df3ac2b9 ) +) + game ( name "Sneaky Snakes (USA, Europe)" description "Sneaky Snakes (USA, Europe)" @@ -31135,12 +31776,6 @@ game ( rom ( name "Snoopy's Magic Show (USA, Europe).gb" size 65536 crc 2b7a5034 sha1 bc21fb3aa1a58e2aef30fabe103b2e5bec02b535 flags verified ) ) -game ( - name "Snooze (World) (Aftermarket) (Unl)" - description "Snooze (World) (Aftermarket) (Unl)" - rom ( name "Snooze (World) (Aftermarket) (Unl).gb" size 262144 crc b246095f sha1 b7fdcc006c9c06dd391ee26d44b278d9d3793f6d ) -) - game ( name "Snow Bros. Jr. (Japan)" description "Snow Bros. Jr. (Japan)" @@ -31225,6 +31860,24 @@ game ( rom ( name "Solomon's Club (USA).gb" size 65536 crc cea9622a sha1 36abf2be4a16df8e9fe30307cbd8cb949a9b9bdb ) ) +game ( + name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" + description "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 665ad70a sha1 c5b6eb610caa2213d8db7ab204bad44d60f7d63a ) +) + +game ( + name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" + description "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl).gb" size 262144 crc feed93e0 sha1 721d78d4ef167acfcc00baf909db4c94d522d681 ) +) + +game ( + name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" + description "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl).gb" size 262144 crc 6547e5c8 sha1 53a42f45b7ed368d7af9d41f2442fe463c26e545 ) +) + game ( name "Sonic 6 (USA) (Pirate)" description "Sonic 6 (USA) (Pirate)" @@ -31285,6 +31938,12 @@ game ( rom ( name "Space Invaders (Europe) (Beta) (SGB Enhanced).gb" size 131072 crc 2d03dc38 sha1 6a2af41de10dbf6496b18963d904cc41d04bb970 ) ) +game ( + name "Space Trouble (World) (Proto) (Aftermarket) (Unl)" + description "Space Trouble (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Space Trouble (World) (Proto) (Aftermarket) (Unl).gb" size 524288 crc f015931c sha1 ec7bc27387d4d2ac01127bc24e1adf45b6ebc936 ) +) + game ( name "Spanky's Quest (Europe)" description "Spanky's Quest (Europe)" @@ -31556,9 +32215,9 @@ game ( ) game ( - name "StarFox - Grounded (World) (Aftermarket) (Unl)" - description "StarFox - Grounded (World) (Aftermarket) (Unl)" - rom ( name "StarFox - Grounded (World) (Aftermarket) (Unl).gb" size 524288 crc 82658661 sha1 dd45b0e3f346ce33668d49092b29a44597686061 ) + name "Stardiver (World) (Aftermarket) (Unl)" + description "Stardiver (World) (Aftermarket) (Unl)" + rom ( name "Stardiver (World) (Aftermarket) (Unl).gb" size 1048576 crc 25ff97f7 sha1 d609b8de2c7a61b7281fec5c761e3504aa4d94e9 ) ) game ( @@ -31615,12 +32274,6 @@ game ( rom ( name "Street Racer (USA, Europe).gb" size 131072 crc fcfb4ce4 sha1 4e1d17772eb939cb0a3bce73e4378384d96836ce flags verified ) ) -game ( - name "Suicide Run (World) (Aftermarket) (Unl)" - description "Suicide Run (World) (Aftermarket) (Unl)" - rom ( name "Suicide Run (World) (Aftermarket) (Unl).gb" size 262144 crc d29ab1aa sha1 df373f58e51155e32fb81825a9082150f6d263c8 ) -) - game ( name "Sumo Fighter (USA)" description "Sumo Fighter (USA)" @@ -31783,12 +32436,6 @@ game ( rom ( name "Super Hunchback (USA).gb" size 131072 crc 1a45706e sha1 9d53fbfeeec5a1a8352177c157ce615621c4b30c ) ) -game ( - name "Super Imposter Bros. (World) (Aftermarket) (Unl)" - description "Super Imposter Bros. (World) (Aftermarket) (Unl)" - rom ( name "Super Imposter Bros. (World) (Aftermarket) (Unl).gb" size 1048576 crc a38d702f sha1 301f93da4e5b0cd8dc3f1bf3e66e38176b8a909b ) -) - game ( name "Super James Pond (Europe)" description "Super James Pond (Europe)" @@ -31982,9 +32629,9 @@ game ( ) game ( - name "SWAPLATFORMER (World) (Aftermarket) (Unl)" - description "SWAPLATFORMER (World) (Aftermarket) (Unl)" - rom ( name "SWAPLATFORMER (World) (Aftermarket) (Unl).gb" size 1048576 crc babe7935 sha1 3df0c37862b7c391a0d091a55db0d305341529c2 ) + name "Swaplatformer (World) (Aftermarket) (Unl)" + description "Swaplatformer (World) (Aftermarket) (Unl)" + rom ( name "Swaplatformer (World) (Aftermarket) (Unl).gb" size 1048576 crc babe7935 sha1 3df0c37862b7c391a0d091a55db0d305341529c2 ) ) game ( @@ -32023,12 +32670,6 @@ game ( rom ( name "Sword of Hope, The (Europe) (Proto).gb" size 131072 crc c360f279 sha1 383ef07e04280f82da374852d04e7f98e9a00ae1 ) ) -game ( - name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (Aftermarket) (Unl)" - description "Swordbird Song - The Iron Owl Tower (World) (v3.1) (Aftermarket) (Unl)" - rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (Aftermarket) (Unl).gb" size 1048576 crc 64921bb1 sha1 b36ec89e0299c19767cc5c6467fa3664abbc3017 ) -) - game ( name "T2 - The Arcade Game (Japan)" description "T2 - The Arcade Game (Japan)" @@ -32090,15 +32731,15 @@ game ( ) game ( - name "Takeda Nobuhiro no Ace Striker (Japan)" - description "Takeda Nobuhiro no Ace Striker (Japan)" - rom ( name "Takeda Nobuhiro no Ace Striker (Japan).gb" size 262144 crc 7ff546df sha1 e354310c9946f48eb325c070e9c2c5ccb2e9f429 ) + name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" + description "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 5898c134 sha1 bd3468395deb0009b190d0b5d487962ae65adbee ) ) game ( - name "Tales of Monsterland (World) (v2.83) (Aftermarket) (Unl)" - description "Tales of Monsterland (World) (v2.83) (Aftermarket) (Unl)" - rom ( name "Tales of Monsterland (World) (v2.83) (Aftermarket) (Unl).gb" size 2097152 crc a685f89a sha1 15a709d4300464b03ede4d774ce69cfb699c0fcf ) + name "Takeda Nobuhiro no Ace Striker (Japan)" + description "Takeda Nobuhiro no Ace Striker (Japan)" + rom ( name "Takeda Nobuhiro no Ace Striker (Japan).gb" size 262144 crc 7ff546df sha1 e354310c9946f48eb325c070e9c2c5ccb2e9f429 ) ) game ( @@ -32426,9 +33067,9 @@ game ( ) game ( - name "There's Nothing To Do In This Town (World) (Aftermarket) (Unl)" - description "There's Nothing To Do In This Town (World) (Aftermarket) (Unl)" - rom ( name "There's Nothing To Do In This Town (World) (Aftermarket) (Unl).gb" size 1048576 crc 173b549a sha1 e000fbecda9ea6bbbd0c0370cf8c3faaa54bf64e ) + name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" + description "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" + rom ( name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl).gb" size 1048576 crc 173b549a sha1 e000fbecda9ea6bbbd0c0370cf8c3faaa54bf64e ) ) game ( @@ -32437,6 +33078,12 @@ game ( rom ( name "Thin Ice Rescue, The (World) (Aftermarket) (Unl).gb" size 32768 crc 3e0483d6 sha1 b789ced0fe26785e7bce765a9d6ee783f9d967d8 ) ) +game ( + name "TimberMan (World) (Aftermarket) (Unl)" + description "TimberMan (World) (Aftermarket) (Unl)" + rom ( name "TimberMan (World) (Aftermarket) (Unl).gb" size 32768 crc e0b8459c sha1 e3f4b4c4816cc0dda2885519f1386385e6a5e817 ) +) + game ( name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" description "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" @@ -32461,18 +33108,6 @@ game ( rom ( name "Tintin in Tibet (Europe) (En,Es,It,Sv) (Beta) (SGB Enhanced).gb" size 262144 crc 68b7fcf2 sha1 63070514f0a692cef70e9344ca0a973f6af510c9 ) ) -game ( - name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (Aftermarket) (Unl)" - description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (Aftermarket) (Unl)" - rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (Aftermarket) (Unl).gb" size 262144 crc af13e718 sha1 307e51664db2101755b6c617f3d81ee58676c485 ) -) - -game ( - name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (Aftermarket) (Unl)" - description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (Aftermarket) (Unl)" - rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (Aftermarket) (Unl).gb" size 262144 crc 0518f5aa sha1 85e5cd0cf7a6cc4a5946c93fa8665235a686e554 ) -) - game ( name "Tiny Toon Adventures (Japan)" description "Tiny Toon Adventures (Japan)" @@ -32707,6 +33342,24 @@ game ( rom ( name "Trappers Tengoku - Spy vs Spy (Japan).gb" size 131072 crc afefd085 sha1 c9eb687f6de7b821255fdd0cbf14f68ad789f97f ) ) +game ( + name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl).gb" size 2097152 crc 15afd765 sha1 c12e603492f8bcfffd28dd4733c7bc445c507642 ) +) + +game ( + name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl).gb" size 2097152 crc e1bdf67f sha1 ba492778121622b5288d4188edc344aa41aa6803 ) +) + +game ( + name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl).gb" size 1048576 crc 42bb7dab sha1 70fded7ce1edc54de85b020460f779feb9bdbc01 ) +) + game ( name "Trax (USA, Europe)" description "Trax (USA, Europe)" @@ -32743,12 +33396,6 @@ game ( rom ( name "Triumph (USA) (Proto).gb" size 131072 crc 746159b2 sha1 90a40fc94709a3ec6945281bde2644d91bef28b5 ) ) -game ( - name "Trouble City - Pocket Mission (World) (Aftermarket) (Unl)" - description "Trouble City - Pocket Mission (World) (Aftermarket) (Unl)" - rom ( name "Trouble City - Pocket Mission (World) (Aftermarket) (Unl).gb" size 524288 crc 4b9143ad sha1 0e51e398d44aaad74a7c622f7818b56a3b34db56 ) -) - game ( name "True Lies (USA, Europe)" description "True Lies (USA, Europe)" @@ -32965,18 +33612,6 @@ game ( rom ( name "Undercover Cops Gaiden - Hakaishin Garumaa (Japan).gb" size 262144 crc b7af37f5 sha1 e391ea099ce371eef858d57e6c2da63a25944472 ) ) -game ( - name "Unearthed (World) (v1.3) (Aftermarket) (Unl)" - description "Unearthed (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Unearthed (World) (v1.3) (Aftermarket) (Unl).gb" size 2097152 crc 29bb9238 sha1 39fbfb220e9be0120090f770249049b3f3583f64 ) -) - -game ( - name "Ungrateful Son, The (World) (v1.1) (Aftermarket) (Unl)" - description "Ungrateful Son, The (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Ungrateful Son, The (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 977b54f4 sha1 016dde406896d827dcad682d40b52d0e9eeefa88 ) -) - game ( name "Universal Soldier (USA, Europe)" description "Universal Soldier (USA, Europe)" @@ -33103,24 +33738,6 @@ game ( rom ( name "Wario Land II (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 9c54358d sha1 c65820b2e52d00e6ce60e0a432fab002fec4386f flags verified ) ) -game ( - name "Warp Coin Catastrophe, The (World) (v1.1) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc a381c914 sha1 adf37c5d2f706743b2a4946378df49ed19212039 ) -) - -game ( - name "Warp Coin Catastrophe, The (World) (v1.0) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (v1.0) (Aftermarket) (Unl).gb" size 1048576 crc 1bfe1bf9 sha1 fae12dbbb75ae024e96a7ee21ad4077fdb5ed9a1 ) -) - -game ( - name "Warp Coin Catastrophe, The (World) (v1.1.2) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (v1.1.2) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (v1.1.2) (Aftermarket) (Unl).gb" size 1048576 crc 5519c167 sha1 04a53af6a77b884af91f8047d70fc0331bf23913 ) -) - game ( name "Waterworld (Europe)" description "Waterworld (Europe)" @@ -33164,9 +33781,9 @@ game ( ) game ( - name "What's Updog (World) (Aftermarket) (Unl)" - description "What's Updog (World) (Aftermarket) (Unl)" - rom ( name "What's Updog (World) (Aftermarket) (Unl).gb" size 262144 crc 2c3d5cbf sha1 a235c0915ac2b826eeb5884d0eccd321236fdb0c ) + name "What Friends Are For (World) (Aftermarket) (Unl)" + description "What Friends Are For (World) (Aftermarket) (Unl)" + rom ( name "What Friends Are For (World) (Aftermarket) (Unl).gb" size 262144 crc cbed3dd6 sha1 58538084a964f779c2f756fbe732656f3f7bef66 ) ) game ( @@ -33481,6 +34098,12 @@ game ( rom ( name "Xenon 2 - Megablast (Japan).gb" size 131072 crc 2feb70d2 sha1 6b2f009b7a443e5ead48a2864bfb1d29096ed6a0 ) ) +game ( + name "Xin Nushen Zhuansheng Waizhuan - Zuihou de Shengjing (Taiwan) (Pirate)" + description "Xin Nushen Zhuansheng Waizhuan - Zuihou de Shengjing (Taiwan) (Pirate)" + rom ( name "Xin Nushen Zhuansheng Waizhuan - Zuihou de Shengjing (Taiwan) (Pirate).gb" size 524288 crc 2298585c sha1 f33091c0bfd840e0ce4c4f99c463cfb92f823a64 ) +) + game ( name "Yakuman (Japan)" description "Yakuman (Japan)" @@ -33500,27 +34123,21 @@ game ( ) game ( - name "Year After, The (World) (Beta 2) (Aftermarket) (Unl)" - description "Year After, The (World) (Beta 2) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Beta 2) (Aftermarket) (Unl).gb" size 1048576 crc 4e463a1a sha1 5d84f53f38aa24f54a6f897ca69ffc5d978805af ) + name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" + description "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc 4e463a1a sha1 5d84f53f38aa24f54a6f897ca69ffc5d978805af ) ) game ( - name "Year After, The (World) (Beta) (Aftermarket) (Unl)" - description "Year After, The (World) (Beta) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc f15351c8 sha1 a78ff2eef780287bbdc37df122cfc1c504526662 ) + name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" + description "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc fbc50ee8 sha1 52c27e64fb37412c97a53d5dde52c3803fd1e4f7 ) ) game ( - name "Year After, The (World) (Pt) (Beta) (Aftermarket) (Unl)" - description "Year After, The (World) (Pt) (Beta) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Pt) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc b70c1c7f sha1 ce25cdf6a6264586423e76e34dc42779d39a1cb1 ) -) - -game ( - name "Year After, The (World) (Fr) (Beta) (Aftermarket) (Unl)" - description "Year After, The (World) (Fr) (Beta) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Fr) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc fbc50ee8 sha1 52c27e64fb37412c97a53d5dde52c3803fd1e4f7 ) + name "Yelu Wangzi (Prince Yeh Rude) (Taiwan) (En) (Unl)" + description "Yelu Wangzi (Prince Yeh Rude) (Taiwan) (En) (Unl)" + rom ( name "Yelu Wangzi (Prince Yeh Rude) (Taiwan) (En) (Unl).gb" size 65536 crc 76ab9719 sha1 e4a762ef26a40fb88b4e89b839da8baa6e06b051 ) ) game ( @@ -33625,6 +34242,12 @@ game ( rom ( name "ZAS (Europe) (Proto).gb" size 131072 crc ae282077 sha1 a480d3a205f4c6fe7da41637180459fb2cff9139 ) ) +game ( + name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" + description "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl).gb" size 524288 crc f86c2766 sha1 ee86a28cf271be43739e406135e4d8bd4edf7686 ) +) + game ( name "Zelda no Densetsu - Yume o Miru Shima (Japan)" description "Zelda no Densetsu - Yume o Miru Shima (Japan)" @@ -33637,6 +34260,18 @@ game ( rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1).gb" size 524288 crc ea20b82a sha1 80f5d111c7e2d79d39f6c25a37b54c3196d2bd12 flags verified ) ) +game ( + name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1) (Demo) (Special Version)" + description "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1) (Demo) (Special Version)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1) (Demo) (Special Version).gb" size 524288 crc bcc0199a sha1 5fc7b8185096c4203536e0d8a302064e63511086 ) +) + +game ( + name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" + description "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" + rom ( name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl).gb" size 2097152 crc 0b10adaf sha1 12f9ba0a4673dd2f59ba38e636332333a199dea5 ) +) + game ( name "Zen - Intergalactic Ninja (Europe)" description "Zen - Intergalactic Ninja (Europe)" @@ -33716,16 +34351,22 @@ game ( ) game ( - name "Zuigao Jimi - Top Secret (Taiwan) (Unl)" - description "Zuigao Jimi - Top Secret (Taiwan) (Unl)" - rom ( name "Zuigao Jimi - Top Secret (Taiwan) (Unl).gb" size 65536 crc f5f8d0b3 sha1 be706d1b46fa1de966f0b3b08e85399177eb148c ) + name "Zuigao Jimi (Top Secret) (Taiwan) (Multicart Rip) (Unl)" + description "Zuigao Jimi (Top Secret) (Taiwan) (Multicart Rip) (Unl)" + rom ( name "Zuigao Jimi (Top Secret) (Taiwan) (Multicart Rip) (Unl).gb" size 65536 crc f5f8d0b3 sha1 be706d1b46fa1de966f0b3b08e85399177eb148c ) +) + +game ( + name "Zuigao Jimi (Top Secret) (Taiwan) (Unl)" + description "Zuigao Jimi (Top Secret) (Taiwan) (Unl)" + rom ( name "Zuigao Jimi (Top Secret) (Taiwan) (Unl).gb" size 65536 crc 46402abe sha1 7afcc6dd82bb236f1ebe01c9b5ccad4d713ccbcf ) ) clrmamepro ( name "Nintendo - Game Boy Color" description "Nintendo - Game Boy Color" - version 20230422-225414 - author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xuom2, zg" + version 20240107-011427 + author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, bikerspade, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, gordonj, halftheisland, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, Psychofox11, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xprism, xuom2, zg" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -33825,6 +34466,24 @@ game ( rom ( name "1942 (USA, Europe).gbc" size 1048576 crc 87431672 sha1 d960e951b18d07e79d046313df49c18313664224 ) ) +game ( + name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 2edc4684 sha1 a00b40a3f31bd875f4a0376d22099c3822c9ef98 ) +) + +game ( + name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc ff0a848b sha1 837cbb4cf3a92266833099fa06b95edfcdb1865f ) +) + +game ( + name "2001 Fatal Fury (Taiwan) (En) (Unl)" + description "2001 Fatal Fury (Taiwan) (En) (Unl)" + rom ( name "2001 Fatal Fury (Taiwan) (En) (Unl).gbc" size 1048576 crc 7eda0e26 sha1 cd632530d71c560111bfc13a341f0f9a234db50a ) +) + game ( name "2002 Adventure Digimon 7 (Taiwan) (En) (Unl)" description "2002 Adventure Digimon 7 (Taiwan) (En) (Unl)" @@ -33849,6 +34508,12 @@ game ( rom ( name "2003 Digimom Sapphii (Taiwan) (En) (Unl).gbc" size 2097152 crc 7cff9f0b sha1 1e42c461e0c6705637a698dbda8b34bc37acc51d ) ) +game ( + name "2003 Digimom Sapphii (Taiwan) (De) (Unl)" + description "2003 Digimom Sapphii (Taiwan) (De) (Unl)" + rom ( name "2003 Digimom Sapphii (Taiwan) (De) (Unl).gbc" size 2097152 crc bd285d64 sha1 1cdffe470fde714898a2b0de92edd88e791a1bdf ) +) + game ( name "2003 Gu Huo Lang II (Taiwan) (Unl)" description "2003 Gu Huo Lang II (Taiwan) (Unl)" @@ -33897,6 +34562,12 @@ game ( rom ( name "2003 Shuma Baolong - Gedou Ban (Taiwan) (Unl).gbc" size 2097152 crc 1219eec6 sha1 4a722c10e3893e04c67a66d0aea401d6d220ec7e ) ) +game ( + name "2123 (World) (Aftermarket) (Unl)" + description "2123 (World) (Aftermarket) (Unl)" + rom ( name "2123 (World) (Aftermarket) (Unl).gbc" size 262144 crc 22836942 sha1 eb9a2aff6485962f1a7773b7138f3c4208fa36e4 ) +) + game ( name "23 in 1 (Taiwan) (Unl)" description "23 in 1 (Taiwan) (Unl)" @@ -33996,7 +34667,7 @@ game ( game ( name "Action Man - Search for Base X (USA, Europe)" description "Action Man - Search for Base X (USA, Europe)" - rom ( name "Action Man - Search for Base X (USA, Europe).gbc" size 1048576 crc 1226499e sha1 4b62b0344b8fed07ceb967f9a9c45bbeed3dc592 ) + rom ( name "Action Man - Search for Base X (USA, Europe).gbc" size 1048576 crc 1226499e sha1 4b62b0344b8fed07ceb967f9a9c45bbeed3dc592 flags verified ) ) game ( @@ -34011,6 +34682,24 @@ game ( rom ( name "Action Replay Xtreme - Special Edition for Pokemon Crystal (Europe) (Unl).gbc" size 131072 crc c288e400 sha1 0280b05885fe5aca8c1884a16bd01513b99f4dc2 flags verified ) ) +game ( + name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 1b5b9e64 sha1 c5dad32be800c36814a0f9b940e99b5eada34150 ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9f81e7a0 sha1 895148bc0a3b6f9ec59bebae43413d1f4eafd21a ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a5d0d1ec sha1 bc6367f77c235640cea5a1230cee253c99f846e5 ) +) + game ( name "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" description "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" @@ -34018,15 +34707,27 @@ game ( ) game ( - name "Agent B (World) (2021-12-29) (GB Compatible) (Aftermarket) (Unl)" - description "Agent B (World) (2021-12-29) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Agent B (World) (2021-12-29) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31b6e3fa sha1 11b3ce59c4eb86cee05873eb473dbf262cf986bd ) + name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" + description "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f689b91e sha1 e55e427819916bb02189efe3883fb1dab3d80d35 ) ) game ( - name "Agent B (World) (2021-12-29) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Agent B (World) (2021-12-29) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Agent B (World) (2021-12-29) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae767ad7 sha1 1a332aac66b24381f16819d1145fd4a917f2e0f3 ) + name "Agency (World) (Aftermarket) (Unl)" + description "Agency (World) (Aftermarket) (Unl)" + rom ( name "Agency (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0d1bb2f7 sha1 5266589244fab2e9ff047af9f72641cda91e1d90 ) +) + +game ( + name "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" + description "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Agent B (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31b6e3fa sha1 11b3ce59c4eb86cee05873eb473dbf262cf986bd ) +) + +game ( + name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae767ad7 sha1 1a332aac66b24381f16819d1145fd4a917f2e0f3 ) ) game ( @@ -34077,6 +34778,12 @@ game ( rom ( name "Aliens - Thanatos Encounter (USA, Europe).gbc" size 1048576 crc bec3c24b sha1 e1b1c79c15a34984dddbe270fc6770b32a31a0d7 ) ) +game ( + name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" + description "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b4d50eed sha1 f4513fc525cbcfa4a2804b55ce20c809e01d1c87 ) +) + game ( name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" description "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" @@ -34173,6 +34880,12 @@ game ( rom ( name "Animorphs (USA).gbc" size 1048576 crc b4f293cc sha1 b3e5b34d5e97c49720861fabb6a29d557029279c ) ) +game ( + name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + description "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc dfcd02ef sha1 041473b2381dd9e11b3cbda5858f9841324327af ) +) + game ( name "Anpfiff - Der RTL Fussball-Manager (Germany)" description "Anpfiff - Der RTL Fussball-Manager (Germany)" @@ -34215,12 +34928,24 @@ game ( rom ( name "Antz World Sportz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 67c7f85c sha1 d8ddf04baad3beadedf85847964f986ba89bc5ee ) ) +game ( + name "Apollo Mission (World) (Aftermarket) (Unl)" + description "Apollo Mission (World) (Aftermarket) (Unl)" + rom ( name "Apollo Mission (World) (Aftermarket) (Unl).gbc" size 262144 crc bec9d9a2 sha1 b2bcc61bcf269c0f5c0ce2a6e0bb1c7015dc9ff9 ) +) + game ( name "Aqualife (Japan) (SGB Enhanced) (GB Compatible)" description "Aqualife (Japan) (SGB Enhanced) (GB Compatible)" rom ( name "Aqualife (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e243feb4 sha1 69eaf53eccdaf98cd7cc0d436209f511b558d761 ) ) +game ( + name "Arena 3000 (World) (Aftermarket) (Unl)" + description "Arena 3000 (World) (Aftermarket) (Unl)" + rom ( name "Arena 3000 (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c17c15c sha1 007d23f73f68de01c250ec3d07403679137851ff ) +) + game ( name "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" description "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" @@ -34248,7 +34973,7 @@ game ( game ( name "Army Men - Air Combat (USA, Europe) (En,Fr,De)" description "Army Men - Air Combat (USA, Europe) (En,Fr,De)" - rom ( name "Army Men - Air Combat (USA, Europe) (En,Fr,De).gbc" size 1048576 crc b0d1de8c sha1 4e1d964d31013e79ecae4a49dcd3777cc7e06af2 ) + rom ( name "Army Men - Air Combat (USA, Europe) (En,Fr,De).gbc" size 1048576 crc b0d1de8c sha1 4e1d964d31013e79ecae4a49dcd3777cc7e06af2 flags verified ) ) game ( @@ -34260,7 +34985,7 @@ game ( game ( name "Army Men 2 (USA, Europe) (En,Fr,De)" description "Army Men 2 (USA, Europe) (En,Fr,De)" - rom ( name "Army Men 2 (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 2272baca sha1 6e52dcaca1a97ae557c4c87e4281667a9d9b14c5 ) + rom ( name "Army Men 2 (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 2272baca sha1 6e52dcaca1a97ae557c4c87e4281667a9d9b14c5 flags verified ) ) game ( @@ -34272,7 +34997,7 @@ game ( game ( name "Asterix - Sur la Trace D'Idefix (Europe) (En,Fr,De,Es,It,Nl)" description "Asterix - Sur la Trace D'Idefix (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Asterix - Sur la Trace D'Idefix (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 408dc5c6 sha1 5c7207137ab422d3326d183d3433db161d8ecbc5 ) + rom ( name "Asterix - Sur la Trace D'Idefix (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 408dc5c6 sha1 5c7207137ab422d3326d183d3433db161d8ecbc5 flags verified ) ) game ( @@ -34293,6 +35018,18 @@ game ( rom ( name "Asteroids (USA, Europe) (GB Compatible).gbc" size 1048576 crc 89d5d936 sha1 026f031e1bb787a4390e7873227dcb52a069a6e0 flags verified ) ) +game ( + name "Astro Plumber (World) (Aftermarket) (Unl)" + description "Astro Plumber (World) (Aftermarket) (Unl)" + rom ( name "Astro Plumber (World) (Aftermarket) (Unl).gbc" size 262144 crc d746db41 sha1 bf46ab2a3a1ffc3b712b9ae5cfa05441781ac9e4 ) +) + +game ( + name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" + description "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc e6a96130 sha1 2cd0ef086c4b89497d9497a17d871a6568a9e2d3 ) +) + game ( name "Atlantis - The Lost Empire (Europe) (En,Es,It)" description "Atlantis - The Lost Empire (Europe) (En,Es,It)" @@ -34311,6 +35048,12 @@ game ( rom ( name "Atlantis - The Lost Empire (USA, Europe).gbc" size 2097152 crc d594d24b sha1 ab5dd8efa36b33ce9aa090b3d990e8fc8828f7e2 ) ) +game ( + name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 0d60b100 sha1 9cc1a5140b96ad072d36151f5d99ff6eb699e605 ) +) + game ( name "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" description "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" @@ -34377,6 +35120,12 @@ game ( rom ( name "Auto Zone (World) (Aftermarket) (Unl).gbc" size 524288 crc 2a86d386 sha1 83a37fb5c5d82e0ff06bb22b63761af996e4ad61 ) ) +game ( + name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" + description "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc eac459fa sha1 68a5520be76c52a4936ad1756ea274667f2ac0e3 ) +) + game ( name "Aventures de Buzz l'Eclair, Les (France)" description "Aventures de Buzz l'Eclair, Les (France)" @@ -34743,6 +35492,12 @@ game ( rom ( name "Bibi und Tina - Fohlen Felix in Gefahr (Germany).gbc" size 1048576 crc 8874acd4 sha1 59843ced1e9cbcb02c6acbb8f533ec77b314882c flags verified ) ) +game ( + name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 65536 crc b0401d96 sha1 ee5f2db597bb2fa06efe4a279a887b97bf23cac6 ) +) + game ( name "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" description "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" @@ -34761,6 +35516,12 @@ game ( rom ( name "Billy Bob's Huntin' 'n' Fishin' (USA, Europe).gbc" size 1048576 crc fa1e6853 sha1 9331fb3103a23340192968715adaa1e4ef140329 flags verified ) ) +game ( + name "Binary Monster 2 (Taiwan) (En) (Unl)" + description "Binary Monster 2 (Taiwan) (En) (Unl)" + rom ( name "Binary Monster 2 (Taiwan) (En) (Unl).gbc" size 131072 crc 16297b29 sha1 bccc7bd374166171f4961b8773bb881050b8a62d ) +) + game ( name "Bingyuan Lixian Ji (Taiwan) (Unl)" description "Bingyuan Lixian Ji (Taiwan) (Unl)" @@ -34791,6 +35552,18 @@ game ( rom ( name "Bionic Commando - Elite Forces (USA, Australia).gbc" size 2097152 crc a663cf31 sha1 33c28a2183f8b95cc2d8e0b6a0b005bfc230f1fc flags verified ) ) +game ( + name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0d464785 sha1 790b9d231f6e66027e76264ef646c7a7cb9c878c ) +) + +game ( + name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + description "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 936443e2 sha1 b874c45d4866d5ef0c0d9837502ae42dd0ea3787 ) +) + game ( name "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" description "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" @@ -34803,6 +35576,12 @@ game ( rom ( name "Black Onyx, The (Japan).gbc" size 1048576 crc 582fe338 sha1 b0f009023a25e575b59e55dec07cda2826f48b65 ) ) +game ( + name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" + description "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 45c5f990 sha1 ec8c467e955d69b2084805f11a954e0d90855461 ) +) + game ( name "Blade (USA, Europe)" description "Blade (USA, Europe)" @@ -34815,6 +35594,12 @@ game ( rom ( name "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2f91e17c sha1 8b2e83d7f2b7d72d5cc1ac81c28c2173ad2fc9ba ) ) +game ( + name "Blaze (World) (Aftermarket) (Unl)" + description "Blaze (World) (Aftermarket) (Unl)" + rom ( name "Blaze (World) (Aftermarket) (Unl).gbc" size 262144 crc 7d2519c7 sha1 f9b1422a91cc1f3a55526ef8ba81b7a8297fc55e ) +) + game ( name "Blinky's Revenge (World) (Aftermarket) (Unl)" description "Blinky's Revenge (World) (Aftermarket) (Unl)" @@ -34833,6 +35618,12 @@ game ( rom ( name "Blue's Clues - Blue's Alphabet Book (USA).gbc" size 1048576 crc 748d1345 sha1 f703b54746cb2ef08deba2518ce7b7a3836142aa ) ) +game ( + name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 440a2260 sha1 8472981264122ea588d991628c51020545779926 ) +) + game ( name "Boarder Zone (USA)" description "Boarder Zone (USA)" @@ -34869,6 +35660,12 @@ game ( rom ( name "Bob the Builder - Fix it Fun! (USA).gbc" size 1048576 crc 93fa37bd sha1 68bd9a1932d4e5333ab5b4dfe0d28f126e5d470f ) ) +game ( + name "Boing! (World) (Aftermarket) (Unl)" + description "Boing! (World) (Aftermarket) (Unl)" + rom ( name "Boing! (World) (Aftermarket) (Unl).gbc" size 2097152 crc 91961796 sha1 09fde4065941784bab4cf8f624a0398049ed4add ) +) + game ( name "Boku no Camp-jou (Japan)" description "Boku no Camp-jou (Japan)" @@ -34893,6 +35690,12 @@ game ( rom ( name "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan) (Rev 1).gbc" size 2097152 crc 75af0e84 sha1 acb2e549fb7d107d20507af88c36f40234f74958 flags verified ) ) +game ( + name "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" + description "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" + rom ( name "Bomb Runner 1-2 (World) (Aftermarket) (Unl).gbc" size 262144 crc d4c95ac0 sha1 3d020eb6e118b431899d79ce4a7bda9bc571c3a0 ) +) + game ( name "Bomberman Max - Ain Version (Japan)" description "Bomberman Max - Ain Version (Japan)" @@ -34965,6 +35768,12 @@ game ( rom ( name "Booty (World) (Aftermarket) (Unl).gbc" size 262144 crc ef6c39c8 sha1 3c487ddc03d935b583e186d1cc395966ef490412 ) ) +game ( + name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e92ce3d4 sha1 1ddf864188dfd741ccda0b0715e75e162d212605 ) +) + game ( name "Bouken! Dondoko Shima (Japan)" description "Bouken! Dondoko Shima (Japan)" @@ -34977,10 +35786,22 @@ game ( rom ( name "Bounced! (Europe) (Proto).gbc" size 1048576 crc 3948aee9 sha1 06d2d0eaea07d7a41834d4c9a5dfdbdda6889be9 ) ) +game ( + name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" + description "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ee1c2e1d sha1 b95dfdf10820671ab5f734ed7180cbf1967ca277 ) +) + game ( name "Brave Saga - Shinshou Astaria (Japan)" description "Brave Saga - Shinshou Astaria (Japan)" - rom ( name "Brave Saga - Shinshou Astaria (Japan).gbc" size 2097152 crc 5d5d294a sha1 952b9e16a938b986a6216b8db6d62f71c4f853fa ) + rom ( name "Brave Saga - Shinshou Astaria (Japan).gbc" size 2097152 crc 5d5d294a sha1 952b9e16a938b986a6216b8db6d62f71c4f853fa flags verified ) +) + +game ( + name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" + description "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" + rom ( name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl).gbc" size 524288 crc 437a2973 sha1 9c219e2c489f5140314e89fbdc0bb387e1f1eed0 ) ) game ( @@ -34989,6 +35810,12 @@ game ( rom ( name "Bubble Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc 3374918b sha1 892388f81f7815ea3bca17632a6a9a33a6edafac ) ) +game ( + name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc e3f64fec sha1 51e302fd27d579c9a4e8109e6ea4af3275d475dd ) +) + game ( name "Buffy the Vampire Slayer (USA, Europe)" description "Buffy the Vampire Slayer (USA, Europe)" @@ -35049,12 +35876,6 @@ game ( rom ( name "Bugs Bunny in - Crazy Castle 4 (USA).gbc" size 1048576 crc 98dbffe0 sha1 a22b9765e901b2a23a48c44b0b829ab73b9c1a82 ) ) -game ( - name "Bulb! (World) (v2.5) (Aftermarket) (Unl)" - description "Bulb! (World) (v2.5) (Aftermarket) (Unl)" - rom ( name "Bulb! (World) (v2.5) (Aftermarket) (Unl).gbc" size 524288 crc 650114a2 sha1 0c32d4b48a34614fb11fc69c17187d35ee22fabe flags verified ) -) - game ( name "Bundesliga Stars 2001 (Germany)" description "Bundesliga Stars 2001 (Germany)" @@ -35079,6 +35900,12 @@ game ( rom ( name "Burger Paradise International (Japan).gbc" size 1048576 crc 9092b0eb sha1 71072a7f0165769649bce8c31c36f67bb0e02963 ) ) +game ( + name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" + description "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a5d6cd6a sha1 7464af8e6d9d0a4b11f510d22789a6830cd4c272 ) +) + game ( name "Bust-A-Move 4 (USA, Europe) (GB Compatible)" description "Bust-A-Move 4 (USA, Europe) (GB Compatible)" @@ -35115,6 +35942,18 @@ game ( rom ( name "Caise Gedou 29 in 1 Diannao Huamian Xuan Game (Taiwan) (Unl).gbc" size 2097152 crc 78c0e5bc sha1 358e628e680bc63227940ca6d76217d14fcd3409 flags verified ) ) +game ( + name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52da152b sha1 1bb4a376c03af67ca1e8426375fe1a644499d9ae ) +) + +game ( + name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" + description "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" + rom ( name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 1f2823cb sha1 8906832db7816be01ed37728f6e5a23e981e7e38 ) +) + game ( name "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" description "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" @@ -35181,6 +36020,12 @@ game ( rom ( name "Cardcaptor Sakura - Tomoeda Shougakkou Daiundoukai (Japan).gbc" size 2097152 crc f78f7998 sha1 1809154979b289750b572a61da1dc93b1b76360f ) ) +game ( + name "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cargo (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a65d66f4 sha1 83c35ad553bde5ce3a6af418d7f8ad1fbe73b0f6 ) +) + game ( name "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl)" description "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl)" @@ -35253,6 +36098,12 @@ game ( rom ( name "Casper (USA).gbc" size 1048576 crc c775d653 sha1 82ac50380c3ed39fad13cc0bbe35e6457806a294 ) ) +game ( + name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 280937cc sha1 9ec53942f0136076b6468671562764e1ab9dee3b ) +) + game ( name "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" description "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" @@ -35295,6 +36146,12 @@ game ( rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gbc" size 262144 crc 6f4641f0 sha1 05b441e3542452b1724017d20e2db602d0997773 ) ) +game ( + name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc defb3151 sha1 94770d13bd9b1b52224fe753f94ec580e1b4017c ) +) + game ( name "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" description "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" @@ -35308,9 +36165,9 @@ game ( ) game ( - name "CGB Test Cartridge (Japan) (En)" - description "CGB Test Cartridge (Japan) (En)" - rom ( name "CGB Test Cartridge (Japan) (En).gbc" size 65536 crc 4c050e29 sha1 5133d3dc7a4ced9d059dc72f0f351cb44e22f096 ) + name "CGB Test Cartridge (Japan) (En) [b]" + description "CGB Test Cartridge (Japan) (En) [b]" + rom ( name "CGB Test Cartridge (Japan) (En) [b].gbc" size 65536 crc 4c050e29 sha1 5133d3dc7a4ced9d059dc72f0f351cb44e22f096 flags baddump ) ) game ( @@ -35373,6 +36230,12 @@ game ( rom ( name "Chase H.Q. - Secret Police (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 7c7fdefc sha1 030b45eb8929c1512826f288e4ba035e0083505c ) ) +game ( + name "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" + description "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" + rom ( name "Chase the Chuck Wagon (World) (Aftermarket) (Unl).gbc" size 262144 crc 3c3d653c sha1 27b462be532a37c15798eba0fd48154eff596753 ) +) + game ( name "Checkmate (Japan) (En,Ja) (GB Compatible)" description "Checkmate (Japan) (En,Ja) (GB Compatible)" @@ -35391,6 +36254,12 @@ game ( rom ( name "Chessmaster (USA, Europe) (GB Compatible).gbc" size 1048576 crc 1c13dbb0 sha1 84930fa75eccc34a8e9fb6a0387791d437d1a442 flags verified ) ) +game ( + name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 490a874a sha1 92567a6a58739a38e0d7b35d1327ccb999527fa0 ) +) + game ( name "Chi to Ase to Namida no Koukou Yakyuu (Japan)" description "Chi to Ase to Namida no Koukou Yakyuu (Japan)" @@ -35421,12 +36290,24 @@ game ( rom ( name "Chongwu Xiao Jingling - Jiejin Ta Zhi Wang (Taiwan) (Unl).gbc" size 1048576 crc 620e785d sha1 74da832c2eeb27a4260fe6f42514539473f48b11 ) ) +game ( + name "Chopper War (World) (Aftermarket) (Unl)" + description "Chopper War (World) (Aftermarket) (Unl)" + rom ( name "Chopper War (World) (Aftermarket) (Unl).gbc" size 524288 crc eb0f4f3e sha1 26970bb0753e792aaeb328e0f88d650acd413a9d ) +) + game ( name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible)" description "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible)" rom ( name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 65610ca4 sha1 8af215c632599aaab9bc4614194ac45802407bbc ) ) +game ( + name "Choro-Q (World) (Aftermarket) (Unl)" + description "Choro-Q (World) (Aftermarket) (Unl)" + rom ( name "Choro-Q (World) (Aftermarket) (Unl).gbc" size 262144 crc e40e99bd sha1 8534c4fe58aef32b8cfd4812fa1f2c1094e6b129 ) +) + game ( name "Chuanshuo (Taiwan) (Unl)" description "Chuanshuo (Taiwan) (Unl)" @@ -35451,6 +36332,12 @@ game ( rom ( name "Climb It (World) (Aftermarket) (Unl).gbc" size 262144 crc e7210290 sha1 19f3b825eada3eda3135350bd0ddca6a20a5281f ) ) +game ( + name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c4b00adb sha1 07e4254c7f74b9d4caa6a1231558b2430dff163a flags verified ) +) + game ( name "Colin McRae Rally (Europe)" description "Colin McRae Rally (Europe)" @@ -35487,6 +36374,12 @@ game ( rom ( name "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc a50be9a8 sha1 e9c3b1bb20ea74f363191ea9144009d1b13246bb flags verified ) ) +game ( + name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" + description "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c53ace00 sha1 02fdc52bc934b80aa41520d92cf0340753d8f668 ) +) + game ( name "Cool Bricks (Europe) (En,Fr,De,Es,It)" description "Cool Bricks (Europe) (En,Fr,De,Es,It)" @@ -35499,6 +36392,24 @@ game ( rom ( name "Cool Hand (Europe) (En,Fr,De) (GB Compatible).gbc" size 524288 crc e6c91fb8 sha1 d116a77c501d5e553d1490993f8c0a9a92c3ea0c ) ) +game ( + name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc fe1bdae6 sha1 00d86bbdbc228ff3ea0684984a261cadbed5fb0a ) +) + +game ( + name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 1780b904 sha1 fcbe2c2389e6c51a38eb17eb80ffb2e51955c7f2 ) +) + +game ( + name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc e983a31f sha1 1d811dd440572243f9e95527d970f3ffa91ddbdf ) +) + game ( name "Crazy Bikers (Europe)" description "Crazy Bikers (Europe)" @@ -35622,7 +36533,7 @@ game ( game ( name "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced) (GB Compatible)" description "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced) (GB Compatible)" - rom ( name "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 2f368da6 sha1 0854b7ea4791a460c75ce9096583934b1af053e8 ) + rom ( name "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 2f368da6 sha1 0854b7ea4791a460c75ce9096583934b1af053e8 flags verified ) ) game ( @@ -35661,6 +36572,36 @@ game ( rom ( name "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e2071293 sha1 2d961353e7242babce49dda8d017a459f4ef7609 ) ) +game ( + name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl).gbc" size 262144 crc 502385c4 sha1 3a310be21d5cc077da6eb8e3afa99ccff2eda84e ) +) + +game ( + name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc a504b906 sha1 4634631f2c0b4a618aeefc114e5b8e4ba9c7ee04 ) +) + +game ( + name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl).gbc" size 262144 crc a9714871 sha1 7d5b22d1c528603007e340f9d3562c1e53f10796 ) +) + +game ( + name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl).gbc" size 262144 crc 26d3fe7a sha1 36c9649d4e99fdcaa4cf590963d0c49a3cf8084e ) +) + +game ( + name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" + description "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc d34b719a sha1 446ca937d3e54ce33a49d1fff4692b3b906b539e ) +) + game ( name "Dance Dance Revolution GB (Japan)" description "Dance Dance Revolution GB (Japan)" @@ -35691,6 +36632,12 @@ game ( rom ( name "Dancing Furby (Japan) (GB Compatible).gbc" size 1048576 crc 3263f692 sha1 f3f7e37d64eef74d65456bae490e0a0b25897ac0 ) ) +game ( + name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc df19aa9f sha1 412f18ba08f2f2a2afbf3bfb5281e360d7aba31d ) +) + game ( name "Data-Navi Pro Yakyuu (Japan)" description "Data-Navi Pro Yakyuu (Japan)" @@ -35727,6 +36674,24 @@ game ( rom ( name "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc c25ee35a sha1 be0703ee2667ddc53cff9d6c7d22b30d272c0738 ) ) +game ( + name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc bb64f51c sha1 1611ddfdb9af72f20ddeca4133d8eebd0f14e424 ) +) + +game ( + name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" + description "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" + rom ( name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl).gbc" size 262144 crc 57ca8f69 sha1 8992f14f02bd37e11cb05511c17fff3d253ccf25 ) +) + +game ( + name "Days Without (World) (Aftermarket) (Unl)" + description "Days Without (World) (Aftermarket) (Unl)" + rom ( name "Days Without (World) (Aftermarket) (Unl).gbc" size 262144 crc 437b4921 sha1 cb21c1bca18d750ecde91dc3adb6b599c2ad75fa ) +) + game ( name "Deadly Skies (Europe) (En,Fr,De)" description "Deadly Skies (Europe) (En,Fr,De)" @@ -35823,6 +36788,12 @@ game ( rom ( name "Dexter's Laboratory - Robot Rampage (USA, Europe).gbc" size 1048576 crc d24d6601 sha1 db107af55df07fb8c771c712b05d6aebb175e3c5 ) ) +game ( + name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c6b965b9 sha1 ac43f43bdcfc0347f24a0a70de213a4b701d8155 ) +) + game ( name "Digimon - Yellow Jade (USA) (Unl)" description "Digimon - Yellow Jade (USA) (Unl)" @@ -35853,6 +36824,12 @@ game ( rom ( name "Digimon Adventure 2001 (USA) (Unl).gbc" size 1048576 crc 01f1fcee sha1 cb4327829bc90c7bb448e7591e6ee3729a12a8cd ) ) +game ( + name "Digimon Amethyst (USA) (Unl)" + description "Digimon Amethyst (USA) (Unl)" + rom ( name "Digimon Amethyst (USA) (Unl).gbc" size 2097152 crc 726eed2a sha1 0b5f44cc2f583182a91ed8a815a3e7cec3bd1a58 ) +) + game ( name "Digimon Crystal II (USA) (Unl)" description "Digimon Crystal II (USA) (Unl)" @@ -35871,6 +36848,12 @@ game ( rom ( name "Digimon Saphire (USA) (Unl).gbc" size 1048576 crc be4c1d83 sha1 f5706a80bae20027d7643ab151607adbe13e6b1d ) ) +game ( + name "Digital Monster 2001 (Taiwan) (En) (Unl)" + description "Digital Monster 2001 (Taiwan) (En) (Unl)" + rom ( name "Digital Monster 2001 (Taiwan) (En) (Unl).gbc" size 524288 crc d9eb3f2a sha1 cc7d4a2e5bf1fbee8e0a0e0960f4038fca3e458f ) +) + game ( name "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced) (GB Compatible)" description "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced) (GB Compatible)" @@ -35907,6 +36890,18 @@ game ( rom ( name "Dinosaur'us (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc f4609fe3 sha1 d0caf4b5172651aee2bbe38efdae084ce3d7a7ff ) ) +game ( + name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" + description "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ef349515 sha1 06fe25086432c82f1e4b4c44473dd5b487a8af05 ) +) + +game ( + name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" + description "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7c0f52cc sha1 8bc16b70838f9245b7e37c6dbe57159b294fbf81 ) +) + game ( name "Diva Starz (Europe)" description "Diva Starz (Europe)" @@ -35932,9 +36927,9 @@ game ( ) game ( - name "Doc Cosmos - The Saga Begins (World) (Aftermarket) (Unl)" - description "Doc Cosmos - The Saga Begins (World) (Aftermarket) (Unl)" - rom ( name "Doc Cosmos - The Saga Begins (World) (Aftermarket) (Unl).gbc" size 262144 crc 754dff51 sha1 a066d9973a2b90a08067dfcd22b04844557e89e2 ) + name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" + description "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f4ff5eb0 sha1 6b421505acc626a34bb9306a3d88e1964a4502f3 ) ) game ( @@ -35967,6 +36962,24 @@ game ( rom ( name "Dokidoki Densetsu - Mahoujin Guruguru (Japan).gbc" size 4194304 crc 83e47a1a sha1 1b4627699b45af36a42e75c1a217b40fb5bec4ba ) ) +game ( + name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52cf7153 sha1 74e6246405dd52d4c5c2eabc417946550c637164 ) +) + +game ( + name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8ca9dbe0 sha1 cf6eaac37c4ae1b3cfc4ed8d2ce73a143635b525 ) +) + +game ( + name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 3d87efd8 sha1 83201c43e9fc89f4393678ade8c6107b4cfdb628 ) +) + game ( name "Donald Duck - Daisy o Sukue! (Japan)" description "Donald Duck - Daisy o Sukue! (Japan)" @@ -36105,6 +37118,12 @@ game ( rom ( name "Doug's Big Game (Europe).gbc" size 1048576 crc b6ffbcca sha1 e9c207bb9b03b5762afd53c8f5295703cc1474b1 ) ) +game ( + name "Downer (World) (GB Compatible) (Aftermarket) (Unl)" + description "Downer (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Downer (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7a1c9a9f sha1 70044dca1282f4445fe05305586ecc69f4e52304 ) +) + game ( name "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" description "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" @@ -36249,6 +37268,18 @@ game ( rom ( name "Dragon Ball Z 3 - 2002 Fighting (Taiwan) (En) (Unl).gbc" size 2097152 crc dbe0f44e sha1 baea9e5ee1411988039d563ece97d8d7f765396a ) ) +game ( + name "Dragon Ball Z Gedou 2005 (Taiwan) (Unl)" + description "Dragon Ball Z Gedou 2005 (Taiwan) (Unl)" + rom ( name "Dragon Ball Z Gedou 2005 (Taiwan) (Unl).gbc" size 2097152 crc d1c48145 sha1 8637ed614dc94e846c32adbc723e09a06b3da3ce ) +) + +game ( + name "Dragon Dance (USA) (SGB Enhanced) (GB Compatible)" + description "Dragon Dance (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Dance (USA) (SGB Enhanced) (GB Compatible).gbc" size 262144 crc 0602dbe1 sha1 a28bfabc4db62ad5aa6bfe29114b0878429586cc ) +) + game ( name "Dragon Dance (Europe) (Proto) (SGB Enhanced) (GB Compatible)" description "Dragon Dance (Europe) (Proto) (SGB Enhanced) (GB Compatible)" @@ -36267,12 +37298,6 @@ game ( rom ( name "Dragon Dance (USA) (Beta 2) (SGB Enhanced) (GB Compatible).gbc" size 262144 crc 9a90adbe sha1 5fc97752a98a18b7e2db238d1ab88c6b09e34602 ) ) -game ( - name "Dragon Dance (USA) (SGB Enhanced) (GB Compatible)" - description "Dragon Dance (USA) (SGB Enhanced) (GB Compatible)" - rom ( name "Dragon Dance (USA) (SGB Enhanced) (GB Compatible).gbc" size 262144 crc 0602dbe1 sha1 a28bfabc4db62ad5aa6bfe29114b0878429586cc ) -) - game ( name "Dragon Quest I & II (Japan) (SGB Enhanced) (GB Compatible)" description "Dragon Quest I & II (Japan) (SGB Enhanced) (GB Compatible)" @@ -36381,6 +37406,24 @@ game ( rom ( name "Dragon's Lair (USA, Europe) (En,Ja,Fr,De,Es,Zh).gbc" size 4194304 crc bf076ca5 sha1 15fb0865314e43a83910d52cca7307502aab29fc ) ) +game ( + name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 9f30b891 sha1 9974d28975a2d8e1e41ce8f32351c6eef144919d ) +) + +game ( + name "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 96f9b7c0 sha1 2b74d076cabff92e5935d922e8f37202a723aaf0 flags verified ) +) + +game ( + name "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc cad7369d sha1 0058096f8fcbb2774f908811aaa0b1ee54111493 ) +) + game ( name "Driver (Europe) (En,Fr,De,Es,It)" description "Driver (Europe) (En,Fr,De,Es,It)" @@ -36453,6 +37496,18 @@ game ( rom ( name "Dungeon Savior (Japan) (Rev 1) (Proto) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 0180364b sha1 c5e93f04cc41404320aaf70eb10b55465edb1083 ) ) +game ( + name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7c41cef6 sha1 e2df238887da0b6cf79513c7799ad707740eae30 ) +) + +game ( + name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc abb154db sha1 f3b456d6318bee05150403efa5a933996e1d744a ) +) + game ( name "DX Jinsei Game (Japan)" description "DX Jinsei Game (Japan)" @@ -36531,6 +37586,12 @@ game ( rom ( name "Elemental Fighter (USA) (Proto).gbc" size 262144 crc 03fc3d03 sha1 92cce7614474d3f9ed9e3fdbd2e2bb434e074565 ) ) +game ( + name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc bffec2e1 sha1 a25cc6ee07e524f9a7121786bd0e513a1c6c2a8d ) +) + game ( name "Elevator Action EX (Europe) (En,Fr,De,Es,It)" description "Elevator Action EX (Europe) (En,Fr,De,Es,It)" @@ -36556,9 +37617,15 @@ game ( ) game ( - name "Emo Cheng DX (Taiwan) (Beta) (Unl)" - description "Emo Cheng DX (Taiwan) (Beta) (Unl)" - rom ( name "Emo Cheng DX (Taiwan) (Beta) (Unl).gbc" size 1048576 crc ebf7bf6e sha1 29b1b595ca8f5ad76ebf4f997d0e4fb8069829f1 ) + name "Emo Cheng DX (Taiwan) (Demo) (Unl)" + description "Emo Cheng DX (Taiwan) (Demo) (Unl)" + rom ( name "Emo Cheng DX (Taiwan) (Demo) (Unl).gbc" size 1048576 crc ebf7bf6e sha1 29b1b595ca8f5ad76ebf4f997d0e4fb8069829f1 ) +) + +game ( + name "Emo Cheng DX (Taiwan) (Unl)" + description "Emo Cheng DX (Taiwan) (Unl)" + rom ( name "Emo Cheng DX (Taiwan) (Unl).gbc" size 4194304 crc 5c388c6d sha1 7919fe7b54a5bc53ebacc13dd338be9e841dadf7 ) ) game ( @@ -36579,6 +37646,12 @@ game ( rom ( name "Emperor's New Groove, The (USA).gbc" size 2097152 crc 6ebad539 sha1 ba663289bd5d9d09bc8b9ac2c1d38293dcba9c02 ) ) +game ( + name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9ca3cf6c sha1 d3f4d21bf543431672268b476802693b2da9b6b9 ) +) + game ( name "Equestriad 2001 (Europe) (Proto)" description "Equestriad 2001 (Europe) (Proto)" @@ -36630,7 +37703,13 @@ game ( game ( name "Evel Knievel (USA) (GB Compatible)" description "Evel Knievel (USA) (GB Compatible)" - rom ( name "Evel Knievel (USA) (GB Compatible).gbc" size 2097152 crc 51e951b5 sha1 24cac6ab0151b33d2b1fd06ee01931802fb98267 ) + rom ( name "Evel Knievel (USA) (GB Compatible).gbc" size 2097152 crc 51e951b5 sha1 24cac6ab0151b33d2b1fd06ee01931802fb98267 flags verified ) +) + +game ( + name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + description "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f222b03b sha1 c14f008cfc182f35fe670e14b57052ae4f8d1c60 ) ) game ( @@ -36759,6 +37838,54 @@ game ( rom ( name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c4d3628f sha1 d07b600cc9af8cadc2581a6ac19aadea79313d69 flags verified ) ) +game ( + name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc bdaf8f3f sha1 d1ed0fb4d926f4c337399ca342644f89cf00790a ) +) + +game ( + name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e61c1dc2 sha1 d7a88a68ec65d9cf3f9521fc9ad9d3f4b51bac5d ) +) + +game ( + name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 63c6c960 sha1 b62ec7a341ea9a0bfe8f0b014da971b73606a86e ) +) + +game ( + name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc de373eba sha1 dbf2228017515b407ed9f4a9b3bf01bc2a5f7b0f ) +) + +game ( + name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" + description "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc 701847f5 sha1 aba3fecd55c0cee7fbe49506b367b7e94b56b81c ) +) + +game ( + name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" + description "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc f87760b3 sha1 ea0dd170812d1bcc38de1cabe12a372cd2178c95 ) +) + +game ( + name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" + description "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" + rom ( name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate).gbc" size 524288 crc 7bec6553 sha1 bdcadc0f98d8c9061cbe83c53a047719280b6e09 ) +) + +game ( + name "Fellowship of the Rings (Taiwan) (En) (Unl)" + description "Fellowship of the Rings (Taiwan) (En) (Unl)" + rom ( name "Fellowship of the Rings (Taiwan) (En) (Unl).gbc" size 524288 crc 4bcc59dc sha1 837232bd2eeb50b276049d0908f8ed4dc7efbcfe ) +) + game ( name "Feng Kuang A Gei III - Chaoji Zhadan Ren (Taiwan) (Unl)" description "Feng Kuang A Gei III - Chaoji Zhadan Ren (Taiwan) (Unl)" @@ -36856,9 +37983,15 @@ game ( ) game ( - name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" - description "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" - rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc a5b09726 sha1 2f7fb1afedd6c9657715b45397dc5492e40dfe45 flags verified ) + name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + description "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 507f9ea2 sha1 28ad64e379dc60d6e1c2617e073f6361c0feb475 flags verified ) +) + +game ( + name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + description "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc fcc05ec4 sha1 64d31f34e189b3af08bf0c659a93f71dbf83ef71 ) ) game ( @@ -36873,12 +38006,30 @@ game ( rom ( name "Flintstones, The - Burgertime in Bedrock (USA).gbc" size 1048576 crc 14d8cc5d sha1 065851358f6720d4926faa42b015da68cafa6c28 ) ) +game ( + name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" + description "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" + rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc a5b09726 sha1 2f7fb1afedd6c9657715b45397dc5492e40dfe45 flags verified ) +) + game ( name "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" rom ( name "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 08b9e4aa sha1 3d538b78ef5f1238f47531c069921056b00e33b3 ) ) +game ( + name "Flooder (World) (Aftermarket) (Unl)" + description "Flooder (World) (Aftermarket) (Unl)" + rom ( name "Flooder (World) (Aftermarket) (Unl).gbc" size 32768 crc 253dcbe0 sha1 8fdcd8b02604ac5259fb6aa80e5ba67a03c861fb ) +) + +game ( + name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" + description "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" + rom ( name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl).gbc" size 32768 crc cdda76f8 sha1 e5eec8efc032aa5bce1826f7b6b8790c61c96e06 ) +) + game ( name "Floracy (Europe) (Proto) (2000-10-10)" description "Floracy (Europe) (Proto) (2000-10-10)" @@ -36892,9 +38043,15 @@ game ( ) game ( - name "Formula One 2000 (USA)" - description "Formula One 2000 (USA)" - rom ( name "Formula One 2000 (USA).gbc" size 1048576 crc 703c057f sha1 7a38195842e536581fdcea42e4ebe50967581736 ) + name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" + description "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fa2d92a1 sha1 24f02d116aafb7b55d6cfd6d263b7595986af843 ) +) + +game ( + name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4c21e563 sha1 f6f84f1a44d41fa7d26a9195ddf791fae53dfcdf ) ) game ( @@ -36903,6 +38060,12 @@ game ( rom ( name "Formula One 2000 (Europe) (En,Fr,De,Es,It) (Proto).gbc" size 1048576 crc e689bf16 sha1 7aa7073b7b494522f7cfcd268aa066b7fe52c671 ) ) +game ( + name "Formula One 2000 (USA)" + description "Formula One 2000 (USA)" + rom ( name "Formula One 2000 (USA).gbc" size 1048576 crc 703c057f sha1 7a38195842e536581fdcea42e4ebe50967581736 ) +) + game ( name "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt)" description "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt)" @@ -36915,6 +38078,24 @@ game ( rom ( name "Freestyle Scooter (Europe).gbc" size 1048576 crc ee79117d sha1 cf6ae174584bbfb5ae30478841114443adc00245 ) ) +game ( + name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" + description "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7543586a sha1 397821751ac6464582f61566f3a7c731a46b24ba ) +) + +game ( + name "Friendly Fire (World) (Aftermarket) (Unl)" + description "Friendly Fire (World) (Aftermarket) (Unl)" + rom ( name "Friendly Fire (World) (Aftermarket) (Unl).gbc" size 262144 crc 5c6dca2b sha1 8f8085010e28aa8bdb312d086b0002b706742282 ) +) + +game ( + name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc d8be10d6 sha1 d09f4d2f799ac2e2731be0171625846d28d0f57e ) +) + game ( name "Frogger (USA) (Rev 2) (GB Compatible)" description "Frogger (USA) (Rev 2) (GB Compatible)" @@ -36951,6 +38132,12 @@ game ( rom ( name "Frogger 2 (USA) (Rev 1).gbc" size 1048576 crc e3227b7d sha1 0d5028ca6fcc10df46d11cd4b56e5add1dc5e63e ) ) +game ( + name "From Below Pocket (World) (Aftermarket) (Unl)" + description "From Below Pocket (World) (Aftermarket) (Unl)" + rom ( name "From Below Pocket (World) (Aftermarket) (Unl).gbc" size 131072 crc 35ad9b5a sha1 c0e072bfb88c84dc68b2eded1f9c088d75ffa5ed ) +) + game ( name "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (Beta 1) (SGB Enhanced) (GB Compatible)" description "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (Beta 1) (SGB Enhanced) (GB Compatible)" @@ -36993,6 +38180,12 @@ game ( rom ( name "Front Row (Japan).gbc" size 1048576 crc 6eea9243 sha1 64c8a9459d7c80e297774dab7775b5edf59432cc ) ) +game ( + name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" + description "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 85edfba4 sha1 8a95571a32c5a23bd6be4edf6429f630d7a1a15a ) +) + game ( name "Full Time Soccer (Europe) (Unl)" description "Full Time Soccer (Europe) (Unl)" @@ -37005,6 +38198,12 @@ game ( rom ( name "Full Time Soccer & Hang Time Basketball (Europe) (Unl).gbc" size 524288 crc 0634c196 sha1 aefb746984b3450b90bbfaa5de21a252685ddabb ) ) +game ( + name "Fury (World) (Aftermarket) (Unl)" + description "Fury (World) (Aftermarket) (Unl)" + rom ( name "Fury (World) (Aftermarket) (Unl).gbc" size 262144 crc 7217c41d sha1 ef532b587eb438f1a39a77086ac0b8bbae23a16d ) +) + game ( name "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (AFMJ)" description "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (AFMJ)" @@ -37023,6 +38222,12 @@ game ( rom ( name "G-Man (World) (Aftermarket) (Unl).gbc" size 524288 crc ff3beab1 sha1 cb9486ca9a6ad3903662963aa966145257ef92a6 ) ) +game ( + name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc fd2e40f4 sha1 e442316132506ff223a9e5f33d874b71ec09d71a flags verified ) +) + game ( name "Gaiamaster Duel - Card Attackers (Japan)" description "Gaiamaster Duel - Card Attackers (Japan)" @@ -37071,6 +38276,12 @@ game ( rom ( name "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1ac625da sha1 64ccb3b41715080a9aa13970678aa9047fc7a9fd flags verified ) ) +game ( + name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f1948966 sha1 14849ab5831c71949ec3a1fe7657050057d2cf29 ) +) + game ( name "Game Boy Color (World) (Demo) (Kiosk)" description "Game Boy Color (World) (Demo) (Kiosk)" @@ -37209,6 +38420,66 @@ game ( rom ( name "GB Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP).gbc" size 131072 crc ec823cc1 sha1 0781eaecb7fd25c068e396b5eb02c6231baf6ea3 ) ) +game ( + name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f20c0097 sha1 691af25434a09931a302ced52c757d28b9b06619 ) +) + +game ( + name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 164999eb sha1 197d3d194d4cb6cae9a358f7fb53d6de649e7c5f ) +) + +game ( + name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 60b075d1 sha1 0a66254b2327b48657de64d6102ac05f1e8700e7 ) +) + +game ( + name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 1a169897 sha1 0636b968e8e24fe7c1910f61db6e94fa84824494 ) +) + +game ( + name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 593965ff sha1 75d566045a680aaed4d40b83b6418cbfab5b4422 ) +) + +game ( + name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc d81ab567 sha1 1dfd3c4508ffb6598662bcf1b16ec109a9282dd5 ) +) + +game ( + name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f795689c sha1 9a332127182e8155d1a3dc53e1382a6c9dde6aeb ) +) + +game ( + name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 660ed37b sha1 0792fbef010cac21c12cbcb8b3c85b3af30faec4 ) +) + +game ( + name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 6dc4faaa sha1 7617083f9b13b2f95bdf1b0b327ffb4f8ccbe3c9 ) +) + +game ( + name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 8780e125 sha1 7163bfbaa2cae2f9d41c472128f69a4fa5879180 ) +) + game ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt)" description "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt)" @@ -37221,6 +38492,12 @@ game ( rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl).gbc" size 1048576 crc 1b1c6f68 sha1 fd06c62b42878e8094e610b180c1848c785f67e9 ) ) +game ( + name "Gedou Zhizun 2003 (Taiwan) (Unl)" + description "Gedou Zhizun 2003 (Taiwan) (Unl)" + rom ( name "Gedou Zhizun 2003 (Taiwan) (Unl).gbc" size 1048576 crc f7630d88 sha1 f43c4055f69a1ff6b325494b5b34c8043914cd9d ) +) + game ( name "Geheimnis der Happy Hippo-Insel, Das (Germany)" description "Geheimnis der Happy Hippo-Insel, Das (Germany)" @@ -37275,6 +38552,24 @@ game ( rom ( name "Gex 3 - Deep Pocket Gecko (USA).gbc" size 2097152 crc 85a98c7d sha1 0da71536a3e92dd537c7067ec1014a262dbc3837 ) ) +game ( + name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc 4aa9a9c2 sha1 ac697bc27a126c1389e6bef94a2c83404e8819f2 ) +) + +game ( + name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 32e2ea48 sha1 ee11d5397316b69eee5ae3023de08c3b919c93df ) +) + +game ( + name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ea87ad5d sha1 433e25df1421e77cdc807296e1ed662d9e43d685 ) +) + game ( name "Ghost Town (World) (Aftermarket) (Unl)" description "Ghost Town (World) (Aftermarket) (Unl)" @@ -37335,6 +38630,12 @@ game ( rom ( name "Gobs of Games (USA) (En,Fr,De).gbc" size 1048576 crc 2e61c391 sha1 89695361ccbca372662f6634678a40ea676076a7 ) ) +game ( + name "Gods of the Universe (World) (Aftermarket) (Unl)" + description "Gods of the Universe (World) (Aftermarket) (Unl)" + rom ( name "Gods of the Universe (World) (Aftermarket) (Unl).gbc" size 262144 crc 27b87354 sha1 74eb8cd698097290b93fb08d9b19486d05411877 ) +) + game ( name "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" description "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" @@ -37419,6 +38720,12 @@ game ( rom ( name "Goraku Ou Tango! (Japan) (GB Compatible).gbc" size 1048576 crc 81fb43e1 sha1 1d49232763c1422a00cbb893d0f900c44a2ccf54 ) ) +game ( + name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ab10cec6 sha1 9dcaa6824fab806683737bdf1c76609c68c451a5 ) +) + game ( name "Grand Casino (Japan) (Proto)" description "Grand Casino (Japan) (Proto)" @@ -37467,6 +38774,24 @@ game ( rom ( name "Granduel - Shinki Dungeon no Hihou (Japan) (Sample).gbc" size 2097152 crc 7122136d sha1 534fc9ae5800eb935460f145e1bbc57f77ab2555 ) ) +game ( + name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a5ad3c0b sha1 1cf0cf6d1da5c5337856ecc0a60d2e9fb3c98f58 ) +) + +game ( + name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" + description "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b29fc03f sha1 2f979202a4bf4f98f3026a7548a8b6c7008806bf ) +) + +game ( + name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a0e998e1 sha1 ab656383e9aaaa2991aa344bdc8f21370f0eda36 ) +) + game ( name "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" description "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" @@ -37503,6 +38828,54 @@ game ( rom ( name "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta).gbc" size 1048576 crc c38d52e7 sha1 675623b58fa0d307355c77d7a4783af7927681e9 ) ) +game ( + name "Grimace's Birthday (World) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (Aftermarket) (Unl).gbc" size 1048576 crc 7f4386e9 sha1 d6358d100ea65d34d95588f800635b64927baf82 ) +) + +game ( + name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl).gbc" size 1048576 crc 7744f551 sha1 035b7417e03c4e264a90212f2a3811012f03c2a2 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl).gbc" size 1048576 crc 9dee42fe sha1 071fa179df96950c3c92b0abbe32092b1816ec40 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc 9baa5f46 sha1 d247c03119ac14f97fdeeaa6bf0defa98e35fa17 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc ab41a9ef sha1 d8e727745e285f5e467f5eccbfd30ee175bafc2e flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl).gbc" size 1048576 crc f8e8e1f3 sha1 a3fdfe3981e800fa7c73ff989bc06426f668c331 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl).gbc" size 1048576 crc a7b59d7b sha1 295fdc3218d1699dea6d5832d068b721fccf9bd4 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc f3879ef0 sha1 27d7ee2f31bf575185711217c3cc9e08cbc5928a flags verified ) +) + game ( name "Grinch (Japan)" description "Grinch (Japan)" @@ -37539,6 +38912,18 @@ game ( rom ( name "Gun Law (World) (Aftermarket) (Unl).gbc" size 262144 crc 3a0b6823 sha1 c49f7e0a5055f836528a7bc0cb6f45f221c76475 ) ) +game ( + name "Gunslinger (World) (Aftermarket) (Unl)" + description "Gunslinger (World) (Aftermarket) (Unl)" + rom ( name "Gunslinger (World) (Aftermarket) (Unl).gbc" size 262144 crc 0dfd765f sha1 8410ef1558649f9badc71629827ba1500510d221 ) +) + +game ( + name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" + description "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" + rom ( name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl).gbc" size 524288 crc 2d9b59bf sha1 d89fe1cd97d1ef2c457aa90b1c00e7b473c57270 ) +) + game ( name "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" description "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" @@ -37557,6 +38942,12 @@ game ( rom ( name "Gute Zeiten Schlechte Zeiten Quiz (Germany) (GB Compatible).gbc" size 1048576 crc 5f13a2d4 sha1 611d8ab71bdeb6b0fd292118676e85e940d11bd4 ) ) +game ( + name "Guzzler (World) (Aftermarket) (Unl)" + description "Guzzler (World) (Aftermarket) (Unl)" + rom ( name "Guzzler (World) (Aftermarket) (Unl).gbc" size 524288 crc 3684abd0 sha1 e36cd02fe2b697901843c4cbf6d83da8a9b7b923 ) +) + game ( name "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" description "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" @@ -37587,6 +38978,12 @@ game ( rom ( name "Halloween Racer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 70f3b431 sha1 15bf27a7847817fbbb9cb7729b8046a6d70164c5 ) ) +game ( + name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" + description "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c7297c31 sha1 c38cc0e80a2e04693e3a86574c03f23f3e472c88 flags verified ) +) + game ( name "Hamster Club (Japan) (GB Compatible)" description "Hamster Club (Japan) (GB Compatible)" @@ -37659,6 +39056,18 @@ game ( rom ( name "Hamtaro - Ham-Hams Unite! (USA).gbc" size 2097152 crc 1271117f sha1 9770bf59e932b41882839ce9eec033f576094fee flags verified ) ) +game ( + name "Hamtaro - Ham-Hams Unite! (USA) (2002-08-07) (Beta)" + description "Hamtaro - Ham-Hams Unite! (USA) (2002-08-07) (Beta)" + rom ( name "Hamtaro - Ham-Hams Unite! (USA) (2002-08-07) (Beta).gbc" size 2097152 crc d0cf0d86 sha1 c85ba2da0a652544f938439c8826c5c6754f5e75 ) +) + +game ( + name "Hamtaro - Ham-Hams Unite! (Europe) (En,Fr,De,Es,It) (2002-11-11) (Beta)" + description "Hamtaro - Ham-Hams Unite! (Europe) (En,Fr,De,Es,It) (2002-11-11) (Beta)" + rom ( name "Hamtaro - Ham-Hams Unite! (Europe) (En,Fr,De,Es,It) (2002-11-11) (Beta).gbc" size 4194304 crc 816b0325 sha1 17c3ff0da5b9733a768ee53eccd13059fda16116 ) +) + game ( name "Hamunaptra - Ushinawareta Sabaku no Miyako (Japan)" description "Hamunaptra - Ushinawareta Sabaku no Miyako (Japan)" @@ -37791,6 +39200,30 @@ game ( rom ( name "Harvest Moon GBC (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ab5738a1 sha1 d407b9c20c5381f46ec460858539a5b6f559e04f ) ) +game ( + name "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" + description "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Haunted (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 4b3670bd sha1 f245b8e21716a400769488b852f15d276f3549a6 ) +) + +game ( + name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" + description "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 287afc75 sha1 42ccc76883c041bc5c6c25a2e61ccc939c14811f ) +) + +game ( + name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6e484d6a sha1 7282ef5cc2354345c8832b4dde66a559de74f73f ) +) + +game ( + name "Heebie Jeebies (World) (Aftermarket) (Unl)" + description "Heebie Jeebies (World) (Aftermarket) (Unl)" + rom ( name "Heebie Jeebies (World) (Aftermarket) (Unl).gbc" size 262144 crc 73762d53 sha1 d427f18cb854e1387d93c19b88cb7193975e6472 ) +) + game ( name "Hejin Zhuangbei II (Taiwan) (Unl)" description "Hejin Zhuangbei II (Taiwan) (Unl)" @@ -37887,6 +39320,12 @@ game ( rom ( name "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 84084e5f sha1 bb00ff88af717b45e08ef421ac77e0546870b1f4 flags verified ) ) +game ( + name "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl)" + description "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6f430dda sha1 e0cfe038063b1cd601a5f1b5af047efc705a7aaa ) +) + game ( name "High Noon (World) (Aftermarket) (Unl)" description "High Noon (World) (Aftermarket) (Unl)" @@ -37894,9 +39333,16 @@ game ( ) game ( - name "Hime's Quest (World) (Aftermarket) (Unl)" - description "Hime's Quest (World) (Aftermarket) (Unl)" - rom ( name "Hime's Quest (World) (Aftermarket) (Unl).gbc" size 2097152 crc de5c21c2 sha1 7b6672c46c23aaa282bd4fded0713c6dfae2eb66 ) + name "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" + description "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" + rom ( name "Hime's Quest (World) (Digital) (Aftermarket) (Unl).gbc" size 2097152 crc de5c21c2 sha1 7b6672c46c23aaa282bd4fded0713c6dfae2eb66 ) +) + +game ( + name "Hime's Quest (World) (Cart) (Aftermarket) (Unl)" + description "Hime's Quest (World) (Cart) (Aftermarket) (Unl)" + rom ( name "Hime's Quest (World) (Cart) (Aftermarket) (Unl).gbc" size 2097152 crc 546f578a sha1 ff90ca3ec7fb5d02865ae3cfd807ad3541dd21fc ) + rom ( name "Hime's Quest (World) (Cart) (Aftermarket) (Unl) (Factory Save).sav" size 32768 crc d5ed60c7 sha1 8d6c2e9da87837ba16bbd07247a91a0c3050d2fe ) ) game ( @@ -37959,6 +39405,12 @@ game ( rom ( name "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 8ed4bbba sha1 222487f14aaaa8f0bb536a09238e63ac95636208 ) ) +game ( + name "Host, The (World) (Aftermarket) (Unl)" + description "Host, The (World) (Aftermarket) (Unl)" + rom ( name "Host, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 5f783000 sha1 05cc1f1e52167c6985ebb0a3e67af1fc2fbff93c ) +) + game ( name "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" description "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" @@ -38037,6 +39489,12 @@ game ( rom ( name "Hyper Olympic Series - Track & Field GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 77f76ebc sha1 6dabafe260b53e61a810cbae2f14287adafffd8e ) ) +game ( + name "Ice Age II (Taiwan) (En) (Unl)" + description "Ice Age II (Taiwan) (En) (Unl)" + rom ( name "Ice Age II (Taiwan) (En) (Unl).gbc" size 2097152 crc 50bc8e9d sha1 c57912e67c135c48233f351f68cdc34020de8d01 ) +) + game ( name "Ide Yousuke no Mahjong Kyoushitsu GB (Japan)" description "Ide Yousuke no Mahjong Kyoushitsu GB (Japan)" @@ -38049,12 +39507,24 @@ game ( rom ( name "Indiana Jones and the Infernal Machine (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 7fff1142 sha1 6d568438aa3b9b67c55aded582cec136b15c46d7 flags verified ) ) +game ( + name "Infall (World) (Aftermarket) (Unl)" + description "Infall (World) (Aftermarket) (Unl)" + rom ( name "Infall (World) (Aftermarket) (Unl).gbc" size 131072 crc d9d90319 sha1 aafaf33fa43c7f0fd65cc8af03a42df25361fc74 ) +) + game ( name "Infinity (USA) (Proto) (2001-03-22)" description "Infinity (USA) (Proto) (2001-03-22)" rom ( name "Infinity (USA) (Proto) (2001-03-22).gbc" size 2097152 crc 4ade94aa sha1 fdfd6d4cbebbf64fc7d1264f0450be270be89823 ) ) +game ( + name "Inspector Gadget - Operation Madkactus (Europe) (Fr) (Beta)" + description "Inspector Gadget - Operation Madkactus (Europe) (Fr) (Beta)" + rom ( name "Inspector Gadget - Operation Madkactus (Europe) (Fr) (Beta).gbc" size 1048576 crc 93ec798b sha1 8444ff17aa3f865eec33cc49398b450e345376c3 ) +) + game ( name "Inspector Gadget - Operation Madkactus (Europe) (En,Fr,De,Es,It,Nl)" description "Inspector Gadget - Operation Madkactus (Europe) (En,Fr,De,Es,It,Nl)" @@ -38067,6 +39537,12 @@ game ( rom ( name "Inspector Gadget - Operation Madkactus (USA).gbc" size 1048576 crc 1af0b489 sha1 b0fa81a35e605948df3b7f1fcb5893bab99d9d6a ) ) +game ( + name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fea1cdb9 sha1 ac10ca63f15ca78af9f7d0eabb85eef8733aef50 ) +) + game ( name "International Karate 2000 (Europe)" description "International Karate 2000 (Europe)" @@ -38121,6 +39597,12 @@ game ( rom ( name "International Track & Field - Summer Games (Europe).gbc" size 1048576 crc d826c75f sha1 53e158cb23fa79026345dae775d9f020218f8bb2 ) ) +game ( + name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d6c1c1ac sha1 d722e95155455cf146a97222ccbc2237bea86509 ) +) + game ( name "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" description "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" @@ -38187,6 +39669,12 @@ game ( rom ( name "Jay und die Spielzeugdiebe (Germany).gbc" size 1048576 crc 73f4f6da sha1 dd01d68bab2d3615f173e4c9c94da56248fab580 ) ) +game ( + name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" + description "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9e97ac30 sha1 c07237d0f9c13b36ac2fcc5324b6e81122b0e189 ) +) + game ( name "Jeff Gordon XS Racing (USA) (GB Compatible)" description "Jeff Gordon XS Racing (USA) (GB Compatible)" @@ -38211,6 +39699,12 @@ game ( rom ( name "Jet de Go! - Let's Go by Airliner (Japan).gbc" size 2097152 crc 20c4ccf6 sha1 97bf75afa0089ddb342ea7046b7cd113ba2c6fec ) ) +game ( + name "Jet Set Willy (World) (Aftermarket) (Unl)" + description "Jet Set Willy (World) (Aftermarket) (Unl)" + rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gbc" size 262144 crc 659295ee sha1 bcb5a0e4566572aeb6cddea0897903ba207dc54f ) +) + game ( name "Jibaku-kun - Rei no Itsuki no Kajitsu (Japan) (Proto)" description "Jibaku-kun - Rei no Itsuki no Kajitsu (Japan) (Proto)" @@ -38313,6 +39807,18 @@ game ( rom ( name "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 9fa5cdb5 sha1 a332817b9561dcab7d1f3dc0cf300e1656b253c3 ) ) +game ( + name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8884d532 sha1 a41195443613fb4414d8536b1f3494677f6f253d ) +) + +game ( + name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" + description "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 570a8043 sha1 1ccbf555412a417135acea0b7b185a7f795a89da ) +) + game ( name "Juedui Wuli (Taiwan) (Unl)" description "Juedui Wuli (Taiwan) (Unl)" @@ -38458,9 +39964,9 @@ game ( ) game ( - name "Katakis 3D (USA, Europe) (Proto)" - description "Katakis 3D (USA, Europe) (Proto)" - rom ( name "Katakis 3D (USA, Europe) (Proto).gbc" size 2097152 crc 7c4b3795 sha1 8cd4be6772c592bbc2908fa826c090ec122e384c ) + name "Katakis 3D (Europe) (Proto)" + description "Katakis 3D (Europe) (Proto)" + rom ( name "Katakis 3D (Europe) (Proto).gbc" size 2097152 crc 7c4b3795 sha1 8cd4be6772c592bbc2908fa826c090ec122e384c ) ) game ( @@ -38535,6 +40041,12 @@ game ( rom ( name "Ken Griffey Jr.'s Slugfest (USA).gbc" size 1048576 crc 1e64d19c sha1 2362bdd8c26f30adb871259ce2d909ac6d505e36 ) ) +game ( + name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6a5abba1 sha1 0b3deef7a27201e81b4d39bc0bd10ff7ec73e380 ) +) + game ( name "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced) (GB Compatible)" description "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced) (GB Compatible)" @@ -38565,6 +40077,12 @@ game ( rom ( name "Kindaichi Shounen no Jikenbo - 10 Nenme no Shoutaijou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc de52ffdc sha1 468ea148eb15eac3b771a2520e0b5248ea5085a1 ) ) +game ( + name "King of Fighters R2 (Taiwan) (Unl)" + description "King of Fighters R2 (Taiwan) (Unl)" + rom ( name "King of Fighters R2 (Taiwan) (Unl).gbc" size 1048576 crc 9913e18b sha1 43c2b6f0c3559ed90032cba6569811047f9e20d0 ) +) + game ( name "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced) (GB Compatible)" description "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced) (GB Compatible)" @@ -38751,12 +40269,30 @@ game ( rom ( name "Koudai Guaishou - Dongzuo Pian (Taiwan) (En) (Unl) (Alt).gbc" size 1048576 crc ec2fbdfd sha1 c7a1020797b57d292e16c5297199d977e025256b ) ) +game ( + name "Koudai Guaishou - Feicui Ban (Taiwan) (Unl)" + description "Koudai Guaishou - Feicui Ban (Taiwan) (Unl)" + rom ( name "Koudai Guaishou - Feicui Ban (Taiwan) (Unl).gbc" size 2097152 crc 8494465f sha1 a3b2818c778fe6b5811841a9f28a1a06334216ea ) +) + +game ( + name "Koudai Guaishou - Sheng Bianshi (China) (Unl)" + description "Koudai Guaishou - Sheng Bianshi (China) (Unl)" + rom ( name "Koudai Guaishou - Sheng Bianshi (China) (Unl).gbc" size 2097152 crc 0791c3a7 sha1 8a61c2dc4d1acf96d8ae871b0f371c7f8a17e9f1 ) +) + game ( name "Koudai Yaoguai - Baijin Ban (Taiwan) (Unl)" description "Koudai Yaoguai - Baijin Ban (Taiwan) (Unl)" rom ( name "Koudai Yaoguai - Baijin Ban (Taiwan) (Unl).gbc" size 2097152 crc 998ad382 sha1 f9013985d7c40eccfa863e2ba808e64deaa4b384 ) ) +game ( + name "Koudai Yaoguai Lu Baoshi (Taiwan) (Unl)" + description "Koudai Yaoguai Lu Baoshi (Taiwan) (Unl)" + rom ( name "Koudai Yaoguai Lu Baoshi (Taiwan) (Unl).gbc" size 2097152 crc ee74e4a2 sha1 59e4550bd3958464188fd9b8c11b2dc1c9ad7d06 ) +) + game ( name "Koushien Pocket (Japan) (SGB Enhanced) (GB Compatible)" description "Koushien Pocket (Japan) (SGB Enhanced) (GB Compatible)" @@ -38794,21 +40330,27 @@ game ( ) game ( - name "Laser Squad (World) (Aftermarket) (Unl)" - description "Laser Squad (World) (Aftermarket) (Unl)" - rom ( name "Laser Squad (World) (Aftermarket) (Unl).gbc" size 1048576 crc 32f24248 sha1 26f4efe636214e72ec724f8887ca79fbc8abad80 ) + name "Laser Squad Alter (World) (Aftermarket) (Unl)" + description "Laser Squad Alter (World) (Aftermarket) (Unl)" + rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gbc" size 1048576 crc 32f24248 sha1 26f4efe636214e72ec724f8887ca79fbc8abad80 ) ) game ( - name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" - description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" - rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta).gbc" size 1048576 crc f90a3dae sha1 772539821e4b703259b2e2ad535d74a03fa22760 ) + name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4a58315b sha1 5a234e33f7429b48f4374b5989e6df4d20352b4c ) ) game ( - name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" - description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" - rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto).gbc" size 1048576 crc cf8e2371 sha1 f7b19c1501d325dd8ee219ccae2eaca130a5a21b ) + name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5c405584 sha1 3ee043ba17f46a6afbbba8ac05f35d093b817fbc ) +) + +game ( + name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9a134100 sha1 75b5188a5b8a720ff08894379147c7870ac8825d ) ) game ( @@ -38823,12 +40365,42 @@ game ( rom ( name "Laura (USA).gbc" size 1048576 crc e2bff286 sha1 3fe3eb99ee818c94e9a07e19640af6a2aad33903 ) ) +game ( + name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" + description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" + rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta).gbc" size 1048576 crc f90a3dae sha1 772539821e4b703259b2e2ad535d74a03fa22760 ) +) + +game ( + name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" + description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" + rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto).gbc" size 1048576 crc cf8e2371 sha1 f7b19c1501d325dd8ee219ccae2eaca130a5a21b ) +) + game ( name "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It)" description "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It)" rom ( name "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 1b49d07d sha1 cb4847cd63c8cc52f04bf4d86d54954be3d8fc1a ) ) +game ( + name "Leaper (World) (Aftermarket) (Unl)" + description "Leaper (World) (Aftermarket) (Unl)" + rom ( name "Leaper (World) (Aftermarket) (Unl).gbc" size 524288 crc ed8cd385 sha1 425db2916263121f4aee91a8cab6286e39364f87 ) +) + +game ( + name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 953e25d1 sha1 018c7cada41e693a02b9c596d307b0aa9207eef4 ) +) + +game ( + name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1096252a sha1 c22cc79b25a05afad66e769dc0365b7c25f1bb85 ) +) + game ( name "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" description "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" @@ -38901,6 +40473,24 @@ game ( rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 2) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 06887a34 sha1 1c091225688d966928cc74336dbef2e07d12a47c flags verified ) ) +game ( + name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1998-12-11) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1998-12-11) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1998-12-11) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc c17259db sha1 a5a6f0251e8eafd0a02b1eeceaa5b51705c12f0d ) +) + +game ( + name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc 8afd751e sha1 797925a26eb39656aea60e10c8e9dd986b515b53 ) +) + +game ( + name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 2) (Beta) (1999-09-23) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 2) (Beta) (1999-09-23) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 2) (Beta) (1999-09-23) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc 0559bc89 sha1 dbe7a909c71d407f01af2cdb0aaf7d164ac7a9bd ) +) + game ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Beta) (1998-12-11) (SGB Enhanced) (GB Compatible)" description "Legend of Zelda, The - Link's Awakening DX (Germany) (Beta) (1998-12-11) (SGB Enhanced) (GB Compatible)" @@ -39051,12 +40641,24 @@ game ( rom ( name "Lemmings VS (Japan).gbc" size 4194304 crc 947d45ae sha1 2ebb428a53acbcbc215f37bb263e44d94f547473 ) ) +game ( + name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" + description "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a91a698f sha1 26f38b3908c086b3e349324da32bc37213975030 ) +) + game ( name "Liberator (World) (Aftermarket) (Unl)" description "Liberator (World) (Aftermarket) (Unl)" rom ( name "Liberator (World) (Aftermarket) (Unl).gbc" size 262144 crc ebe70d3d sha1 e3afce5a2357732ed15d7f3c0900f7b48113efdc ) ) +game ( + name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" + description "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b8dd8409 sha1 281abb583ec0039e2c981c2e95f7a92002da081b ) +) + game ( name "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" description "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" @@ -39250,9 +40852,9 @@ game ( ) game ( - name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (SGB Enhanced, GB Compatible) (NP) [b]" - description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (SGB Enhanced, GB Compatible) (NP) [b]" - rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (SGB Enhanced, GB Compatible) (NP) [b].gbc" size 262144 crc a30ad68d sha1 bbb3c1b9d0dcfabc177f443ea11efa6b6e3112e1 flags baddump ) + name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (SGB Enhanced, GB Compatible) (NP)" + description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (SGB Enhanced, GB Compatible) (NP)" + rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (SGB Enhanced, GB Compatible) (NP).gbc" size 262144 crc 27ab2187 sha1 49a63339bc253d1bd55f6db75f7324980572925a ) ) game ( @@ -39312,7 +40914,7 @@ game ( game ( name "Lucky Luke (Europe) (En,Fr,De,Es)" description "Lucky Luke (Europe) (En,Fr,De,Es)" - rom ( name "Lucky Luke (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 412fb57c sha1 36b59251751a55285dbedc3bd4b33b2c73b811c9 ) + rom ( name "Lucky Luke (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 412fb57c sha1 36b59251751a55285dbedc3bd4b33b2c73b811c9 flags verified ) ) game ( @@ -39358,9 +40960,15 @@ game ( ) game ( - name "Lunar Docking (World) (Aftermarket) (Unl)" - description "Lunar Docking (World) (Aftermarket) (Unl)" - rom ( name "Lunar Docking (World) (Aftermarket) (Unl).gbc" size 262144 crc 9edd066c sha1 4d43a38e8b5df41309f5b6ec13e4829db739d980 ) + name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" + description "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" + rom ( name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl).gbc" size 262144 crc 9edd066c sha1 4d43a38e8b5df41309f5b6ec13e4829db739d980 ) +) + +game ( + name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" + description "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" + rom ( name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl).gbc" size 262144 crc de5d5c0b sha1 5f038ef3657d3fbfb3be6917b24c3f933363ad4c ) ) game ( @@ -39394,21 +41002,15 @@ game ( ) game ( - name "Machine, The (USA) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Machine, The (USA) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Machine, The (USA) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f55a9d95 sha1 2b22fbd76e11e6e45053b1e6989de303e3033c9e ) + name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f55a9d95 sha1 2b22fbd76e11e6e45053b1e6989de303e3033c9e ) ) game ( - name "Machine, The (USA) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Machine, The (USA) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Machine, The (USA) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5662865e sha1 a5ac99a4087bd5ea45417e5b4a7c9af10433911a ) -) - -game ( - name "Machine, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Machine, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Machine, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc da01eb3e sha1 cd9a27077ba7ed49d2f2878577cb6ff005d6f785 ) + name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5662865e sha1 a5ac99a4087bd5ea45417e5b4a7c9af10433911a ) ) game ( @@ -39453,6 +41055,12 @@ game ( rom ( name "Magi-Nation - Keeper's Quest (USA) (Proto).gbc" size 1048576 crc 89de57b7 sha1 7c6b427810be2f0d7496ccb5eff2226d3ed1194e ) ) +game ( + name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" + description "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c276843d sha1 852697a2952d2e7375b73aba877ebc17aa4f4179 ) +) + game ( name "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" description "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" @@ -39702,7 +41310,7 @@ game ( game ( name "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible)" description "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible)" - rom ( name "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 5b8ffd37 sha1 48fc8c6e84c63ee47f5a2c5e99dc1666d6e9f496 ) + rom ( name "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 5b8ffd37 sha1 48fc8c6e84c63ee47f5a2c5e99dc1666d6e9f496 flags verified ) ) game ( @@ -39819,6 +41427,18 @@ game ( rom ( name "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc cabdd802 sha1 0858a619d716b0191713734d506d9f113f0d1c62 ) ) +game ( + name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f614bdff sha1 7e46c193f6566f620acf20ead3a1fca1d677c221 ) +) + +game ( + name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 949c6ab9 sha1 34269af4db6c37b92fdc7f7f914c282174603ba8 ) +) + game ( name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" description "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" @@ -39975,6 +41595,18 @@ game ( rom ( name "Microsoft Pinball Arcade (Europe).gbc" size 1048576 crc 4eb7db14 sha1 f2874f0f3023d96edbdb94e5c0dc181d8baa3efb flags verified ) ) +game ( + name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" + description "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f9a5ed4e sha1 8b3e18287d5adf3b5a711e28a896f843927f22a2 ) +) + +game ( + name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" + description "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 177f0b6e sha1 e5fdb741d870de25affdc841c07eaa3000da25f5 ) +) + game ( name "Midway Presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" description "Midway Presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" @@ -40066,9 +41698,9 @@ game ( ) game ( - name "Mission to Mars (World) (Aftermarket) (Unl)" - description "Mission to Mars (World) (Aftermarket) (Unl)" - rom ( name "Mission to Mars (World) (Aftermarket) (Unl).gbc" size 262144 crc f651fcf4 sha1 479c70dd9c63cdcad99ca44720a9e0e2582df119 ) + name "Mission Mars (World) (Aftermarket) (Unl)" + description "Mission Mars (World) (Aftermarket) (Unl)" + rom ( name "Mission Mars (World) (Aftermarket) (Unl).gbc" size 262144 crc f651fcf4 sha1 479c70dd9c63cdcad99ca44720a9e0e2582df119 ) ) game ( @@ -40077,12 +41709,6 @@ game ( rom ( name "Mizuki Shigeru no Shin Youkaiden (Japan).gbc" size 4194304 crc fc1f100f sha1 ab12770558fb95434bba0da0d3b8a91e2d9179fb ) ) -game ( - name "Mo Jie 3-bu Wanme de Shijie (Taiwan) (Unl)" - description "Mo Jie 3-bu Wanme de Shijie (Taiwan) (Unl)" - rom ( name "Mo Jie 3-bu Wanme de Shijie (Taiwan) (Unl).gbc" size 524288 crc d91e3f98 sha1 556913f2687a49034e1229ef1e375f6036ec5719 ) -) - game ( name "Mobile Golf (Japan)" description "Mobile Golf (Japan)" @@ -40095,16 +41721,28 @@ game ( rom ( name "Mobile Trainer (Japan).gbc" size 2097152 crc 7226ead0 sha1 ecc0579edeaf9eccd722d605cc288cd023c8576a flags verified ) ) +game ( + name "Mojie 3-bu Wanme de Shijie (Taiwan) (Zh) (Unl)" + description "Mojie 3-bu Wanme de Shijie (Taiwan) (Zh) (Unl)" + rom ( name "Mojie 3-bu Wanme de Shijie (Taiwan) (Zh) (Unl).gbc" size 524288 crc d91e3f98 sha1 556913f2687a49034e1229ef1e375f6036ec5719 ) +) + game ( name "Mojie Chuanshuo (Taiwan) (Unl)" description "Mojie Chuanshuo (Taiwan) (Unl)" rom ( name "Mojie Chuanshuo (Taiwan) (Unl).gbc" size 524288 crc 7aa7eea5 sha1 109e4ba61b04afe15cc5a5ee994f56405938cee3 ) ) +game ( + name "Mojie Zhanshi Chuanshuo (Taiwan) (Unl)" + description "Mojie Zhanshi Chuanshuo (Taiwan) (Unl)" + rom ( name "Mojie Zhanshi Chuanshuo (Taiwan) (Unl).gbc" size 2097152 crc 620c56b8 sha1 25fd8c132601cd9f74784a010141572505a2ef66 ) +) + game ( name "Momotarou Densetsu 1-2 (Japan)" description "Momotarou Densetsu 1-2 (Japan)" - rom ( name "Momotarou Densetsu 1-2 (Japan).gbc" size 2097152 crc da7fb08f sha1 acffa3417c85be574aa28432e29e1d40f28a565b ) + rom ( name "Momotarou Densetsu 1-2 (Japan).gbc" size 2097152 crc da7fb08f sha1 acffa3417c85be574aa28432e29e1d40f28a565b flags verified ) ) game ( @@ -40281,6 +41919,12 @@ game ( rom ( name "Motocross Maniacs 2 (USA).gbc" size 1048576 crc 17d27fa9 sha1 5a0e7a9a71a88ee79529531274eb3696cf0fa42c ) ) +game ( + name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + description "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 362a84ba sha1 b4b3afa2379a07acab6965ae8fcf6d2ba82d6d7e ) +) + game ( name "Mr. Angry (World) (Aftermarket) (Unl)" description "Mr. Angry (World) (Aftermarket) (Unl)" @@ -40359,6 +42003,12 @@ game ( rom ( name "Muchang Wuyu GB 6 (Taiwan) (Unl).gbc" size 2097152 crc 416e6efa sha1 86b2de0fc2806f3d13145e2c0296389ec0897a6a ) ) +game ( + name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 846afc79 sha1 dae84fbc60839da29878714cd845c3704b915323 ) +) + game ( name "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" description "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" @@ -40383,12 +42033,36 @@ game ( rom ( name "Mummy, The (USA).gbc" size 1048576 crc c6ba9f27 sha1 35b10f392d514bce858c8c64f9c489500466d0ff ) ) +game ( + name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" + description "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" + rom ( name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl).gbc" size 524288 crc ec4f9d49 sha1 357db81755f1f0eb732367dd4090c446eb226ddf ) +) + +game ( + name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" + description "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" + rom ( name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl).gbc" size 524288 crc 1ba7d27f sha1 d4c4be65ba469369cd90aaa733d0a8e8af6bcdc1 ) +) + game ( name "Muteki Ou Tri-Zenon (Japan)" description "Muteki Ou Tri-Zenon (Japan)" rom ( name "Muteki Ou Tri-Zenon (Japan).gbc" size 2097152 crc 0bab7a61 sha1 2a7f422bf9af9aff126e47ede8b5ceec0630eb08 ) ) +game ( + name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9bff7b15 sha1 1f3aac8a3725cd1d0968529afc1c2031372d8ed1 ) +) + +game ( + name "My Friendly Little Island (World) (Aftermarket) (Unl)" + description "My Friendly Little Island (World) (Aftermarket) (Unl)" + rom ( name "My Friendly Little Island (World) (Aftermarket) (Unl).gbc" size 1048576 crc f6bf0584 sha1 81d724ad696084283712145adfef15769648b045 ) +) + game ( name "Mythri (USA) (Proto 1) (2000-08-02)" description "Mythri (USA) (Proto 1) (2000-08-02)" @@ -40576,9 +42250,9 @@ game ( ) game ( - name "Neclaus' Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - description "Neclaus' Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Neclaus' Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc eedefa0c sha1 e63c16fe987fe655408be66198366a0147ac607c ) + name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc eedefa0c sha1 e63c16fe987fe655408be66198366a0147ac607c ) ) game ( @@ -40587,6 +42261,12 @@ game ( rom ( name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 53cf930c sha1 bd3272ca7ead64da3f68f774661a560add433b94 ) ) +game ( + name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" + description "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 705b150f sha1 6258cf6ad167c9ae86609a8e620face1674a7ea7 ) +) + game ( name "Net de Get - Minigame @ 100 (Japan)" description "Net de Get - Minigame @ 100 (Japan)" @@ -40683,6 +42363,12 @@ game ( rom ( name "Ninja JaJaMaru - The Great World Adventure DX (USA, Europe) (Ninja JaJaMaru Retro Collection) (Switch).gbc" size 262144 crc b5af4ca5 sha1 73efaca14c998dd6790e08f2ce2b6f73e7909ce4 flags verified ) ) +game ( + name "Ninja Master (World) (Aftermarket) (Unl)" + description "Ninja Master (World) (Aftermarket) (Unl)" + rom ( name "Ninja Master (World) (Aftermarket) (Unl).gbc" size 262144 crc bc550b84 sha1 0def135723ac40e4981c88f8888afbd40a15bb40 ) +) + game ( name "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" description "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" @@ -40704,7 +42390,7 @@ game ( game ( name "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible)" description "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible)" - rom ( name "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 233862d0 sha1 a61e35306405e41c03b98b162ee14442e77c0da1 ) + rom ( name "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 233862d0 sha1 a61e35306405e41c03b98b162ee14442e77c0da1 flags verified ) ) game ( @@ -40719,6 +42405,12 @@ game ( rom ( name "NSYNC - Get to the Show (USA).gbc" size 1048576 crc f770878b sha1 23b031d03a139c4d963099070b0b290f5f806a6d ) ) +game ( + name "Number Builder (World) (Aftermarket) (Unl)" + description "Number Builder (World) (Aftermarket) (Unl)" + rom ( name "Number Builder (World) (Aftermarket) (Unl).gbc" size 262144 crc b8609d43 sha1 92952b752f50af889db891acc9eed8436ac6b87e ) +) + game ( name "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" description "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" @@ -40738,9 +42430,9 @@ game ( ) game ( - name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta, Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta, Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta, Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc ef42955e sha1 485b4d672d9edda40f9191f5f5cc223046000e67 flags verified ) + name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc ef42955e sha1 485b4d672d9edda40f9191f5f5cc223046000e67 flags verified ) ) game ( @@ -40773,6 +42465,24 @@ game ( rom ( name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl).gbc" size 2097152 crc 63bddc68 sha1 fab777e607bd8aba70eb65829143039dbe6ac08e ) ) +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 1f1af42a sha1 ddcdbfa716d716e1b7bb258caaaa7b76d041b5a9 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" + description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt).gbc" size 524288 crc 834a8021 sha1 d5af2bf38eda4c181993e992764788003509ebfd ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 42d9c38c sha1 ae719190cf2f433c359bc425775710f4aa67e860 ) +) + game ( name "NYR - New York Race (Europe) (En,Fr,De,Es,It,Pt)" description "NYR - New York Race (Europe) (En,Fr,De,Es,It,Pt)" @@ -40786,9 +42496,15 @@ game ( ) game ( - name "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" - description "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" - rom ( name "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 5c260d5a sha1 a35ccdf0789ce84df3c12cfe7c4b9b98af08ca9a ) + name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c055ef9 sha1 d4fa4e02753a9fe539f70d0927ba5bf9caa02d3c ) +) + +game ( + name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" + description "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7ed58128 sha1 e543c39f8e55b1788476b94028a54fc2fc9c7ea0 ) ) game ( @@ -40797,6 +42513,18 @@ game ( rom ( name "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 4b83b14f sha1 c9d4d1dd1c33a9fa9b54e9f2a7a5f6dd90069b91 flags verified ) ) +game ( + name "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" + description "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 5c260d5a sha1 a35ccdf0789ce84df3c12cfe7c4b9b98af08ca9a ) +) + +game ( + name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" + description "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9742276d sha1 cd8f18d6e5fabaa130a42e5618e29c5ff26f6a93 ) +) + game ( name "Ohasuta Dance Dance Revolution GB (Japan)" description "Ohasuta Dance Dance Revolution GB (Japan)" @@ -40833,6 +42561,12 @@ game ( rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gbc" size 524288 crc 5e81cef7 sha1 a7a552a9eb984098a67e063c2eca907eec000fc1 ) ) +game ( + name "One Day (World) (GB Compatible) (Aftermarket) (Unl)" + description "One Day (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "One Day (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fd52acc7 sha1 bdb5590b61791b89e9afa871d32648d7a66ce1f4 ) +) + game ( name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" description "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" @@ -40917,6 +42651,30 @@ game ( rom ( name "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1e443d1b sha1 969d5352c15e3e5daa891edcda91bd48a8380308 ) ) +game ( + name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c6e83f41 sha1 44b117d94a80617a77abbdcc76d9d69b66efe56b ) +) + +game ( + name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 69483f81 sha1 4d162c9637a20cfc7c92e6ea7a61fad0ed22137a ) +) + +game ( + name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" + description "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" + rom ( name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 262144 crc 0db301c2 sha1 58ec8f209ed6e33adfb253014ea69ae1ee53c145 ) +) + +game ( + name "Pact, The (World) (Aftermarket) (Unl)" + description "Pact, The (World) (Aftermarket) (Unl)" + rom ( name "Pact, The (World) (Aftermarket) (Unl).gbc" size 262144 crc 304df19a sha1 97af064f9063cd353e55ac0e1f6d1ca8b4a6d2b9 ) +) + game ( name "Painter (Europe) (Unl)" description "Painter (Europe) (Unl)" @@ -40971,6 +42729,12 @@ game ( rom ( name "Peugeot - Orbital Diagnostic System (Unknown) (Alt) (Unl) [b].gbc" size 32768 crc 424912fe sha1 bd5735021e4593ec07082e6197e683496d0ecf0b flags baddump ) ) +game ( + name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" + description "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 154cb547 sha1 3b217c595e6a5b115dc7130123a321049cf01d22 ) +) + game ( name "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" description "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" @@ -40990,15 +42754,21 @@ game ( ) game ( - name "Pie Crust (World) (v1.0) (Unl)" - description "Pie Crust (World) (v1.0) (Unl)" - rom ( name "Pie Crust (World) (v1.0) (Unl).gbc" size 32768 crc f39c8119 sha1 b01cad9652bf1c65151dd8d2bd21251a9cf44d43 ) + name "Piecrust (World) (Unl)" + description "Piecrust (World) (Unl)" + rom ( name "Piecrust (World) (Unl).gbc" size 32768 crc f39c8119 sha1 b01cad9652bf1c65151dd8d2bd21251a9cf44d43 ) ) game ( - name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (GB Compatible) (Aftermarket) (Unl)" - description "Pine Creek (World) (En-US,Es-MX,Pt-BR) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 189aa999 sha1 2cf46a36502eaf22ac9572fe1136d369fcbe9e46 ) + name "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 3c2bafdc sha1 d38f3f5e491dbaed84e88099987712449db9b33d ) +) + +game ( + name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 189aa999 sha1 2cf46a36502eaf22ac9572fe1136d369fcbe9e46 ) ) game ( @@ -41037,6 +42807,12 @@ game ( rom ( name "Player Manager 2001 (Europe) (En,Fr).gbc" size 1048576 crc 375c35e0 sha1 6e21a85257361be76914f418409124c5bc315429 ) ) +game ( + name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 29415ff7 sha1 89b3fd633e8cef3b8523b1ef2a0072db2d7416d7 ) +) + game ( name "Pocket Billiards - Funk the 9 Ball (Japan)" description "Pocket Billiards - Funk the 9 Ball (Japan)" @@ -41206,9 +42982,9 @@ game ( ) game ( - name "Pocket Music (USA) (En,Fr,De,Es,It) (Proto)" - description "Pocket Music (USA) (En,Fr,De,Es,It) (Proto)" - rom ( name "Pocket Music (USA) (En,Fr,De,Es,It) (Proto).gbc" size 1048576 crc c4387812 sha1 ad547a79af864eb56a18e1c2ad4346eb35df41ed ) + name "Pocket Music (USA) (En,Es) (Proto)" + description "Pocket Music (USA) (En,Es) (Proto)" + rom ( name "Pocket Music (USA) (En,Es) (Proto).gbc" size 1048576 crc c4387812 sha1 ad547a79af864eb56a18e1c2ad4346eb35df41ed ) ) game ( @@ -41433,6 +43209,12 @@ game ( rom ( name "Pokemon Diamond (Taiwan) (En) (Unl).gbc" size 524288 crc 1b5bef4b sha1 433e7991b706baedf59af8b91bc142ba2f72112f ) ) +game ( + name "Pokemon Gold (Taiwan) (En) (Unl)" + description "Pokemon Gold (Taiwan) (En) (Unl)" + rom ( name "Pokemon Gold (Taiwan) (En) (Unl).gbc" size 1048576 crc 479f3c4e sha1 26503e3262022be29b845a0b2ba555013d8ad12f ) +) + game ( name "Pokemon Gold Version 2 (Taiwan) (Unl)" description "Pokemon Gold Version 2 (Taiwan) (Unl)" @@ -41530,9 +43312,15 @@ game ( ) game ( - name "Polaris SnoCross (USA) (Beta) (Rumble Version)" - description "Polaris SnoCross (USA) (Beta) (Rumble Version)" - rom ( name "Polaris SnoCross (USA) (Beta) (Rumble Version).gbc" size 1048576 crc 673623c4 sha1 4176ef1f9fd37156a4cac37a2d146ed2deeb5a7b ) + name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 42298fd8 sha1 90c535bf70e2ca7b91af67b8f08865f423c3034f ) +) + +game ( + name "Pokettohiro! (World) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc b9e724ef sha1 28a01fd6ea95a146008435c5bc27b51b607bb86b ) ) game ( @@ -41541,6 +43329,12 @@ game ( rom ( name "Polaris SnoCross (USA) (Rumble Version).gbc" size 1048576 crc dd8b189e sha1 e893808fe227a1608c0604382d6a0340ec704c3b flags verified ) ) +game ( + name "Polaris SnoCross (USA) (Beta) (Rumble Version)" + description "Polaris SnoCross (USA) (Beta) (Rumble Version)" + rom ( name "Polaris SnoCross (USA) (Beta) (Rumble Version).gbc" size 1048576 crc 673623c4 sha1 4176ef1f9fd37156a4cac37a2d146ed2deeb5a7b ) +) + game ( name "Pong - The Next Level (USA, Europe)" description "Pong - The Next Level (USA, Europe)" @@ -41596,21 +43390,51 @@ game ( ) game ( - name "Powa! (World) (En) (GB Compatible) (Aftermarket) (Unl)" - description "Powa! (World) (En) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Powa! (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f0191467 sha1 3876f1aa896759f427ad2dc88a48788817e60c06 flags verified ) + name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 50393a65 sha1 2c2c6ed8be7a13bf279e435c5984f175c8affcad ) ) game ( - name "Powa! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" - description "Powa! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Powa! (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e8f68acc sha1 156d315b7a2a035d5cd429fb8c7e051e67e83c93 flags verified ) + name "Postie (World) (GB Compatible) (Aftermarket) (Unl)" + description "Postie (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Postie (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ff6bbc83 sha1 3ff236972d1e344eb50e696db3cc090f2b5d28b1 ) ) game ( - name "Powa! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Powa! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Powa! (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 592b6097 sha1 874d5e4ffc7d36259bef6ec6a86a1de8289b8d54 ) + name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6da19041 sha1 eb581935ad9223d723fdbc8339c03436df051947 ) +) + +game ( + name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" + description "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d0d8386d sha1 fbddf81a1663388ff0efeeb9051e68e0c323c839 ) +) + +game ( + name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f0191467 sha1 3876f1aa896759f427ad2dc88a48788817e60c06 flags verified ) +) + +game ( + name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e8f68acc sha1 156d315b7a2a035d5cd429fb8c7e051e67e83c93 flags verified ) +) + +game ( + name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 592b6097 sha1 874d5e4ffc7d36259bef6ec6a86a1de8289b8d54 ) +) + +game ( + name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b01c4ff1 sha1 898dbf10550af7e39b8f7a0818a78083ae40f4fe ) ) game ( @@ -41775,6 +43599,18 @@ game ( rom ( name "Prince of Persia (Japan) (Proto).gbc" size 1048576 crc d7dbbe1e sha1 6fd97e1f75570e7568b3dc4ab28834813afb4484 ) ) +game ( + name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" + description "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a86cada1 sha1 b02096c489c0f36582061d6eb62beb17e8294b61 ) +) + +game ( + name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" + description "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e171f327 sha1 b03df48f48529ac1be79699d6f34f324adcfb436 ) +) + game ( name "Pro Darts (USA)" description "Pro Darts (USA)" @@ -41967,6 +43803,12 @@ game ( rom ( name "Quan Ba Tianxia (Taiwan) (Unl).gbc" size 4194304 crc 2c922ed6 sha1 c19eb98a9745d2c2ce9e4dba3f17ae0b3dee0f49 ) ) +game ( + name "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" + description "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quartet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 46743216 sha1 bf866b438a602af386f8fad02727b4084edf6047 ) +) + game ( name "Quest - Brian's Journey (USA) (GB Compatible)" description "Quest - Brian's Journey (USA) (GB Compatible)" @@ -41979,6 +43821,12 @@ game ( rom ( name "Quest - Fantasy Challenge (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 98285775 sha1 86812b2cd4304dc7ee2dd3faf16737b0414aaffb ) ) +game ( + name "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9ac546d5 sha1 25b3a21135bfc7587c096b10f4a20d8b3095d721 ) +) + game ( name "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced) (GB Compatible)" description "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced) (GB Compatible)" @@ -42033,6 +43881,12 @@ game ( rom ( name "Radikal Bikers (Europe) (En,Fr,De,Es) (Proto).gbc" size 2097152 crc 81e25d37 sha1 f16aa29669b15153a63ad92388768e38aa18fbf8 ) ) +game ( + name "Raffles (World) (Aftermarket) (Unl)" + description "Raffles (World) (Aftermarket) (Unl)" + rom ( name "Raffles (World) (Aftermarket) (Unl).gbc" size 262144 crc e41d6472 sha1 4b5eb518ff52c235c674e0695fdde2b8b01f58fa ) +) + game ( name "Rainbow Islands (Europe) (En,Fr,De,Es,It)" description "Rainbow Islands (Europe) (En,Fr,De,Es,It)" @@ -42166,15 +44020,27 @@ game ( ) game ( - name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc f8c7f180 sha1 07674d42f5d4efaec14750ae56d8f28c4b54c020 ) + name "Remen Gaoxiao - Shuma Guaishou III (Taiwan) (Unl)" + description "Remen Gaoxiao - Shuma Guaishou III (Taiwan) (Unl)" + rom ( name "Remen Gaoxiao - Shuma Guaishou III (Taiwan) (Unl).gbc" size 524288 crc 9f64fb1c sha1 b8d6910c8b5c1cab044c61679bbbc4f213648f56 ) ) game ( - name "Repugnant Bounty (World) (Rev B) (Beta) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (Rev B) (Beta) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (Rev B) (Beta) (Aftermarket) (Unl).gbc" size 4194304 crc 9cce02d9 sha1 b83f9aca2a382729a490856c4100dc4a17594921 ) + name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc e92034d8 sha1 14b9614cea9be7d5c6e12aece692582ba2ca2b75 flags verified ) +) + +game ( + name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 3a1b1d83 sha1 4dda0cce6907de94eeae3f11a40238c3f5155ca7 ) +) + +game ( + name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc f8c7f180 sha1 07674d42f5d4efaec14750ae56d8f28c4b54c020 flags verified ) ) game ( @@ -42219,6 +44085,18 @@ game ( rom ( name "Resident Evil Gaiden (USA).gbc" size 2097152 crc f8c5021b sha1 a302cddc085d65ca778153e2a591bd648ce963c9 ) ) +game ( + name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" + description "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 8bd98942 sha1 3a5dbafa829e57089de8cfc93c806f7ee023ff1b ) +) + +game ( + name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c761189c sha1 f7f18d83218b66b9d1cd7267d6d4acfd4eded6c7 ) +) + game ( name "Return of the Ninja (Europe)" description "Return of the Ninja (Europe)" @@ -42255,6 +44133,12 @@ game ( rom ( name "Rip-Tide Racer (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc ab8c3a31 sha1 3354d6e79b8094bbaa4ef48eb8bd2b0774c46e1a ) ) +game ( + name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" + description "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae3f980b sha1 67f63517eacfea22922d07be0efc5fc8f8b8a1d2 ) +) + game ( name "Road Champs - BXS Stunt Biking (USA, Europe)" description "Road Champs - BXS Stunt Biking (USA, Europe)" @@ -42297,6 +44181,12 @@ game ( rom ( name "Robin to the Rescue (World) (Aftermarket) (Unl).gbc" size 262144 crc 9cd52c18 sha1 ef3bea9ed0de41e311b5f15fccbb0f451848d56c ) ) +game ( + name "Robo Knight (World) (Aftermarket) (Unl)" + description "Robo Knight (World) (Aftermarket) (Unl)" + rom ( name "Robo Knight (World) (Aftermarket) (Unl).gbc" size 524288 crc 8d4507f0 sha1 6012f9a3ae6201e363f46a75e0100552ecb91335 ) +) + game ( name "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" description "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" @@ -42490,15 +44380,15 @@ game ( ) game ( - name "Ruby & Rusty Save the Crows (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a46baa15 sha1 87dd5a6ccb5db59dae09f1953062420977ad2d92 ) + name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a46baa15 sha1 87dd5a6ccb5db59dae09f1953062420977ad2d92 ) ) game ( - name "Ruby & Rusty Save the Crows (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5602ca84 sha1 49d692796a6d0f3dcfc988648b446c0934f0e794 ) + name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5602ca84 sha1 49d692796a6d0f3dcfc988648b446c0934f0e794 ) ) game ( @@ -42522,7 +44412,7 @@ game ( game ( name "Rugrats - Totally Angelica (USA, Europe)" description "Rugrats - Totally Angelica (USA, Europe)" - rom ( name "Rugrats - Totally Angelica (USA, Europe).gbc" size 1048576 crc fc6195ef sha1 d4396a974aee16f74a5a80f4845c24dde5a083d6 ) + rom ( name "Rugrats - Totally Angelica (USA, Europe).gbc" size 1048576 crc fc6195ef sha1 d4396a974aee16f74a5a80f4845c24dde5a083d6 flags verified ) ) game ( @@ -42567,6 +44457,24 @@ game ( rom ( name "Runelords (USA) (Proto).gbc" size 4194304 crc 392af730 sha1 2bdcf8208cd0530c75195fd23f2f7839a3480bff ) ) +game ( + name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" + description "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 2097152 crc 96b1ceec sha1 771135edfbc64f7332a9cbd0d72af7a9d0d71f82 ) +) + +game ( + name "RunieStory (World) (Aftermarket) (Unl)" + description "RunieStory (World) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (Aftermarket) (Unl).gbc" size 2097152 crc 2249b449 sha1 0f6a391d7e05f66092a98e411069fab8e3f24221 ) +) + +game ( + name "Runner (World) (Aftermarket) (Unl)" + description "Runner (World) (Aftermarket) (Unl)" + rom ( name "Runner (World) (Aftermarket) (Unl).gbc" size 262144 crc 4cd8ccb2 sha1 da735d415ed463a953bac45f4793342bd9be2e96 ) +) + game ( name "Saban's Power Rangers - Lightspeed Rescue (USA, Europe)" description "Saban's Power Rangers - Lightspeed Rescue (USA, Europe)" @@ -42616,9 +44524,15 @@ game ( ) game ( - name "Sam the Optimistic Hedgehog (World) (GB Compatible) (Aftermarket) (Unl)" - description "Sam the Optimistic Hedgehog (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sam the Optimistic Hedgehog (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 4e4af60b sha1 ab8d49a99d02eb5c97d75f62dfb3720eec2b5abd ) + name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" + description "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 4e4af60b sha1 ab8d49a99d02eb5c97d75f62dfb3720eec2b5abd ) +) + +game ( + name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" + description "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 40dc168d sha1 af25acc86f0eef4ce72199383b96fcb4c9f0115e ) ) game ( @@ -42694,9 +44608,9 @@ game ( ) game ( - name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (Aftermarket) (Unl)" - description "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (Aftermarket) (Unl)" - rom ( name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (Aftermarket) (Unl).gbc" size 262144 crc db928e22 sha1 e175d35e6112c347ecd1e0a379e98f430823ba94 ) + name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" + description "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc db928e22 sha1 e175d35e6112c347ecd1e0a379e98f430823ba94 ) ) game ( @@ -42825,6 +44739,12 @@ game ( rom ( name "Sewing Machine Operation Software (Europe) (En,Fr,Es,Pt) (Proto) (GB Compatible).gbc" size 1048576 crc e34b5ce8 sha1 500439c5e14400ef2bc45cacf5ff834b70c2acd4 ) ) +game ( + name "SGB Test Program (World) (1994.4) (Demo) (SGB Enhanced)" + description "SGB Test Program (World) (1994.4) (Demo) (SGB Enhanced)" + rom ( name "SGB Test Program (World) (1994.4) (Demo) (SGB Enhanced).gbc" size 49152 crc 8960ac1d sha1 a310a9629ce6ad0a607ac9e985056fe257f305b5 ) +) + game ( name "Sgt. Rock - On the Frontline (USA)" description "Sgt. Rock - On the Frontline (USA)" @@ -42951,6 +44871,18 @@ game ( rom ( name "Sheng Shou Wuyu - Shenlong Chuanshuo (Taiwan) (Unl).gbc" size 1048576 crc 99a6e58a sha1 13bd97249b68eb824858a9d7a6061edf94140ac3 ) ) +game ( + name "Shenghuo Jiangmo Lu Waizhuan (Taiwan) (Unl)" + description "Shenghuo Jiangmo Lu Waizhuan (Taiwan) (Unl)" + rom ( name "Shenghuo Jiangmo Lu Waizhuan (Taiwan) (Unl).gbc" size 2097152 crc 1066ec96 sha1 394709afedc0632c09fee33785b0c4f00a45d3e6 ) +) + +game ( + name "Shenghuo Jiangmo Lu Waizhuan - Guang Yu An De Lunhui (Taiwan) (Unl)" + description "Shenghuo Jiangmo Lu Waizhuan - Guang Yu An De Lunhui (Taiwan) (Unl)" + rom ( name "Shenghuo Jiangmo Lu Waizhuan - Guang Yu An De Lunhui (Taiwan) (Unl).gbc" size 2097152 crc 808f19d7 sha1 62620a2cb01fe93388adc42da0b7cbaf53c11ba8 ) +) + game ( name "Shengui Diguo Zhi Emo Cheng (Taiwan) (Unl)" description "Shengui Diguo Zhi Emo Cheng (Taiwan) (Unl)" @@ -42972,7 +44904,7 @@ game ( game ( name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced) (GB Compatible)" description "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced) (GB Compatible)" - rom ( name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc f90c4977 sha1 b15cbd01a21048d0fd022f0e023ab5d91faaf442 ) + rom ( name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc f90c4977 sha1 b15cbd01a21048d0fd022f0e023ab5d91faaf442 flags verified ) ) game ( @@ -43026,7 +44958,7 @@ game ( game ( name "Shougi 2 (Japan) (GB Compatible)" description "Shougi 2 (Japan) (GB Compatible)" - rom ( name "Shougi 2 (Japan) (GB Compatible).gbc" size 262144 crc a7748d2b sha1 7c89cebc4dfcf8713c94b0553e4f4d4f8945052f ) + rom ( name "Shougi 2 (Japan) (GB Compatible).gbc" size 262144 crc a7748d2b sha1 7c89cebc4dfcf8713c94b0553e4f4d4f8945052f flags verified ) ) game ( @@ -43126,9 +45058,33 @@ game ( ) game ( - name "Shuma Baolong 02 4 (Taiwan) (Zh) (Unl)" - description "Shuma Baolong 02 4 (Taiwan) (Zh) (Unl)" - rom ( name "Shuma Baolong 02 4 (Taiwan) (Zh) (Unl).gbc" size 1048576 crc 2ee18ab2 sha1 839f0880749735ba2113e437f8efede171b7474d ) + name "Shuma Baolong 02 4 (Taiwan) (Unl)" + description "Shuma Baolong 02 4 (Taiwan) (Unl)" + rom ( name "Shuma Baolong 02 4 (Taiwan) (Unl).gbc" size 1048576 crc 2ee18ab2 sha1 839f0880749735ba2113e437f8efede171b7474d ) +) + +game ( + name "Shuma Baolong 02 4 (China) (Unl)" + description "Shuma Baolong 02 4 (China) (Unl)" + rom ( name "Shuma Baolong 02 4 (China) (Unl).gbc" size 1048576 crc 6f67dfc6 sha1 5c5d1675188a5f618f9babf2b3848942ce08c659 ) +) + +game ( + name "Shuma Baolong 02 5 (China) (Unl)" + description "Shuma Baolong 02 5 (China) (Unl)" + rom ( name "Shuma Baolong 02 5 (China) (Unl).gbc" size 1048576 crc 5ba9f8b5 sha1 c441fcbdb343e0c3c76803aa55ceb728158a8948 ) +) + +game ( + name "Shuma Baolong 2 (China) (Unl)" + description "Shuma Baolong 2 (China) (Unl)" + rom ( name "Shuma Baolong 2 (China) (Unl).gbc" size 1048576 crc acbfc58f sha1 76b1eccf666ea01320134d88d6f7558c24016ca8 ) +) + +game ( + name "Shuma Baolong 3 (China) (Unl)" + description "Shuma Baolong 3 (China) (Unl)" + rom ( name "Shuma Baolong 3 (China) (Unl).gbc" size 1048576 crc dab66d8c sha1 3902ecd4b233d0dff168a285788843de0b6df05e ) ) game ( @@ -43149,6 +45105,48 @@ game ( rom ( name "Shutokou Racing, The (Japan) (SGB Enhanced) (GB Compatible).gbc" size 131072 crc 36e781cd sha1 0f29818190ea9ce8c242b648ba64d50cc5408e5a ) ) +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 599132ec sha1 762087df0e5820f1e50da2a22f9ee3b8d16c3e49 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5370b1bf sha1 966e2d79ab4930039c3d6c43fdbb8cdc068ba347 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 16f34bcc sha1 c34e744b9120e3a1b2b054d3708e4ab594726c5a ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 31ce3f27 sha1 c33d685d5ea5cd6cd954af3bc9ee92719b9578b1 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc d54b53cb sha1 08948befa0227b795d00fe60e9eede6a1f56597b ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 314be6b5 sha1 37978f85ae92e7d9a53611659513fd360f57a5b1 ) +) + +game ( + name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" + description "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc 7ebcdd4e sha1 b99f43719155cafbc3dbd7df0ade281c3c7ba171 ) +) + game ( name "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe)" description "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe)" @@ -43167,6 +45165,12 @@ game ( rom ( name "Skycon (World) (Aftermarket) (Unl).gbc" size 524288 crc 195dbc30 sha1 df29ece6c5f5b14840663495230135dd79c5163a ) ) +game ( + name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" + description "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c906c5af sha1 0e0d472b282e3ea590e0f126baf633ef0d9298fa ) +) + game ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" description "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" @@ -43179,6 +45183,18 @@ game ( rom ( name "Smurfs Nightmare, The (USA).gbc" size 1048576 crc b50cafe4 sha1 1d0d3512f32176b7035f9c2a77d4636b1d08b349 ) ) +game ( + name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1aecd096 sha1 8ce256d963a55badf71fd45047c173a74d76a92c ) +) + +game ( + name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6cf39388 sha1 9cf5a1d3e8119303a1f4b04b8f4d8b683aee699e ) +) + game ( name "Snobow Champion (Japan)" description "Snobow Champion (Japan)" @@ -43209,6 +45225,12 @@ game ( rom ( name "Snoopy Tennis (Europe) (En,Fr,De,Es,It,Nl) (Beta).gbc" size 1048576 crc 49db04a6 sha1 03adc2731945bc86588fffedfee2050a00679ce6 ) ) +game ( + name "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" + description "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snooze (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b246095f sha1 b7fdcc006c9c06dd391ee26d44b278d9d3793f6d ) +) + game ( name "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)" description "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)" @@ -43233,6 +45255,12 @@ game ( rom ( name "Soccer Manager (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 237ecef9 sha1 353eb6aaf40a78ebf1bca9298726d068a5986efa ) ) +game ( + name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" + description "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 9e864f1c sha1 ce5dc23c04ff18dfac2367e53d241e81c4bbc3a3 ) +) + game ( name "Solomon (Japan)" description "Solomon (Japan)" @@ -43353,6 +45381,12 @@ game ( rom ( name "Spawn (USA).gbc" size 2097152 crc 72fcb0ad sha1 4f816eec1b5dc79928ade9f3a3c687b8aa5b2f87 ) ) +game ( + name "Spectipede (World) (Aftermarket) (Unl)" + description "Spectipede (World) (Aftermarket) (Unl)" + rom ( name "Spectipede (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c33f76e sha1 834a450d9ceb78b9d89d551300d4d0ea08cd8a6a ) +) + game ( name "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" description "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" @@ -43461,6 +45495,12 @@ game ( rom ( name "Star Heritage (Europe) (Proto) (Password Version).gbc" size 1048576 crc b39b4532 sha1 6eb2c27e2eedb22b4055ded87fce0621d460fe5b ) ) +game ( + name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" + description "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 29320841 sha1 890fda255106ea64bac4973e2e9f4b31bb925d35 ) +) + game ( name "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" description "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" @@ -43497,6 +45537,24 @@ game ( rom ( name "Star Wars Episode I - Racer (USA, Europe) (Rumble Version).gbc" size 2097152 crc 0ebc5758 sha1 c0613d654a4382f0c50fd4d389d3a6aeef4d5207 flags verified ) ) +game ( + name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" + description "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 82658661 sha1 dd45b0e3f346ce33668d49092b29a44597686061 ) +) + +game ( + name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" + description "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ce90a95b sha1 75457c5affd0c126f2c916e857950b5cde46a95e ) +) + +game ( + name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" + description "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b3a04b44 sha1 b16f21b46dfe4e6ce0368e3c5a3fae397274ebbf ) +) + game ( name "Startled 911 (Taiwan) (En) (Unl)" description "Startled 911 (Taiwan) (En) (Unl)" @@ -43563,12 +45621,24 @@ game ( rom ( name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2dc3fdae sha1 a551d904c4af661bd4b6e88063cb5541900117b0 ) ) +game ( + name "Suicide Run (World) (Aftermarket) (Unl)" + description "Suicide Run (World) (Aftermarket) (Unl)" + rom ( name "Suicide Run (World) (Aftermarket) (Unl).gbc" size 262144 crc d29ab1aa sha1 df373f58e51155e32fb81825a9082150f6d263c8 ) +) + game ( name "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" description "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" rom ( name "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl).gbc" size 2097152 crc 6a99a079 sha1 bcb683600278094e4d40a7da0226b83ec1f92c81 ) ) +game ( + name "Super 21 in 1 - New GB Rumble (Taiwan) (Unl)" + description "Super 21 in 1 - New GB Rumble (Taiwan) (Unl)" + rom ( name "Super 21 in 1 - New GB Rumble (Taiwan) (Unl).gbc" size 2097152 crc 21746216 sha1 829cc0fcd4b96cf5cac909a7c0697583f4c62241 ) +) + game ( name "Super 6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl)" description "Super 6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl)" @@ -43605,6 +45675,12 @@ game ( rom ( name "Super Breakout! (USA) (GB Compatible).gbc" size 1048576 crc 52f51cb5 sha1 8c795b6d8ebc3a796821a6b2879f3e5cebf9215c ) ) +game ( + name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c47330e2 sha1 6151286e93b2e2fb92f583371e650e36ab91aaf7 ) +) + game ( name "Super Chinese Fighter EX (Japan)" description "Super Chinese Fighter EX (Japan)" @@ -43620,7 +45696,7 @@ game ( game ( name "Super Donkey Kong 5 (Taiwan) (En) (Rumble Version) (Unl)" description "Super Donkey Kong 5 (Taiwan) (En) (Rumble Version) (Unl)" - rom ( name "Super Donkey Kong 5 (Taiwan) (En) (Rumble Version) (Unl).gbc" size 524288 crc d44c9806 sha1 c761dca73b520711b3205e11091e2bf8d4fd7549 ) + rom ( name "Super Donkey Kong 5 (Taiwan) (En) (Rumble Version) (Unl).gbc" size 524288 crc d44c9806 sha1 c761dca73b520711b3205e11091e2bf8d4fd7549 flags verified ) ) game ( @@ -43635,6 +45711,12 @@ game ( rom ( name "Super Fighters 99 (Taiwan) (SGB Enhanced) (Unl).gbc" size 2097152 crc ce41b1bb sha1 e5af8afdce844f02c4128748067933840a759773 ) ) +game ( + name "Super Fighters S (Taiwan) (GB Compatible) (Unl)" + description "Super Fighters S (Taiwan) (GB Compatible) (Unl)" + rom ( name "Super Fighters S (Taiwan) (GB Compatible) (Unl).gbc" size 2097152 crc 64db799a sha1 ef0bf0feaf9e2bdfb10acd469e915266655adb43 ) +) + game ( name "Super Gals! Kotobuki Ran (Japan)" description "Super Gals! Kotobuki Ran (Japan)" @@ -43654,15 +45736,33 @@ game ( ) game ( - name "Super Jacked Up Tomato Face Johnson (World) (Aftermarket) (Unl)" - description "Super Jacked Up Tomato Face Johnson (World) (Aftermarket) (Unl)" - rom ( name "Super Jacked Up Tomato Face Johnson (World) (Aftermarket) (Unl).gbc" size 524288 crc 87956ddf sha1 b23320d5d3fde2a55b301f7bea324833c31c32d5 ) + name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a38d702f sha1 301f93da4e5b0cd8dc3f1bf3e66e38176b8a909b ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl).gbc" size 524288 crc 8e1f6bb0 sha1 27522a35211b0f015fa9550c2520f1da1c346886 ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl).gbc" size 524288 crc f9731ee2 sha1 23855b95d04a6c7c6d2ce7977bb31dbe6c0e68a0 ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl).gbc" size 524288 crc 87956ddf sha1 b23320d5d3fde2a55b301f7bea324833c31c32d5 ) ) game ( name "Super JetPak DX (World) (GB Compatible) (Aftermarket)" description "Super JetPak DX (World) (GB Compatible) (Aftermarket)" - rom ( name "Super JetPak DX (World) (GB Compatible) (Aftermarket).gbc" size 131072 crc 22def6f9 sha1 e7438db01fbbdeea2404dbf3d093370421ec4e1c ) + rom ( name "Super JetPak DX (World) (GB Compatible) (Aftermarket).gbc" size 131072 crc 22def6f9 sha1 e7438db01fbbdeea2404dbf3d093370421ec4e1c flags verified ) ) game ( @@ -43851,6 +45951,18 @@ game ( rom ( name "SWiV (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 44d30b7a sha1 7e037008eabf01fa647cdfb0d5c88766a6f77423 ) ) +game ( + name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" + description "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 64921bb1 sha1 b36ec89e0299c19767cc5c6467fa3664abbc3017 ) +) + +game ( + name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + description "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b2b5dc4b sha1 aaa66863b2e68865359d1c0db2047bab6f64f9ee ) +) + game ( name "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced) (GB Compatible)" description "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced) (GB Compatible)" @@ -43935,10 +46047,22 @@ game ( rom ( name "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6a0c272d sha1 d6d90667ebf295016f01b4604ab03ab5b1876d00 ) ) +game ( + name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" + description "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a685f89a sha1 15a709d4300464b03ede4d774ce69cfb699c0fcf ) +) + game ( name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible)" description "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible)" - rom ( name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 725cf31c sha1 ef322f4160ceebd8da67758ebd73225190af6d23 ) + rom ( name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 725cf31c sha1 ef322f4160ceebd8da67758ebd73225190af6d23 flags verified ) +) + +game ( + name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" + description "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" + rom ( name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl).gbc" size 262144 crc 257d9201 sha1 d78e0b03a3915531e780057c4ad7ed2b3f849825 ) ) game ( @@ -44008,15 +46132,15 @@ game ( ) game ( - name "Tazz (World) (2022-10-14) (Aftermarket) (Unl)" - description "Tazz (World) (2022-10-14) (Aftermarket) (Unl)" - rom ( name "Tazz (World) (2022-10-14) (Aftermarket) (Unl).gbc" size 262144 crc 1d97b754 sha1 39226ed715ae8d94f9187c3e5e8a849eac92ca26 ) + name "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" + description "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" + rom ( name "Tazz (World) (2022-10-13) (Aftermarket) (Unl).gbc" size 262144 crc 1d97b754 sha1 39226ed715ae8d94f9187c3e5e8a849eac92ca26 ) ) game ( - name "Tazz (World) (2022-10-18) (Aftermarket) (Unl)" - description "Tazz (World) (2022-10-18) (Aftermarket) (Unl)" - rom ( name "Tazz (World) (2022-10-18) (Aftermarket) (Unl).gbc" size 262144 crc 6fb0ba23 sha1 543118e54b166ea2b8b5979f8468cc2f5662161f ) + name "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" + description "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" + rom ( name "Tazz (World) (2022-10-17) (Aftermarket) (Unl).gbc" size 262144 crc 6fb0ba23 sha1 543118e54b166ea2b8b5979f8468cc2f5662161f ) ) game ( @@ -44110,9 +46234,9 @@ game ( ) game ( - name "Tezhong Budui (Taiwan) (Unl) (Alt)" - description "Tezhong Budui (Taiwan) (Unl) (Alt)" - rom ( name "Tezhong Budui (Taiwan) (Unl) (Alt).gbc" size 1048576 crc bf0028d9 sha1 99f536400bb99892b736f66305e1b11d8229c668 ) + name "Tezhong Budui (Taiwan) (Unl) (Alt) [b]" + description "Tezhong Budui (Taiwan) (Unl) (Alt) [b]" + rom ( name "Tezhong Budui (Taiwan) (Unl) (Alt) [b].gbc" size 1048576 crc bf0028d9 sha1 99f536400bb99892b736f66305e1b11d8229c668 flags baddump ) ) game ( @@ -44175,6 +46299,18 @@ game ( rom ( name "Tintin au Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 6832f38a sha1 eef17d4a827efab90c03083edb0bee534cd64188 ) ) +game ( + name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc af13e718 sha1 307e51664db2101755b6c617f3d81ee58676c485 ) +) + +game ( + name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0518f5aa sha1 85e5cd0cf7a6cc4a5946c93fa8665235a686e554 ) +) + game ( name "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It)" description "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It)" @@ -44310,7 +46446,7 @@ game ( game ( name "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De)" description "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De)" - rom ( name "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De).gbc" size 1048576 crc e72f2683 sha1 7e9e21db84d1bfdab3c604c9e3328f624f86a9b1 ) + rom ( name "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De).gbc" size 1048576 crc e72f2683 sha1 7e9e21db84d1bfdab3c604c9e3328f624f86a9b1 flags verified ) ) game ( @@ -44343,6 +46479,12 @@ game ( rom ( name "Tomb Raider 2 (Taiwan) (Unl).gbc" size 4194304 crc 717a5d19 sha1 5b9325b6e322a806677c6ea37a0054381609b99e ) ) +game ( + name "Tomte Trouble (World) (Aftermarket) (Unl)" + description "Tomte Trouble (World) (Aftermarket) (Unl)" + rom ( name "Tomte Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc a43d6b82 sha1 99730fe00703d655b1c806f49c9e3c2fb3dec58e flags verified ) +) + game ( name "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" description "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" @@ -44571,6 +46713,12 @@ game ( rom ( name "Trade & Battle Card Hero (Japan) (Rev 1) (3DS Virtual Console) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc d98a877d sha1 c6c1e0365166b53d25a1f84bc380948a9661df30 ) ) +game ( + name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b0a32d51 sha1 4c0d639722d1cd8393e008d174b8f7266d089ead ) +) + game ( name "Treasure Island Color (World) (Aftermarket) (Unl)" description "Treasure Island Color (World) (Aftermarket) (Unl)" @@ -44607,6 +46755,12 @@ game ( rom ( name "Trouballs (USA).gbc" size 524288 crc 260eed04 sha1 dc4d0f608354e7cc32df7501dbacf8c50d70e728 ) ) +game ( + name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4b9143ad sha1 0e51e398d44aaad74a7c622f7818b56a3b34db56 ) +) + game ( name "True Color 25 in 1 (Taiwan) (Unl)" description "True Color 25 in 1 (Taiwan) (Unl)" @@ -44673,6 +46827,12 @@ game ( rom ( name "Tutty (Europe) (Demo).gbc" size 131072 crc c4655f0a sha1 51883c4cc1469987483f993e3904da22690faeb9 ) ) +game ( + name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 01239312 sha1 4f21c3539ef40a7630581fe50533371e0d1a1ba9 ) +) + game ( name "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" description "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" @@ -44715,6 +46875,18 @@ game ( rom ( name "Tycoon Tex (World) (Aftermarket) (Unl).gbc" size 262144 crc fa8436ba sha1 d37bcd93d647ac7efb761c539785a4ef570cdcc8 ) ) +game ( + name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" + description "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" + rom ( name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl).gbc" size 2097152 crc 8067298a sha1 e44280161ca9d482fae08de844ccc9754abf68b0 ) +) + +game ( + name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" + description "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" + rom ( name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0ce45101 sha1 f61677146ef67b026c636742f0109b8c478d0942 ) +) + game ( name "Tyrannosaurus Tex (USA) (Proto)" description "Tyrannosaurus Tex (USA) (Proto)" @@ -44781,6 +46953,24 @@ game ( rom ( name "Ultimate Surfing (USA).gbc" size 1048576 crc e84df1f0 sha1 264c19ab212d938839306f7e8230d5caee3cf3e7 ) ) +game ( + name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 29bb9238 sha1 39fbfb220e9be0120090f770249049b3f3583f64 ) +) + +game ( + name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 977b54f4 sha1 016dde406896d827dcad682d40b52d0e9eeefa88 ) +) + +game ( + name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" + description "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 36e4ff4c sha1 b5c9b5f07e31729678637d883b2564c1448b0e57 ) +) + game ( name "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" description "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" @@ -44949,6 +47139,24 @@ game ( rom ( name "Warlocked (USA).gbc" size 2097152 crc cfa0df0f sha1 2f9c05f74476368bd6dbba7d675e7870cf8ca27c flags verified ) ) +game ( + name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1bfe1bf9 sha1 fae12dbbb75ae024e96a7ee21ad4077fdb5ed9a1 ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a381c914 sha1 adf37c5d2f706743b2a4946378df49ed19212039 ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 5519c167 sha1 04a53af6a77b884af91f8047d70fc0331bf23913 ) +) + game ( name "Warriors of Might and Magic (USA) (En,Fr,De)" description "Warriors of Might and Magic (USA) (En,Fr,De)" @@ -44991,6 +47199,12 @@ game ( rom ( name "Watashi no Restaurant (Japan) (Beta 3).gbc" size 1048576 crc a0ed2859 sha1 343bf8ebb6fa3ce89501f7c4c219fb7e864c38a3 ) ) +game ( + name "Water Grandprix (World) (Aftermarket) (Unl)" + description "Water Grandprix (World) (Aftermarket) (Unl)" + rom ( name "Water Grandprix (World) (Aftermarket) (Unl).gbc" size 262144 crc 82f54e7e sha1 4029e003870b2afb78a3644e24397d80fc5a3210 ) +) + game ( name "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" description "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" @@ -45057,6 +47271,18 @@ game ( rom ( name "Wetrix GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6215c5b3 sha1 92944052b6e4448abf0103f085998662e0140825 ) ) +game ( + name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 776fc18e sha1 5c4a227c0b2f53e4a349e482c5ba87cb83404f8e ) +) + +game ( + name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" + description "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c3d5cbf sha1 a235c0915ac2b826eeb5884d0eccd321236fdb0c ) +) + game ( name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" description "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" @@ -45075,6 +47301,12 @@ game ( rom ( name "Wild Thornberrys, The - Rambler (USA).gbc" size 1048576 crc 0e1465cb sha1 0e806f0e6c1a41e764683850a3c15a80ac7fc9a5 ) ) +game ( + name "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 04e04980 sha1 574cf911d6d8f73699203cd6db42ceec777f7f93 ) +) + game ( name "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl)" description "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl)" @@ -45285,6 +47517,12 @@ game ( rom ( name "Xiao Taiji - Shenhua Lixian (Taiwan) (Unl).gbc" size 2097152 crc 322c3816 sha1 c89f8d19a52ab5f183a03d65680bf80d1af4a0ee ) ) +game ( + name "Xin Fengkuang A Gei Pao Pao Tang (Taiwan) (Unl)" + description "Xin Fengkuang A Gei Pao Pao Tang (Taiwan) (Unl)" + rom ( name "Xin Fengkuang A Gei Pao Pao Tang (Taiwan) (Unl).gbc" size 2097152 crc e40f757f sha1 6d1332456e10e9da78726415640117262fe53e99 ) +) + game ( name "Xin Fengshenbang (Taiwan) (Unl)" description "Xin Fengshenbang (Taiwan) (Unl)" @@ -45303,6 +47541,12 @@ game ( rom ( name "Xin Shediao Yingxiong Chuan (Taiwan) (Unl).gbc" size 1048576 crc 20e40d8f sha1 a11aa648810f3e69d3678d2c53137575bfbd34d6 ) ) +game ( + name "Xin Shiqi Shidai (Taiwan) (Unl)" + description "Xin Shiqi Shidai (Taiwan) (Unl)" + rom ( name "Xin Shiqi Shidai (Taiwan) (Unl).gbc" size 2097152 crc f55342ca sha1 d51300e59c67f88dd2281ca53ae7c035489a723c ) +) + game ( name "Xingqiu Dazhan II - Kelong Ren Zhanyi (Taiwan) (Unl)" description "Xingqiu Dazhan II - Kelong Ren Zhanyi (Taiwan) (Unl)" @@ -45339,6 +47583,12 @@ game ( rom ( name "Xtreme Sports (USA).gbc" size 4194304 crc 19828751 sha1 ffca13207e6284a3cc16f7f130b68fca87663d08 ) ) +game ( + name "Xtreme Sports (World) (Switch)" + description "Xtreme Sports (World) (Switch)" + rom ( name "Xtreme Sports (World) (Switch).gbc" size 4194304 crc c0437e08 sha1 5da3ad1c5354f29a74c571c2b598da96213afbe1 flags verified ) +) + game ( name "Xtreme Wheels (Europe)" description "Xtreme Wheels (Europe)" @@ -45357,6 +47607,12 @@ game ( rom ( name "Xtreme Wheels (Japan) (Possible Proto) (NP).gbc" size 1048576 crc 30132ab8 sha1 a9f67640d20771e64b1474144fcca9beebdde85d ) ) +game ( + name "Xzap (World) (Aftermarket) (Unl)" + description "Xzap (World) (Aftermarket) (Unl)" + rom ( name "Xzap (World) (Aftermarket) (Unl).gbc" size 262144 crc 68ceec9c sha1 35ae73d3ec93c95fdad9a358ccc34bcfc12445b1 ) +) + game ( name "Yakouchuu GB (Japan)" description "Yakouchuu GB (Japan)" @@ -45375,12 +47631,30 @@ game ( rom ( name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b304833d sha1 c2be46b8230bfcf509d031902c9bf144de97ef58 ) ) +game ( + name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc f15351c8 sha1 a78ff2eef780287bbdc37df122cfc1c504526662 ) +) + +game ( + name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b70c1c7f sha1 ce25cdf6a6264586423e76e34dc42779d39a1cb1 ) +) + game ( name "Yin Ban Zhongwen RPG Zhanlve + Dongzuo + Yizhi 12 in 1 (Taiwan) (Unl)" description "Yin Ban Zhongwen RPG Zhanlve + Dongzuo + Yizhi 12 in 1 (Taiwan) (Unl)" rom ( name "Yin Ban Zhongwen RPG Zhanlve + Dongzuo + Yizhi 12 in 1 (Taiwan) (Unl).gbc" size 8388608 crc dc3171ad sha1 bfb93e7b4b523ef21c2b98ba9dcb15eb7d4f07e4 ) ) +game ( + name "Yinghan Zidian (Taiwan) (Unl)" + description "Yinghan Zidian (Taiwan) (Unl)" + rom ( name "Yinghan Zidian (Taiwan) (Unl).gbc" size 1048576 crc 87158db6 sha1 5d42f3b769176df569a99c167c67e685c70501e1 ) +) + game ( name "Yingxiong Jian 2 (Taiwan) (Unl)" description "Yingxiong Jian 2 (Taiwan) (Unl)" @@ -45393,6 +47667,12 @@ game ( rom ( name "Yingxiong Tianxia (Taiwan) (Zh) (Unl).gbc" size 2097152 crc 5f2d6317 sha1 41f5f0c11e4e99b7d2d1433b09922a0fd2c48d7f ) ) +game ( + name "Yinyang (Taiwan) (De) (Unl)" + description "Yinyang (Taiwan) (De) (Unl)" + rom ( name "Yinyang (Taiwan) (De) (Unl).gbc" size 2097152 crc 1dd042ab sha1 2da9f06d57dcd397d0333b5d85a26a593acea8b3 ) +) + game ( name "Yixing VS Tiexue Zhanshi (Taiwan) (Unl)" description "Yixing VS Tiexue Zhanshi (Taiwan) (Unl)" @@ -45540,7 +47820,7 @@ game ( game ( name "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan)" description "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan)" - rom ( name "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan).gbc" size 1048576 crc 3272e6f9 sha1 596aa066ccee9fae71643576f7526baa22d26d6d ) + rom ( name "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan).gbc" size 1048576 crc 3272e6f9 sha1 596aa066ccee9fae71643576f7526baa22d26d6d flags verified ) ) game ( @@ -45552,7 +47832,7 @@ game ( game ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc bd8a1041 sha1 d3de302d44bdb240bcf55a5dc70f491f5456d721 ) + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc bd8a1041 sha1 d3de302d44bdb240bcf55a5dc70f491f5456d721 flags verified ) ) game ( @@ -45568,15 +47848,15 @@ game ( ) game ( - name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05 18.00.56) (GB Compatible)" - description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05 18.00.56) (GB Compatible)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05 18.00.56) (GB Compatible).gbc" size 1048576 crc 11290c31 sha1 8d7ab85686ced1642b9519bcb6a3e157c6bd8938 ) + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05T180056) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05T180056) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05T180056) (GB Compatible).gbc" size 1048576 crc 11290c31 sha1 8d7ab85686ced1642b9519bcb6a3e157c6bd8938 ) ) game ( - name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05 21.55.32) (GB Compatible)" - description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05 21.55.32) (GB Compatible)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05 21.55.32) (GB Compatible).gbc" size 1048576 crc 3c63e083 sha1 a068abd403a1dad70bd9b53d215995f8159aea47 ) + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05T215532) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05T215532) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-05T215532) (GB Compatible).gbc" size 1048576 crc 3c63e083 sha1 a068abd403a1dad70bd9b53d215995f8159aea47 ) ) game ( @@ -45586,9 +47866,93 @@ game ( ) game ( - name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14) (GB Compatible)" - description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14) (GB Compatible)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14) (GB Compatible).gbc" size 1048576 crc 13c76902 sha1 08dea3565740a4b5bd5c13e82adb61e3d5669a31 ) + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14T022124) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14T022124) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14T022124) (GB Compatible).gbc" size 1048576 crc 13c76902 sha1 08dea3565740a4b5bd5c13e82adb61e3d5669a31 ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-02) (SGB Enhanced)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-02) (SGB Enhanced)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-02) (SGB Enhanced).gbc" size 1048576 crc 34ff47ba sha1 5ccc4c05123b4c38d0d93916ae8a0c93fb63f23f ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-03) (SGB Enhanced)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-03) (SGB Enhanced)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-03) (SGB Enhanced).gbc" size 1048576 crc ac0ef411 sha1 5aeb68b00a3a4f391afb324d9513311cb796a51f ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-04) (SGB Enhanced)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-04) (SGB Enhanced)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-04) (SGB Enhanced).gbc" size 1048576 crc 260bd98a sha1 ce1e48c82a09de0f93d5a60016318a9116331ccb ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-09-04) (SGB Enhanced)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-09-04) (SGB Enhanced)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-09-04) (SGB Enhanced).gbc" size 1048576 crc 883ef4ef sha1 87ca50396ba25914131866c74633afbe0007b2fb ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced).gbc" size 1048576 crc 89a4a355 sha1 48931a00f5fec39492c264e9979646e88242c53e ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced) (Alt)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced) (Alt)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced) (Alt).gbc" size 1048576 crc e5312966 sha1 fedd0fa70bbf5039dfec37b8e27674be839c47ca ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced) (Alt 2)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced) (Alt 2)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-08-07) (SGB Enhanced) (Alt 2).gbc" size 1048576 crc 1c374afd sha1 800db3d07a7abcca2138a0c7808cf25386e87712 ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-06-15) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-06-15) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-06-15) (GB Compatible).gbc" size 1048576 crc 3fd6c8fc sha1 017b81b26fc37db662063482e3947dfc2d814390 ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-06-15) (GB Compatible) (Alt)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-06-15) (GB Compatible) (Alt)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-06-15) (GB Compatible) (Alt).gbc" size 1048576 crc 9367653b sha1 544b803db49d8f312e193e4c105f0762d9e3fbf4 ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14T181500) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14T181500) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-07-14T181500) (GB Compatible).gbc" size 1048576 crc 2f884286 sha1 a7cb241de2139ddac5d1172a6ef1184b5fbb827e ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-11-09) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-11-09) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Beta) (1998-11-09) (GB Compatible).gbc" size 1048576 crc 3e5216c3 sha1 0fe1c48e36cb8e6e975c5421bf881c550746d29c ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (Demo) (Special Version 1) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (Demo) (Special Version 1) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (Demo) (Special Version 1) (GB Compatible).gbc" size 1048576 crc e05757f6 sha1 ee2df3c8449187fcd82f2fc830386bfe8144b387 ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (Demo) (Special Version 2) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (Demo) (Special Version 2) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (Demo) (Special Version 2) (GB Compatible).gbc" size 1048576 crc e6101132 sha1 515f8d2fcaebe9495fb21f46ec32cce877c35e56 ) +) + +game ( + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc c07979bf sha1 4a9ce5ced2234fa668dace888bd5d6130e375985 ) ) game ( @@ -45597,6 +47961,12 @@ game ( rom ( name "Zen-Nihon Shounen Soccer Taikai - Mezase Nihon Ichi! (Japan).gbc" size 2097152 crc efad8b34 sha1 bffe5fdb803f0872d1c0de9d152eb626c5b36147 ) ) +game ( + name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" + description "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" + rom ( name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc db0951d3 sha1 7b74c658f24894659cfda1fc3c7775fd9f7b6013 ) +) + game ( name "Zhen Sanguo Wushuang 2 - Shin Sangokumusou (Taiwan) (Unl)" description "Zhen Sanguo Wushuang 2 - Shin Sangokumusou (Taiwan) (Unl)" @@ -45663,6 +48033,12 @@ game ( rom ( name "Zok Zok Heroes (Japan).gbc" size 2097152 crc c09f9e1b sha1 91ab908fddebd926e7db8d61295a40955b2adc39 ) ) +game ( + name "Zone Control (World) (Aftermarket) (Unl)" + description "Zone Control (World) (Aftermarket) (Unl)" + rom ( name "Zone Control (World) (Aftermarket) (Unl).gbc" size 262144 crc 856ed536 sha1 a191d41fd86a7c17015e04156ffff8222302d36e ) +) + game ( name "Zook Z (USA) (Unl)" description "Zook Z (USA) (Unl)" From 4717d25eb53dddea15765dcad160489cf0903648 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jan 2024 19:15:52 -0800 Subject: [PATCH 039/336] Res: Update patrons.txt --- res/patrons.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/patrons.txt b/res/patrons.txt index 5126cc891..8e61ae237 100644 --- a/res/patrons.txt +++ b/res/patrons.txt @@ -1,14 +1,14 @@ Akatsuki -AVjoyu__Chan Benedikt Feih Brandon Emily A. Bellows -G +EmuDeck gocha Jaime J. Denizard MichaelK__ Miras Absar -Nic Losby +Molly Howell +Nic Losby (blurbdust) Petru-Sebastian Toader Stevoisiak William K. Leung From 72a620a484cebd05696a4c69a1120dc58973b65e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jan 2024 19:19:46 -0800 Subject: [PATCH 040/336] CHANGES: Update for 0.10.3 --- CHANGES | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index e6567d3e9..da14c8b59 100644 --- a/CHANGES +++ b/CHANGES @@ -6,37 +6,17 @@ Features: - New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81 - Debugger: Add range watchpoints Emulation fixes: - - ARM: Remove obsolete force-alignment in `bx pc` (fixes mgba.io/i/2964) - - ARM: Fake bpkt instruction should take no cycles (fixes mgba.io/i/2551) - - GB Audio: Fix channels 1/2 staying muted if restarted after long silence - - GB Audio: Fix channel 1 restarting if sweep applies after stop (fixes mgba.io/i/2965) - - GB Audio: Fix restarting envelope when writing to register (fixes mgba.io/i/3067) - - GB Audio: Improve "zombie mode" emulation in CGB mode (fixes mgba.io/i/2029) - - GB I/O: Read back proper SVBK value after writing 0 (fixes mgba.io/i/2921) - GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501) - GB Serialize: Add missing Pocket Cam state to savestates - - GB SIO: Disabling SIO should cancel pending transfers (fixes mgba.io/i/2537) - GB Video: Implement DMG-style sprite ordering - GBA: Unhandled bkpt should be treated as an undefined exception - - GBA Audio: Fix sample timing drifting when changing sample interval - - GBA Audio: Fix initial channel 3 wave RAM (fixes mgba.io/i/2947) - - GBA Audio: Fix sample position issues when rate changes (fixes mgba.io/i/3006) - - GBA BIOS: Fix clobbering registers with word-sized CpuSet - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - - GBA SIO: Fix normal mode SI/SO semantics (fixes mgba.io/i/2925) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - - GB: Fix applying a patch that changes the cartridge mapper (fixes mgba.io/i/3077) - - GBA Savedata: Fix crash when resizing flash save games for RTC data - - mGUI: Fix cases where an older save state screenshot would be shown. (fixes mgba.io/i/2183) - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - - Qt: Re-enable sync for multiplayer windows that aren't connected (fixes mgba.io/i/2974) - - Qt: Fix mute settings not being loaded on setting screen (fixes mgba.io/i/2990) - - Qt: Fix screen freezing on macOS after closing save state window (fixes mgba.io/i/2885) - - Vita: Fix camera setting not appearing (fixes mgba.io/i/3012) Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) - GB: Prevent incompatible BIOSes from being used on differing models @@ -44,10 +24,37 @@ Misc: - GBA: Improve detection of valid ELF ROMs - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) - - Qt: Add exporting of SAV + RTC saves from Save Converter to strip RTC data - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Scripting: Add `callbacks:oneshot` for single-call callbacks + +0.10.3: (2024-01-07) +Emulation fixes: + - ARM: Remove obsolete force-alignment in `bx pc` (fixes mgba.io/i/2964) + - ARM: Fake bpkt instruction should take no cycles (fixes mgba.io/i/2551) + - GB Audio: Fix channels 1/2 staying muted if restarted after long silence + - GB Audio: Fix channel 1 restarting if sweep applies after stop (fixes mgba.io/i/2965) + - GB Audio: Fix restarting envelope when writing to register (fixes mgba.io/i/3067) + - GB Audio: Improve "zombie mode" emulation in CGB mode (fixes mgba.io/i/2029) + - GB I/O: Read back proper SVBK value after writing 0 (fixes mgba.io/i/2921) + - GB SIO: Disabling SIO should cancel pending transfers (fixes mgba.io/i/2537) + - GBA Audio: Fix sample timing drifting when changing sample interval + - GBA Audio: Fix initial channel 3 wave RAM (fixes mgba.io/i/2947) + - GBA Audio: Fix sample position issues when rate changes (fixes mgba.io/i/3006) + - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) + - GBA BIOS: Fix clobbering registers with word-sized CpuSet + - GBA SIO: Fix normal mode SI/SO semantics (fixes mgba.io/i/2925) +Other fixes: + - GB: Fix applying a patch that changes the cartridge mapper (fixes mgba.io/i/3077) + - GBA Savedata: Fix crash when resizing flash save games for RTC data + - mGUI: Fix cases where an older save state screenshot would be shown (fixes mgba.io/i/2183) + - Qt: Re-enable sync for multiplayer windows that aren't connected (fixes mgba.io/i/2974) + - Qt: Fix mute settings not being loaded on setting screen (fixes mgba.io/i/2990) + - Qt: Fix screen freezing on macOS after closing save state window (fixes mgba.io/i/2885) + - Vita: Fix camera setting not appearing (fixes mgba.io/i/3012) +Misc: + - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) + - Qt: Add exporting of SAV + RTC saves from Save Converter to strip RTC data - VFS: Use anonymousMemoryMap for large 7z allocations (fixes mgba.io/i/3013) 0.10.2: (2023-04-23) From 2c5882df3e345091a88002c777af0464ff948196 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 9 Jan 2024 22:17:33 -0800 Subject: [PATCH 041/336] All: Fix some warnings --- src/debugger/debugger.c | 3 ++- src/platform/sdl/gl-common.c | 2 +- src/util/sfo.c | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/debugger/debugger.c b/src/debugger/debugger.c index cc0b32683..f1d876005 100644 --- a/src/debugger/debugger.c +++ b/src/debugger/debugger.c @@ -58,10 +58,11 @@ struct mDebuggerModule* mDebuggerCreateModule(enum mDebuggerType type, struct mC break; #endif case DEBUGGER_NONE: + case DEBUGGER_ACCESS_LOGGER: case DEBUGGER_CUSTOM: case DEBUGGER_MAX: free(debugger); - return 0; + return NULL; break; } diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index 076429f6b..4bd8643b7 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -170,7 +170,7 @@ void mSDLGLCommonRunloop(struct mSDLRenderer* renderer, void* user) { renderer->core->currentVideoSize(renderer->core, &renderer->width, &renderer->height); struct mRectangle dims; v->layerDimensions(v, VIDEO_LAYER_IMAGE, &dims); - if (renderer->width != dims.width || renderer->height != dims.height) { + if (dims.width < 0 || dims.height < 0 || renderer->width != (unsigned) dims.width || renderer->height != (unsigned) dims.height) { renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, renderer->width); dims.width = renderer->width; dims.height = renderer->height; diff --git a/src/util/sfo.c b/src/util/sfo.c index 90142897b..21ffd0f0f 100644 --- a/src/util/sfo.c +++ b/src/util/sfo.c @@ -161,6 +161,8 @@ bool SfoWrite(struct Table* sfo, struct VFile* vf) { case PSF_TYPE_U32: sortedEntries[i].size = 4; break; + default: + return false; } } dataSize += ALIGN4(sortedEntries[i].size); From 328bebbc01e9b99edbf791363e0e4ca56bc72d8b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 9 Jan 2024 23:26:14 -0800 Subject: [PATCH 042/336] GBA Video: Migrate window precalculation into a function --- .../internal/gba/renderers/video-software.h | 2 + src/gba/renderers/software-bg.c | 6 +- src/gba/renderers/software-private.h | 29 +------ src/gba/renderers/video-software.c | 87 +++++++++++-------- 4 files changed, 60 insertions(+), 64 deletions(-) diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index d9985f960..969ffed64 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -42,6 +42,8 @@ struct GBAVideoSoftwareBackground { uint16_t mapCache[64]; uint32_t flags; uint32_t objwinFlags; + int objwinForceEnable; + bool objwinOnly; bool variant; int32_t offsetX; int32_t offsetY; diff --git a/src/gba/renderers/software-bg.c b/src/gba/renderers/software-bg.c index 8c48b41ad..7d50b5088 100644 --- a/src/gba/renderers/software-bg.c +++ b/src/gba/renderers/software-bg.c @@ -127,7 +127,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode3(struct GBAVideoSoftwareRenderer } uint32_t current = *pixel; - if (!objwinSlowPath || (!(current & FLAG_OBJWIN)) != objwinOnly) { + if (!objwinSlowPath || (!(current & FLAG_OBJWIN)) != background->objwinOnly) { unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { mergedFlags = objwinFlags; @@ -172,7 +172,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer if (color && IS_WRITABLE(current)) { if (!objwinSlowPath) { _compositeBlendNoObjwin(renderer, pixel, palette[color] | flags, current); - } else if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { + } else if (background->objwinForceEnable || (!(current & FLAG_OBJWIN)) == background->objwinOnly) { color_t* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette; unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { @@ -211,7 +211,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode5(struct GBAVideoSoftwareRenderer } uint32_t current = *pixel; - if (!objwinSlowPath || (!(current & FLAG_OBJWIN)) != objwinOnly) { + if (!objwinSlowPath || (!(current & FLAG_OBJWIN)) != background->objwinOnly) { unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { mergedFlags = objwinFlags; diff --git a/src/gba/renderers/software-private.h b/src/gba/renderers/software-private.h index ec8ef4175..8a195534b 100644 --- a/src/gba/renderers/software-private.h +++ b/src/gba/renderers/software-private.h @@ -85,7 +85,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re } #define COMPOSITE_16_OBJWIN(BLEND, IDX) \ - if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { \ + if (background->objwinForceEnable || (!(current & FLAG_OBJWIN)) == background->objwinOnly) { \ unsigned color; \ unsigned mergedFlags = flags; \ if (current & FLAG_OBJWIN) { \ @@ -111,7 +111,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re } #define COMPOSITE_256_OBJWIN(BLEND, IDX) \ - if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { \ + if (background->objwinForceEnable || (!(current & FLAG_OBJWIN)) == background->objwinOnly) { \ unsigned color; \ unsigned mergedFlags = flags; \ if (current & FLAG_OBJWIN) { \ @@ -155,9 +155,6 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re // TODO: Remove UNUSEDs after implementing OBJWIN for modes 3 - 5 #define PREPARE_OBJWIN \ int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); \ - int objwinOnly = 0; \ - int objwinForceEnable = 0; \ - UNUSED(objwinForceEnable); \ color_t* objwinPalette = renderer->normalPalette; \ if (renderer->d.highlightAmount && background->highlight) { \ objwinPalette = renderer->highlightPalette; \ @@ -171,28 +168,6 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re palette = renderer->highlightVariantPalette; \ } \ } \ - switch (background->index) { \ - case 0: \ - objwinForceEnable = GBAWindowControlIsBg0Enable(renderer->objwin.packed) && \ - GBAWindowControlIsBg0Enable(renderer->currentWindow.packed); \ - objwinOnly = !GBAWindowControlIsBg0Enable(renderer->objwin.packed); \ - break; \ - case 1: \ - objwinForceEnable = GBAWindowControlIsBg1Enable(renderer->objwin.packed) && \ - GBAWindowControlIsBg1Enable(renderer->currentWindow.packed); \ - objwinOnly = !GBAWindowControlIsBg1Enable(renderer->objwin.packed); \ - break; \ - case 2: \ - objwinForceEnable = GBAWindowControlIsBg2Enable(renderer->objwin.packed) && \ - GBAWindowControlIsBg2Enable(renderer->currentWindow.packed); \ - objwinOnly = !GBAWindowControlIsBg2Enable(renderer->objwin.packed); \ - break; \ - case 3: \ - objwinForceEnable = GBAWindowControlIsBg3Enable(renderer->objwin.packed) && \ - GBAWindowControlIsBg3Enable(renderer->currentWindow.packed); \ - objwinOnly = !GBAWindowControlIsBg3Enable(renderer->objwin.packed); \ - break; \ - } \ } #define BACKGROUND_BITMAP_INIT \ diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 7b9c65623..6c78c08e0 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -505,6 +505,58 @@ static void _breakWindowInner(struct GBAVideoSoftwareRenderer* softwareRenderer, #endif } +static void GBAVideoSoftwareRendererPrepareWindow(struct GBAVideoSoftwareRenderer* renderer) { + int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); + if (objwinSlowPath) { + renderer->bg[0].objwinForceEnable = GBAWindowControlIsBg0Enable(renderer->objwin.packed) && + GBAWindowControlIsBg0Enable(renderer->currentWindow.packed); + renderer->bg[0].objwinOnly = !GBAWindowControlIsBg0Enable(renderer->objwin.packed); + renderer->bg[1].objwinForceEnable = GBAWindowControlIsBg1Enable(renderer->objwin.packed) && + GBAWindowControlIsBg1Enable(renderer->currentWindow.packed); + renderer->bg[1].objwinOnly = !GBAWindowControlIsBg1Enable(renderer->objwin.packed); + renderer->bg[2].objwinForceEnable = GBAWindowControlIsBg2Enable(renderer->objwin.packed) && + GBAWindowControlIsBg2Enable(renderer->currentWindow.packed); + renderer->bg[2].objwinOnly = !GBAWindowControlIsBg2Enable(renderer->objwin.packed); + renderer->bg[3].objwinForceEnable = GBAWindowControlIsBg3Enable(renderer->objwin.packed) && + GBAWindowControlIsBg3Enable(renderer->currentWindow.packed); + renderer->bg[3].objwinOnly = !GBAWindowControlIsBg3Enable(renderer->objwin.packed); + } + + switch (GBARegisterDISPCNTGetMode(renderer->dispcnt)) { + case 0: + if (renderer->bg[0].enabled == ENABLED_MAX) { + _updateFlags(renderer, &renderer->bg[0]); + } + if (renderer->bg[1].enabled == ENABLED_MAX) { + _updateFlags(renderer, &renderer->bg[1]); + } + // Fall through + case 2: + if (renderer->bg[3].enabled == ENABLED_MAX) { + _updateFlags(renderer, &renderer->bg[3]); + } + // Fall through + case 3: + case 4: + case 5: + if (renderer->bg[2].enabled == ENABLED_MAX) { + _updateFlags(renderer, &renderer->bg[2]); + } + break; + case 1: + if (renderer->bg[0].enabled == ENABLED_MAX) { + _updateFlags(renderer, &renderer->bg[0]); + } + if (renderer->bg[1].enabled == ENABLED_MAX) { + _updateFlags(renderer, &renderer->bg[1]); + } + if (renderer->bg[2].enabled == ENABLED_MAX) { + _updateFlags(renderer, &renderer->bg[2]); + } + break; + } +} + static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; @@ -569,40 +621,7 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render softwareRenderer->start = softwareRenderer->end; softwareRenderer->end = softwareRenderer->windows[w].endX; softwareRenderer->currentWindow = softwareRenderer->windows[w].control; - switch (GBARegisterDISPCNTGetMode(softwareRenderer->dispcnt)) { - case 0: - if (softwareRenderer->bg[0].enabled == ENABLED_MAX) { - _updateFlags(softwareRenderer, &softwareRenderer->bg[0]); - } - if (softwareRenderer->bg[1].enabled == ENABLED_MAX) { - _updateFlags(softwareRenderer, &softwareRenderer->bg[1]); - } - // Fall through - case 2: - if (softwareRenderer->bg[3].enabled == ENABLED_MAX) { - _updateFlags(softwareRenderer, &softwareRenderer->bg[3]); - } - // Fall through - case 3: - case 4: - case 5: - if (softwareRenderer->bg[2].enabled == ENABLED_MAX) { - _updateFlags(softwareRenderer, &softwareRenderer->bg[2]); - } - break; - case 1: - if (softwareRenderer->bg[0].enabled == ENABLED_MAX) { - _updateFlags(softwareRenderer, &softwareRenderer->bg[0]); - } - if (softwareRenderer->bg[1].enabled == ENABLED_MAX) { - _updateFlags(softwareRenderer, &softwareRenderer->bg[1]); - } - if (softwareRenderer->bg[2].enabled == ENABLED_MAX) { - _updateFlags(softwareRenderer, &softwareRenderer->bg[2]); - } - break; - } - + GBAVideoSoftwareRendererPrepareWindow(softwareRenderer); for (priority = 0; priority < 4; ++priority) { if (spriteLayers & (1 << priority)) { GBAVideoSoftwareRendererPostprocessSprite(softwareRenderer, priority); From c2e2b6d93ccc510c7dfd9699ddd81bc0ab606b33 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 18 Jan 2024 02:58:50 -0800 Subject: [PATCH 043/336] Switch: Add bilinear filtering option (closes #3111) --- CHANGES | 1 + src/platform/switch/main.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index da14c8b59..0f4783510 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Misc: - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Scripting: Add `callbacks:oneshot` for single-call callbacks + - Switch: Add bilinear filtering option (closes mgba.io/i/3111) 0.10.3: (2024-01-07) Emulation fixes: diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 3e891ab3d..36f2627ad 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -125,6 +125,12 @@ static enum ScreenMode { SM_MAX } screenMode = SM_PA; +static enum FilterMode { + FM_NEAREST, + FM_LINEAR, + FM_MAX +} filterMode = FM_NEAREST; + static bool eglInit() { s_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!s_display) { @@ -314,6 +320,9 @@ static void _setup(struct mGUIRunner* runner) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; } + if (mCoreConfigGetUIntValue(&runner->config, "filterMode", &mode) && mode < FM_MAX) { + filterMode = mode; + } runner->core->setAudioBufferSize(runner->core, SAMPLES); } @@ -331,6 +340,9 @@ static void _gameLoaded(struct mGUIRunner* runner) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; } + if (mCoreConfigGetUIntValue(&runner->config, "filterMode", &mode) && mode < FM_MAX) { + filterMode = mode; + } int fakeBool; if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { @@ -381,6 +393,8 @@ static void _gameUnloaded(struct mGUIRunner* runner) { static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded, bool blendTop) { glViewport(0, 1080 - vheight, vwidth, vheight); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode == FM_LINEAR ? GL_LINEAR : GL_NEAREST); + glUseProgram(program); glBindVertexArray(vao); float inwidth = width; @@ -711,21 +725,18 @@ static void glInit(void) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenTextures(1, &oldTex); glBindTexture(GL_TEXTURE_2D, oldTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenTextures(1, &screenshotTex); glBindTexture(GL_TEXTURE_2D, screenshotTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); @@ -981,11 +992,22 @@ int main(int argc, char* argv[]) { }, .nStates = 16 }, + { + .title = "Filtering", + .data = GUI_V_S("filterMode"), + .submenu = 0, + .state = FM_NEAREST, + .validStates = (const char*[]) { + "None", + "Bilinear", + }, + .nStates = 2 + }, { .title = "GPU-accelerated renderer", .data = GUI_V_S("hwaccelVideo"), .submenu = 0, - .state = 0, + .state = FM_NEAREST, .validStates = (const char*[]) { "Off", "On", From 7157729ac39f5757352ce6d9b03b3371a0242a1a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 18 Jan 2024 18:10:32 -0800 Subject: [PATCH 044/336] Swtich: Fix config item count --- src/platform/switch/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 36f2627ad..ef3e12164 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -1049,7 +1049,7 @@ int main(int argc, char* argv[]) { .nStates = 2 }, }, - .nConfigExtra = 5, + .nConfigExtra = 6, .setup = _setup, .teardown = NULL, .gameLoaded = _gameLoaded, From 12ed251c0ba45c7a1ec2f58c35a2d36b3bf3ea3c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Jan 2024 02:17:25 -0800 Subject: [PATCH 045/336] GB: Fix uninitialized save data when loading undersized temporary saves --- CHANGES | 1 + src/gb/gb.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 0f4783510..38c28727d 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Emulation fixes: Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger + - GB: Fix uninitialized save data when loading undersized temporary saves - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/gb/gb.c b/src/gb/gb.c index bb9fafa5d..958312524 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -260,9 +260,13 @@ void GBResizeSram(struct GB* gb, size_t size) { } struct VFile* vf = gb->sramVf; if (vf) { + // We have a vf + ssize_t vfSize = vf->size(vf); if (vf == gb->sramRealVf) { - ssize_t vfSize = vf->size(vf); + // This is the real save file, not a masked one if (vfSize >= 0 && (size_t) vfSize < size) { + // We need to grow the file + // Make sure to copy the footer data, if any uint8_t extdataBuffer[0x100]; if (vfSize & 0xFF) { vf->seek(vf, -(vfSize & 0xFF), SEEK_END); @@ -270,6 +274,7 @@ void GBResizeSram(struct GB* gb, size_t size) { } if (gb->memory.sram) { vf->unmap(vf, gb->memory.sram, gb->sramSize); + gb->memory.sram = NULL; } vf->truncate(vf, size + (vfSize & 0xFF)); if (vfSize & 0xFF) { @@ -281,24 +286,36 @@ void GBResizeSram(struct GB* gb, size_t size) { memset(&gb->memory.sram[vfSize], 0xFF, size - vfSize); } } else if (size > gb->sramSize || !gb->memory.sram) { + // We aren't growing the file, but we are changing our mapping of it if (gb->memory.sram) { vf->unmap(vf, gb->memory.sram, gb->sramSize); + gb->memory.sram = NULL; } if (size) { gb->memory.sram = vf->map(vf, size, MAP_WRITE); } } } else { + // This is a masked save file if (gb->memory.sram) { vf->unmap(vf, gb->memory.sram, gb->sramSize); } - if (vf->size(vf) < gb->sramSize) { - void* sram = vf->map(vf, vf->size(vf), MAP_READ); - struct VFile* newVf = VFileMemChunk(sram, vf->size(vf)); - vf->unmap(vf, sram,vf->size(vf)); - vf = newVf; - gb->sramVf = newVf; - vf->truncate(vf, size); + if ((vfSize <= 0 && size) || (size_t) vfSize < size) { + // The loaded mask file is too small. Since these can be read-only, + // we need to make a new one of the right size + if (vfSize < 0) { + vfSize = 0; + } + gb->sramVf = VFileMemChunk(NULL, size); + uint8_t* sram = gb->sramVf->map(gb->sramVf, size, MAP_WRITE); + if (vfSize > 0) { + vf->seek(vf, 0, SEEK_SET); + vf->read(vf, sram, vfSize); + } + memset(&sram[vfSize], 0xFF, size - vfSize); + gb->sramVf->unmap(gb->sramVf, sram, size); + vf->close(vf); + vf = gb->sramVf; } if (size) { gb->memory.sram = vf->map(vf, size, MAP_READ); @@ -308,6 +325,8 @@ void GBResizeSram(struct GB* gb, size_t size) { gb->memory.sram = NULL; } } else if (size) { + // There's no vf, so let's make it only memory-backed + // TODO: Investigate just using a VFileMemChunk instead of this hybrid approach uint8_t* newSram = anonymousMemoryMap(size); if (gb->memory.sram) { if (size > gb->sramSize) { From 6e773eafeae96c8904cf6e6de0b3f8a3b33f4235 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Jan 2024 02:21:41 -0800 Subject: [PATCH 046/336] VFS: Modernize VDeviceList implementation --- src/util/vfs/vfs-devlist.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/util/vfs/vfs-devlist.c b/src/util/vfs/vfs-devlist.c index 667ffd193..8f61d49c8 100644 --- a/src/util/vfs/vfs-devlist.c +++ b/src/util/vfs/vfs-devlist.c @@ -20,7 +20,7 @@ static enum VFSType _vdleType(struct VDirEntry* vde); struct VDirEntryDevList { struct VDirEntry d; size_t index; - char* name; + char name[PATH_MAX + 1]; }; struct VDirDevList { @@ -31,7 +31,7 @@ struct VDirDevList { struct VDir* VDeviceList() { struct VDirDevList* vd = malloc(sizeof(struct VDirDevList)); if (!vd) { - return 0; + return NULL; } vd->d.close = _vdlClose; @@ -44,50 +44,42 @@ struct VDir* VDeviceList() { vd->vde.d.name = _vdleName; vd->vde.d.type = _vdleType; vd->vde.index = 0; - vd->vde.name = 0; + vd->vde.name[0] = '\0'; return &vd->d; } static bool _vdlClose(struct VDir* vd) { struct VDirDevList* vdl = (struct VDirDevList*) vd; - free(vdl->vde.name); free(vdl); return true; } static void _vdlRewind(struct VDir* vd) { struct VDirDevList* vdl = (struct VDirDevList*) vd; - free(vdl->vde.name); - vdl->vde.name = 0; - vdl->vde.index = 3; + vdl->vde.name[0] = '\0'; + vdl->vde.index = 0; } static struct VDirEntry* _vdlListNext(struct VDir* vd) { struct VDirDevList* vdl = (struct VDirDevList*) vd; - if (vdl->vde.name) { - ++vdl->vde.index; - free(vdl->vde.name); - vdl->vde.name = 0; - } while (vdl->vde.index < STD_MAX) { const devoptab_t *devops = devoptab_list[vdl->vde.index]; - if (devops->dirStateSize > 0) { - vdl->vde.name = malloc(strlen(devops->name) + 3); - sprintf(vdl->vde.name, "%s:", devops->name); - return &vdl->vde.d; - } - ++vdl->vde.index; + if (!devops || !devops->name || devops->dirStateSize <= 0) { + continue; + } + snprintf(vdl->vde.name, sizeof(vdl->vde.name), "%s:", devops->name); + return &vdl->vde.d; } - return 0; + return NULL; } static struct VFile* _vdlOpenFile(struct VDir* vd, const char* path, int mode) { UNUSED(vd); UNUSED(path); UNUSED(mode); - return 0; + return NULL; } static struct VDir* _vdlOpenDir(struct VDir* vd, const char* path) { From 4e87dc61ee7065778312bd14560aad5c27cfe45d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Jan 2024 02:45:07 -0800 Subject: [PATCH 047/336] Vita: Add imc0 and xmc0 mount point support --- CHANGES | 1 + src/platform/psp2/sce-vfs.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 38c28727d..be9dd6692 100644 --- a/CHANGES +++ b/CHANGES @@ -29,6 +29,7 @@ Misc: - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Scripting: Add `callbacks:oneshot` for single-call callbacks - Switch: Add bilinear filtering option (closes mgba.io/i/3111) + - Vita: Add imc0 and xmc0 mount point support 0.10.3: (2024-01-07) Emulation fixes: diff --git a/src/platform/psp2/sce-vfs.c b/src/platform/psp2/sce-vfs.c index 621fd1f67..4e0fc5c02 100644 --- a/src/platform/psp2/sce-vfs.c +++ b/src/platform/psp2/sce-vfs.c @@ -284,7 +284,10 @@ struct VDirSceDevList { static const char* _devs[] = { "ux0:", "ur0:", - "uma0:" + "uma0:", + "imc0:", + "xmc0:", + NULL }; struct VDir* VDeviceList() { @@ -322,7 +325,7 @@ static void _vdlsceRewind(struct VDir* vd) { static struct VDirEntry* _vdlsceListNext(struct VDir* vd) { struct VDirSceDevList* vdl = (struct VDirSceDevList*) vd; - while (vdl->vde.index < 3) { + while (vdl->vde.index < 0 || _devs[vdl->vde.index]) { ++vdl->vde.index; vdl->vde.name = _devs[vdl->vde.index]; SceUID dir = sceIoDopen(vdl->vde.name); From 5479ab13075c6f2a4cb1fcbeb837e3fabb6097ae Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Jan 2024 02:45:54 -0800 Subject: [PATCH 048/336] Vita: Use sceIoPwrite in VFileSce.sync --- src/platform/psp2/sce-vfs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/platform/psp2/sce-vfs.c b/src/platform/psp2/sce-vfs.c index 4e0fc5c02..a98e9943d 100644 --- a/src/platform/psp2/sce-vfs.c +++ b/src/platform/psp2/sce-vfs.c @@ -153,11 +153,10 @@ ssize_t _vfsceSize(struct VFile* vf) { bool _vfsceSync(struct VFile* vf, void* buffer, size_t size) { struct VFileSce* vfsce = (struct VFileSce*) vf; if (buffer && size) { - SceOff cur = sceIoLseek(vfsce->fd, 0, SEEK_CUR); - sceIoLseek(vfsce->fd, 0, SEEK_SET); - int res = sceIoWrite(vfsce->fd, buffer, size); - sceIoLseek(vfsce->fd, cur, SEEK_SET); - return res == size; + int res = sceIoPwrite(vfsce->fd, buffer, size, 0); + if (res < 0 || (size_t) res != size) { + return false; + } } return sceIoSyncByFd(vfsce->fd, 0) >= 0; } From 845d69e81733bbbbf15b2111074f1dde6d5b87f1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Jan 2024 17:28:16 -0800 Subject: [PATCH 049/336] Qt: Fix input event threading regression (fixes #3116) --- src/platform/qt/InputController.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 212c55c09..337e7df6b 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -350,6 +350,7 @@ int InputController::pollEvents() { activeButtons |= im.mapAxes(pad->currentAxes()); activeButtons |= im.mapHats(pad->currentHats()); } + QReadLocker l(&m_eventsLock); for (int i = 0; i < GBA_KEY_MAX; ++i) { if ((activeButtons & (1 << i)) && hasPendingEvent(i)) { activeButtons ^= 1 << i; From 11e16d1ad9fe8b7140312475afee60d4c7aa9742 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Jan 2024 17:42:55 -0800 Subject: [PATCH 050/336] GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes #3110) --- CHANGES | 1 + src/gba/sio/lockstep.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index be9dd6692..ec1979f92 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Emulation fixes: - GBA: Unhandled bkpt should be treated as an undefined exception - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) + - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 4b7ff858d..71373a237 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -213,8 +213,6 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver mTimingDeschedule(&driver->p->p->timing, &node->event); } mTimingSchedule(&driver->p->p->timing, &node->event, 0); - } else { - value &= ~0x0080; } } value &= 0xFF83; From e1ebaed508e453ab42634affd7bf618ece4c7b1b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Jan 2024 00:28:30 -0800 Subject: [PATCH 051/336] OpenGL: Mark interframe shader as dirty too (fixes #3099) --- src/platform/opengl/gles2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 469047b19..51180813e 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -293,6 +293,7 @@ static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h) } } context->finalShader.dirty = true; + context->interframeShader.dirty = true; glBindTexture(GL_TEXTURE_2D, context->finalShader.tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, drawW, drawH, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glBindFramebuffer(GL_FRAMEBUFFER, context->finalShader.fbo); From e5b14977ce815f815c719ebb952377aa8ddd289e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Jan 2024 00:31:27 -0800 Subject: [PATCH 052/336] Qt: Remember to set m_dims for the early return --- src/platform/qt/DisplayGL.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index eaae3f63c..a1e806ef4 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -647,6 +647,7 @@ void PainterGL::resizeContext() { mRectangle dims = {0, 0, size.width(), size.height()}; m_backend->setLayerDimensions(m_backend, VIDEO_LAYER_IMAGE, &dims); recenterLayers(); + m_dims = size; } void PainterGL::setMessagePainter(MessagePainter* messagePainter) { From 6243a578329779df44ce1b7577b6b8392733b84b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Jan 2024 20:34:06 -0500 Subject: [PATCH 053/336] GBA Debugger defaults to loopback address --- src/debugger/debugger.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/debugger/debugger.c b/src/debugger/debugger.c index f1d876005..7de4772d7 100644 --- a/src/debugger/debugger.c +++ b/src/debugger/debugger.c @@ -54,7 +54,11 @@ struct mDebuggerModule* mDebuggerCreateModule(enum mDebuggerType type, struct mC case DEBUGGER_GDB: #ifdef USE_GDB_STUB GDBStubCreate(&debugger->gdb); - GDBStubListen(&debugger->gdb, 2345, 0, GDB_WATCHPOINT_STANDARD_LOGIC); + struct Address localHost = { + .version = IPV4, + .ipv4 = 0x7F000001 + }; + GDBStubListen(&debugger->gdb, 2345, &localHost, GDB_WATCHPOINT_STANDARD_LOGIC); break; #endif case DEBUGGER_NONE: From 3e86758a9fb24e46a1b8b29d608e43a55e074622 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Jan 2024 20:34:31 -0500 Subject: [PATCH 054/336] Qt GDB Window defaults to loopback address --- src/platform/qt/GDBWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/GDBWindow.cpp b/src/platform/qt/GDBWindow.cpp index 3f1f86efb..8c4738387 100644 --- a/src/platform/qt/GDBWindow.cpp +++ b/src/platform/qt/GDBWindow.cpp @@ -44,7 +44,7 @@ GDBWindow::GDBWindow(GDBController* controller, QWidget* parent) connect(m_portEdit, &QLineEdit::textChanged, this, &GDBWindow::portChanged); settingsGrid->addWidget(m_portEdit, 0, 1, Qt::AlignLeft); - m_bindAddressEdit = new QLineEdit("0.0.0.0"); + m_bindAddressEdit = new QLineEdit("127.0.0.1"); m_bindAddressEdit->setMaxLength(15); connect(m_bindAddressEdit, &QLineEdit::textChanged, this, &GDBWindow::bindAddressChanged); settingsGrid->addWidget(m_bindAddressEdit, 1, 1, Qt::AlignLeft); From 398df56ac96d0eb42c0f592f9baa4a8fc0fbfa67 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Sun, 21 Jan 2024 15:09:30 -0800 Subject: [PATCH 055/336] core: Add support for specifying an arbitrary portable directory. --- include/mgba/core/config.h | 3 +- src/core/config.c | 90 +++++++++++++++++++--------- src/platform/qt/ConfigController.cpp | 2 +- 3 files changed, 65 insertions(+), 30 deletions(-) diff --git a/include/mgba/core/config.h b/include/mgba/core/config.h index ef7437487..2082c11db 100644 --- a/include/mgba/core/config.h +++ b/include/mgba/core/config.h @@ -72,8 +72,9 @@ bool mCoreConfigSavePath(const struct mCoreConfig*, const char* path); bool mCoreConfigLoadVFile(struct mCoreConfig*, struct VFile* vf); bool mCoreConfigSaveVFile(const struct mCoreConfig*, struct VFile* vf); -void mCoreConfigMakePortable(const struct mCoreConfig*); +void mCoreConfigMakePortable(const struct mCoreConfig*, const char* path); void mCoreConfigDirectory(char* out, size_t outLength); +void mCoreConfigPortableIniPath(char* out, size_t outLength); void mCoreConfigPortablePath(char* out, size_t outLength); bool mCoreConfigIsPortable(void); #endif diff --git a/src/core/config.c b/src/core/config.c index d0cd4603c..4d4733cd9 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -198,38 +198,46 @@ bool mCoreConfigSaveVFile(const struct mCoreConfig* config, struct VFile* vf) { return ConfigurationWriteVFile(&config->configTable, vf); } -void mCoreConfigMakePortable(const struct mCoreConfig* config) { +void mCoreConfigMakePortable(const struct mCoreConfig* config, const char* path) { struct VFile* portable = NULL; + struct Configuration portableConfig; char out[PATH_MAX]; - mCoreConfigPortablePath(out, sizeof(out)); + mCoreConfigPortableIniPath(out, sizeof(out)); if (!out[0]) { // Cannot be made portable return; } - portable = VFileOpen(out, O_WRONLY | O_CREAT); + + ConfigurationInit(&portableConfig); + + portable = VFileOpen(out, O_RDONLY); if (portable) { + ConfigurationReadVFile(&portableConfig, portable); portable->close(portable); - mCoreConfigSave(config); } + + if (path && path[0]) { + ConfigurationSetValue(&portableConfig, "portable", "path", path); + } else { + ConfigurationClearValue(&portableConfig, "portable", "path"); + } + + portable = VFileOpen(out, O_WRONLY | O_CREAT | O_TRUNC); + if (portable) { + ConfigurationWriteVFile(&portableConfig, portable); + portable->close(portable); + } + + ConfigurationDeinit(&portableConfig); + mCoreConfigSave(config); } void mCoreConfigDirectory(char* out, size_t outLength) { - struct VFile* portable; char portableDir[PATH_MAX]; mCoreConfigPortablePath(portableDir, sizeof(portableDir)); if (portableDir[0]) { - portable = VFileOpen(portableDir, O_RDONLY); - if (portable) { - portable->close(portable); - if (outLength < PATH_MAX) { - char outTmp[PATH_MAX]; - separatePath(portableDir, outTmp, NULL, NULL); - strlcpy(out, outTmp, outLength); - } else { - separatePath(portableDir, out, NULL, NULL); - } - return; - } + strlcpy(out, portableDir, outLength); + return; } #ifdef _WIN32 WCHAR wpath[MAX_PATH]; @@ -276,7 +284,7 @@ void mCoreConfigDirectory(char* out, size_t outLength) { #endif } -void mCoreConfigPortablePath(char* out, size_t outLength) { +void mCoreConfigPortableIniPath(char* out, size_t outLength) { #ifdef _WIN32 wchar_t wpath[MAX_PATH]; GetModuleFileNameW(NULL, wpath, MAX_PATH); @@ -308,18 +316,44 @@ void mCoreConfigPortablePath(char* out, size_t outLength) { #endif } -bool mCoreConfigIsPortable(void) { - struct VFile* portable; - char portableDir[PATH_MAX]; - mCoreConfigPortablePath(portableDir, sizeof(portableDir)); - if (portableDir[0]) { - portable = VFileOpen(portableDir, O_RDONLY); - if (portable) { - portable->close(portable); - return true; +void mCoreConfigPortablePath(char* out, size_t outLength) { + struct VFile* portableIni; + char portableIniPath[PATH_MAX]; + mCoreConfigPortableIniPath(portableIniPath, sizeof(portableIniPath)); + out[0] = '\0'; + if (portableIniPath[0]) { + portableIni = VFileOpen(portableIniPath, O_RDONLY); + if (portableIni) { + // Start with the path that the portable.ini file exists in. + char iniDir[PATH_MAX]; + separatePath(portableIniPath, iniDir, NULL, NULL); + strlcpy(out, iniDir, outLength); + + struct Configuration portableConfig; + ConfigurationInit(&portableConfig); + if (ConfigurationReadVFile(&portableConfig, portableIni)) { + const char* path = ConfigurationGetValue(&portableConfig, "portable", "path"); + if (path) { + if (path[0] == '/') { + // User specified an absolute path. + strlcpy(out, path, outLength); + } else { + // User specified a relative path, append to the portable.ini path. + snprintf(out, outLength, "%s" PATH_SEP "%s", iniDir, path); + } + } + } + ConfigurationDeinit(&portableConfig); + + portableIni->close(portableIni); } } - return false; +} + +bool mCoreConfigIsPortable(void) { + char portableDir[PATH_MAX]; + mCoreConfigPortablePath(portableDir, sizeof(portableDir)); + return portableDir[0]; } #endif diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 8922830fc..086fcdc8a 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -366,7 +366,7 @@ void ConfigController::write() { } void ConfigController::makePortable() { - mCoreConfigMakePortable(&m_config); + mCoreConfigMakePortable(&m_config, nullptr); QString fileName(configDir()); fileName.append(QDir::separator()); From 05bf592dec254abdff48e9cc02426efdab77cf5b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 29 Jan 2024 01:39:59 -0800 Subject: [PATCH 056/336] SDL: Refactor out layer recentering, fix for GB --- include/mgba/feature/video-backend.h | 1 + src/feature/video-backend.c | 20 ++++++++++++++++++++ src/platform/qt/DisplayGL.cpp | 17 +---------------- src/platform/sdl/gl-common.c | 17 +++++------------ 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/include/mgba/feature/video-backend.h b/include/mgba/feature/video-backend.h index 292dc9c82..adf6f8395 100644 --- a/include/mgba/feature/video-backend.h +++ b/include/mgba/feature/video-backend.h @@ -74,6 +74,7 @@ struct VideoShader { void VideoBackendGetFrame(const struct VideoBackend*, struct mRectangle* frame); void VideoBackendGetFrameSize(const struct VideoBackend*, unsigned* width, unsigned* height); +void VideoBackendRecenter(struct VideoBackend* v, unsigned scale); CXX_GUARD_END diff --git a/src/feature/video-backend.c b/src/feature/video-backend.c index ae2f0257d..ba13bbe7d 100644 --- a/src/feature/video-backend.c +++ b/src/feature/video-backend.c @@ -23,3 +23,23 @@ void VideoBackendGetFrameSize(const struct VideoBackend* v, unsigned* width, uns *width = frame.width; *height = frame.height; } + +void VideoBackendRecenter(struct VideoBackend* v, unsigned scale) { + static const int centeredLayers[] = {VIDEO_LAYER_BACKGROUND, -1}; + struct mRectangle frame = {0}; + v->imageSize(v, VIDEO_LAYER_IMAGE, &frame.width, &frame.height); + if (scale == 0) { + scale = 1; + } + + size_t i; + for (i = 0; centeredLayers[i] >= 0; ++i) { + int width, height; + struct mRectangle dims = {0}; + v->imageSize(v, centeredLayers[i], &width, &height); + dims.width = width * scale; + dims.height = height * scale; + mRectangleCenter(&frame, &dims); + v->setLayerDimensions(v, centeredLayers[i], &dims); + } +} diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index a1e806ef4..d2de7b9f4 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -658,22 +658,7 @@ void PainterGL::recenterLayers() { if (!m_context) { return; } - const static std::initializer_list centeredLayers{VIDEO_LAYER_BACKGROUND}; - int width, height; - mRectangle frame = {0}; - m_backend->imageSize(m_backend, VIDEO_LAYER_IMAGE, &width, &height); - frame.width = width; - frame.height = height; - unsigned scale = std::max(1U, m_context->videoScale()); - - for (VideoLayer l : centeredLayers) { - mRectangle dims{}; - m_backend->imageSize(m_backend, l, &width, &height); - dims.width = width * scale; - dims.height = height * scale; - mRectangleCenter(&frame, &dims); - m_backend->setLayerDimensions(m_backend, l, &dims); - } + VideoBackendRecenter(m_backend, std::max(1U, m_context->videoScale())); } void PainterGL::resize(const QSize& size) { diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index 4bd8643b7..1ce9100e8 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -135,19 +135,11 @@ void mSDLGLCommonRunloop(struct mSDLRenderer* renderer, void* user) { if (mSDLGLCommonLoadBackground(v)) { renderer->player.windowUpdated = true; - - struct mRectangle frame; - v->layerDimensions(v, VIDEO_LAYER_IMAGE, &frame); - int i; - for (i = 0; i < VIDEO_LAYER_IMAGE; ++i) { - struct mRectangle dims; - v->layerDimensions(v, i, &dims); - mRectangleCenter(&frame, &dims); - v->setLayerDimensions(v, i, &dims); - } - + VideoBackendRecenter(v, 1); #if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_SetWindowSize(renderer->window, frame.width * renderer->ratio, frame.height * renderer->ratio); + int width, height; + v->imageSize(v, VIDEO_LAYER_IMAGE, &width, &height); + SDL_SetWindowSize(renderer->window, width * renderer->ratio, height * renderer->ratio); #endif } @@ -175,6 +167,7 @@ void mSDLGLCommonRunloop(struct mSDLRenderer* renderer, void* user) { dims.width = renderer->width; dims.height = renderer->height; v->setLayerDimensions(v, VIDEO_LAYER_IMAGE, &dims); + VideoBackendRecenter(v, 1); } if (mCoreSyncWaitFrameStart(&context->impl->sync)) { From 1fc37e9962f451bbd1e7e9d5da2fb437e7ca7be9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 01:31:47 -0800 Subject: [PATCH 057/336] Core: Migrate thread context TLS to its own key --- include/mgba/core/log.h | 3 +++ include/mgba/core/thread.h | 1 - src/core/log.c | 53 +++++++++++++++++++++++++++++++++++--- src/core/thread.c | 11 ++------ 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/include/mgba/core/log.h b/include/mgba/core/log.h index 9f55ec772..892a8f2f9 100644 --- a/include/mgba/core/log.h +++ b/include/mgba/core/log.h @@ -44,6 +44,9 @@ struct mStandardLogger { struct mLogger* mLogGetContext(void); void mLogSetDefaultLogger(struct mLogger*); +void mLogSetThreadLogger(struct mLogger*); +struct mLogger* mLogGetThreadLogger(void); + int mLogGenerateCategory(const char*, const char*); const char* mLogCategoryName(int); const char* mLogCategoryId(int); diff --git a/include/mgba/core/thread.h b/include/mgba/core/thread.h index fee447ae7..d3d8a9e92 100644 --- a/include/mgba/core/thread.h +++ b/include/mgba/core/thread.h @@ -128,7 +128,6 @@ void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool); void mCoreThreadRewindParamsChanged(struct mCoreThread* threadContext); struct mCoreThread* mCoreThreadGet(void); -struct mLogger* mCoreThreadLogger(void); CXX_GUARD_END diff --git a/src/core/log.c b/src/core/log.c index 5fe2fe9ee..b897fedb4 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #define MAX_CATEGORY 64 @@ -14,11 +14,56 @@ static struct mLogger* _defaultLogger = NULL; -struct mLogger* mLogGetContext(void) { - struct mLogger* logger = NULL; #ifndef DISABLE_THREADING - logger = mCoreThreadLogger(); +static ThreadLocal _contextKey; + +#ifdef USE_PTHREADS +static pthread_once_t _contextOnce = PTHREAD_ONCE_INIT; + +static void _createTLS(void) { + ThreadLocalInitKey(&_contextKey); +} +#elif _WIN32 +static INIT_ONCE _contextOnce = INIT_ONCE_STATIC_INIT; + +static BOOL CALLBACK _createTLS(PINIT_ONCE once, PVOID param, PVOID* context) { + UNUSED(once); + UNUSED(param); + UNUSED(context); + ThreadLocalInitKey(&_contextKey); + return TRUE; +} #endif + +static void _setupTLS(void) { +#ifdef USE_PTHREADS + pthread_once(&_contextOnce, _createTLS); +#elif _WIN32 + InitOnceExecuteOnce(&_contextOnce, _createTLS, NULL, 0); +#endif +} +#endif + +void mLogSetThreadLogger(struct mLogger* logger) { +#ifndef DISABLE_THREADING + _setupTLS(); + ThreadLocalSetKey(_contextKey, logger); +#else + UNUSED(logger); +#endif +} + +struct mLogger* mLogGetThreadLogger(void) { +#ifndef DISABLE_THREADING + _setupTLS(); + return ThreadLocalGetValue(_contextKey); +#else + return NULL; +#endif +} + +struct mLogger* mLogGetContext(void) { + struct mLogger* logger = mLogGetThreadLogger(); if (logger) { return logger; } diff --git a/src/core/thread.c b/src/core/thread.c index 983395c12..903d4b844 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -246,6 +246,8 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { ThreadLocalSetKey(_contextKey, threadContext); ThreadSetName("CPU Thread"); + mLogSetThreadLogger(&threadContext->logger.d); + #if !defined(_WIN32) && defined(USE_PTHREADS) sigset_t signals; sigemptyset(&signals); @@ -762,12 +764,3 @@ struct mCoreThread* mCoreThreadGet(void) { return NULL; } #endif - -struct mLogger* mCoreThreadLogger(void) { - struct mCoreThread* thread = mCoreThreadGet(); - if (thread) { - return &thread->logger.d; - } - return NULL; -} - From 4590dfc68bdee76ff204438a5c667a11096b92a5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 02:26:00 -0800 Subject: [PATCH 058/336] Qt: Switch VideoProxy to using QMutexLocker --- src/platform/qt/VideoProxy.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index 17168da0e..44a59d2ae 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -76,10 +76,9 @@ void VideoProxy::init() { } void VideoProxy::reset() { - m_mutex.lock(); + QMutexLocker locker(&m_mutex); RingFIFOClear(&m_dirtyQueue); m_toThreadCond.wakeAll(); - m_mutex.unlock(); } void VideoProxy::deinit() { @@ -92,10 +91,9 @@ bool VideoProxy::writeData(const void* data, size_t length) { mVideoLoggerRendererRun(&m_logger, false); } else { emit dataAvailable(); - m_mutex.lock(); + QMutexLocker locker(&m_mutex); m_toThreadCond.wakeAll(); m_fromThreadCond.wait(&m_mutex); - m_mutex.unlock(); } } return true; @@ -108,10 +106,9 @@ bool VideoProxy::readData(void* data, size_t length, bool block) { if (!block || read) { break; } - m_mutex.lock(); + QMutexLocker locker(&m_mutex); m_fromThreadCond.wakeAll(); m_toThreadCond.wait(&m_mutex); - m_mutex.unlock(); } return read; } @@ -126,9 +123,8 @@ void VideoProxy::postEvent(enum mVideoLoggerEvent event) { } void VideoProxy::handleEvent(int event) { - m_mutex.lock(); + QMutexLocker locker(&m_mutex); m_logger.handleEvent(&m_logger, static_cast(event)); - m_mutex.unlock(); } void VideoProxy::lock() { @@ -140,7 +136,7 @@ void VideoProxy::unlock() { } void VideoProxy::wait() { - m_mutex.lock(); + QMutexLocker locker(&m_mutex); while (RingFIFOSize(&m_dirtyQueue)) { if (QThread::currentThread() == thread()) { // We're on the main thread @@ -151,7 +147,6 @@ void VideoProxy::wait() { m_fromThreadCond.wait(&m_mutex, 1); } } - m_mutex.unlock(); } void VideoProxy::wake(int y) { From 7727b6434d18d8f1a5a935e71224c9c1b7e86e09 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 02:28:34 -0800 Subject: [PATCH 059/336] Qt: Pass logging context through to video proxy thread (fixes #3095) --- CHANGES | 1 + src/platform/qt/VideoProxy.cpp | 7 +++++++ src/platform/qt/VideoProxy.h | 2 ++ 3 files changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index ec1979f92..d43f3ad1a 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Misc: - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) + - Qt: Pass logging context through to video proxy thread (fixes mgba.io/i/3095) - Scripting: Add `callbacks:oneshot` for single-call callbacks - Switch: Add bilinear filtering option (closes mgba.io/i/3111) - Vita: Add imc0 and xmc0 mount point support diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index 44a59d2ae..2b24e7121 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -48,12 +48,14 @@ VideoProxy::~VideoProxy() { void VideoProxy::attach(CoreController* controller) { CoreController::Interrupter interrupter(controller); + m_logContext = &controller->thread()->logger.d; controller->thread()->core->videoLogger = &m_logger; } void VideoProxy::detach(CoreController* controller) { CoreController::Interrupter interrupter(controller); if (controller->thread()->core->videoLogger == &m_logger) { + m_logContext = nullptr; controller->thread()->core->videoLogger = nullptr; } } @@ -64,11 +66,13 @@ void VideoProxy::setProxiedBackend(VideoBackend* backend) { } void VideoProxy::processData() { + mLogSetThreadLogger(m_logContext); mVideoLoggerRendererRun(&m_logger, false); m_fromThreadCond.wakeAll(); } void VideoProxy::processCommands() { + mLogSetThreadLogger(m_logContext); mVideoProxyBackendRun(&m_backend, false); } @@ -88,6 +92,7 @@ bool VideoProxy::writeData(const void* data, size_t length) { while (!RingFIFOWrite(&m_dirtyQueue, data, length)) { if (QThread::currentThread() == thread()) { // We're on the main thread + mLogSetThreadLogger(m_logContext); mVideoLoggerRendererRun(&m_logger, false); } else { emit dataAvailable(); @@ -124,6 +129,7 @@ void VideoProxy::postEvent(enum mVideoLoggerEvent event) { void VideoProxy::handleEvent(int event) { QMutexLocker locker(&m_mutex); + mLogSetThreadLogger(m_logContext); m_logger.handleEvent(&m_logger, static_cast(event)); } @@ -140,6 +146,7 @@ void VideoProxy::wait() { while (RingFIFOSize(&m_dirtyQueue)) { if (QThread::currentThread() == thread()) { // We're on the main thread + mLogSetThreadLogger(m_logContext); mVideoLoggerRendererRun(&m_logger, false); } else { emit dataAvailable(); diff --git a/src/platform/qt/VideoProxy.h b/src/platform/qt/VideoProxy.h index 43bb280c3..8cb1020cd 100644 --- a/src/platform/qt/VideoProxy.h +++ b/src/platform/qt/VideoProxy.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -72,6 +73,7 @@ private: } m_logger; struct mVideoProxyBackend m_backend; + struct mLogger* m_logContext = nullptr; RingFIFO m_dirtyQueue; QMutex m_mutex; From 7b0e400710c3e451f9c3f712652780406e602fb2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 02:36:32 -0800 Subject: [PATCH 060/336] Util: Fix leak in SfoWrite --- src/util/sfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/sfo.c b/src/util/sfo.c index 21ffd0f0f..339da1d8e 100644 --- a/src/util/sfo.c +++ b/src/util/sfo.c @@ -162,6 +162,7 @@ bool SfoWrite(struct Table* sfo, struct VFile* vf) { sortedEntries[i].size = 4; break; default: + free(sortedEntries); return false; } } From c0a323dbcd2d5b9468c723793320ef6add9b8db8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 02:37:48 -0800 Subject: [PATCH 061/336] VFS: Fix UB --- src/util/vfs/vfs-lzma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/vfs/vfs-lzma.c b/src/util/vfs/vfs-lzma.c index 0ded446bd..c9f88411d 100644 --- a/src/util/vfs/vfs-lzma.c +++ b/src/util/vfs/vfs-lzma.c @@ -94,12 +94,12 @@ static void _vd7zFree(ISzAllocPtr p, void* address) { struct VDir7zAlloc* alloc = (struct VDir7zAlloc*) p; size_t size = (size_t) TableLookup(&alloc->allocs, (uintptr_t) address >> 2); if (size) { + TableRemove(&alloc->allocs, (uintptr_t) address >> 2); if (size >= 0x10000) { mappedMemoryFree(address, size); } else { free(address); } - TableRemove(&alloc->allocs, (uintptr_t) address >> 2); } } From 3133105fc943439445e4950a5f2c26171da85a48 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 02:51:32 -0800 Subject: [PATCH 062/336] Qt: Pay down a bit of MemoryAccessLogView tech debt --- src/platform/qt/MemoryAccessLogView.cpp | 3 ++- src/platform/qt/MemoryAccessLogView.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/MemoryAccessLogView.cpp b/src/platform/qt/MemoryAccessLogView.cpp index 0c9325ed3..5998dd517 100644 --- a/src/platform/qt/MemoryAccessLogView.cpp +++ b/src/platform/qt/MemoryAccessLogView.cpp @@ -8,6 +8,7 @@ #include #include "GBAApp.h" +#include "LogController.h" #include "utils.h" #include "VFileDevice.h" @@ -78,7 +79,7 @@ void MemoryAccessLogView::start() { m_controller->attachDebuggerModule(&m_logger.d); if (!mDebuggerAccessLoggerOpen(&m_logger, vf, flags)) { mDebuggerAccessLoggerDeinit(&m_logger); - // log error + LOG(QT, ERROR) << tr("Failed to open memory log file"); return; } diff --git a/src/platform/qt/MemoryAccessLogView.h b/src/platform/qt/MemoryAccessLogView.h index 896ba5a07..ffe31cc43 100644 --- a/src/platform/qt/MemoryAccessLogView.h +++ b/src/platform/qt/MemoryAccessLogView.h @@ -44,7 +44,7 @@ private: QSet m_watchedRegions; QHash m_regionBoxes; QHash m_regionMapping; - struct mDebuggerAccessLogger m_logger; + struct mDebuggerAccessLogger m_logger{}; bool m_active = false; mDebuggerAccessLogRegionFlags activeFlags() const; From 0815443aeb292cd23ddd296860c92060783a1ced Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 02:59:25 -0800 Subject: [PATCH 063/336] Qt: Use && in some places that coverity recommends --- src/platform/qt/Action.cpp | 4 ++-- src/platform/qt/Action.h | 4 ++-- src/platform/qt/ActionMapper.cpp | 16 ++++++++-------- src/platform/qt/ActionMapper.h | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/platform/qt/Action.cpp b/src/platform/qt/Action.cpp index e5d6600d4..133a4c512 100644 --- a/src/platform/qt/Action.cpp +++ b/src/platform/qt/Action.cpp @@ -12,7 +12,7 @@ Action::Action(QObject* parent) { } -Action::Action(Function function, const QString& name, const QString& visibleName, QObject* parent) +Action::Action(Function&& function, const QString& name, const QString& visibleName, QObject* parent) : QObject(parent) , m_function(function) , m_name(name) @@ -20,7 +20,7 @@ Action::Action(Function function, const QString& name, const QString& visibleNam { } -Action::Action(Action::BooleanFunction function, const QString& name, const QString& visibleName, QObject* parent) +Action::Action(Action::BooleanFunction&& function, const QString& name, const QString& visibleName, QObject* parent) : QObject(parent) , m_booleanFunction(function) , m_name(name) diff --git a/src/platform/qt/Action.h b/src/platform/qt/Action.h index 9fe2f6aa2..3546f6767 100644 --- a/src/platform/qt/Action.h +++ b/src/platform/qt/Action.h @@ -24,8 +24,8 @@ public: QUIT, }; - Action(Function, const QString& name, const QString& visibleName, QObject* parent = nullptr); - Action(BooleanFunction, const QString& name, const QString& visibleName, QObject* parent = nullptr); + Action(Function&&, const QString& name, const QString& visibleName, QObject* parent = nullptr); + Action(BooleanFunction&&, const QString& name, const QString& visibleName, QObject* parent = nullptr); Action(const QString& name, const QString& visibleName, QObject* parent = nullptr); Action(QObject* parent = nullptr); diff --git a/src/platform/qt/ActionMapper.cpp b/src/platform/qt/ActionMapper.cpp index 890ea8893..7bf7b73cb 100644 --- a/src/platform/qt/ActionMapper.cpp +++ b/src/platform/qt/ActionMapper.cpp @@ -141,8 +141,8 @@ std::shared_ptr ActionMapper::addAction(const Action& act, const QString return getAction(name); } -std::shared_ptr ActionMapper::addAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu, const QKeySequence& shortcut) { - return addAction(Action(action, name, visibleName), name, menu, shortcut); +std::shared_ptr ActionMapper::addAction(const QString& visibleName, const QString& name, Action::Function&& action, const QString& menu, const QKeySequence& shortcut) { + return addAction(Action(std::move(action), name, visibleName), name, menu, shortcut); } std::shared_ptr ActionMapper::addAction(const QString& visibleName, ConfigOption* option, const QVariant& variant, const QString& menu) { @@ -151,8 +151,8 @@ std::shared_ptr ActionMapper::addAction(const QString& visibleName, Conf }, option->name(), visibleName), QString("%1.%2").arg(option->name()).arg(variant.toString()), menu, {}); } -std::shared_ptr ActionMapper::addBooleanAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu, const QKeySequence& shortcut) { - return addAction(Action(action, name, visibleName), name, menu, shortcut); +std::shared_ptr ActionMapper::addBooleanAction(const QString& visibleName, const QString& name, Action::BooleanFunction&& action, const QString& menu, const QKeySequence& shortcut) { + return addAction(Action(std::move(action), name, visibleName), name, menu, shortcut); } std::shared_ptr ActionMapper::addBooleanAction(const QString& visibleName, ConfigOption* option, const QString& menu) { @@ -161,15 +161,15 @@ std::shared_ptr ActionMapper::addBooleanAction(const QString& visibleNam }, option->name(), visibleName), option->name(), menu, {}); } -std::shared_ptr ActionMapper::addHeldAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu, const QKeySequence& shortcut) { +std::shared_ptr ActionMapper::addHeldAction(const QString& visibleName, const QString& name, Action::BooleanFunction&& action, const QString& menu, const QKeySequence& shortcut) { m_hiddenActions.insert(name); m_heldActions.insert(name); - return addBooleanAction(visibleName, name, action, menu, shortcut); + return addBooleanAction(visibleName, name, std::move(action), menu, shortcut); } -std::shared_ptr ActionMapper::addHiddenAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu, const QKeySequence& shortcut) { +std::shared_ptr ActionMapper::addHiddenAction(const QString& visibleName, const QString& name, Action::Function&& action, const QString& menu, const QKeySequence& shortcut) { m_hiddenActions.insert(name); - return addAction(visibleName, name, action, menu, shortcut); + return addAction(visibleName, name, std::move(action), menu, shortcut); } QStringList ActionMapper::menuItems(const QString& menu) const { diff --git a/src/platform/qt/ActionMapper.h b/src/platform/qt/ActionMapper.h index 0b690e32b..f1cc3262f 100644 --- a/src/platform/qt/ActionMapper.h +++ b/src/platform/qt/ActionMapper.h @@ -34,16 +34,16 @@ public: void addSeparator(const QString& menu); - std::shared_ptr addAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu = {}, const QKeySequence& = {}); + std::shared_ptr addAction(const QString& visibleName, const QString& name, Action::Function&& action, const QString& menu = {}, const QKeySequence& = {}); template std::shared_ptr addAction(const QString& visibleName, const QString& name, T* obj, V (T::*method)(), const QString& menu = {}, const QKeySequence& = {}); std::shared_ptr addAction(const QString& visibleName, ConfigOption* option, const QVariant& variant, const QString& menu = {}); - std::shared_ptr addBooleanAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu = {}, const QKeySequence& = {}); + std::shared_ptr addBooleanAction(const QString& visibleName, const QString& name, Action::BooleanFunction&& action, const QString& menu = {}, const QKeySequence& = {}); std::shared_ptr addBooleanAction(const QString& visibleName, ConfigOption* option, const QString& menu = {}); - std::shared_ptr addHeldAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu = {}, const QKeySequence& = {}); + std::shared_ptr addHeldAction(const QString& visibleName, const QString& name, Action::BooleanFunction&& action, const QString& menu = {}, const QKeySequence& = {}); - std::shared_ptr addHiddenAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu = {}, const QKeySequence& = {}); + std::shared_ptr addHiddenAction(const QString& visibleName, const QString& name, Action::Function&& action, const QString& menu = {}, const QKeySequence& = {}); template std::shared_ptr addHiddenAction(const QString& visibleName, const QString& name, T* obj, V (T::*method)(), const QString& menu = {}, const QKeySequence& = {}); bool isHeld(const QString& name) const { return m_heldActions.contains(name); } From 7cacae126207de5499857439b9c7919bf8e882c2 Mon Sep 17 00:00:00 2001 From: Bastien Orivel Date: Fri, 19 Jan 2024 17:45:37 +0100 Subject: [PATCH 064/336] Add a `--script` option to load scripts automatically on startup --- src/platform/qt/ConfigController.cpp | 21 ++++++++++++++++++++- src/platform/qt/Window.cpp | 12 ++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 086fcdc8a..527922791 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -19,6 +19,9 @@ static const mOption s_frontendOptions[] = { { "ecard", true, '\0' }, { "mb", true, '\0' }, +#ifdef ENABLE_SCRIPTING + { "script", true, '\0' }, +#endif { 0 } }; @@ -153,7 +156,12 @@ ConfigController::ConfigController(QObject* parent) m_subparsers[1].usage = "Frontend options:\n" " --ecard FILE Scan an e-Reader card in the first loaded game\n" " Can be passed multiple times for multiple cards\n" - " --mb FILE Boot a multiboot image with FILE inserted into the ROM slot"; + " --mb FILE Boot a multiboot image with FILE inserted into the ROM slot" +#ifdef ENABLE_SCRIPTING + "\n --script FILE Script file to load on start" +#endif + ; + m_subparsers[1].parse = nullptr; m_subparsers[1].parseLong = [](struct mSubParser* parser, const char* option, const char* arg) { ConfigController* self = static_cast(parser->opts); @@ -171,6 +179,17 @@ ConfigController::ConfigController(QObject* parent) self->m_argvOptions[optionName] = QString::fromUtf8(arg); return true; } +#ifdef ENABLE_SCRIPTING + if (optionName == QLatin1String("script")) { + QStringList scripts; + if (self->m_argvOptions.contains(optionName)) { + scripts = self->m_argvOptions[optionName].toStringList(); + } + scripts.append(QString::fromUtf8(arg)); + self->m_argvOptions[optionName] = scripts; + return true; + } +#endif return false; }; m_subparsers[1].apply = nullptr; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 800453489..d394ae45b 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -2184,6 +2184,18 @@ void Window::setController(CoreController* controller, const QString& fname) { m_controller->setPaused(true); m_pendingPause = false; } + +#ifdef ENABLE_SCRIPTING + if (!m_scripting) { + QStringList scripts = m_config->getArgvOption("script").toStringList(); + if (!scripts.isEmpty()) { + scriptingOpen(); + for (const auto& scriptPath : scripts) { + m_scripting->loadFile(scriptPath); + } + } + } +#endif } void Window::attachDisplay() { From 1723a353c206996882d9bdb4b138dd19d128d378 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 16:01:49 -0800 Subject: [PATCH 065/336] Updater: Fix updating appimage across filesystems --- CHANGES | 1 + src/tools/updater-main.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d43f3ad1a..d850f2002 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Other fixes: - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) + - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) - GB: Prevent incompatible BIOSes from being used on differing models diff --git a/src/tools/updater-main.c b/src/tools/updater-main.c index 6a1e2a822..a27a07a08 100644 --- a/src/tools/updater-main.c +++ b/src/tools/updater-main.c @@ -271,7 +271,7 @@ int main(int argc, char* argv[]) { // Cross-dev, need to copy manually int infd = open(updateArchive, O_RDONLY); int outfd = -1; - if (infd >= 0) { + if (infd < 0) { ok = 2; } else { outfd = open(bin, O_CREAT | O_WRONLY | O_TRUNC, 0755); From 530b997d7e0f906a2a964ef71266568f99d7a90e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 16:06:57 -0800 Subject: [PATCH 066/336] Qt: Fix uninitialized variable --- src/platform/qt/DebuggerConsole.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/DebuggerConsole.h b/src/platform/qt/DebuggerConsole.h index f98635a68..fd2d4e952 100644 --- a/src/platform/qt/DebuggerConsole.h +++ b/src/platform/qt/DebuggerConsole.h @@ -25,7 +25,7 @@ protected: private: Ui::DebuggerConsole m_ui; - int m_historyOffset; + int m_historyOffset = 0; DebuggerConsoleController* m_consoleController; }; From 4cdcfe6dd3b19703ef3cad9ed448a7b45af00a22 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 16:09:25 -0800 Subject: [PATCH 067/336] Qt: Fix potential null deref --- src/platform/qt/utils.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/platform/qt/utils.cpp b/src/platform/qt/utils.cpp index 99859dbc4..c445c41b8 100644 --- a/src/platform/qt/utils.cpp +++ b/src/platform/qt/utils.cpp @@ -138,7 +138,14 @@ bool extractMatchingFile(VDir* dir, std::function filter) continue; } VFile* outfile = VFileOpen(target.toUtf8().constData(), O_WRONLY | O_TRUNC | O_CREAT); + if (!outfile) { + return false; + } VFile* infile = dir->openFile(dir, entry->name(entry), O_RDONLY); + if (!infile) { + outfile->close(outfile); + return false; + } VFileDevice::copyFile(infile, outfile); infile->close(infile); outfile->close(outfile); From eff1785ce0850ac9fdb67abbec31ebb2b4e17e05 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Jan 2024 16:16:36 -0800 Subject: [PATCH 068/336] Qt: Coverity complains about this but I have no idea if it matters --- src/platform/qt/GBAApp.cpp | 14 +++++++------- src/platform/qt/GBAApp.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index e21dbef05..99c5cb180 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -274,17 +274,17 @@ QNetworkReply* GBAApp::httpGet(const QUrl& url) { return m_netman.get(req); } -qint64 GBAApp::submitWorkerJob(std::function job, std::function callback) { - return submitWorkerJob(job, nullptr, callback); +qint64 GBAApp::submitWorkerJob(std::function&& job, std::function&& callback) { + return submitWorkerJob(std::move(job), nullptr, std::move(callback)); } -qint64 GBAApp::submitWorkerJob(std::function job, QObject* context, std::function callback) { +qint64 GBAApp::submitWorkerJob(std::function&& job, QObject* context, std::function&& callback) { qint64 jobId = m_nextJob; ++m_nextJob; - WorkerJob* jobRunnable = new WorkerJob(jobId, job, this); + WorkerJob* jobRunnable = new WorkerJob(jobId, std::move(job), this); m_workerJobs.insert(jobId, jobRunnable); if (callback) { - waitOnJob(jobId, context, callback); + waitOnJob(jobId, context, std::move(callback)); } m_workerThreads.start(jobRunnable); return jobId; @@ -308,7 +308,7 @@ bool GBAApp::removeWorkerJob(qint64 jobId) { return success; } -bool GBAApp::waitOnJob(qint64 jobId, QObject* context, std::function callback) { +bool GBAApp::waitOnJob(qint64 jobId, QObject* context, std::function&& callback) { if (!m_workerJobs.contains(jobId)) { return false; } @@ -396,7 +396,7 @@ void GBAApp::finishJob(qint64 jobId) { m_workerJobCallbacks.remove(jobId); } -GBAApp::WorkerJob::WorkerJob(qint64 id, std::function job, GBAApp* owner) +GBAApp::WorkerJob::WorkerJob(qint64 id, std::function&& job, GBAApp* owner) : m_id(id) , m_job(job) , m_owner(owner) diff --git a/src/platform/qt/GBAApp.h b/src/platform/qt/GBAApp.h index e9907685f..2388bc297 100644 --- a/src/platform/qt/GBAApp.h +++ b/src/platform/qt/GBAApp.h @@ -74,10 +74,10 @@ public: QNetworkAccessManager* netman(); QNetworkReply* httpGet(const QUrl&); - qint64 submitWorkerJob(std::function job, std::function callback = {}); - qint64 submitWorkerJob(std::function job, QObject* context, std::function callback); + qint64 submitWorkerJob(std::function&& job, std::function&& callback = {}); + qint64 submitWorkerJob(std::function&& job, QObject* context, std::function&& callback); bool removeWorkerJob(qint64 jobId); - bool waitOnJob(qint64 jobId, QObject* context, std::function callback); + bool waitOnJob(qint64 jobId, QObject* context, std::function&& callback); ApplicationUpdater* updater() { return &m_updater; } QString invokeOnExit() { return m_invokeOnExit; } @@ -103,7 +103,7 @@ private slots: private: class WorkerJob : public QRunnable { public: - WorkerJob(qint64 id, std::function job, GBAApp* owner); + WorkerJob(qint64 id, std::function&& job, GBAApp* owner); public: void run() override; From 7bd877dfbd111f2a05f717c0114024dec06f6fa9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 31 Jan 2024 01:22:18 -0800 Subject: [PATCH 069/336] Qt: Shut up coverity some, despite this probably not doing anything --- src/platform/qt/Action.cpp | 8 ++++---- src/platform/qt/Action.h | 2 +- src/platform/qt/ActionMapper.cpp | 2 +- src/platform/qt/AssetView.cpp | 14 ++++++-------- src/platform/qt/AudioProcessor.cpp | 10 +++++----- src/platform/qt/AudioProcessorQt.cpp | 2 +- src/platform/qt/AudioProcessorSDL.cpp | 2 +- src/platform/qt/BattleChipModel.cpp | 3 +-- src/platform/qt/BattleChipView.cpp | 2 +- src/platform/qt/ConfigController.cpp | 4 ++-- src/platform/qt/CoreController.cpp | 4 ++-- src/platform/qt/DebuggerConsoleController.cpp | 2 +- src/platform/qt/Display.h | 2 +- src/platform/qt/DisplayGL.cpp | 6 +++--- src/platform/qt/DisplayQt.cpp | 7 +++---- src/platform/qt/FrameView.cpp | 2 +- src/platform/qt/GBAApp.cpp | 7 ++++--- src/platform/qt/IOViewer.cpp | 4 ++-- src/platform/qt/IOViewer.h | 2 +- src/platform/qt/MemoryAccessLogView.cpp | 2 +- src/platform/qt/MemoryDump.cpp | 4 ++-- 21 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/platform/qt/Action.cpp b/src/platform/qt/Action.cpp index 133a4c512..850b64934 100644 --- a/src/platform/qt/Action.cpp +++ b/src/platform/qt/Action.cpp @@ -14,7 +14,7 @@ Action::Action(QObject* parent) Action::Action(Function&& function, const QString& name, const QString& visibleName, QObject* parent) : QObject(parent) - , m_function(function) + , m_function(std::move(function)) , m_name(name) , m_visibleName(visibleName) { @@ -22,7 +22,7 @@ Action::Action(Function&& function, const QString& name, const QString& visibleN Action::Action(Action::BooleanFunction&& function, const QString& name, const QString& visibleName, QObject* parent) : QObject(parent) - , m_booleanFunction(function) + , m_booleanFunction(std::move(function)) , m_name(name) , m_visibleName(visibleName) { @@ -57,9 +57,9 @@ Action::Action(Action& other) { } -void Action::connect(Function func) { +void Action::connect(Function&& func) { m_booleanFunction = {}; - m_function = func; + m_function = std::move(func); } void Action::trigger(bool active) { diff --git a/src/platform/qt/Action.h b/src/platform/qt/Action.h index 3546f6767..ee3d4587d 100644 --- a/src/platform/qt/Action.h +++ b/src/platform/qt/Action.h @@ -45,7 +45,7 @@ public: return m_name == other.m_name; } - void connect(Function); + void connect(Function&&); bool isEnabled() const { return m_enabled; } bool isActive() const { return m_active; } diff --git a/src/platform/qt/ActionMapper.cpp b/src/platform/qt/ActionMapper.cpp index 7bf7b73cb..90302c350 100644 --- a/src/platform/qt/ActionMapper.cpp +++ b/src/platform/qt/ActionMapper.cpp @@ -107,7 +107,7 @@ void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, QWidget* conte } }); QObject::connect(action.get(), &Action::enabled, qaction, &QAction::setEnabled); - QObject::connect(action.get(), &Action::activated, [qaction, weakAction](bool active) { + QObject::connect(action.get(), &Action::activated, [qaction, weakAction = std::move(weakAction)](bool active) { std::shared_ptr action(weakAction.lock()); if (qaction->isCheckable()) { qaction->setChecked(active); diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index f79111734..98f7d9e05 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -199,7 +199,7 @@ bool AssetView::lookupObjGBA(int id, struct ObjInfo* info) { paletteSet = 2; bits = 4; } - ObjInfo newInfo{ + *info = (ObjInfo) { tile, width / 8, height / 8, @@ -218,16 +218,15 @@ bool AssetView::lookupObjGBA(int id, struct ObjInfo* info) { int matIndex = GBAObjAttributesBGetMatIndex(obj->b); const GBAOAMMatrix* mat = &gba->video.oam.mat[matIndex]; QTransform invXform(mat->a / 256., mat->c / 256., mat->b / 256., mat->d / 256., 0, 0); - newInfo.xform = invXform.inverted(); + info->xform = invXform.inverted(); } else { - newInfo.hflip = bool(GBAObjAttributesBIsHFlip(obj->b)); - newInfo.vflip = bool(GBAObjAttributesBIsVFlip(obj->b)); + info->hflip = bool(GBAObjAttributesBIsHFlip(obj->b)); + info->vflip = bool(GBAObjAttributesBIsVFlip(obj->b)); } GBARegisterDISPCNT dispcnt = gba->memory.io[0]; // FIXME: Register name can't be imported due to namespacing issues if (!GBARegisterDISPCNTIsObjCharacterMapping(dispcnt)) { - newInfo.stride = 0x20 >> (GBAObjAttributesAGet256Color(obj->a)); + info->stride = 0x20 >> (GBAObjAttributesAGet256Color(obj->a)); }; - *info = newInfo; return true; } #endif @@ -258,7 +257,7 @@ bool AssetView::lookupObjGB(int id, struct ObjInfo* info) { } palette += 8; - ObjInfo newInfo{ + *info = (ObjInfo) { tile, 1, height / 8, @@ -273,7 +272,6 @@ bool AssetView::lookupObjGB(int id, struct ObjInfo* info) { bool(GBObjAttributesIsXFlip(obj->attr)), bool(GBObjAttributesIsYFlip(obj->attr)), }; - *info = newInfo; return true; } #endif diff --git a/src/platform/qt/AudioProcessor.cpp b/src/platform/qt/AudioProcessor.cpp index d0b2b1f24..f46e63529 100644 --- a/src/platform/qt/AudioProcessor.cpp +++ b/src/platform/qt/AudioProcessor.cpp @@ -60,11 +60,11 @@ void AudioProcessor::configure(ConfigController* config) { } void AudioProcessor::setInput(std::shared_ptr input) { - m_context = input; - connect(input.get(), &CoreController::stopping, this, &AudioProcessor::stop); - connect(input.get(), &CoreController::fastForwardChanged, this, &AudioProcessor::inputParametersChanged); - connect(input.get(), &CoreController::paused, this, &AudioProcessor::pause); - connect(input.get(), &CoreController::unpaused, this, &AudioProcessor::start); + m_context = std::move(input); + connect(m_context.get(), &CoreController::stopping, this, &AudioProcessor::stop); + connect(m_context.get(), &CoreController::fastForwardChanged, this, &AudioProcessor::inputParametersChanged); + connect(m_context.get(), &CoreController::paused, this, &AudioProcessor::pause); + connect(m_context.get(), &CoreController::unpaused, this, &AudioProcessor::start); } void AudioProcessor::stop() { diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index 3b12d2e07..8d12cd935 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -21,7 +21,7 @@ AudioProcessorQt::AudioProcessorQt(QObject* parent) } void AudioProcessorQt::setInput(std::shared_ptr controller) { - AudioProcessor::setInput(controller); + AudioProcessor::setInput(std::move(controller)); if (m_device) { m_device->setInput(input()); if (m_audioOutput) { diff --git a/src/platform/qt/AudioProcessorSDL.cpp b/src/platform/qt/AudioProcessorSDL.cpp index bf0a5dbdd..bfa9782d1 100644 --- a/src/platform/qt/AudioProcessorSDL.cpp +++ b/src/platform/qt/AudioProcessorSDL.cpp @@ -17,7 +17,7 @@ AudioProcessorSDL::AudioProcessorSDL(QObject* parent) } void AudioProcessorSDL::setInput(std::shared_ptr controller) { - AudioProcessor::setInput(controller); + AudioProcessor::setInput(std::move(controller)); if (m_audio.core && input()->core != m_audio.core) { mSDLDeinitAudio(&m_audio); mSDLInitAudio(&m_audio, input()); diff --git a/src/platform/qt/BattleChipModel.cpp b/src/platform/qt/BattleChipModel.cpp index 2acbd9b7f..941b3f547 100644 --- a/src/platform/qt/BattleChipModel.cpp +++ b/src/platform/qt/BattleChipModel.cpp @@ -118,8 +118,7 @@ void BattleChipModel::setFlavor(int flavor) { if (line.trimmed().isEmpty()) { continue; } - QString name = QString::fromUtf8(line).trimmed(); - m_chipIdToName[id] = name; + m_chipIdToName[id] = QString::fromUtf8(line).trimmed(); } } diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 93f239b7e..d72f78c41 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -24,7 +24,7 @@ using namespace QGBA; BattleChipView::BattleChipView(std::shared_ptr controller, Window* window, QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) - , m_controller(controller) + , m_controller(std::move(controller)) , m_window(window) { m_ui.setupUi(this); diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 527922791..e1bf35408 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -34,7 +34,7 @@ ConfigOption::ConfigOption(const QString& name, QObject* parent) } void ConfigOption::connect(std::function slot, QObject* parent) { - m_slots[parent] = slot; + m_slots[parent] = std::move(slot); QObject::connect(parent, &QObject::destroyed, this, [this, parent]() { m_slots.remove(parent); }); @@ -53,7 +53,7 @@ std::shared_ptr ConfigOption::addValue(const QString& text, const QVaria } action->setExclusive(); std::weak_ptr weakAction(action); - QObject::connect(action.get(), &QObject::destroyed, this, [this, weakAction, value]() { + QObject::connect(action.get(), &QObject::destroyed, this, [this, weakAction = std::move(weakAction), value]() { if (weakAction.expired()) { return; } diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 6b21f2c8e..2e2bd5fed 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -980,7 +980,7 @@ void CoreController::scanCard(const QString& path) { } } scanCards(lines); - m_eReaderData = eReaderData; + m_eReaderData = std::move(eReaderData); } else if (image.size() == QSize(989, 44) || image.size() == QSize(639, 44)) { const uchar* bits = image.constBits(); size_t size; @@ -1055,7 +1055,7 @@ void CoreController::attachPrinter() { colors.append(qRgb(0xA8, 0xA8, 0xA8)); colors.append(qRgb(0x50, 0x50, 0x50)); colors.append(qRgb(0x00, 0x00, 0x00)); - image.setColorTable(colors); + image.setColorTable(std::move(colors)); for (int y = 0; y < height; ++y) { for (int x = 0; x < GB_VIDEO_HORIZONTAL_PIXELS; x += 4) { uint8_t byte = data[(x + y * GB_VIDEO_HORIZONTAL_PIXELS) / 4]; diff --git a/src/platform/qt/DebuggerConsoleController.cpp b/src/platform/qt/DebuggerConsoleController.cpp index 7d6624d77..dffd71bcf 100644 --- a/src/platform/qt/DebuggerConsoleController.cpp +++ b/src/platform/qt/DebuggerConsoleController.cpp @@ -167,7 +167,7 @@ void DebuggerConsoleController::historyLoad() { history.append(QString::fromUtf8(line)); } QMutexLocker lock(&m_mutex); - m_history = history; + m_history = std::move(history); } void DebuggerConsoleController::historySave() { diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index 3c723ba91..ff6f0c23b 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -58,7 +58,7 @@ public: virtual void setBackgroundImage(const QImage&) = 0; virtual QSize contentSize() const = 0; - virtual void setVideoProxy(std::shared_ptr proxy) { m_videoProxy = proxy; } + virtual void setVideoProxy(std::shared_ptr proxy) { m_videoProxy = std::move(proxy); } std::shared_ptr videoProxy() { return m_videoProxy; } virtual VideoBackend* videoBackend(); diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index d2de7b9f4..e31437cad 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -245,7 +245,7 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { m_isDrawing = true; m_painter->setContext(controller); m_painter->setMessagePainter(messagePainter()); - m_context = controller; + m_context = std::move(controller); if (videoProxy()) { videoProxy()->moveToThread(&m_drawThread); } @@ -466,7 +466,7 @@ void DisplayGL::setVideoProxy(std::shared_ptr proxy) { if (proxy) { proxy->moveToThread(&m_drawThread); } - m_painter->setVideoProxy(proxy); + m_painter->setVideoProxy(std::move(proxy)); } void DisplayGL::updateContentSize() { @@ -624,7 +624,7 @@ void PainterGL::destroy() { } void PainterGL::setContext(std::shared_ptr context) { - m_context = context; + m_context = std::move(context); } void PainterGL::resizeContext() { diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index 51874cb40..1d9efebec 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -43,7 +43,7 @@ void DisplayQt::startDrawing(std::shared_ptr controller) { m_height = size.height(); m_oldBacking = QImage(); m_isDrawing = true; - m_context = controller; + m_context = std::move(controller); emit drawingStarted(); } @@ -241,9 +241,8 @@ void DisplayQt::setImage(struct VideoBackend* v, enum VideoLayer layer, const vo if (layer > self->m_layers.size()) { return; } - QImage image = self->m_layers[layer]; - image = QImage(static_cast(frame), image.width(), image.height(), QImage::Format_ARGB32).rgbSwapped(); - self->m_layers[layer] = image; + QImage& image = self->m_layers[layer]; + self->m_layers[layer] = QImage(static_cast(frame), image.width(), image.height(), QImage::Format_ARGB32).rgbSwapped(); } void DisplayQt::drawFrame(struct VideoBackend* v) { diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 76b56be3a..2fe37e64c 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -31,7 +31,7 @@ using namespace QGBA; FrameView::FrameView(std::shared_ptr controller, QWidget* parent) - : AssetView(controller, parent) + : AssetView(std::move(controller), parent) { m_ui.setupUi(this); diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index 99c5cb180..fdc710c0c 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -315,7 +315,8 @@ bool GBAApp::waitOnJob(qint64 jobId, QObject* context, std::function&& if (!context) { context = this; } - QMetaObject::Connection connection = connect(this, &GBAApp::jobFinished, context, [jobId, callback](qint64 testedJobId) { + QMetaObject::Connection connection = connect(this, &GBAApp::jobFinished, context, + [jobId, callback = std::move(callback)](qint64 testedJobId) { if (jobId != testedJobId) { return; } @@ -381,7 +382,7 @@ void GBAApp::restartForUpdate() { #ifndef Q_OS_WIN QFile(extractedPath).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner); #endif - m_invokeOnExit = extractedPath; + m_invokeOnExit = std::move(extractedPath); } for (auto& window : m_windows) { @@ -398,7 +399,7 @@ void GBAApp::finishJob(qint64 jobId) { GBAApp::WorkerJob::WorkerJob(qint64 id, std::function&& job, GBAApp* owner) : m_id(id) - , m_job(job) + , m_job(std::move(job)) , m_owner(owner) { setAutoDelete(true); diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index b354ff415..531ba6955 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -1025,7 +1025,7 @@ const QList& IOViewer::registerDescriptions(mPlat regGBA.append({ { tr("Enable IRQs"), 0 }, }); - s_registers[mPLATFORM_GBA] = regGBA; + s_registers[mPLATFORM_GBA] = std::move(regGBA); #endif #ifdef M_CORE_GB QList regGB; @@ -1555,7 +1555,7 @@ const QList& IOViewer::registerDescriptions(mPlat { tr("Serial"), 3 }, { tr("Joypad"), 4 }, }); - s_registers[mPLATFORM_GB] = regGB; + s_registers[mPLATFORM_GB] = std::move(regGB); #endif return s_registers[platform]; } diff --git a/src/platform/qt/IOViewer.h b/src/platform/qt/IOViewer.h index 120f201e0..fabe478ac 100644 --- a/src/platform/qt/IOViewer.h +++ b/src/platform/qt/IOViewer.h @@ -28,7 +28,7 @@ public: , size(size) , readonly(readonly) , description(description) {} - RegisterItem(const QString& description, uint start, int size, QStringList items, bool readonly = false) + RegisterItem(const QString& description, uint start, int size, const QStringList& items, bool readonly = false) : start(start) , size(size) , readonly(readonly) diff --git a/src/platform/qt/MemoryAccessLogView.cpp b/src/platform/qt/MemoryAccessLogView.cpp index 5998dd517..3c846b440 100644 --- a/src/platform/qt/MemoryAccessLogView.cpp +++ b/src/platform/qt/MemoryAccessLogView.cpp @@ -16,7 +16,7 @@ using namespace QGBA; MemoryAccessLogView::MemoryAccessLogView(std::shared_ptr controller, QWidget* parent) : QWidget(parent) - , m_controller(controller) + , m_controller(std::move(controller)) { m_ui.setupUi(this); diff --git a/src/platform/qt/MemoryDump.cpp b/src/platform/qt/MemoryDump.cpp index 982353ee2..59cef31be 100644 --- a/src/platform/qt/MemoryDump.cpp +++ b/src/platform/qt/MemoryDump.cpp @@ -13,7 +13,7 @@ using namespace QGBA; MemoryDump::MemoryDump(std::shared_ptr controller, QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) - , m_controller(controller) + , m_controller(std::move(controller)) { m_ui.setupUi(this); @@ -117,4 +117,4 @@ QByteArray MemoryDump::serialize() { } return mem; -} \ No newline at end of file +} From 3b32da60faceb66bd8e3d4ac82cf0c27f6f679ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 31 Jan 2024 02:36:35 -0800 Subject: [PATCH 070/336] Qt: Attempt to fix MSVC build --- src/platform/qt/AssetView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index 98f7d9e05..c648982c6 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -199,7 +199,7 @@ bool AssetView::lookupObjGBA(int id, struct ObjInfo* info) { paletteSet = 2; bits = 4; } - *info = (ObjInfo) { + *info = ObjInfo{ tile, width / 8, height / 8, @@ -257,7 +257,7 @@ bool AssetView::lookupObjGB(int id, struct ObjInfo* info) { } palette += 8; - *info = (ObjInfo) { + *info = ObjInfo{ tile, 1, height / 8, From bba2c131a172d6a209e9a96b827e670723deb0af Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 31 Jan 2024 15:41:34 -0800 Subject: [PATCH 071/336] Qt: Shut coverity up a bit more --- src/platform/qt/PlacementControl.cpp | 2 +- src/platform/qt/ShortcutController.cpp | 2 +- src/platform/qt/VideoView.h | 2 +- src/platform/qt/Window.cpp | 6 +++--- src/platform/qt/scripting/ScriptingController.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/platform/qt/PlacementControl.cpp b/src/platform/qt/PlacementControl.cpp index fc031d019..0011dff5f 100644 --- a/src/platform/qt/PlacementControl.cpp +++ b/src/platform/qt/PlacementControl.cpp @@ -15,7 +15,7 @@ using namespace QGBA; PlacementControl::PlacementControl(std::shared_ptr controller, QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) - , m_controller(controller) + , m_controller(std::move(controller)) { m_ui.setupUi(this); diff --git a/src/platform/qt/ShortcutController.cpp b/src/platform/qt/ShortcutController.cpp index 0ed445cd2..d1165a9ba 100644 --- a/src/platform/qt/ShortcutController.cpp +++ b/src/platform/qt/ShortcutController.cpp @@ -326,7 +326,7 @@ void ShortcutController::loadProfile(const QString& profile) { m_profileName = profile; m_profile = InputProfile::findProfile(profile); onSubitems({}, [this](std::shared_ptr item) { - loadGamepadShortcuts(item); + loadGamepadShortcuts(std::move(item)); }); } diff --git a/src/platform/qt/VideoView.h b/src/platform/qt/VideoView.h index 23b5ef034..9e3ab5ca2 100644 --- a/src/platform/qt/VideoView.h +++ b/src/platform/qt/VideoView.h @@ -75,7 +75,7 @@ private: QSize dims; Preset() {} - Preset(QString container, QString vcodec, QString acodec, int vbr, int abr, QSize dims = QSize()) + Preset(const QString& container, const QString& vcodec, const QString& acodec, int vbr, int abr, QSize dims = QSize()) : container(container) , vcodec(vcodec) , acodec(acodec) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index d394ae45b..6b77a1ef3 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1612,7 +1612,7 @@ void Window::setupMenu(QMenuBar* menubar) { double nativeGB = double(GBA_ARM7TDMI_FREQUENCY) / double(VIDEO_TOTAL_LENGTH); fpsTargets[nativeGB] = fpsTargetOption->addValue(tr("Native (59.7275)"), nativeGB, &m_actions, "target"); - fpsTargetOption->connect([this, fpsTargets](const QVariant& value) { + fpsTargetOption->connect([this, fpsTargets = std::move(fpsTargets)](const QVariant& value) { reloadConfig(); for (auto iter = fpsTargets.begin(); iter != fpsTargets.end(); ++iter) { bool enableSignals = iter.value()->blockSignals(true); @@ -1982,7 +1982,7 @@ void Window::updateMRU() { } std::shared_ptr Window::addGameAction(const QString& visibleName, const QString& name, Action::Function function, const QString& menu, const QKeySequence& shortcut) { - auto action = m_actions.addAction(visibleName, name, [this, function]() { + auto action = m_actions.addAction(visibleName, name, [this, function = std::move(function)]() { if (m_controller) { function(); } @@ -2006,7 +2006,7 @@ std::shared_ptr Window::addGameAction(const QString& visibleName, const } std::shared_ptr Window::addGameAction(const QString& visibleName, const QString& name, Action::BooleanFunction function, const QString& menu, const QKeySequence& shortcut) { - auto action = m_actions.addBooleanAction(visibleName, name, [this, function](bool value) { + auto action = m_actions.addBooleanAction(visibleName, name, [this, function = std::move(function)](bool value) { if (m_controller) { function(value); } diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index 95180d1de..065754bf1 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -73,7 +73,7 @@ void ScriptingController::setController(std::shared_ptr controll if (!controller) { return; } - m_controller = controller; + m_controller = std::move(controller); CoreController::Interrupter interrupter(m_controller); m_controller->thread()->scriptContext = &m_scriptContext; if (m_controller->hasStarted()) { From 55c7c2f48e51214dfa9eaf15742a8494370e6a6b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 7 Feb 2024 01:44:57 -0800 Subject: [PATCH 072/336] CMake: Remove leftover debug print --- src/platform/qt/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 610fa362d..cb224b0a6 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -335,7 +335,6 @@ if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY) install(DIRECTORY ${PROJECT_SOURCE_DIR}/res/shaders DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) else() file(GLOB SHADERS ${PROJECT_SOURCE_DIR}/res/shaders/*.shader) - message(STATUS ${SHADERS}) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shaders) foreach(SHADER_DIR ${SHADERS}) get_filename_component(SHADER ${SHADER_DIR} NAME) From c917a71ef8ac653bde6a9dfaf6bd09f2a5c70cb6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 7 Feb 2024 03:38:07 -0800 Subject: [PATCH 073/336] Qt: Improve OpenGLES support and cleanup ifdef maze --- src/platform/qt/Display.cpp | 48 ++++++++++++----------------------- src/platform/qt/DisplayGL.cpp | 47 ++++++++++++++++++++++++++++++++++ src/platform/qt/DisplayGL.h | 1 + 3 files changed, 64 insertions(+), 32 deletions(-) diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp index 8bec92f28..2cc7df66e 100644 --- a/src/platform/qt/Display.cpp +++ b/src/platform/qt/Display.cpp @@ -33,49 +33,33 @@ QGBA::Display* QGBA::Display::create(QWidget* parent) { switch (s_driver) { #if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) case Driver::OPENGL: -#if defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { - format.setVersion(2, 0); - } else { - format.setVersion(3, 3); + default: + if (DisplayGL::highestCompatible(format)) { + return new DisplayGL(format, parent); } - format.setProfile(QSurfaceFormat::CoreProfile); - if (DisplayGL::supportsFormat(format)) { - QSurfaceFormat::setDefaultFormat(format); - } else { -#ifdef BUILD_GL - LOG(QT, WARN) << ("Failed to create an OpenGL Core context, trying old-style..."); - format.setVersion(1, 4); - format.setOption(QSurfaceFormat::DeprecatedFunctions); - if (!DisplayGL::supportsFormat(format)) { - return nullptr; - } -#else - return nullptr; -#endif - } - return new DisplayGL(format, parent); -#endif + break; #endif #ifdef BUILD_GL case Driver::OPENGL1: - format.setVersion(1, 4); - if (!DisplayGL::supportsFormat(format)) { - return nullptr; + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(1, 4); + } else { + format.setVersion(1, 1); } - return new DisplayGL(format, parent); + if (DisplayGL::supportsFormat(format)) { + return new DisplayGL(format, parent); + } + break; #endif case Driver::QT: +#if !defined(BUILD_GL) && !defined(BUILD_GLES2) && !defined(BUILD_GLES3) && !defined(USE_EPOXY) + default: +#endif return new DisplayQt(parent); - default: -#if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) - return new DisplayGL(format, parent); -#else - return new DisplayQt(parent); -#endif } + return nullptr; } QGBA::Display::Display(QWidget* parent) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index e31437cad..3a4c3ffdd 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -53,6 +53,12 @@ typedef struct _XDisplay Display; #define OVERHEAD_NSEC 300000 #endif +// Legacy define from X11/X.h +#ifdef Unsorted +#undef Unsorted +#endif + +#include "LogController.h" #include "OpenGLBug.h" #include "utils.h" @@ -277,6 +283,47 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { QTimer::singleShot(8, this, &DisplayGL::updateContentSize); } +bool DisplayGL::highestCompatible(QSurfaceFormat& format) { +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(3, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + if (DisplayGL::supportsFormat(format)) { + return true; + } + } else { +#if defined(BUILD_GLES3) || defined(USE_EPOXY) + format.setVersion(3, 1); + if (DisplayGL::supportsFormat(format)) { + return true; + } +#endif +#if defined(BUILD_GLES2) || defined(USE_EPOXY) + format.setVersion(2, 0); + if (DisplayGL::supportsFormat(format)) { + return true; + } +#endif + } +#endif + +#ifdef BUILD_GL +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) + LOG(QT, WARN) << tr("Failed to create an OpenGL 3 context, trying old-style..."); +#endif + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(1, 4); + } else { + format.setVersion(1, 1); + } + format.setOption(QSurfaceFormat::DeprecatedFunctions); + if (DisplayGL::supportsFormat(format)) { + return true; + } +#endif + return false; +} + bool DisplayGL::supportsFormat(const QSurfaceFormat& format) { if (!s_supports.contains(format)) { QOpenGLContext context; diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index d94a68621..71e2de597 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -96,6 +96,7 @@ public: int framebufferHandle() override; QSize contentSize() const override { return m_cachedContentSize; } + static bool highestCompatible(QSurfaceFormat&); static bool supportsFormat(const QSurfaceFormat&); public slots: From 49d9b70e6f2015165b6719a6da8ea842e996fde0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 8 Feb 2024 17:15:18 -0800 Subject: [PATCH 074/336] Core: Move rewind state coalescing into mCoreRewindRestore --- include/mgba/core/rewind.h | 2 +- src/core/rewind.c | 48 ++++++++++++++++-------------- src/core/thread.c | 2 +- src/platform/qt/CoreController.cpp | 6 +--- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/include/mgba/core/rewind.h b/include/mgba/core/rewind.h index 9d2595557..2f33886ca 100644 --- a/include/mgba/core/rewind.h +++ b/include/mgba/core/rewind.h @@ -40,7 +40,7 @@ void mCoreRewindContextDeinit(struct mCoreRewindContext*); struct mCore; void mCoreRewindAppend(struct mCoreRewindContext*, struct mCore*); -bool mCoreRewindRestore(struct mCoreRewindContext*, struct mCore*); +bool mCoreRewindRestore(struct mCoreRewindContext*, struct mCore*, unsigned count); CXX_GUARD_END diff --git a/src/core/rewind.c b/src/core/rewind.c index 21120ec21..b8ba752dd 100644 --- a/src/core/rewind.c +++ b/src/core/rewind.c @@ -115,7 +115,7 @@ void _rewindDiff(struct mCoreRewindContext* context) { context->currentState->unmap(context->currentState, next, size); } -bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core) { +bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core, unsigned count) { #ifndef DISABLE_THREADING if (context->onThread) { MutexLock(&context->mutex); @@ -129,30 +129,34 @@ bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core) #endif return false; } - --context->size; - mCoreLoadStateNamed(core, context->previousState, SAVESTATE_SAVEDATA | SAVESTATE_RTC); - if (context->current == 0) { - context->current = mCoreRewindPatchesSize(&context->patchMemory); - } - --context->current; - - if (context->size) { - struct PatchFast* patch = mCoreRewindPatchesGetPointer(&context->patchMemory, context->current); - size_t size2 = context->previousState->size(context->previousState); - size_t size = context->currentState->size(context->currentState); - if (size2 < size) { - size = size2; + for (; count && context->size; --count, --context->size) { + if (context->current == 0) { + context->current = mCoreRewindPatchesSize(&context->patchMemory); } - void* current = context->currentState->map(context->currentState, size, MAP_READ); - void* previous = context->previousState->map(context->previousState, size, MAP_WRITE); - patch->d.applyPatch(&patch->d, previous, size, current, size); - context->currentState->unmap(context->currentState, current, size); - context->previousState->unmap(context->previousState, previous, size); + --context->current; + + if (context->size > 1) { + struct PatchFast* patch = mCoreRewindPatchesGetPointer(&context->patchMemory, context->current); + size_t size2 = context->previousState->size(context->previousState); + size_t size = context->currentState->size(context->currentState); + if (size2 < size) { + size = size2; + } + void* current = context->currentState->map(context->currentState, size, MAP_READ); + void* previous = context->previousState->map(context->previousState, size, MAP_WRITE); + patch->d.applyPatch(&patch->d, previous, size, current, size); + context->currentState->unmap(context->currentState, current, size); + context->previousState->unmap(context->previousState, previous, size); + } + struct VFile* nextState = context->previousState; + context->previousState = context->currentState; + context->currentState = nextState; } - struct VFile* nextState = context->previousState; - context->previousState = context->currentState; - context->currentState = nextState; + + mCoreLoadStateNamed(core, context->currentState, SAVESTATE_SAVEDATA | SAVESTATE_RTC); + + #ifndef DISABLE_THREADING if (context->onThread) { MutexUnlock(&context->mutex); diff --git a/src/core/thread.c b/src/core/thread.c index 903d4b844..b458f5e12 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -153,7 +153,7 @@ void _frameStarted(void* context) { return; } if (thread->core->opts.rewindEnable && thread->core->opts.rewindBufferCapacity > 0) { - if (!thread->impl->rewinding || !mCoreRewindRestore(&thread->impl->rewind, thread->core)) { + if (!thread->impl->rewinding || !mCoreRewindRestore(&thread->impl->rewind, thread->core, 1)) { if (thread->impl->rewind.rewindFrameCounter == 0) { mCoreRewindAppend(&thread->impl->rewind, thread->core); thread->impl->rewind.rewindFrameCounter = thread->core->opts.rewindBufferInterval; diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 2e2bd5fed..dd74cce78 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -556,11 +556,7 @@ void CoreController::rewind(int states) { if (!states) { states = INT_MAX; } - for (int i = 0; i < states; ++i) { - if (!mCoreRewindRestore(&m_threadContext.impl->rewind, m_threadContext.core)) { - break; - } - } + mCoreRewindRestore(&m_threadContext.impl->rewind, m_threadContext.core, states); interrupter.resume(); emit frameAvailable(); emit rewound(); From cf54ddd864291a873dff0d5bb9583f27f1011ad0 Mon Sep 17 00:00:00 2001 From: oltolm Date: Sun, 7 Jan 2024 12:13:26 +0100 Subject: [PATCH 075/336] CMake: make compile with mingw-w64 and Qt6 --- .gitignore | 4 ++++ CMakeLists.txt | 4 +++- CMakePresets.json | 21 +++++++++++++++++++++ src/platform/sdl/CMakeLists.txt | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 CMakePresets.json diff --git a/.gitignore b/.gitignore index 999fdd673..fedbc461f 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,10 @@ CMakeCache.txt CMakeFiles CMakeSettings.json +CMakeUserPresets.json +compile_commands.json +/.cache +/.vscode cmake_install.cmake hle-bios.bin version.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a1e730e04..4bf160665 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,13 +217,15 @@ endif() # Platform support if(WIN32) set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}") - add_definitions(-D_WIN32_WINNT=0x0600) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) if(MSVC) add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN) add_definitions(-D_UNICODE -DUNICODE) else() add_definitions(-D_GNU_SOURCE) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + add_compile_definitions(_FILE_OFFSET_BITS=64) + endif() endif() list(APPEND OS_LIB ws2_32 shlwapi) list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/vfs-w32.c) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000..584b1987d --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,21 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "clang", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" + } + }, + { + "name": "gcc", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" + } + } + ] +} \ No newline at end of file diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index ca1919da9..07c773fb2 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -125,6 +125,7 @@ target_link_libraries(${BINARY_NAME}-sdl ${BINARY_NAME} ${PLATFORM_LIBRARY} ${OP if(NOT WIN32) set_target_properties(${BINARY_NAME}-sdl PROPERTIES OUTPUT_NAME ${BINARY_NAME}) else() + target_compile_definitions(${BINARY_NAME}-sdl PRIVATE _WIN32_WINNT=0x0600) set_target_properties(${BINARY_NAME}-sdl PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") endif() install(TARGETS ${BINARY_NAME}-sdl DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-sdl) From 3571b112dc821d3612e5073afb8b6be41a35dc55 Mon Sep 17 00:00:00 2001 From: oltolm Date: Sun, 7 Jan 2024 12:16:52 +0100 Subject: [PATCH 076/336] fix compilation warnings --- include/mgba-util/common.h | 4 ---- include/mgba-util/platform/windows/threading.h | 2 +- src/core/thread.c | 16 ++++++++-------- src/platform/qt/AudioProcessorSDL.h | 1 + src/platform/qt/ColorPicker.cpp | 4 +--- src/platform/qt/ForwarderController.cpp | 4 ++-- src/platform/qt/ForwarderGenerator3DS.h | 2 +- src/platform/qt/GBAKeyEditor.cpp | 1 + src/platform/qt/SettingsView.cpp | 1 + src/platform/qt/ShortcutController.cpp | 8 ++++---- src/platform/qt/input/SDLInputDriver.h | 2 ++ src/platform/qt/main.cpp | 10 ++++++---- .../qt/scripting/ScriptingController.cpp | 16 ++++++++-------- src/platform/qt/scripting/ScriptingController.h | 2 +- src/platform/sdl/main.c | 1 + 15 files changed, 38 insertions(+), 36 deletions(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index 0fc10be58..4a4054c9e 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -14,10 +14,6 @@ #define CXX_GUARD_END #endif -#ifdef __MINGW32__ -#define __USE_MINGW_ANSI_STDIO 1 -#endif - CXX_GUARD_START #include diff --git a/include/mgba-util/platform/windows/threading.h b/include/mgba-util/platform/windows/threading.h index 3f5de5a77..df1e90205 100644 --- a/include/mgba-util/platform/windows/threading.h +++ b/include/mgba-util/platform/windows/threading.h @@ -8,7 +8,7 @@ #include -#define _WIN32_WINNT 0x0600 +#define WIN32_LEAN_AND_MEAN #include #define THREAD_ENTRY DWORD WINAPI typedef THREAD_ENTRY ThreadEntry(LPVOID); diff --git a/src/core/thread.c b/src/core/thread.c index b458f5e12..63b8e0d56 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -218,17 +218,17 @@ ADD_CALLBACK(savedataUpdated) ADD_CALLBACK(alarm) #undef ADD_CALLBACK -#define CALLBACK(NAME) _script_ ## NAME +#define SCRIPT(NAME) _script_ ## NAME static void _mCoreThreadAddCallbacks(struct mCoreThread* threadContext) { struct mCoreCallbacks callbacks = { - .videoFrameEnded = CALLBACK(frame), - .coreCrashed = CALLBACK(crashed), - .sleep = CALLBACK(sleep), - .shutdown = CALLBACK(stop), - .keysRead = CALLBACK(keysRead), - .savedataUpdated = CALLBACK(savedataUpdated), - .alarm = CALLBACK(alarm), + .videoFrameEnded = SCRIPT(frame), + .coreCrashed = SCRIPT(crashed), + .sleep = SCRIPT(sleep), + .shutdown = SCRIPT(stop), + .keysRead = SCRIPT(keysRead), + .savedataUpdated = SCRIPT(savedataUpdated), + .alarm = SCRIPT(alarm), .context = threadContext }; threadContext->core->addCoreCallbacks(threadContext->core, &callbacks); diff --git a/src/platform/qt/AudioProcessorSDL.h b/src/platform/qt/AudioProcessorSDL.h index c2d5d0ee1..2f86c0e16 100644 --- a/src/platform/qt/AudioProcessorSDL.h +++ b/src/platform/qt/AudioProcessorSDL.h @@ -9,6 +9,7 @@ #ifdef BUILD_SDL +#define SDL_MAIN_HANDLED #include "platform/sdl/sdl-audio.h" namespace QGBA { diff --git a/src/platform/qt/ColorPicker.cpp b/src/platform/qt/ColorPicker.cpp index 22d995c0f..8cebab520 100644 --- a/src/platform/qt/ColorPicker.cpp +++ b/src/platform/qt/ColorPicker.cpp @@ -44,13 +44,11 @@ bool ColorPicker::eventFilter(QObject* obj, QEvent* event) { return false; } - QWidget* swatch = static_cast(obj); - QColorDialog* colorPicker = new QColorDialog; colorPicker->setAttribute(Qt::WA_DeleteOnClose); colorPicker->setCurrentColor(m_defaultColor); colorPicker->open(); - connect(colorPicker, &QColorDialog::colorSelected, [this, swatch](const QColor& color) { + connect(colorPicker, &QColorDialog::colorSelected, [this](const QColor& color) { setColor(color); emit colorChanged(color); }); diff --git a/src/platform/qt/ForwarderController.cpp b/src/platform/qt/ForwarderController.cpp index 56e202019..0934f1c69 100644 --- a/src/platform/qt/ForwarderController.cpp +++ b/src/platform/qt/ForwarderController.cpp @@ -232,9 +232,9 @@ bool ForwarderController::toolInstalled(const QString& tool) { void ForwarderController::connectReply(QNetworkReply* reply, Download download, void (ForwarderController::*next)(QNetworkReply*)) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - connect(reply, &QNetworkReply::errorOccurred, this, [this, reply]() { + connect(reply, &QNetworkReply::errorOccurred, this, [this]() { #else - connect(reply, qOverload<>(&QNetworkReply::error), this, [this, reply]() { + connect(reply, qOverload<>(&QNetworkReply::error), this, [this]() { #endif emit buildFailed(); }); diff --git a/src/platform/qt/ForwarderGenerator3DS.h b/src/platform/qt/ForwarderGenerator3DS.h index b22585063..8713be1bf 100644 --- a/src/platform/qt/ForwarderGenerator3DS.h +++ b/src/platform/qt/ForwarderGenerator3DS.h @@ -23,7 +23,7 @@ public: System system() const override { return System::N3DS; } QString extension() const override { return QLatin1String("cia"); } - virtual QStringList externalTools() const { return {"bannertool", "3dstool", "ctrtool", "makerom"}; } + virtual QStringList externalTools() const override { return {"bannertool", "3dstool", "ctrtool", "makerom"}; } void rebuild(const QString& source, const QString& target) override; diff --git a/src/platform/qt/GBAKeyEditor.cpp b/src/platform/qt/GBAKeyEditor.cpp index 88963afa2..4536bda2a 100644 --- a/src/platform/qt/GBAKeyEditor.cpp +++ b/src/platform/qt/GBAKeyEditor.cpp @@ -18,6 +18,7 @@ #include "KeyEditor.h" #ifdef BUILD_SDL +#define SDL_MAIN_HANDLED #include "platform/sdl/sdl-events.h" #endif diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 7f0fef53f..04d7d1649 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -26,6 +26,7 @@ #include #ifdef BUILD_SDL +#define SDL_MAIN_HANDLED #include "platform/sdl/sdl-events.h" #endif diff --git a/src/platform/qt/ShortcutController.cpp b/src/platform/qt/ShortcutController.cpp index d1165a9ba..db7f27e6a 100644 --- a/src/platform/qt/ShortcutController.cpp +++ b/src/platform/qt/ShortcutController.cpp @@ -143,7 +143,7 @@ bool ShortcutController::eventFilter(QObject* obj, QEvent* event) { QKeyEvent* keyEvent = static_cast(event); #ifdef ENABLE_SCRIPTING if (m_scripting) { - m_scripting->event(obj, event); + m_scripting->scriptingEvent(obj, event); } #endif if (keyEvent->isAutoRepeat()) { @@ -165,7 +165,7 @@ bool ShortcutController::eventFilter(QObject* obj, QEvent* event) { if (event->type() == GamepadButtonEvent::Down()) { #ifdef ENABLE_SCRIPTING if (m_scripting) { - m_scripting->event(obj, event); + m_scripting->scriptingEvent(obj, event); } #endif auto item = m_buttons.find(static_cast(event)->value()); @@ -186,7 +186,7 @@ bool ShortcutController::eventFilter(QObject* obj, QEvent* event) { if (event->type() == GamepadButtonEvent::Up()) { #ifdef ENABLE_SCRIPTING if (m_scripting) { - m_scripting->event(obj, event); + m_scripting->scriptingEvent(obj, event); } #endif auto item = m_buttons.find(static_cast(event)->value()); @@ -224,7 +224,7 @@ bool ShortcutController::eventFilter(QObject* obj, QEvent* event) { #ifdef ENABLE_SCRIPTING if (event->type() == GamepadHatEvent::Type()) { if (m_scripting) { - m_scripting->event(obj, event); + m_scripting->scriptingEvent(obj, event); } } #endif diff --git a/src/platform/qt/input/SDLInputDriver.h b/src/platform/qt/input/SDLInputDriver.h index 61f1e6238..4a4916ad3 100644 --- a/src/platform/qt/input/SDLInputDriver.h +++ b/src/platform/qt/input/SDLInputDriver.h @@ -8,6 +8,8 @@ #include "input/Gamepad.h" #include "input/InputDriver.h" +#define SDL_MAIN_HANDLED + #include "platform/sdl/sdl-events.h" #include diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index c245cff53..62967bf1a 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -109,8 +109,9 @@ int main(int argc, char* argv[]) { #endif QTranslator qtTranslator; - qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - application.installTranslator(&qtTranslator); + if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { + application.installTranslator(&qtTranslator); + } #ifdef QT_STATIC QTranslator qtStaticTranslator; @@ -119,8 +120,9 @@ int main(int argc, char* argv[]) { #endif QTranslator langTranslator; - langTranslator.load(locale, binaryName, "-", ":/translations/"); - application.installTranslator(&langTranslator); + if (langTranslator.load(locale, binaryName, "-", ":/translations/")) { + application.installTranslator(&langTranslator); + } Window* w = application.newWindow(); w->loadConfig(); diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index 065754bf1..06adafdf5 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -170,11 +170,11 @@ void ScriptingController::flushStorage() { } bool ScriptingController::eventFilter(QObject* obj, QEvent* ev) { - event(obj, ev); + scriptingEvent(obj, ev); return false; } -void ScriptingController::event(QObject* obj, QEvent* event) { +void ScriptingController::scriptingEvent(QObject* obj, QEvent* event) { if (!m_controller) { return; } @@ -188,7 +188,7 @@ void ScriptingController::event(QObject* obj, QEvent* event) { return; case QEvent::KeyPress: case QEvent::KeyRelease: { - struct mScriptKeyEvent ev{mSCRIPT_EV_TYPE_KEY}; + struct mScriptKeyEvent ev{{mSCRIPT_EV_TYPE_KEY}}; auto keyEvent = static_cast(event); ev.state = event->type() == QEvent::KeyRelease ? mSCRIPT_INPUT_STATE_UP : static_cast(event)->isAutoRepeat() ? mSCRIPT_INPUT_STATE_HELD : mSCRIPT_INPUT_STATE_DOWN; @@ -199,7 +199,7 @@ void ScriptingController::event(QObject* obj, QEvent* event) { } case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: { - struct mScriptMouseButtonEvent ev{mSCRIPT_EV_TYPE_MOUSE_BUTTON}; + struct mScriptMouseButtonEvent ev{{mSCRIPT_EV_TYPE_MOUSE_BUTTON}}; auto mouseEvent = static_cast(event); ev.mouse = 0; ev.state = event->type() == QEvent::MouseButtonPress ? mSCRIPT_INPUT_STATE_DOWN : mSCRIPT_INPUT_STATE_UP; @@ -208,7 +208,7 @@ void ScriptingController::event(QObject* obj, QEvent* event) { return; } case QEvent::MouseMove: { - struct mScriptMouseMoveEvent ev{mSCRIPT_EV_TYPE_MOUSE_MOVE}; + struct mScriptMouseMoveEvent ev{{mSCRIPT_EV_TYPE_MOUSE_MOVE}}; auto mouseEvent = static_cast(event); QPoint pos = mouseEvent->pos(); pos = static_cast(obj)->normalizedPoint(m_controller.get(), pos); @@ -219,7 +219,7 @@ void ScriptingController::event(QObject* obj, QEvent* event) { return; } case QEvent::Wheel: { - struct mScriptMouseWheelEvent ev{mSCRIPT_EV_TYPE_MOUSE_WHEEL}; + struct mScriptMouseWheelEvent ev{{mSCRIPT_EV_TYPE_MOUSE_WHEEL}}; auto wheelEvent = static_cast(event); QPoint adelta = wheelEvent->angleDelta(); QPoint pdelta = wheelEvent->pixelDelta(); @@ -240,7 +240,7 @@ void ScriptingController::event(QObject* obj, QEvent* event) { auto type = event->type(); if (type == GamepadButtonEvent::Down() || type == GamepadButtonEvent::Up()) { - struct mScriptGamepadButtonEvent ev{mSCRIPT_EV_TYPE_GAMEPAD_BUTTON}; + struct mScriptGamepadButtonEvent ev{{mSCRIPT_EV_TYPE_GAMEPAD_BUTTON}}; auto gamepadEvent = static_cast(event); ev.pad = 0; ev.state = event->type() == GamepadButtonEvent::Down() ? mSCRIPT_INPUT_STATE_DOWN : mSCRIPT_INPUT_STATE_UP; @@ -248,7 +248,7 @@ void ScriptingController::event(QObject* obj, QEvent* event) { mScriptContextFireEvent(&m_scriptContext, &ev.d); } if (type == GamepadHatEvent::Type()) { - struct mScriptGamepadHatEvent ev{mSCRIPT_EV_TYPE_GAMEPAD_HAT}; + struct mScriptGamepadHatEvent ev{{mSCRIPT_EV_TYPE_GAMEPAD_HAT}}; updateGamepad(); auto gamepadEvent = static_cast(event); ev.pad = 0; diff --git a/src/platform/qt/scripting/ScriptingController.h b/src/platform/qt/scripting/ScriptingController.h index a44e52b2e..9e5b3f6b5 100644 --- a/src/platform/qt/scripting/ScriptingController.h +++ b/src/platform/qt/scripting/ScriptingController.h @@ -43,7 +43,7 @@ public: bool loadFile(const QString& path); bool load(VFileDevice& vf, const QString& name); - void event(QObject* obj, QEvent* ev); + void scriptingEvent(QObject* obj, QEvent* ev); mScriptContext* context() { return &m_scriptContext; } ScriptingTextBufferModel* textBufferModel() const { return m_bufferModel; } diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index f71f1cfc5..d6a41f611 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -47,6 +47,7 @@ static void _loadState(struct mCoreThread* thread) { int main(int argc, char** argv) { #ifdef _WIN32 AttachConsole(ATTACH_PARENT_PROCESS); + freopen("CONOUT$", "w", stdout); #endif struct mSDLRenderer renderer = {0}; From c541a79e9564310d7a81d9668f41317acf30dda1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2024 21:52:25 -0800 Subject: [PATCH 077/336] Windows: Fix compilation woes from last commit --- include/mgba-util/common.h | 18 +++++++++++++----- include/mgba-util/platform/windows/threading.h | 2 -- src/platform/sdl/CMakeLists.txt | 1 - 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index 4a4054c9e..d91a6557c 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -16,6 +16,19 @@ CXX_GUARD_START +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +// Require Windows 7 or newer +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0601 +#elif _WIN32_WINNT < 0x0601 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0601 +#endif +// WinSock2 gets very angry if it's included too late +#include +#endif + #include #include #include @@ -31,11 +44,6 @@ CXX_GUARD_START #include #include -#ifdef _WIN32 -// WinSock2 gets very angry if it's included too late -#include -#endif - #if defined(_MSC_VER) || defined(__cplusplus) #define restrict __restrict #endif diff --git a/include/mgba-util/platform/windows/threading.h b/include/mgba-util/platform/windows/threading.h index df1e90205..7b1589075 100644 --- a/include/mgba-util/platform/windows/threading.h +++ b/include/mgba-util/platform/windows/threading.h @@ -8,8 +8,6 @@ #include -#define WIN32_LEAN_AND_MEAN -#include #define THREAD_ENTRY DWORD WINAPI typedef THREAD_ENTRY ThreadEntry(LPVOID); #define THREAD_EXIT(RES) return RES diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 07c773fb2..ca1919da9 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -125,7 +125,6 @@ target_link_libraries(${BINARY_NAME}-sdl ${BINARY_NAME} ${PLATFORM_LIBRARY} ${OP if(NOT WIN32) set_target_properties(${BINARY_NAME}-sdl PROPERTIES OUTPUT_NAME ${BINARY_NAME}) else() - target_compile_definitions(${BINARY_NAME}-sdl PRIVATE _WIN32_WINNT=0x0600) set_target_properties(${BINARY_NAME}-sdl PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") endif() install(TARGETS ${BINARY_NAME}-sdl DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-sdl) From 4ee633925c5389e214307b3dd64c7e575ff47efb Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 12 Aug 2023 00:17:04 +0200 Subject: [PATCH 078/336] 3DS: Implement 3x sharp bilinear scaling and make it the default - Old method was 2x. 3x looks quite a bit sharper in aspect-fit mode on non-O2DS as the width is an integer number of half-width pixels. Since resulting upscaling ratio is 3x:1.5x, this gives very good results, althought it might be too sharp for your liking (YMMV). Not as much of a difference in screen-fit mode - Remove duplicate rendertarget as it was not necessary --- src/platform/3ds/main.c | 97 +++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 470c50db7..0f7bb27b9 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -47,8 +47,9 @@ static enum FilterMode { FM_NEAREST, FM_LINEAR_1x, FM_LINEAR_2x, + FM_LINEAR_3x, FM_MAX -} filterMode = FM_LINEAR_2x; +} filterMode = FM_LINEAR_3x; static enum DarkenMode { DM_NATIVE, @@ -97,9 +98,8 @@ static int bufferId = 0; static bool frameLimiter = true; static u32 frameCounter; -static C3D_RenderTarget* topScreen[2]; -static C3D_RenderTarget* bottomScreen[2]; -static int doubleBuffer = 0; +static C3D_RenderTarget* topScreen; +static C3D_RenderTarget* bottomScreen; static bool frameStarted = false; static C3D_RenderTarget* upscaleBuffer; @@ -115,28 +115,26 @@ static bool _initGpu(void) { } if (gfxIsWide()) { - topScreen[0] = C3D_RenderTargetCreate(240, 800, GPU_RB_RGB8, 0); - topScreen[1] = C3D_RenderTargetCreate(240, 800, GPU_RB_RGB8, 0); + topScreen = C3D_RenderTargetCreate(240, 800, GPU_RB_RGB8, 0); } else { - topScreen[0] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); - topScreen[1] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); + topScreen = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); } - bottomScreen[0] = C3D_RenderTargetCreate(240, 320, GPU_RB_RGB8, 0); - bottomScreen[1] = C3D_RenderTargetCreate(240, 320, GPU_RB_RGB8, 0); - if (!topScreen[0] || !topScreen[1] || !bottomScreen[0] || !bottomScreen[1]) { + bottomScreen = C3D_RenderTargetCreate(240, 320, GPU_RB_RGB8, 0); + if (!topScreen || !bottomScreen) { return false; } C3D_FrameBegin(0); - C3D_FrameDrawOn(bottomScreen[0]); - C3D_RenderTargetClear(bottomScreen[0], C3D_CLEAR_COLOR, 0, 0); - C3D_FrameDrawOn(topScreen[0]); - C3D_RenderTargetClear(topScreen[0], C3D_CLEAR_COLOR, 0, 0); - C3D_RenderTargetSetOutput(topScreen[0], GFX_TOP, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); - C3D_RenderTargetSetOutput(bottomScreen[0], GFX_BOTTOM, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); + C3D_FrameDrawOn(bottomScreen); + C3D_RenderTargetClear(bottomScreen, C3D_CLEAR_COLOR, 0, 0); + C3D_FrameDrawOn(topScreen); + C3D_RenderTargetClear(topScreen, C3D_CLEAR_COLOR, 0, 0); + C3D_RenderTargetSetOutput(topScreen, GFX_TOP, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); + C3D_RenderTargetSetOutput(bottomScreen, GFX_BOTTOM, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); C3D_FrameEnd(0); - if (!C3D_TexInitVRAM(&upscaleBufferTex, 512, 512, GPU_RGB8)) { + if (!C3D_TexInitVRAM(&upscaleBufferTex, 1024, 512, GPU_RGB8)) { + __builtin_trap(); return false; } upscaleBuffer = C3D_RenderTargetCreateFromTex(&upscaleBufferTex, GPU_TEXFACE_2D, 0, 0); @@ -164,10 +162,8 @@ static void _cleanup(void) { screenshotBuffer = NULL; } - C3D_RenderTargetDelete(topScreen[0]); - C3D_RenderTargetDelete(topScreen[1]); - C3D_RenderTargetDelete(bottomScreen[0]); - C3D_RenderTargetDelete(bottomScreen[1]); + C3D_RenderTargetDelete(topScreen); + C3D_RenderTargetDelete(bottomScreen); C3D_RenderTargetDelete(upscaleBuffer); C3D_TexDelete(&upscaleBufferTex); C3D_TexDelete(&outputTexture[0]); @@ -216,10 +212,10 @@ static void _drawStart(void) { C3D_FrameBegin(0); ctrStartFrame(); - C3D_FrameDrawOn(bottomScreen[doubleBuffer]); - C3D_RenderTargetClear(bottomScreen[doubleBuffer], C3D_CLEAR_COLOR, 0, 0); - C3D_FrameDrawOn(topScreen[doubleBuffer]); - C3D_RenderTargetClear(topScreen[doubleBuffer], C3D_CLEAR_COLOR, 0, 0); + C3D_FrameDrawOn(bottomScreen); + C3D_RenderTargetClear(bottomScreen, C3D_CLEAR_COLOR, 0, 0); + C3D_FrameDrawOn(topScreen); + C3D_RenderTargetClear(topScreen, C3D_CLEAR_COLOR, 0, 0); } static void _drawEnd(void) { @@ -227,12 +223,10 @@ static void _drawEnd(void) { return; } ctrEndFrame(); - C3D_RenderTargetSetOutput(topScreen[doubleBuffer], GFX_TOP, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); - C3D_RenderTargetSetOutput(bottomScreen[doubleBuffer], GFX_BOTTOM, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); + C3D_RenderTargetSetOutput(topScreen, GFX_TOP, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); + C3D_RenderTargetSetOutput(bottomScreen, GFX_BOTTOM, GFX_LEFT, GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8)); C3D_FrameEnd(0); frameStarted = false; - - doubleBuffer ^= 1; } static int _batteryState(void) { @@ -256,7 +250,7 @@ static int _batteryState(void) { } static void _guiPrepare(void) { - C3D_FrameDrawOn(bottomScreen[doubleBuffer]); + C3D_FrameDrawOn(bottomScreen); ctrSetViewportSize(320, 240, true); } @@ -476,21 +470,33 @@ static u32 _setupTex(int out, bool faded) { static void _drawTex(struct mCore* core, bool faded, bool both) { unsigned screen_w, screen_h; bool isWide = screenMode >= SM_PA_TOP && gfxIsWide(); + + if (filterMode < FM_LINEAR_1x || filterMode > FM_LINEAR_3x) { + // Out-of-range filtering modes are not supported + filterMode = FM_LINEAR_3x; + } + int mult = 1 + filterMode - FM_LINEAR_1x; + switch (screenMode) { case SM_PA_BOTTOM: - C3D_FrameDrawOn(bottomScreen[doubleBuffer]); + C3D_FrameDrawOn(bottomScreen); screen_w = 320; screen_h = 240; break; case SM_PA_TOP: - C3D_FrameDrawOn(topScreen[doubleBuffer]); + C3D_FrameDrawOn(topScreen); screen_w = isWide ? 800 : 400; screen_h = 240; break; default: C3D_FrameDrawOn(upscaleBuffer); - screen_w = 512; - screen_h = 512; + // PICA200 erratum: if viewport X coord exceeds 1023, entire polygon + // is not rendered. If viewport Y coord exceeds 1016, GPU hangs. + // This can not be mitigated by scissor testing. + // C3D_FrameDrawOn sets the viewport dims to the texture's dims, + // thus we must re-set the viewport ourselves. + screen_w = 256 * mult; + screen_h = 256 * mult; break; } int wide = isWide ? 2 : 1; @@ -523,17 +529,13 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { case SM_AF_BOTTOM: case SM_SF_TOP: case SM_SF_BOTTOM: - default: - if (filterMode == FM_LINEAR_1x) { - w = corew; - h = coreh; - } else { - w = corew * 2; - h = coreh * 2; - } + default: { + w = corew * mult; + h = coreh * mult; ctrSetViewportSize(screen_w, screen_h, false); break; } + } uint32_t color = _setupTex(activeOutputTexture, faded); ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0); @@ -549,10 +551,10 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { coreh = h; screen_h = 240; if (screenMode < SM_PA_TOP) { - C3D_FrameDrawOn(bottomScreen[doubleBuffer]); + C3D_FrameDrawOn(bottomScreen); screen_w = 320; } else { - C3D_FrameDrawOn(topScreen[doubleBuffer]); + C3D_FrameDrawOn(topScreen); screen_w = isWide ? 800 : 400; } ctrSetViewportSize(screen_w, screen_h, true); @@ -979,13 +981,14 @@ int main(int argc, char* argv[]) { .title = "Filtering", .data = GUI_V_S("filterMode"), .submenu = 0, - .state = FM_LINEAR_2x, + .state = FM_LINEAR_3x, .validStates = (const char*[]) { NULL, // Disable choosing nearest neighbor; it always looks bad "Bilinear (smoother)", "Bilinear (pixelated)", + "Bilinear (ultrasharp)", }, - .nStates = 3 + .nStates = 4 }, { .title = "Screen darkening", From 369e6a03f4b09b3585a4923dd682faa34e0bbf67 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sun, 17 Sep 2023 18:20:47 +0200 Subject: [PATCH 079/336] Fix menu bug that allowed the selection of invalid states when wrap=true --- src/util/gui/menu.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/util/gui/menu.c b/src/util/gui/menu.c index 584f2d0d5..f0c624f17 100644 --- a/src/util/gui/menu.c +++ b/src/util/gui/menu.c @@ -18,30 +18,33 @@ DEFINE_VECTOR(GUIMenuItemList, struct GUIMenuItem); DEFINE_VECTOR(GUIMenuSavedList, struct GUIMenuSavedState); void _itemNext(struct GUIMenuItem* item, bool wrap) { - if (item->state < item->nStates - 1) { + if (wrap || item->state < item->nStates - 1) { unsigned oldState = item->state; do { ++item->state; + if (item->state >= item->nStates) { + item->state -= item->nStates; + } } while (!item->validStates[item->state] && item->state < item->nStates - 1); if (!item->validStates[item->state]) { item->state = oldState; } - } else if (wrap) { - item->state = 0; } } void _itemPrev(struct GUIMenuItem* item, bool wrap) { - if (item->state > 0) { + if (wrap || item->state > 0) { unsigned oldState = item->state; do { - --item->state; + if (item->state > 0) { + --item->state; + } else { + item->state = item->nStates - 1; + } } while (!item->validStates[item->state] && item->state > 0); if (!item->validStates[item->state]) { item->state = oldState; } - } else if (wrap) { - item->state = item->nStates - 1; } } From d8ab5529a700cdf2ec5dd09cab580180d53fe717 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Mar 2024 21:39:45 -0700 Subject: [PATCH 080/336] GB: Fix type coercion --- src/gb/gb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index 958312524..b3bb62a80 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -106,7 +106,7 @@ static void GBDeinit(struct mCPUComponent* component) { bool GBLoadGBX(struct GBXMetadata* metadata, struct VFile* vf) { uint8_t footer[16]; - if (vf->seek(vf, -sizeof(footer), SEEK_END) < 0) { + if (vf->seek(vf, -(off_t) sizeof(footer), SEEK_END) < 0) { return false; } if (vf->read(vf, footer, sizeof(footer)) < (ssize_t) sizeof(footer)) { @@ -1100,7 +1100,7 @@ bool GBIsROM(struct VFile* vf) { } uint8_t footer[16]; - vf->seek(vf, -sizeof(footer), SEEK_END); + vf->seek(vf, -(off_t) sizeof(footer), SEEK_END); if (vf->read(vf, footer, sizeof(footer)) < (ssize_t) sizeof(footer)) { return false; } From c8c9fcb665271054e8ed9a87f555c7b37d64e39c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 12 Mar 2024 17:46:25 -0700 Subject: [PATCH 081/336] SDL: Use SDL_GameControllerRumble instead of SDL_JoystickRumble if available --- src/platform/sdl/sdl-events.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index a675ff2c0..41783b3c3 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -665,13 +665,22 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, #if SDL_VERSION_ATLEAST(2, 0, 0) static void _mSDLSetRumble(struct mRumble* rumble, int enable) { struct mSDLRumble* sdlRumble = (struct mSDLRumble*) rumble; - if (!sdlRumble->p->joystick -#if !SDL_VERSION_ATLEAST(2, 0, 9) - || !sdlRumble->p->joystick->haptic || !SDL_HapticRumbleSupported(sdlRumble->p->joystick->haptic) -#endif - ) { + if (!sdlRumble->p->joystick) { return; } + +#if !SDL_VERSION_ATLEAST(2, 0, 9) + if (!sdlRumble->p->joystick->haptic || !SDL_HapticRumbleSupported(sdlRumble->p->joystick->haptic)) { + return; + } +#endif + +#if SDL_VERSION_ATLEAST(2, 0, 18) + if (!sdlRumble->p->joystick->controller || !SDL_GameControllerHasRumble(sdlRumble->p->joystick->controller)) { + return; + } +#endif + int8_t originalLevel = sdlRumble->level; sdlRumble->level += enable; if (CircleBufferSize(&sdlRumble->history) == RUMBLE_PWM) { @@ -689,7 +698,11 @@ static void _mSDLSetRumble(struct mRumble* rumble, int enable) { } sdlRumble->activeLevel = activeLevel; #if SDL_VERSION_ATLEAST(2, 0, 9) - SDL_JoystickRumble(sdlRumble->p->joystick->joystick, activeLevel * 0xFFFF, activeLevel * 0xFFFF, 500); + if (sdlRumble->p->joystick->controller) { + SDL_GameControllerRumble(sdlRumble->p->joystick->controller, activeLevel * 0xFFFF, activeLevel * 0xFFFF, 500); + } else { + SDL_JoystickRumble(sdlRumble->p->joystick->joystick, activeLevel * 0xFFFF, activeLevel * 0xFFFF, 500); + } #else if (sdlRumble->activeLevel > 0.5 / RUMBLE_STEPS) { SDL_HapticRumbleStop(sdlRumble->p->joystick->haptic); From 4fdadc585d2f5d7e389b8b23f737ef13f1c99852 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Mar 2024 19:53:41 -0700 Subject: [PATCH 082/336] GB Audio: Fix audio envelope timing resetting too often (fixes #3164) --- CHANGES | 1 + .../nrx2_speed_change/xbaseline_0000.png | Bin 1388 -> 1193 bytes .../nrx2_speed_change/xbaseline_0000.png | Bin 1402 -> 1201 bytes src/gb/audio.c | 27 +++++++++++------- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index d850f2002..efb7d494e 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ Features: - New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81 - Debugger: Add range watchpoints Emulation fixes: + - GB Audio: Fix audio envelope timing resetting too often (fixes mgba.io/i/3164) - GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501) - GB Serialize: Add missing Pocket Cam state to savestates - GB Video: Implement DMG-style sprite ordering diff --git a/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_1/nrx2_speed_change/xbaseline_0000.png index 0032b919f1aaef5acc9573be68705c0633b9bf45..e541e5c0ba570a3e33559ffc29e4b643a51c3c73 100644 GIT binary patch literal 1193 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|QHer;B4q#hkZu1B)Ij2)I1G zGVen9ly#nVD`bV)QW`sX=YF>fQeM_O;kJNUk!CbU;{ETsKrC?RK-v6W&HF{`wjT?4 zR9gGGBJHw!(&@(r*}r;kL~XjUea`E*lbkxQe_i`{rmwuyjqiW!_Ag%<&GE2ocVxe2 z=5OtdU(?zRzvX6gD=@k_tG|2QecN)a`yNj#ka0iLoAv$Xj8D4BU#~^%`PAQ&zWTqA&HMZNpTzvXaFb`-OXmlm^fa>{Pd3f2l3rn7yvU^Puyt*q{iO$= zeXqHv`2_w9DZa?iy*+pL{rCP~3x93id@;IoE1S{rT(LatkxJ7T@-=UUhfVw&UHJ_l?5l@0=k3FN~9eE`1C0%@xR;^KVZP z;|uFA`gisAgzn3~{iW#3{#EbIf4G)Ev@N-IaK~<*hsC7@AFo^f+F11}q4d!6R}WPG z32oVP&!(gE;YQvQ$G7VIYW(%b&}*Oac~M@ULno|e{61(rNq4Pg=I-lrwx`S$f2=xf z$JMVu@3OpuyY9+C?U!epXGqB1Zm5Yly-0q=az3%;|0^$kJ3Y0kJZsZZQ`Ox3t8l%x zr3Uxs#&sUhi;D7>UBhP_5tA=>8o1K7c~bc2O{ZLZnw_ox3pkUTl<+LSGO zLnoKU^-Pa=6m~tBeYNlnS5UAVeOcpoEv(AO>io%Bf%(Q3YU_?H{Ip`tBD<-ng}U8! zOYY4s&x@#v$T{+0HTVS|N)4j)_h&}7~}l3@QPfcfnQP!Z(m>gTe~DWM4f DU*lx* literal 1388 zcmdUv?N<^86vk;4^a8lrI-w4A&6m^4Nz+I{GZQu6h}2Wl&}4W{h%|J)fRRXyEmKOQQc@iFPQo!3MuI2}|BQXO&pr2kxaapgA8rK>8v|MAwhjOQ zKw|e{lAOK4SygL3b1FbRuLb~C2gYI|QVKY;H&ul#UZ0o!afI7X4WbrB_ni-OKXwiv zSog{nuux6Jt2W37gD6^iwg&%1n60JBJKp{CIR7tNKs6O-hXL|jMED8Z0j$LnG4b^sdS4Ef+3rd3q;+xBd{d$V(ICH&Wtxge|ueP zAdsD_diOxqL+7hf+;G7)O~u@E}wyB zfb2EmKeyxaS zZM#Z26=Ay4+06r`<&;MoDi5GjqG$2BSS6~1v{=2v6LRTeA#a&enRPn=yfvhl@D|nK zo8*Dv%0i}M5}Q|ySwH2&L)kL;X3SIpv;0hyBW?+59A$QVBSp#)B_JTB9h=s#P|URq zE~7Z_f|~5I%CjNM`ET^%s(b&I3lN7QOdjIKI>YqArGW{N%AVPb8!Em7%^464zPL3o zgj{%5d*wnD&21=Ca_#PJHTvrAj3{;04}aUarBZZ)OkblJQ{GtF&=sjm2CaW2MQ0Cl7UC^SKyE&JB$5PA zpz>tlhd_S1KE7z+J~X=9IVj(UQcg<>+Nrf7;vVr$W3v|LS#p_)ZQ`q{BHCN&F*J_^ z4*GpvE7?1){^$L_T&hb~qG0eV_R!kGZWN5maD9%ldPr8KUtC)c(iie|8ZRZ?=wi(^ z7$I1LT^f+4#iyDw%3jPJ?HeUnLWry`9(0<-BmJ4TDeR8cbLN#3#BbMJ>$sV`=t}2r zcKHaM6N2}N@+7a_4Yp7iC)u;^a=qPr=HFj2qQNSJ_D%)UPm??{o~2&4khckPmjnl6 z_4CIbecEN{m#Vt_P6kOIfC-)`fp(d1)1EkH4Hu---+XSi}S?G3TQZVo{`lh^CaO~>;2Ucf4UI`8oG4x^`n*p{CA)Q9yH zM6i76==L8KeCc=I6OnY;Z?e(;%u~k^!9lRE+`v!>upCJL|E>GNckJxus7M#&%U?7$ L3X2i!%`E*7PTjq& diff --git a/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/xbaseline_0000.png b/cinema/gb/samesuite/apu/channel_2/nrx2_speed_change/xbaseline_0000.png index 2804b6f3a5f9ecfc563b1f9f493e383099380a35..5173a31fdeba2b6065b2a4d660eecb5cf72d6bd5 100644 GIT binary patch literal 1201 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|QHir;B4q#hkZuFHU--AmCb< zwf{oBPu=9&1>3q?8yqBBUt9X;7CU!@PnZ`W`FyW^-(gpo;}7@FpK(6gIe4BYN0S$S z`Io(qBYovL)=qt0+WEpf>9k7Wyq$X)h+lg}(>=pIk1x=O^1egYw;0?=S5>vF6ssx~s7zwR2v-zQ4Kq+r_$9LHEB4 zw!QsPcy8|VpB)zGjklaV^?dC@&GUCI&R%fo@a*G{|NTFe{oY>Y(z^9u^NlUyI-VUn z>6HX@_~Q7reBW|Qv*vhSd-&~R$d{D|PclkN#$1nyO9=nZ{LAHA(I2;hs;;_a2fzAW zlTPz-4K`eJk>RxU^Lgi=d)Lm`xA*VywZZr1m%e@wSNn3s&R>lmpC7#Q?{(Fy2ak5o z>1O{`zh_Nw{+IiQ`iu2+)|yF0XQn@0d-Yod*lEY#FXLUX&b+XDU%AcCUzXedyV;g* zu&R5ZA6)4hbm{i#4Uaim9x0wbvS9vVbABghZyD*A%6eZn8g+WFeUbi3I5|#g+8oYi z@$1WXzYr^$ofzrH)7JarmDLaJ4}W*RIPK?ERlW1nx=*LS?2lvLELSsa;_rin!FR&{ z)_qW#|6={++dO={x`w46{C*voF}+PS{m_G>UyWZs_;r@;2M@FH4%Nveb&~mp%w^Yu z*;hYa*}U}Ym4mN%&OBIGGpF+3Z^5WPo4#T`;gc=bt|_sHbk3ouQiAx$jwC z%X9WKdqndRq(Iiwd}ar0vo-pi{`Ib&L{T# z+WEA}zxUnYkDHj1+1vSf@2n-CPgiuS=9PnV%!}Q!Wu8^UoP*C(cK)9~_1>cRC&GVA zt7acuxKQ<5t9xqftK>+b=}{NYUwQuQDsOjuoSI>U=3ft4nQL*U?$}DqIJlHqdlt|* z$ql>f{#Zt;CC}euQupOQ<8$K~RuzsQxBp4jDg3cq=25~13ke-Qw(jPGLz8(f{=hE# UH?f-xJwQc~r>mdKI;Vst0G@ehoB#j- literal 1402 zcmdUv`BTyf0L9tb$lR2*3u8hmrghycz|>qt%_}nvODanikIalvL|YM9(2{1WwLFHz z`^Yj+OhnyAGa`?~V@<@PG+{HZ(2(ORNgiu|#{Tf$n|VKd=Kb*Qp2m5b7{iP~AdrdA z3D1D_EM8Z-(S~&g4eN(NpiOQ*o^EI9`SS&0nsV<}PoKW8?rV>P%A=ZHlyk|)%)Z}) z&1o({8}*n&;bo*dn9pA=wk@*LFs9YRd~a^eUChbe#%O86Xyc_*MsAR>d)XaXH#+Xn z>IK@O9j+&e>eoiJ#CfyL4N7p-=l}ft0dn~Ay&Ti zqBAkB6Ibk{>Y2RE_}QD@YbEmOxFYi}OQ~b!A|q+XLais~0L>VzGD; z>1Ye9M)fenxQ)7==oJB*Fj2<$H=#(CPiDcxU6HV{SdUxBH}Y)gqm8;_HNa^GHA>GncBMS1yolbu#EsF`|e@KLs6%?lis zw!=xiGHj+Hj6ua;grMviYyc#XgRvs9tDe|DUfWQPC{al`nlZZh|Ml4c(E;` zY{pKf&N%apNk$tlXD-Dyz_nIPwc@IIFmKCj96!@=llcMyo-R%6y`o|-xzN4pyvZkn zQ}o;B{F$^QYQ$iSii diff --git a/src/gb/audio.c b/src/gb/audio.c index 996fce66d..cf5445e15 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -33,10 +33,10 @@ static void _writeDuty(struct GBAudioEnvelope* envelope, uint8_t value); static bool _writeEnvelope(struct GBAudioEnvelope* envelope, uint8_t value, enum GBAudioStyle style); static void _resetSweep(struct GBAudioSweep* sweep); -static bool _resetEnvelope(struct GBAudioEnvelope* sweep); +static bool _resetEnvelope(struct GBAudioEnvelope* sweep, enum GBAudioStyle style); static void _updateEnvelope(struct GBAudioEnvelope* envelope); -static void _updateEnvelopeDead(struct GBAudioEnvelope* envelope); +static void _updateEnvelopeDead(struct GBAudioEnvelope* envelope, enum GBAudioStyle style); static bool _updateSweep(struct GBAudioSquareChannel* sweep, bool initial); static void _updateSquareSample(struct GBAudioSquareChannel* ch); @@ -192,7 +192,7 @@ void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) { } } if (GBAudioRegisterControlIsRestart(value << 8)) { - audio->playingCh1 = _resetEnvelope(&audio->ch1.envelope); + audio->playingCh1 = _resetEnvelope(&audio->ch1.envelope, audio->style); audio->ch1.sweep.realFrequency = audio->ch1.control.frequency; _resetSweep(&audio->ch1.sweep); if (audio->playingCh1 && audio->ch1.sweep.shift) { @@ -243,7 +243,7 @@ void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) { } } if (GBAudioRegisterControlIsRestart(value << 8)) { - audio->playingCh2 = _resetEnvelope(&audio->ch2.envelope); + audio->playingCh2 = _resetEnvelope(&audio->ch2.envelope, audio->style); if (!audio->ch2.control.length) { audio->ch2.control.length = 64; @@ -383,7 +383,7 @@ void GBAudioWriteNR44(struct GBAudio* audio, uint8_t value) { } } if (GBAudioRegisterNoiseControlIsRestart(value)) { - audio->playingCh4 = _resetEnvelope(&audio->ch4.envelope); + audio->playingCh4 = _resetEnvelope(&audio->ch4.envelope, audio->style); audio->ch4.lfsr = 0; if (!audio->ch4.length) { @@ -877,9 +877,10 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { mTimingSchedule(timing, &audio->sampleEvent, audio->sampleInterval * audio->timingFactor - cyclesLate); } -bool _resetEnvelope(struct GBAudioEnvelope* envelope) { +bool _resetEnvelope(struct GBAudioEnvelope* envelope, enum GBAudioStyle style) { envelope->currentVolume = envelope->initialVolume; - _updateEnvelopeDead(envelope); + envelope->nextStep = envelope->stepTime; + _updateEnvelopeDead(envelope, style); return envelope->initialVolume || envelope->direction; } @@ -932,7 +933,7 @@ bool _writeEnvelope(struct GBAudioEnvelope* envelope, uint8_t value, enum GBAudi } envelope->currentVolume &= 0xF; } - _updateEnvelopeDead(envelope); + _updateEnvelopeDead(envelope, style); return envelope->initialVolume || envelope->direction; } @@ -968,16 +969,20 @@ static void _updateEnvelope(struct GBAudioEnvelope* envelope) { } } -static void _updateEnvelopeDead(struct GBAudioEnvelope* envelope) { +static void _updateEnvelopeDead(struct GBAudioEnvelope* envelope, enum GBAudioStyle style) { if (!envelope->stepTime) { envelope->dead = envelope->currentVolume ? 1 : 2; } else if (!envelope->direction && !envelope->currentVolume) { envelope->dead = 2; } else if (envelope->direction && envelope->currentVolume == 0xF) { envelope->dead = 1; - } else { + } else if (envelope->dead) { + // TODO: Figure out if this happens on DMG/CGB or just AGB + // TODO: Figure out the exact circumstances that lead to reloading the step + if (style == GB_AUDIO_GBA) { + envelope->nextStep = envelope->stepTime; + } envelope->dead = 0; - envelope->nextStep = envelope->stepTime; } } From 776d52a2c6000bb690fc2f81bbb86a5958c2b9d3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 18 Mar 2024 23:17:42 -0700 Subject: [PATCH 083/336] Scripting: Export new image masking function --- include/mgba-util/image.h | 1 + res/scripts/color-mask.lua | 34 +++++++++++++ res/scripts/logo-bg.png | Bin 0 -> 1268 bytes res/scripts/logo-bounce.lua | 39 ++++++++++----- res/scripts/logo-fg.png | Bin 0 -> 888 bytes res/scripts/wheel.png | Bin 0 -> 6931 bytes src/script/image.c | 8 ++++ src/util/image.c | 90 ++++++++++++++++++++++++++++++---- src/util/test/image.c | 93 ++++++++++++++++++++++++++++++++++++ 9 files changed, 246 insertions(+), 19 deletions(-) create mode 100644 res/scripts/color-mask.lua create mode 100644 res/scripts/logo-bg.png create mode 100644 res/scripts/logo-fg.png create mode 100644 res/scripts/wheel.png diff --git a/include/mgba-util/image.h b/include/mgba-util/image.h index 31514687d..b86b2135a 100644 --- a/include/mgba-util/image.h +++ b/include/mgba-util/image.h @@ -138,6 +138,7 @@ void mPainterInit(struct mPainter*, struct mImage* backing); void mPainterDrawRectangle(struct mPainter*, int x, int y, int width, int height); void mPainterDrawLine(struct mPainter*, int x1, int y1, int x2, int y2); void mPainterDrawCircle(struct mPainter*, int x, int y, int diameter); +void mPainterDrawMask(struct mPainter*, const struct mImage* mask, int x, int y); uint32_t mColorConvert(uint32_t color, enum mColorFormat from, enum mColorFormat to); uint32_t mImageColorConvert(uint32_t color, const struct mImage* from, enum mColorFormat to); diff --git a/res/scripts/color-mask.lua b/res/scripts/color-mask.lua new file mode 100644 index 000000000..25a51f805 --- /dev/null +++ b/res/scripts/color-mask.lua @@ -0,0 +1,34 @@ +local state = {} +state.wheel = image.load(script.dir .. "/wheel.png") +state.overlay = canvas:newLayer(state.wheel.width, state.wheel.height) +state.painter = image.newPainter(state.overlay.image) +state.phase = 0 +state.speed = 0.01 +state.painter:setFill(true) +state.painter:setStrokeWidth(0) + +function state.update() + local r = math.fmod(state.phase * 3, math.pi * 2) + local g = math.fmod(state.phase * 5, math.pi * 2) + local b = math.fmod(state.phase * 7, math.pi * 2) + local color = 0xFF000000 + color = color | math.floor((math.sin(r) + 1) * 127.5) << 16 + color = color | math.floor((math.sin(g) + 1) * 127.5) << 8 + color = color | math.floor((math.sin(b) + 1) * 127.5) + + -- Clear image + state.painter:setBlend(false) + state.painter:setFillColor(0) + state.painter:drawRectangle(0, 0, state.wheel.width, state.wheel.height) + -- Draw mask + state.painter:setBlend(true) + state.painter:setFillColor(color | 0xFF000000) + state.painter:drawMask(state.wheel, 0, 0) + + state.overlay:update() + state.phase = math.fmod(state.phase + state.speed, math.pi * 2 * 3 * 5 * 7) +end + +callbacks:add("frame", state.update) + + diff --git a/res/scripts/logo-bg.png b/res/scripts/logo-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..908e410d972802b97a3819d83beddf167b1279ef GIT binary patch literal 1268 zcmV*Aei51Z+QvjE8`~)(hwY+{q2LXAWMze3{P9PD)ElsjaPL z$BrG;)YRbj`!lB+Kt<9%PV+xbgY5@?0e-UsXh?bs=*b+2Mx*%ser9H705DAx(=?f# zoyF~TQ(axn-o1MX1OfyC0g8%>R=ejPz>mNf@EwWF=a!^8Wl>L0kBW*UFkx^d%%!r^eXCDYZNY!@W`B&kV~TN0Uu zr2W}exN_x+3JVJrkH?qz!{M;Hy1LZT(xSS$I_2l*F9I8eA|&lS=mDVE_IlJsT@@Nl-MBS(%1(CFx>Ex>FF27@XnC|GIA14#oJzBx$^ z4iXh&nI-f4*+Or%#{a zcDorJ9evT%-N5VockNX=fN-{%(P(r@yB?)Jc5G~HHPceU~1 z?b;Rhdc86XaYWtvezzMy7c{_Lx*NIZQ8W#AmuX4 zvUL6WbvuAVl7ediOqnYb3N^L0wG9LUfw*a!vMej-ziL^QB9Vw4z)4A;8d~~rU#m(d zCnuY3-@g4>C={yc@9#H;hliP-p2p+xP*G7qYilce_Uu{hdgCOXzvUYRn65J51K>ko zKVYt5jb0M(^iN&}V7l^wcY*hTcSyXO4PXwK23}3}( canvas:screenWidth() - state.logo.width then - state.x = (canvas:screenWidth() - state.logo.width) * 2 - state.x + if state.x > canvas:screenWidth() - state.logo_fg.width then + state.x = (canvas:screenWidth() - state.logo_fg.width) * 2 - state.x state.direction = state.direction ~ 1 + state.recolor() end else state.x = state.x - 1 if state.x < 0 then state.x = -state.x state.direction = state.direction ~ 1 + state.recolor() end end if state.direction & 2 == 2 then state.y = state.y + 1 - if state.y > canvas:screenHeight() - state.logo.height then - state.y = (canvas:screenHeight() - state.logo.height) * 2 - state.y + if state.y > canvas:screenHeight() - state.logo_fg.height then + state.y = (canvas:screenHeight() - state.logo_fg.height) * 2 - state.y state.direction = state.direction ~ 2 + state.recolor() end else state.y = state.y - 1 if state.y < 0 then state.y = -state.y state.direction = state.direction ~ 2 + state.recolor() end end state.overlay:setPosition(math.floor(state.x), math.floor(state.y)) end +state.recolor() callbacks:add("frame", state.update) diff --git a/res/scripts/logo-fg.png b/res/scripts/logo-fg.png new file mode 100644 index 0000000000000000000000000000000000000000..c401fb0112f85b8018412906cd23cc7f2abf03ae GIT binary patch literal 888 zcmV-;1Bd*HP)zp&^&OQBManId*?R9=fV|_W9tO0wQ=ft^+E>Z2SosT)UVXp>Vhc1y$0c8 z8?FAF0l8Bhl?Qk$YIsilNc~H_ULqjsfgu1>eXB0a0_;@Min z1ndCL181s){03nLcSeo_<*@;9yH5XQ09D}k42McXI8WEb-sEjy7!JW zQODMz?p6m9r+?M<5&>@}aUYsrq^NFB6LqXUU>jkRbP@9731C-AuRFb8Ga=vQ>3%$* zR;PhCfK!BYvyJe<^mc=QLsjirx(ht@ifgT6D8o9UsXwo-HPn9fyxuVmmUczd?htD* z&z2gBigbNmQ$JCs792mj4meGUmys;=Hg%8M9R>SN{Y+i1KASP_V4Z-iYUX!w5w#H3 zhz35ocXI%59;yj)}r7PS}Dt?FrqPaj2eB#qt33})$hU=`3# zNLSAAqq&1B-!`z^e@AzB|CU#9Dz#gxq);*hl!V2jD;ITEqaeo}m%| O0000tXP)c^ONwML97T5Exv@z}rAsLsJF%=pp1t0!}1g79q!LXeJWSO@KoHiCIBp$`brO@V05Feh>Z=;Qto9 zKSI||5E`iUz!5ks8-?hd3X%L0-~yFF;LIfCbOJs|z)S)r5#SISfQjZxCWuV=P4HHO z{|NXGf%goQcPW^BpauvWelQBr-iAmn(%Qz=58MadVk#kL5O5A5vk2&IfDvYZCVp-Z zM5Pvh@^*m#H28Oew;a~5g=4gKl7NT9w?`q`8xYCAjli=NhcYt>nWy2I)@Y)_j2b8D z{UC@+8DJ_!?4c%@0Dm2L_kh0?cp7@D>NBY|)3u`z4F^Q>T3{7$BG3)I$#H}%AmBVg z4$cIQ4Vw75Y8;}H0VJE2^5Vy@gLgOhH$(qZFhRmNU=I#|KMK)MK_qX`aG+l+97@PV z1kBextpRw#0^r17tF8s0k_DiW4Wjz%7VwsW_wUfPR;gBW6SruehsbTK02Tui^>cwP z;Ip{ghs)Inrr@GFL2gQRbdDZJvlaj77fdEF~O7uPaGtxf;GY98lXwaB7U>eL3|IyQgBXC|6f9K z3zFMMA!-?(pMYG_&^`i(3lQ9e;6eoD#xqC*$fS|n6egT3FlB{DB;1^cf98QZ7sOrQ zEC8pZnmvK!$D<^aF2x07zs3CLw$EjzK+|pz$&k%mc*XAbtSu+4cXC zJTVGU1E6Q941jqbvi0gn?A{96Mc&r&hHg!fsX5*eE_BUD*5kj-%RGJxb6YK{kZhk*Az@aCxZ zYmltj$2HNwK=u)MEN(PmnPr-@QfKvO=k{1<@d;(A4W^ng==d=3ZUpZ=a2((vd1>E- zNUm@Af_m}z79OVJgpBQ33j6uNBn%>o)t)p1(0vuex!^nrWgNyO%YCHGCzACC z3SETUN{tH#0ThKN2_PFtae(6R>;~2W&!JX-yxs01cL4_j?*O)~Qh5Sb>hnbfba z7=A7w?g#N{aCSfmhw{jUD3l=f0PtCA+)R~n6GUm+C`}VZbDuu{BJhNUC>ZLZd%&T< zNvJWexK{EFAf>h6)?PzZ%}bKs1*p=47kdOFVp3Ya1h)p1ITVk-#-nVsf08tO{CjCF zfzYkY85+bFhXWuq;V%I@fxpz+Nsv6l(K8g<&k2|>z*`7iGbCNglpAS=^>#VXldig4 zBt2#}$&JB+U0$32hl)6b%b)c4{sncYcw9vxS z3SbuS9(_J~17FqJX~@%|S_^rRb3z;3Cj-5)8&B)8nR5+66*p=o?jOKc`oMF5jUBFy z8W6oA6)?qx2M30ZR_H*r-o#~rDSB=Ua5OL}<*qK! zEz6LlKL@^;@|_7^@WX>S0Z+YPSU;Sf0h&q?Jy0j9d}OBaqx zoBP)|R|BVN=;}x5tDz!)^k%%X@%uY~jk?74uDwK1!=)DUgw%A7 z9_##C4L$<=p$~XBPUm*<-yV3@X9O@U&tlX;OmuNI!)Lw^y}dALlFAb%K&fQ- z@{z!0w7yEp1-g-xsNxae4lc6=po$%+?m)G%9Xs2|`Hch#Juckq!iVzAN;WOFsgGuq zVqTb*(`_22Dhig9PlnmE;n-tg$`mN;fy_z;Hg1H~tKqT7VC72KRG+_dy>7~irD%U4 z+Lx%s4Cw?Tx{+n`@o%Lvu(!Ui16wrb*XpKcy6~_A2P8q{kZ*xa9i*}Cf@lZuwJEUw zJeYUBf~Q=z|0W3F`RC!M%V5ci@bZncV@xH~9mbI6@#vbNHzo}bMP7GGHG25ishtSX z!|J9#@4)R2IB|&bhCQes_h?T`@z^y&^`>@T4Lv8c_J?bB!*yd|nQm7KB#D{}w>t%( zEE-4-K3)Xe@SzTb$So=LJS)i1D>Ka<)+Z1g5wC z7u_21J_|_w>EJ~DMSdqkG%d-fu4I6xlF*dZoz<My#OWyD3$6dWKDECuR*@q+@q(*j8B>dVW;QZk${U=d#(^~AMb;kh81CIfuLpv3s$+jje zNHL`2!s{+{J0}Cj4qxeyq|m&jo{Ta{lBEHpj_sXIw1tY!;v1@Kp-SPd{p@1hrrf2c zwei?US3fk^MYdj=MHBUQDn#S*`iS}sMs--o9`c7*3pE^(t#>C&)c3eaZq~8@6oYAO zM?w^Wm!%m?b2iqy_pSSf#^|2eFsFl1(}h~ZJ~U{de$u_ymF6B=M|!NCYa~0surS`I7522Pnn&gsK4&RV_Zx6bbA^JuF zM6Hei_5&+W1C)6rA%TfZ;&vWk+Au@(rw#C_Iq=H*e7#DkJy{=5WdayZMlBva z|4$tVksCnOH2pQJlQC)&wQ5-Rv71e79CiV0*#f(Ev~Cksv3so3#?WH2uhD_Y4Pa-U zX|T2)T7CcDR#Jrut64ql0(kB@*tM%TL|MnsQo8uNIu)XACV&F+4S56w{X~!P7{Ty_ z1W`?~RI_M{_=y5b?<}p0p8(SKPK9W5UQJ}vMnyc6if1D;)_@ z2x|k7X`4MKspzDkkD{aaOIX61VF(<)VFTQ9OY6U{motkN%CWKb+D_F(F9gt+bs9*T z*P4P&+RMDmbzDbZ(?P;eMXKybh}Oo9>nvUUibZfm zXErWl8Q&Ry6&Fz=?_KcSXZdbk$Yxc7dq0uD1R9ESf0Kn3>M61$5@V4eke(7W#db9$MC^vXbHxI<~Qmg)HPo zZlqFlv6ybc?zjUkzBsZdwm{e3$*F}hEE!r;RS~;852AaOT7Dv=^)>iIweD;yTlqR) z=Muiki>zQA_MT_8)ONs*o&Fju=BlkA{TP#Azs=f{ln&xVFejC7>d785{pd{^? z*U(QtxAJ2?&Kj;mMJUcPHXu>qu)hPG`7(U>N5z`3dJ>KMN}ha{Wtbx&?+##9r-t2g zbO3>IHCQg;RNLBd(^_*=ob>iZN4)^J9q8gv)Qr|sQS-?TiZq=SU<;~?^BC|5+QMDYgk4wXP_3;7VMJA5>!1E z&?~L^${2R9KZIY5DJZ4A3el5JquF^Tgr~CxxiSG&#YHw&W!0lxjcw7)J_h(o`${|C z$YXjMql=;=z)4?4(XGRjW=LBirmYTOWk*L!12{}|&36TGcgBE~O@a$?k&V3;l7cpl z%Xw=86|DTQ_LcTPQ~;N}Qw_$VLN>-@fBGOj75vn;OgaUmd-uQ_eZbS5Hy>>PqCe_d z5Ww;f*2OmqvgIlcwMG=|B!J5LsZA!|jQGDTo?*~4c@}2Rh=>Pj+-z6YH1X4iNZLWYZn05wmN1tM@qf-MS-JBtn zaea5fUKCVuG(2e=eE134ss1_vwYkS+!!1ogg_RjX1@8ctV2%nhN#Eim()TN|Y|bc! z+FU0|mH|9ig%u-Vr=bQ!n;iA#ZK#HDvu>|-p;gnBefy@As!A_v-Tm~0j_sHA6CC0+ z4Y)LRc?T6{>J-%CIWI#|GVEF8ncF>e|hJwFAQtNYO#hR5wz zLv5EXQPKUTl5M+J(>AZRq7L4GaWP|gM*1T|3t@C4OHXSF#)4Q1Vy-#ld6Fiwfn(Y; ztQ>Jn9?8J)YN@>?4j34veGzy|pNkK}+vaVgX`-Y^=}HUziYn(Jc~dRaYZm{A+0tB< zrbjBjXOe4D9w( zpOE3GES-U7s<9(7DrCo7+U(lJKs2r_Q99cPQI#rJQsR2{=xc2sIS`o#j-4I)iMW7R z0^TilZPQ9l(rQWCPHG~yYBjPMctg{%M?I;k@=vf`Yn=Mmw(9dW!(~j$RHWQ`zGD9b zkDD5%-u6y+FJ^@Zz}cc}dZ_~5HQ+teEM<`al%)5<0#tm4PJ9;;hvwZeB5$Lmb1i=* zEZn96B{Bo_I38Eyvl|E4GO_?lhX^7~hPMU8BJh6Ky5>m&DbL(MCzfL^vXhYGGr&x< z$4q?%ksF$5UW>;S_-ts~eBq9S$XTZ)@<+h`1Bgq(d%0P%NmW^-Xc>_cBqsr;1dy=6 zKL?< zliXdf0hFal%i_^6*PE>f7UA(gV*%dtBNL$P5CJ&9i%8yE4&GN4NH(e3B%P#rlAtna zA4`AJF>vR$8K~rXvlYQYN-S#><98z$pnMPkI8R0;c@KDB0kJMks;xC$Y0X#yP)-JI zYyBp)eckX)t0XUHXzb-9`J#G18zCIqreDD{7cSQ53zHRDY3Hw~_ zghAY@NZ%96G_X3bgvC72s$O3uWHBK(%Wv^!L~ilTCik>Uj-3RN#N1gf2-82z0PiyJ z&j)XR^XPsnF!{|81uej1Ti>HzcM$S30=^@!;h9MBWNPvEk>)HZ#A0{5E+DyP4U{ei zcP_X~K)jVJUWRqN%+k$I>-J}HKDz8g@SnJxi^rE^0F9=ICYlHh)m%^eqb5AY3E-au-p9b71O9aI$K_t*7KJE#-c7(-LRJv)3qn@PPw__1BJ5T9 zjY8A})Pobjn*shT@MeL3EcjCtRK9P8DIKDakevj)M!*^ZRuQm@kk#^|g|!$8z6ERm|b6=Jrion#1s}k$+wc_cSWvc`<@f|zhDR;8m{uD`T9(s7n6~c za-wWb6Qz`7$aAEWw@Y)nT}nAS_M0pz>38kA)*VvHv!s-hbv{d5kl^>GQV8 z$ZgqVXOk|8nQWVVx#hlbntL9#6UM4|SzmVYtpg4D1y$iRN7$_t&q5Wi(Wwlk=C?g|mBR7pLm0&U2B!L8$KSf6W*(9woS!vHE7ta1^hY_4f4Yx+b*4La{3K$ zHELMpz1r5iI>83~yg^2%N1n&&Ii5#u8JQqD3^o2UF_!CwSbst-xlkK?GiZ(-{6mW` zBrPRfYZh=3Dl}C^*SbBZRrfY0;#-EM@hw{03A!6NAmRK07NhkrEu*7T%-8MXR6^2?}&Zm5j-F|wvPDP7Gh{-~_U*1evtbJp`|_m<^eWD9Z{+k#u5UC$%8 zjPf|dk{ng1WpDt_$>{V-%W2n=Qp&$cxmI^hp9#YRQIebv*AB%zziG$w$StGj^w=zZ zgQRJnj&9%mm}|biWxTZbF!Ii~NxD}3dV37*yy;qb&)b@`ZiAeXdQBhIZjCoG$f*_C zw)1&pI`4F1P^At^Ne~@{ijFa21n-VM=OIl=+U!pw37}C;G(2g@7D0?cv~Q(WZNQF5 Z{}1R4%vk=CZo2>g002ovPDHLkV1f&Z^~L}I literal 0 HcmV?d00001 diff --git a/src/script/image.c b/src/script/image.c index f056c7d49..7705ebd9a 100644 --- a/src/script/image.c +++ b/src/script/image.c @@ -141,6 +141,7 @@ mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mPainter, setStrokeColor, _mPainterSetStrokeC mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mPainter, drawRectangle, mPainterDrawRectangle, 4, S32, x, S32, y, S32, width, S32, height); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mPainter, drawLine, mPainterDrawLine, 4, S32, x1, S32, y1, S32, x2, S32, y2); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mPainter, drawCircle, mPainterDrawCircle, 3, S32, x, S32, y, S32, diameter); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mPainter, drawMask, mPainterDrawMask, 3, CS(mImage), mask, S32, x, S32, y); mSCRIPT_DEFINE_STRUCT(mPainter) mSCRIPT_DEFINE_CLASS_DOCSTRING( @@ -162,6 +163,13 @@ mSCRIPT_DEFINE_STRUCT(mPainter) mSCRIPT_DEFINE_STRUCT_METHOD(mPainter, drawLine) mSCRIPT_DEFINE_DOCSTRING("Draw a circle with the specified diameter with the given origin at the top-left corner of the bounding box") mSCRIPT_DEFINE_STRUCT_METHOD(mPainter, drawCircle) + mSCRIPT_DEFINE_DOCSTRING( + "Draw a mask image with each color channel multiplied by the current fill color. This can " + "be useful for displaying graphics with dynamic colors. By making a grayscale template " + "image on a transparent background in advance, a script can set the fill color to a desired " + "target color and use this function to draw it into a destination image." + ) + mSCRIPT_DEFINE_STRUCT_METHOD(mPainter, drawMask) mSCRIPT_DEFINE_END; mSCRIPT_DECLARE_STRUCT_METHOD(mScriptPainter, W(mPainter), _get, _mScriptPainterGet, 1, CHARP, name); diff --git a/src/util/image.c b/src/util/image.c index a0fefafe7..f1f1a0fef 100644 --- a/src/util/image.c +++ b/src/util/image.c @@ -42,6 +42,53 @@ memcpy((void*) (DST), &_color, (DEPTH)); \ } while (0); +static uint32_t _mColorMultiply(uint32_t colorA, uint32_t colorB) { + uint32_t color = 0; + + uint32_t a, b; + a = colorA & 0xFF; + b = colorB & 0xFF; + b = a * b; + b /= 0xFF; + if (b > 0xFF) { + color |= 0xFF; + } else { + color |= b; + } + + a = (colorA >> 8) & 0xFF; + b = (colorB >> 8) & 0xFF; + b = a * b; + b /= 0xFF; + if (b > 0xFF) { + color |= 0xFF00; + } else { + color |= b << 8; + } + + a = (colorA >> 16) & 0xFF; + b = (colorB >> 16) & 0xFF; + b = a * b; + b /= 0xFF; + if (b > 0xFF) { + color |= 0xFF0000; + } else { + color |= b << 16; + } + + a = (colorA >> 24) & 0xFF; + b = (colorB >> 24) & 0xFF; + b = a * b; + b /= 0xFF; + if (b > 0xFF) { + color |= 0xFF000000; + } else { + color |= b << 24; + } + + return color; +} + struct mImage* mImageCreate(unsigned width, unsigned height, enum mColorFormat format) { return mImageCreateWithStride(width, height, width, format); } @@ -395,18 +442,18 @@ void mImageSetPaletteEntry(struct mImage* image, unsigned index, uint32_t color) image->palette[index] = color; } -#define COMPOSITE_BOUNDS_INIT \ +#define COMPOSITE_BOUNDS_INIT(SOURCE, DEST) \ struct mRectangle dstRect = { \ .x = 0, \ .y = 0, \ - .width = image->width, \ - .height = image->height \ + .width = (DEST)->width, \ + .height = (DEST)->height \ }; \ struct mRectangle srcRect = { \ .x = x, \ .y = y, \ - .width = source->width, \ - .height = source->height \ + .width = (SOURCE)->width, \ + .height = (SOURCE)->height \ }; \ if (!mRectangleIntersection(&srcRect, &dstRect)) { \ return; \ @@ -436,7 +483,7 @@ void mImageBlit(struct mImage* image, const struct mImage* source, int x, int y) return; } - COMPOSITE_BOUNDS_INIT; + COMPOSITE_BOUNDS_INIT(source, image); for (y = 0; y < srcRect.height; ++y) { uintptr_t srcPixel = (uintptr_t) PIXEL(source, srcStartX, srcStartY + y); @@ -461,7 +508,7 @@ void mImageComposite(struct mImage* image, const struct mImage* source, int x, i return; } - COMPOSITE_BOUNDS_INIT; + COMPOSITE_BOUNDS_INIT(source, image); for (y = 0; y < srcRect.height; ++y) { uintptr_t srcPixel = (uintptr_t) PIXEL(source, srcStartX, srcStartY + y); @@ -498,7 +545,7 @@ void mImageCompositeWithAlpha(struct mImage* image, const struct mImage* source, alpha = 256; } - COMPOSITE_BOUNDS_INIT; + COMPOSITE_BOUNDS_INIT(source, image); int fixedAlpha = alpha * 0x200; @@ -821,6 +868,33 @@ void mPainterDrawCircle(struct mPainter* painter, int x, int y, int diameter) { } } +void mPainterDrawMask(struct mPainter* painter, const struct mImage* mask, int x, int y) { + if (!painter->fill) { + return; + } + + COMPOSITE_BOUNDS_INIT(mask, painter->backing); + + for (y = 0; y < srcRect.height; ++y) { + uintptr_t dstPixel = (uintptr_t) PIXEL(painter->backing, dstStartX, dstStartY + y); + uintptr_t maskPixel = (uintptr_t) PIXEL(mask, srcStartX, srcStartY + y); + for (x = 0; x < srcRect.width; ++x, dstPixel += painter->backing->depth, maskPixel += mask->depth) { + uint32_t color; + GET_PIXEL(color, maskPixel, mask->depth); + color = mColorConvert(color, mask->format, mCOLOR_ARGB8); + color = _mColorMultiply(painter->fillColor, color); + if (painter->blend || painter->fillColor < 0xFF000000) { + uint32_t current; + GET_PIXEL(current, dstPixel, painter->backing->depth); + current = mColorConvert(current, painter->backing->format, mCOLOR_ARGB8); + color = mColorMixARGB8(color, current); + } + color = mColorConvert(color, mCOLOR_ARGB8, painter->backing->format); + PUT_PIXEL(color, dstPixel, painter->backing->depth); + } + } +} + uint32_t mColorConvert(uint32_t color, enum mColorFormat from, enum mColorFormat to) { if (from == to) { return color; diff --git a/src/util/test/image.c b/src/util/test/image.c index a27e53d5c..e3ea16e24 100644 --- a/src/util/test/image.c +++ b/src/util/test/image.c @@ -2038,6 +2038,97 @@ M_TEST_DEFINE(painterDrawCircleInvalid) { mImageDestroy(image); } +M_TEST_DEFINE(painterDrawMask) { + struct mImage* image; + struct mImage* mask; + struct mPainter painter; + + image = mImageCreate(4, 4, mCOLOR_XRGB8); + mPainterInit(&painter, image); + painter.blend = false; + painter.fill = true; + + mask = mImageCreate(2, 2, mCOLOR_XRGB8); + mImageSetPixel(mask, 0, 0, 0xFFFFFFFF); + mImageSetPixel(mask, 1, 0, 0xFFFF0000); + mImageSetPixel(mask, 0, 1, 0xFF00FF00); + mImageSetPixel(mask, 1, 1, 0xFF0000FF); + + painter.fillColor = 0xFFFFFFFF; + mPainterDrawMask(&painter, mask, 0, 0); + painter.fillColor = 0xFFFF0000; + mPainterDrawMask(&painter, mask, 2, 0); + painter.fillColor = 0xFF00FF00; + mPainterDrawMask(&painter, mask, 0, 2); + painter.fillColor = 0xFF0000FF; + mPainterDrawMask(&painter, mask, 2, 2); + + COMPARE4X(0xFFFFFF, 0xFF0000, 0xFF0000, 0xFF0000, + 0x00FF00, 0x0000FF, 0x000000, 0x000000, + 0x00FF00, 0x000000, 0x0000FF, 0x000000, + 0x00FF00, 0x000000, 0x000000, 0x0000FF); + + painter.fillColor = 0xFF808080; + mPainterDrawMask(&painter, mask, 0, 0); + painter.fillColor = 0xFFFFFF00; + mPainterDrawMask(&painter, mask, 2, 0); + painter.fillColor = 0xFF00FFFF; + mPainterDrawMask(&painter, mask, 0, 2); + painter.fillColor = 0xFFFF00FF; + mPainterDrawMask(&painter, mask, 2, 2); + + COMPARE4X(0x808080, 0x800000, 0xFFFF00, 0xFF0000, + 0x008000, 0x000080, 0x00FF00, 0x000000, + 0x00FFFF, 0x000000, 0xFF00FF, 0xFF0000, + 0x00FF00, 0x0000FF, 0x000000, 0x0000FF); + + painter.fillColor = 0xFFFFFFFF; + mPainterDrawMask(&painter, mask, -1, -1); + mPainterDrawMask(&painter, mask, 3, 3); + assert_int_equal(0xFF0000FF, mImageGetPixel(image, 0, 0)); + assert_int_equal(0xFFFFFFFF, mImageGetPixel(image, 3, 3)); + + mImageDestroy(image); + mImageDestroy(mask); +} + +M_TEST_DEFINE(painterDrawMaskBlend) { + struct mImage* image; + struct mImage* mask; + struct mPainter painter; + const uint8_t lut[4] = { 0x00, 0x55, 0xAA, 0xFF }; + int x, y; + + image = mImageCreate(4, 4, mCOLOR_XRGB8); + mPainterInit(&painter, image); + painter.blend = true; + painter.fill = true; + painter.fillColor = 0xFFFF8000; + + for (y = 0; y < 4; ++y) { + for (x = 0; x < 4; ++x) { + mImageSetPixel(image, x, y, 0xFF808080); + } + } + + mask = mImageCreate(4, 4, mCOLOR_ARGB8); + for (y = 0; y < 4; ++y) { + for (x = 0; x < 4; ++x) { + mImageSetPixel(mask, x, y, (lut[x] << 24) | (lut[y] * 0x010101)); + } + } + + mPainterDrawMask(&painter, mask, 0, 0); + + COMPARE4X(0x808080, 0x555555, 0x2A2A2A, 0x000000, + 0x808080, 0x716355, 0x63462A, 0x552A00, + 0x808080, 0x8E7155, 0x9C632A, 0xAA5500, + 0x808080, 0xAA8055, 0xD4802A, 0xFF8000); + + mImageDestroy(image); + mImageDestroy(mask); +} + #undef COMPARE3X #undef COMPARE3 #undef COMPARE4X @@ -2083,4 +2174,6 @@ M_TEST_SUITE_DEFINE(Image, cmocka_unit_test(painterDrawCircleOffset), cmocka_unit_test(painterDrawCircleBlend), cmocka_unit_test(painterDrawCircleInvalid), + cmocka_unit_test(painterDrawMask), + cmocka_unit_test(painterDrawMaskBlend), ) From c80f3afd7708e2e7d2f0f5175ba21fa2b70a424c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 18 Mar 2024 23:26:01 -0700 Subject: [PATCH 084/336] Qt: Reattach video backend when resetting scripts (fixes #3167) --- src/platform/qt/scripting/ScriptingController.cpp | 2 ++ src/platform/qt/scripting/ScriptingController.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index 06adafdf5..79b46e9d0 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -92,6 +92,7 @@ void ScriptingController::setInputController(InputController* input) { } void ScriptingController::setVideoBackend(VideoBackend* backend) { + m_videoBackend = backend; mScriptCanvasUpdateBackend(&m_scriptContext, backend); } @@ -339,6 +340,7 @@ void ScriptingController::init() { mScriptContextAttachLogger(&m_scriptContext, &m_logger); m_bufferModel->attachToContext(&m_scriptContext); + mScriptCanvasUpdateBackend(&m_scriptContext, m_videoBackend); HashTableEnumerate(&m_scriptContext.engines, [](const char* key, void* engine, void* context) { ScriptingController* self = static_cast(context); diff --git a/src/platform/qt/scripting/ScriptingController.h b/src/platform/qt/scripting/ScriptingController.h index 9e5b3f6b5..5c579a768 100644 --- a/src/platform/qt/scripting/ScriptingController.h +++ b/src/platform/qt/scripting/ScriptingController.h @@ -87,6 +87,7 @@ private: mScriptEngineContext* m_activeEngine = nullptr; QHash m_engines; ScriptingTextBufferModel* m_bufferModel; + VideoBackend* m_videoBackend = nullptr; mScriptGamepad m_gamepad; From aa7b9349f843da4bc9427e0c20b71b7c0097123a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 19 Mar 2024 21:30:47 -0700 Subject: [PATCH 085/336] Core: Clean up thread state mutex usage --- src/core/thread.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/core/thread.c b/src/core/thread.c index 63b8e0d56..4b470777d 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -42,13 +42,9 @@ static BOOL CALLBACK _createTLS(PINIT_ONCE once, PVOID param, PVOID* context) { static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args); -static void _changeState(struct mCoreThreadInternal* threadContext, enum mCoreThreadState newState, bool broadcast) { - MutexLock(&threadContext->stateMutex); +static void _changeState(struct mCoreThreadInternal* threadContext, enum mCoreThreadState newState) { threadContext->state = newState; - if (broadcast) { - ConditionWake(&threadContext->stateCond); - } - MutexUnlock(&threadContext->stateMutex); + ConditionWake(&threadContext->stateCond); } static void _waitOnInterrupt(struct mCoreThreadInternal* threadContext) { @@ -178,7 +174,9 @@ void _crashed(void* context) { if (!thread) { return; } - _changeState(thread->impl, mTHREAD_CRASHED, true); + MutexLock(&thread->impl->stateMutex); + _changeState(thread->impl, mTHREAD_CRASHED); + MutexUnlock(&thread->impl->stateMutex); } void _coreSleep(void* context) { @@ -196,7 +194,9 @@ void _coreShutdown(void* context) { if (!thread) { return; } - _changeState(thread->impl, mTHREAD_EXITING, true); + MutexLock(&thread->impl->stateMutex); + _changeState(thread->impl, mTHREAD_EXITING); + MutexUnlock(&thread->impl->stateMutex); } #ifdef ENABLE_SCRIPTING @@ -303,7 +303,9 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { core->reset(core); threadContext->impl->core = core; - _changeState(threadContext->impl, mTHREAD_RUNNING, true); + MutexLock(&threadContext->impl->stateMutex); + _changeState(threadContext->impl, mTHREAD_RUNNING); + MutexUnlock(&threadContext->impl->stateMutex); if (threadContext->resetCallback) { threadContext->resetCallback(threadContext); @@ -326,23 +328,27 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { bool wasPaused = false; int pendingRequests = 0; + MutexLock(&impl->stateMutex); while (impl->state < mTHREAD_EXITING) { #ifdef USE_DEBUGGERS struct mDebugger* debugger = core->debugger; if (debugger) { + MutexUnlock(&impl->stateMutex); mDebuggerRun(debugger); + MutexLock(&impl->stateMutex); if (debugger->state == DEBUGGER_SHUTDOWN) { - _changeState(impl, mTHREAD_EXITING, false); + impl->state = mTHREAD_EXITING; } } else #endif { while (impl->state == mTHREAD_RUNNING) { + MutexUnlock(&impl->stateMutex); core->runLoop(core); + MutexLock(&impl->stateMutex); } } - MutexLock(&impl->stateMutex); while (impl->state >= mTHREAD_MIN_WAITING && impl->state < mTHREAD_EXITING) { if (impl->state == mTHREAD_INTERRUPTING) { impl->state = mTHREAD_INTERRUPTED; @@ -430,7 +436,9 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { } while (impl->state < mTHREAD_SHUTDOWN) { - _changeState(impl, mTHREAD_SHUTDOWN, false); + MutexLock(&impl->stateMutex); + impl->state = mTHREAD_SHUTDOWN; + MutexUnlock(&impl->stateMutex); } if (core->opts.rewindEnable) { From a2587cb8cff265d9f327a9413b4f2c5e607850fb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 19 Mar 2024 21:40:38 -0700 Subject: [PATCH 086/336] Util: Code cleanup to remove unreachable code --- src/util/string.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/util/string.c b/src/util/string.c index 1a2ffe7a4..b2bf376c6 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -177,16 +177,12 @@ size_t toUtf8(uint32_t unichar, char* buffer) { buffer[2] = (unichar & 0x3F) | 0x80; return 3; } - if (unichar < 0x200000) { - buffer[0] = (unichar >> 18) | 0xF0; - buffer[1] = ((unichar >> 12) & 0x3F) | 0x80; - buffer[2] = ((unichar >> 6) & 0x3F) | 0x80; - buffer[3] = (unichar & 0x3F) | 0x80; - return 4; - } - // This shouldn't be possible - return 0; + buffer[0] = (unichar >> 18) | 0xF0; + buffer[1] = ((unichar >> 12) & 0x3F) | 0x80; + buffer[2] = ((unichar >> 6) & 0x3F) | 0x80; + buffer[3] = (unichar & 0x3F) | 0x80; + return 4; } size_t toUtf16(uint32_t unichar, uint16_t* buffer) { From cf0d8fdc28f9b451fb2c86357db035e195a923b1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 14:46:34 -0700 Subject: [PATCH 087/336] Qt: Get InputController compiling with Qt6 Cameras still don't work though --- src/platform/qt/InputController.cpp | 49 +++++++++++++++++++++++++++-- src/platform/qt/InputController.h | 9 ++++-- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 337e7df6b..e195505a4 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -16,8 +16,13 @@ #include #include #ifdef BUILD_QT_MULTIMEDIA +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #include #include +#else +#include +#include +#endif #endif #include @@ -50,7 +55,9 @@ InputController::InputController(QWidget* topLevel, QObject* parent) m_gamepadTimer.start(); #ifdef BUILD_QT_MULTIMEDIA +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) connect(&m_videoDumper, &VideoDumper::imageAvailable, this, &InputController::setCamImage); +#endif #endif mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A); @@ -90,10 +97,20 @@ InputController::InputController(QWidget* topLevel, QObject* parent) #ifdef BUILD_QT_MULTIMEDIA image->p->m_cameraActive = true; QByteArray camera = image->p->m_config->getQtOption("camera").toByteArray(); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (!camera.isNull()) { image->p->m_cameraDevice = camera; } QMetaObject::invokeMethod(image->p, "setupCam"); +#else + if (!camera.isNull()) { + for (const auto& cam : QMediaDevices::videoInputs()) { + if (cam.id() == camera) { + image->p->m_cameraDevice = cam; + } + } + } +#endif #endif }; @@ -595,9 +612,13 @@ void InputController::setCamImage(const QImage& image) { QList> InputController::listCameras() const { QList> out; #ifdef BUILD_QT_MULTIMEDIA - QList cams = QCameraInfo::availableCameras(); - for (const auto& cam : cams) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + for (const auto& cam : QCameraInfo::availableCameras()) { out.append(qMakePair(cam.deviceName().toLatin1(), cam.description())); +#else + for (const auto& cam : QMediaDevices::videoInputs()) { + out.append(qMakePair(cam.id(), cam.description())); +#endif } #endif return out; @@ -639,6 +660,7 @@ void InputController::setupCam() { return; } +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (!m_camera) { m_camera = std::make_unique(m_cameraDevice); connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings, Qt::QueuedConnection); @@ -650,10 +672,16 @@ void InputController::setupCam() { m_camera->setCaptureMode(QCamera::CaptureVideo); m_camera->setViewfinder(&m_videoDumper); m_camera->load(); +#else + if (!m_camera) { + m_camera = std::make_unique(m_cameraDevice); + m_captureSession.setCamera(m_camera.get()); + } +#endif #endif } -#ifdef BUILD_QT_MULTIMEDIA +#if defined(BUILD_QT_MULTIMEDIA) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) void InputController::prepareCamSettings(QCamera::Status status) { if (status != QCamera::LoadedStatus || m_camera->state() == QCamera::ActiveState) { return; @@ -697,7 +725,11 @@ void InputController::prepareCamSettings(QCamera::Status status) { void InputController::teardownCam() { #ifdef BUILD_QT_MULTIMEDIA if (m_camera) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) m_camera->unload(); +#else + m_captureSession.setCamera(nullptr); +#endif m_camera.reset(); } #endif @@ -705,6 +737,7 @@ void InputController::teardownCam() { void InputController::setCamera(const QByteArray& name) { #ifdef BUILD_QT_MULTIMEDIA +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (m_cameraDevice == name) { return; } @@ -715,5 +748,15 @@ void InputController::setCamera(const QByteArray& name) { if (m_cameraActive) { setupCam(); } +#else + if (m_cameraDevice.id() == name) { + return; + } + for (const auto& cam : QMediaDevices::videoInputs()) { + if (cam.id() == name) { + m_cameraDevice = cam; + } + } +#endif #endif } diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index 06871ff1e..51be333ed 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -27,6 +27,8 @@ #ifdef BUILD_QT_MULTIMEDIA #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #include "VideoDumper.h" +#else +#include #endif #include #endif @@ -126,7 +128,7 @@ public slots: void setCamera(const QByteArray& id); private slots: -#ifdef BUILD_QT_MULTIMEDIA +#if defined(BUILD_QT_MULTIMEDIA) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) void prepareCamSettings(QCamera::Status); #endif void setupCam(); @@ -168,10 +170,13 @@ private: #ifdef BUILD_QT_MULTIMEDIA bool m_cameraActive = false; - QByteArray m_cameraDevice; std::unique_ptr m_camera; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + QByteArray m_cameraDevice; VideoDumper m_videoDumper; +#else + QCameraDevice m_cameraDevice; + QMediaCaptureSession m_captureSession; #endif #endif From 3f21de2b7caaf148cd0b3a279f07c3f3a0eb9781 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 15:55:39 -0700 Subject: [PATCH 088/336] Qt: Port AudioProcessorQt to Qt6 --- src/platform/qt/AudioProcessorQt.cpp | 33 +++++++++++++++++++++------- src/platform/qt/AudioProcessorQt.h | 12 +++++++++- src/platform/qt/Window.cpp | 4 +++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index 8d12cd935..4b53c7bb7 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -9,6 +9,9 @@ #include "LogController.h" #include +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include +#endif #include #include @@ -31,10 +34,13 @@ void AudioProcessorQt::setInput(std::shared_ptr controller) { } void AudioProcessorQt::stop() { + if (m_audioOutput) { + m_audioOutput->stop(); + m_audioOutput.reset(); + } if (m_device) { m_device.reset(); } - pause(); AudioProcessor::stop(); } @@ -52,25 +58,36 @@ bool AudioProcessorQt::start() { QAudioFormat format; format.setSampleRate(m_sampleRate); format.setChannelCount(2); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::Endian(QSysInfo::ByteOrder)); format.setSampleType(QAudioFormat::SignedInt); - m_audioOutput = new QAudioOutput(format, this); + m_audioOutput = std::make_unique(format); m_audioOutput->setCategory("game"); +#else + format.setSampleFormat(QAudioFormat::Int16); + + QAudioDevice device(QMediaDevices::defaultAudioOutput()); + m_audioOutput = std::make_unique(device, format); + LOG(QT, INFO) << "Audio outputting to " << device.description(); +#endif } - m_device->setInput(input()); - m_device->setFormat(m_audioOutput->format()); - - m_audioOutput->start(m_device.get()); - return m_audioOutput->state() == QAudio::ActiveState; + if (m_audioOutput->state() == QAudio::SuspendedState) { + m_audioOutput->resume(); + } else { + m_device->setInput(input()); + m_device->setFormat(m_audioOutput->format()); + m_audioOutput->start(m_device.get()); + } + return m_audioOutput->state() == QAudio::ActiveState && m_audioOutput->error() == QAudio::NoError; } void AudioProcessorQt::pause() { if (m_audioOutput) { - m_audioOutput->stop(); + m_audioOutput->suspend(); } } diff --git a/src/platform/qt/AudioProcessorQt.h b/src/platform/qt/AudioProcessorQt.h index 0e56907e1..1648b967f 100644 --- a/src/platform/qt/AudioProcessorQt.h +++ b/src/platform/qt/AudioProcessorQt.h @@ -7,6 +7,12 @@ #include "AudioProcessor.h" +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +#include +#else +#include +#endif + class QAudioOutput; namespace QGBA { @@ -33,7 +39,11 @@ public slots: virtual void requestSampleRate(unsigned) override; private: - QAudioOutput* m_audioOutput = nullptr; +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + std::unique_ptr m_audioOutput; +#else + std::unique_ptr m_audioOutput; +#endif std::unique_ptr m_device; unsigned m_sampleRate = 44100; }; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 6b77a1ef3..cc439f60f 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1093,7 +1093,9 @@ void Window::reloadAudioDriver() { m_audioProcessor = std::unique_ptr(AudioProcessor::create()); m_audioProcessor->setInput(m_controller); m_audioProcessor->configure(m_config); - m_audioProcessor->start(); + if (!m_audioProcessor->start()) { + LOG(QT, WARN) << "Failed to start audio processor"; + } } void Window::changeRenderer() { From 06448e844577601167577b644bfb60f6c493d65a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 19:51:09 -0700 Subject: [PATCH 089/336] Qt: Get VideoDumper compiling with Qt6 Cameras still don't work though --- src/platform/qt/CMakeLists.txt | 7 +- src/platform/qt/VideoDumper.cpp | 126 ++++++++++++++++++++++---------- src/platform/qt/VideoDumper.h | 34 ++++++++- 3 files changed, 121 insertions(+), 46 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index cb224b0a6..19d4293d0 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -225,11 +225,8 @@ endif() if(${QT}Multimedia_FOUND) list(APPEND AUDIO_SRC AudioProcessorQt.cpp - AudioDevice.cpp) - if(QT_V LESS 6) - list(APPEND SOURCE_FILES - VideoDumper.cpp) - endif() + AudioDevice.cpp + VideoDumper.cpp) if (WIN32 AND QT_STATIC) list(APPEND QT_LIBRARIES ${QT}::QWindowsAudioPlugin ${QT}::DSServicePlugin ${QT}::QWindowsVistaStylePlugin ${QT}::QJpegPlugin strmiids mfuuid mfplat mf ksguid dxva2 evr d3d9) diff --git a/src/platform/qt/VideoDumper.cpp b/src/platform/qt/VideoDumper.cpp index 7fdb433bb..1f1185200 100644 --- a/src/platform/qt/VideoDumper.cpp +++ b/src/platform/qt/VideoDumper.cpp @@ -5,59 +5,69 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "VideoDumper.h" +#include "VideoProcessor.h" + #include -#include using namespace QGBA; VideoDumper::VideoDumper(QObject* parent) +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) : QAbstractVideoSurface(parent) +#else + : QObject(parent) +#endif { } bool VideoDumper::present(const QVideoFrame& frame) { QVideoFrame mappedFrame(frame); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (!mappedFrame.map(QAbstractVideoBuffer::ReadOnly)) { return false; } - QVideoFrame::PixelFormat vFormat = mappedFrame.pixelFormat(); - QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(vFormat); +#else + if (!mappedFrame.map(QVideoFrame::ReadOnly)) { + return false; + } +#endif + PixelFormat vFormat = mappedFrame.pixelFormat(); + QImage::Format format = imageFormatFromPixelFormat(vFormat); bool swap = false; #ifdef USE_FFMPEG bool useScaler = false; #endif if (format == QImage::Format_Invalid) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (vFormat < QVideoFrame::Format_BGRA5658_Premultiplied) { vFormat = static_cast(vFormat - QVideoFrame::Format_BGRA32 + QVideoFrame::Format_ARGB32); - format = QVideoFrame::imageFormatFromPixelFormat(vFormat); - if (format == QImage::Format_ARGB32) { - format = QImage::Format_RGBA8888; - } else if (format == QImage::Format_ARGB32_Premultiplied) { - format = QImage::Format_RGBA8888_Premultiplied; - } +#else + if (vFormat < PixelFormat::Format_AYUV) { +#endif + format = imageFormatFromPixelFormat(vFormat); swap = true; } else { #ifdef USE_FFMPEG enum AVPixelFormat pixelFormat; switch (vFormat) { - case QVideoFrame::Format_YUV420P: + case VideoDumper::PixelFormat::Format_YUV420P: pixelFormat = AV_PIX_FMT_YUV420P; break; #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - case QVideoFrame::Format_YUV422P: + case VideoDumper::PixelFormat::Format_YUV422P: pixelFormat = AV_PIX_FMT_YUV422P; break; #endif - case QVideoFrame::Format_YUYV: + case VideoDumper::PixelFormat::Format_YUYV: pixelFormat = AV_PIX_FMT_YUYV422; break; - case QVideoFrame::Format_UYVY: + case VideoDumper::PixelFormat::Format_UYVY: pixelFormat = AV_PIX_FMT_UYVY422; break; - case QVideoFrame::Format_NV12: + case VideoDumper::PixelFormat::Format_NV12: pixelFormat = AV_PIX_FMT_NV12; break; - case QVideoFrame::Format_NV21: + case VideoDumper::PixelFormat::Format_NV21: pixelFormat = AV_PIX_FMT_NV12; break; default: @@ -80,11 +90,15 @@ bool VideoDumper::present(const QVideoFrame& frame) { #endif } } - uchar* bits = mappedFrame.bits(); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + Direction direction = surfaceFormat().scanLineDirection(); +#else + Direction direction = mappedFrame.surfaceFormat().scanLineDirection(); +#endif #ifdef USE_FFMPEG QImage image; if (!useScaler) { - image = QImage(bits, mappedFrame.width(), mappedFrame.height(), mappedFrame.bytesPerLine(), format); + image = QImage(mappedFrame.bits(0), mappedFrame.width(), mappedFrame.height(), mappedFrame.bytesPerLine(0), format); } if (useScaler) { image = QImage(mappedFrame.width(), mappedFrame.height(), format); @@ -99,14 +113,14 @@ bool VideoDumper::present(const QVideoFrame& frame) { sws_scale(m_scaler, planes, strides, 0, mappedFrame.height(), &outBits, &outStride); } else #else - QImage image(bits, mappedFrame.width(), mappedFrame.height(), mappedFrame.bytesPerLine(), format); + QImage image(mappedFrame.bits(0), mappedFrame.width(), mappedFrame.height(), mappedFrame.bytesPerLine(0), format); #endif if (swap) { image = image.rgbSwapped(); - } else if (surfaceFormat().scanLineDirection() != QVideoSurfaceFormat::BottomToTop) { + } else if (direction != Direction::BottomToTop) { image = image.copy(); // Create a deep copy of the bits } - if (surfaceFormat().scanLineDirection() == QVideoSurfaceFormat::BottomToTop) { + if (direction == Direction::BottomToTop) { image = image.mirrored(); } mappedFrame.unmap(); @@ -114,29 +128,63 @@ bool VideoDumper::present(const QVideoFrame& frame) { return true; } +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QList VideoDumper::supportedPixelFormats(QAbstractVideoBuffer::HandleType) const { - QList list; - list.append(QVideoFrame::Format_RGB32); - list.append(QVideoFrame::Format_ARGB32); - list.append(QVideoFrame::Format_RGB24); - list.append(QVideoFrame::Format_ARGB32_Premultiplied); - list.append(QVideoFrame::Format_RGB565); - list.append(QVideoFrame::Format_RGB555); - list.append(QVideoFrame::Format_BGR32); - list.append(QVideoFrame::Format_BGRA32); - list.append(QVideoFrame::Format_BGR24); - list.append(QVideoFrame::Format_BGRA32_Premultiplied); - list.append(QVideoFrame::Format_BGR565); - list.append(QVideoFrame::Format_BGR555); + return VideoDumper::supportedPixelFormats(); +} +#endif + +QList VideoDumper::supportedPixelFormats() { + QList list{{ +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + VideoDumper::PixelFormat::Format_RGB32, + VideoDumper::PixelFormat::Format_ARGB32, + VideoDumper::PixelFormat::Format_RGB24, + VideoDumper::PixelFormat::Format_ARGB32_Premultiplied, + VideoDumper::PixelFormat::Format_RGB565, + VideoDumper::PixelFormat::Format_RGB555, + VideoDumper::PixelFormat::Format_BGR32, + VideoDumper::PixelFormat::Format_BGRA32, + VideoDumper::PixelFormat::Format_BGR24, + VideoDumper::PixelFormat::Format_BGRA32_Premultiplied, + VideoDumper::PixelFormat::Format_BGR565, + VideoDumper::PixelFormat::Format_BGR555, +#else + VideoDumper::PixelFormat::Format_XRGB8888, + VideoDumper::PixelFormat::Format_ARGB8888, + VideoDumper::PixelFormat::Format_ARGB8888_Premultiplied, + VideoDumper::PixelFormat::Format_RGBX8888, + VideoDumper::PixelFormat::Format_RGBA8888, + VideoDumper::PixelFormat::Format_XBGR8888, + VideoDumper::PixelFormat::Format_ABGR8888, + VideoDumper::PixelFormat::Format_BGRX8888, + VideoDumper::PixelFormat::Format_BGRA8888, + VideoDumper::PixelFormat::Format_BGRA8888_Premultiplied, +#endif #ifdef USE_FFMPEG - list.append(QVideoFrame::Format_YUYV); - list.append(QVideoFrame::Format_UYVY); + VideoDumper::PixelFormat::Format_YUYV, + VideoDumper::PixelFormat::Format_UYVY, #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - list.append(QVideoFrame::Format_YUV422P); + VideoDumper::PixelFormat::Format_YUV422P, #endif - list.append(QVideoFrame::Format_YUV420P); - list.append(QVideoFrame::Format_NV12); - list.append(QVideoFrame::Format_NV21); + VideoDumper::PixelFormat::Format_YUV420P, + VideoDumper::PixelFormat::Format_NV12, + VideoDumper::PixelFormat::Format_NV21, #endif + }}; return list; } + +QImage::Format VideoDumper::imageFormatFromPixelFormat(VideoDumper::PixelFormat vFormat) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(vFormat); +#else + QImage::Format format = QVideoFrameFormat::imageFormatFromPixelFormat(vFormat); +#endif + if (format == QImage::Format_ARGB32) { + format = QImage::Format_RGBA8888; + } else if (format == QImage::Format_ARGB32_Premultiplied) { + format = QImage::Format_RGBA8888_Premultiplied; + } + return format; +} diff --git a/src/platform/qt/VideoDumper.h b/src/platform/qt/VideoDumper.h index c22688c2b..65433462c 100644 --- a/src/platform/qt/VideoDumper.h +++ b/src/platform/qt/VideoDumper.h @@ -5,7 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once +#include +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #include +#include +#else +#include +#endif #ifdef USE_FFMPEG extern "C" { @@ -15,14 +21,38 @@ extern "C" { namespace QGBA { -class VideoDumper : public QAbstractVideoSurface { +class VideoDumper : public +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +QAbstractVideoSurface +#else +QObject +#endif +{ Q_OBJECT public: +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + using PixelFormat = QVideoFrame::PixelFormat; + using Direction = QVideoSurfaceFormat::Direction; +#else + using PixelFormat = QVideoFrameFormat::PixelFormat; + using Direction = QVideoFrameFormat::Direction; +#endif + VideoDumper(QObject* parent = nullptr); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + QList supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override; +#endif + static QList supportedPixelFormats(); + static QImage::Format imageFormatFromPixelFormat(PixelFormat); + +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) bool present(const QVideoFrame& frame) override; - QList supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const override; +#else +public slots: + bool present(const QVideoFrame& frame); +#endif signals: void imageAvailable(const QImage& image); From dc29af82624b9791e58c8b3cd937c5663311e563 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 21:18:41 -0700 Subject: [PATCH 090/336] Qt: Hook up cameras in Qt6 --- src/platform/qt/InputController.cpp | 47 +++++++++++++++++++++++------ src/platform/qt/InputController.h | 16 +++++++--- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index e195505a4..4a0236199 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -54,11 +54,11 @@ InputController::InputController(QWidget* topLevel, QObject* parent) m_gamepadTimer.setInterval(15); m_gamepadTimer.start(); -#ifdef BUILD_QT_MULTIMEDIA -#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +#if defined(BUILD_QT_MULTIMEDIA) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + m_captureSession.setVideoSink(&m_videoSink); + connect(&m_videoSink, &QVideoSink::videoFrameChanged, &m_videoDumper, &VideoDumper::present); +#endif connect(&m_videoDumper, &VideoDumper::imageAvailable, this, &InputController::setCamImage); -#endif -#endif mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A); mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B); @@ -101,7 +101,6 @@ InputController::InputController(QWidget* topLevel, QObject* parent) if (!camera.isNull()) { image->p->m_cameraDevice = camera; } - QMetaObject::invokeMethod(image->p, "setupCam"); #else if (!camera.isNull()) { for (const auto& cam : QMediaDevices::videoInputs()) { @@ -111,6 +110,7 @@ InputController::InputController(QWidget* topLevel, QObject* parent) } } #endif + QMetaObject::invokeMethod(image->p, "setupCam"); #endif }; @@ -677,18 +677,26 @@ void InputController::setupCam() { m_camera = std::make_unique(m_cameraDevice); m_captureSession.setCamera(m_camera.get()); } + prepareCamFormat(); #endif #endif } -#if defined(BUILD_QT_MULTIMEDIA) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +#ifdef BUILD_QT_MULTIMEDIA +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) void InputController::prepareCamSettings(QCamera::Status status) { if (status != QCamera::LoadedStatus || m_camera->state() == QCamera::ActiveState) { return; } + prepareCamFormat(); +} +#endif + +void InputController::prepareCamFormat() { #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) - QCameraViewfinderSettings settings; QSize size(1280, 720); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + QCameraViewfinderSettings settings; auto cameraRes = m_camera->supportedViewfinderResolutions(settings); for (auto& cameraSize : cameraRes) { if (cameraSize.width() < m_image.w || cameraSize.height() < m_image.h) { @@ -717,6 +725,25 @@ void InputController::prepareCamSettings(QCamera::Status status) { } } m_camera->setViewfinderSettings(settings); +#else + bool goodFormatFound = false; + auto goodFormats = m_videoDumper.supportedPixelFormats(); + QCameraFormat bestFormat; + for (const auto& format : m_cameraDevice.videoFormats()) { + if (!goodFormats.contains(format.pixelFormat())) { + continue; + } + if (format.resolution().width() <= size.width() && format.resolution().height() <= size.height()) { + size = format.resolution(); + bestFormat = format; + goodFormatFound = true; + } + } + if (!goodFormatFound) { + LOG(QT, WARN) << "Could not find a valid camera format!"; + } + m_camera->setCameraFormat(bestFormat); +#endif #endif m_camera->start(); } @@ -745,9 +772,6 @@ void InputController::setCamera(const QByteArray& name) { if (m_camera && m_camera->state() == QCamera::ActiveState) { teardownCam(); } - if (m_cameraActive) { - setupCam(); - } #else if (m_cameraDevice.id() == name) { return; @@ -758,5 +782,8 @@ void InputController::setCamera(const QByteArray& name) { } } #endif + if (m_cameraActive) { + setupCam(); + } #endif } diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index 51be333ed..07e752fd7 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -25,12 +25,13 @@ #include #ifdef BUILD_QT_MULTIMEDIA -#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #include "VideoDumper.h" -#else -#include -#endif + #include +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include +#include +#endif #endif struct mRotationSource; @@ -152,6 +153,10 @@ private: QSet> activeGamepadAxes(uint32_t type); QSet> activeGamepadHats(uint32_t type); +#if defined(BUILD_QT_MULTIMEDIA) + void prepareCamFormat(); +#endif + struct InputControllerLux : GBALuminanceSource { InputController* p; uint8_t value; @@ -171,12 +176,13 @@ private: #ifdef BUILD_QT_MULTIMEDIA bool m_cameraActive = false; std::unique_ptr m_camera; + VideoDumper m_videoDumper; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QByteArray m_cameraDevice; - VideoDumper m_videoDumper; #else QCameraDevice m_cameraDevice; QMediaCaptureSession m_captureSession; + QVideoSink m_videoSink; #endif #endif From 04bbcdfdd1f3c2352eb3f2f7b25980deb6055066 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 21:31:53 -0700 Subject: [PATCH 091/336] Qt: Fix build --- src/platform/qt/VideoDumper.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/platform/qt/VideoDumper.cpp b/src/platform/qt/VideoDumper.cpp index 1f1185200..913406a70 100644 --- a/src/platform/qt/VideoDumper.cpp +++ b/src/platform/qt/VideoDumper.cpp @@ -5,8 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "VideoDumper.h" -#include "VideoProcessor.h" - #include using namespace QGBA; From 6940b424df95ba22dec250f828d44df2834d3cf9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 22:07:31 -0700 Subject: [PATCH 092/336] Qt: Fix non-Multimedia build --- src/platform/qt/InputController.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 4a0236199..d5e799b5a 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -54,11 +54,13 @@ InputController::InputController(QWidget* topLevel, QObject* parent) m_gamepadTimer.setInterval(15); m_gamepadTimer.start(); -#if defined(BUILD_QT_MULTIMEDIA) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#ifdef BUILD_QT_MULTIMEDIA +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) m_captureSession.setVideoSink(&m_videoSink); connect(&m_videoSink, &QVideoSink::videoFrameChanged, &m_videoDumper, &VideoDumper::present); #endif connect(&m_videoDumper, &VideoDumper::imageAvailable, this, &InputController::setCamImage); +#endif mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A); mInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B); @@ -115,10 +117,12 @@ InputController::InputController(QWidget* topLevel, QObject* parent) }; m_image.stopRequestImage = [](mImageSource* context) { - InputControllerImage* image = static_cast(context); #ifdef BUILD_QT_MULTIMEDIA + InputControllerImage* image = static_cast(context); image->p->m_cameraActive = false; QMetaObject::invokeMethod(image->p, "teardownCam"); +#else + UNUSED(context); #endif }; @@ -785,5 +789,7 @@ void InputController::setCamera(const QByteArray& name) { if (m_cameraActive) { setupCam(); } +#else + UNUSED(name); #endif } From ea5339304a8923f31853cba98863d3b87bb6dd9e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 22:57:51 -0700 Subject: [PATCH 093/336] GBA Savedata: Prefix SavedataType constants and type name --- include/mgba/internal/gba/overrides.h | 2 +- include/mgba/internal/gba/savedata.h | 22 +-- src/gba/core.c | 14 +- src/gba/dma.c | 6 +- src/gba/gba.c | 4 +- src/gba/memory.c | 28 +-- src/gba/overrides.c | 260 +++++++++++++------------- src/gba/savedata.c | 128 ++++++------- src/gba/sharkport.c | 10 +- src/platform/libretro/libretro.c | 2 +- src/platform/qt/OverrideView.cpp | 4 +- src/platform/qt/SaveConverter.cpp | 56 +++--- src/platform/qt/SaveConverter.h | 4 +- 13 files changed, 270 insertions(+), 270 deletions(-) diff --git a/include/mgba/internal/gba/overrides.h b/include/mgba/internal/gba/overrides.h index c835a62a1..83a63f0a4 100644 --- a/include/mgba/internal/gba/overrides.h +++ b/include/mgba/internal/gba/overrides.h @@ -16,7 +16,7 @@ CXX_GUARD_START struct GBACartridgeOverride { char id[4]; - enum SavedataType savetype; + enum GBASavedataType savetype; int hardware; uint32_t idleLoop; bool mirroring; diff --git a/include/mgba/internal/gba/savedata.h b/include/mgba/internal/gba/savedata.h index 102c23041..a03f2960c 100644 --- a/include/mgba/internal/gba/savedata.h +++ b/include/mgba/internal/gba/savedata.h @@ -17,15 +17,15 @@ mLOG_DECLARE_CATEGORY(GBA_SAVE); struct VFile; -enum SavedataType { - SAVEDATA_AUTODETECT = -1, - SAVEDATA_FORCE_NONE = 0, - SAVEDATA_SRAM = 1, - SAVEDATA_FLASH512 = 2, - SAVEDATA_FLASH1M = 3, - SAVEDATA_EEPROM = 4, - SAVEDATA_EEPROM512 = 5, - SAVEDATA_SRAM512 = 6, +enum GBASavedataType { + GBA_SAVEDATA_AUTODETECT = -1, + GBA_SAVEDATA_FORCE_NONE = 0, + GBA_SAVEDATA_SRAM = 1, + GBA_SAVEDATA_FLASH512 = 2, + GBA_SAVEDATA_FLASH1M = 3, + GBA_SAVEDATA_EEPROM = 4, + GBA_SAVEDATA_EEPROM512 = 5, + GBA_SAVEDATA_SRAM512 = 6, }; enum SavedataCommand { @@ -68,7 +68,7 @@ enum { }; struct GBASavedata { - enum SavedataType type; + enum GBASavedataType type; uint8_t* data; enum SavedataCommand command; struct VFile* vf; @@ -108,7 +108,7 @@ void GBASavedataUnmask(struct GBASavedata* savedata); size_t GBASavedataSize(const struct GBASavedata* savedata); bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out); bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in); -void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type); +void GBASavedataForceType(struct GBASavedata* savedata, enum GBASavedataType type); void GBASavedataInitFlash(struct GBASavedata* savedata); void GBASavedataInitEEPROM(struct GBASavedata* savedata); diff --git a/src/gba/core.c b/src/gba/core.c index 46ad70f08..89bcaafc6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1004,27 +1004,27 @@ size_t _GBACoreListMemoryBlocks(const struct mCore* core, const struct mCoreMemo if (gbacore->memoryBlockType != gba->memory.savedata.type) { switch (gba->memory.savedata.type) { - case SAVEDATA_SRAM: + case GBA_SAVEDATA_SRAM: memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksSRAM, sizeof(_GBAMemoryBlocksSRAM)); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksSRAM) / sizeof(*_GBAMemoryBlocksSRAM); break; - case SAVEDATA_SRAM512: + case GBA_SAVEDATA_SRAM512: memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksSRAM512, sizeof(_GBAMemoryBlocksSRAM512)); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksSRAM512) / sizeof(*_GBAMemoryBlocksSRAM512); break; - case SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH512: memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash512, sizeof(_GBAMemoryBlocksFlash512)); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash512) / sizeof(*_GBAMemoryBlocksFlash512); break; - case SAVEDATA_FLASH1M: + case GBA_SAVEDATA_FLASH1M: memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash1M, sizeof(_GBAMemoryBlocksFlash1M)); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash1M) / sizeof(*_GBAMemoryBlocksFlash1M); break; - case SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM: memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksEEPROM, sizeof(_GBAMemoryBlocksEEPROM)); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksEEPROM) / sizeof(*_GBAMemoryBlocksEEPROM); break; - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM512: memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksEEPROM512, sizeof(_GBAMemoryBlocksEEPROM512)); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksEEPROM512) / sizeof(*_GBAMemoryBlocksEEPROM512); break; @@ -1076,7 +1076,7 @@ void* _GBACoreGetMemoryBlock(struct mCore* core, size_t id, size_t* sizeOut) { *sizeOut = gba->memory.romSize; return gba->memory.rom; case GBA_REGION_SRAM: - if (gba->memory.savedata.type == SAVEDATA_FLASH1M) { + if (gba->memory.savedata.type == GBA_SAVEDATA_FLASH1M) { *sizeOut = GBA_SIZE_FLASH1M; return gba->memory.savedata.currentBank; } diff --git a/src/gba/dma.c b/src/gba/dma.c index 7c75184ea..290341361 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -274,7 +274,7 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { } cpu->memory.store32(cpu, dest, memory->dmaTransferRegister, 0); } else { - if (sourceRegion == GBA_REGION_ROM2_EX && (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512)) { + if (sourceRegion == GBA_REGION_ROM2_EX && (memory->savedata.type == GBA_SAVEDATA_EEPROM || memory->savedata.type == GBA_SAVEDATA_EEPROM512)) { memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata); memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; } else if (source) { @@ -282,11 +282,11 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; } if (destRegion == GBA_REGION_ROM2_EX) { - if (memory->savedata.type == SAVEDATA_AUTODETECT) { + if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) { mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); GBASavedataInitEEPROM(&memory->savedata); } - if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) { + if (memory->savedata.type == GBA_SAVEDATA_EEPROM512 || memory->savedata.type == GBA_SAVEDATA_EEPROM) { GBASavedataWriteEEPROM(&memory->savedata, memory->dmaTransferRegister, info->nextCount); } } else { diff --git a/src/gba/gba.c b/src/gba/gba.c index 7586ae66c..409bd2b3a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -469,10 +469,10 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) { } bool GBALoadSave(struct GBA* gba, struct VFile* sav) { - enum SavedataType type = gba->memory.savedata.type; + enum GBASavedataType type = gba->memory.savedata.type; GBASavedataDeinit(&gba->memory.savedata); GBASavedataInit(&gba->memory.savedata, sav); - if (type != SAVEDATA_AUTODETECT) { + if (type != GBA_SAVEDATA_AUTODETECT) { GBASavedataForceType(&gba->memory.savedata, type); } return sav; diff --git a/src/gba/memory.c b/src/gba/memory.c index 9418a2706..455c70bdb 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -595,7 +595,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { break; case GBA_REGION_ROM2_EX: wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; - if (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512) { + if (memory->savedata.type == GBA_SAVEDATA_EEPROM || memory->savedata.type == GBA_SAVEDATA_EEPROM512) { value = GBASavedataReadEEPROM(&memory->savedata); } else if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) { value = GBACartEReaderRead(&memory->ereader, address); @@ -702,7 +702,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { case GBA_REGION_SRAM: case GBA_REGION_SRAM_MIRROR: wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; - if (memory->savedata.type == SAVEDATA_AUTODETECT) { + if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) { mLOG(GBA_MEM, INFO, "Detected SRAM savegame"); GBASavedataInitSRAM(&memory->savedata); } @@ -711,13 +711,13 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { } if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) { value = GBACartEReaderReadFlash(&memory->ereader, address); - } else if (memory->savedata.type == SAVEDATA_SRAM) { + } else if (memory->savedata.type == GBA_SAVEDATA_SRAM) { value = memory->savedata.data[address & (GBA_SIZE_SRAM - 1)]; - } else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) { + } else if (memory->savedata.type == GBA_SAVEDATA_FLASH512 || memory->savedata.type == GBA_SAVEDATA_FLASH1M) { value = GBASavedataReadFlash(&memory->savedata, address); } else if (memory->hw.devices & HW_TILT) { value = GBAHardwareTiltRead(&memory->hw, address & OFFSET_MASK); - } else if (memory->savedata.type == SAVEDATA_SRAM512) { + } else if (memory->savedata.type == GBA_SAVEDATA_SRAM512) { value = memory->savedata.data[address & (GBA_SIZE_SRAM512 - 1)]; } else { mLOG(GBA_MEM, GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address); @@ -975,11 +975,11 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) { GBACartEReaderWrite(&memory->ereader, address, value); break; - } else if (memory->savedata.type == SAVEDATA_AUTODETECT) { + } else if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) { mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); GBASavedataInitEEPROM(&memory->savedata); } - if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) { + if (memory->savedata.type == GBA_SAVEDATA_EEPROM512 || memory->savedata.type == GBA_SAVEDATA_EEPROM) { GBASavedataWriteEEPROM(&memory->savedata, value, 1); break; } @@ -1050,7 +1050,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo break; case GBA_REGION_SRAM: case GBA_REGION_SRAM_MIRROR: - if (memory->savedata.type == SAVEDATA_AUTODETECT) { + if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) { if (address == SAVEDATA_FLASH_BASE) { mLOG(GBA_MEM, INFO, "Detected Flash savegame"); GBASavedataInitFlash(&memory->savedata); @@ -1061,9 +1061,9 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo } if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) { GBACartEReaderWriteFlash(&memory->ereader, address, value); - } else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) { + } else if (memory->savedata.type == GBA_SAVEDATA_FLASH512 || memory->savedata.type == GBA_SAVEDATA_FLASH1M) { GBASavedataWriteFlash(&memory->savedata, address, value); - } else if (memory->savedata.type == SAVEDATA_SRAM) { + } else if (memory->savedata.type == GBA_SAVEDATA_SRAM) { if (memory->vfame.cartType) { GBAVFameSramWrite(&memory->vfame, address, value, memory->savedata.data); } else { @@ -1072,7 +1072,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo memory->savedata.dirty |= mSAVEDATA_DIRT_NEW; } else if (memory->hw.devices & HW_TILT) { GBAHardwareTiltWrite(&memory->hw, address & OFFSET_MASK, value); - } else if (memory->savedata.type == SAVEDATA_SRAM512) { + } else if (memory->savedata.type == GBA_SAVEDATA_SRAM512) { memory->savedata.data[address & (GBA_SIZE_SRAM512 - 1)] = value; memory->savedata.dirty |= mSAVEDATA_DIRT_NEW; } else { @@ -1263,7 +1263,7 @@ void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* o break; case GBA_REGION_SRAM: case GBA_REGION_SRAM_MIRROR: - if (memory->savedata.type == SAVEDATA_SRAM) { + if (memory->savedata.type == GBA_SAVEDATA_SRAM) { LOAD_32(oldValue, address & (GBA_SIZE_SRAM - 4), memory->savedata.data); STORE_32(value, address & (GBA_SIZE_SRAM - 4), memory->savedata.data); } else { @@ -1333,7 +1333,7 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o break; case GBA_REGION_SRAM: case GBA_REGION_SRAM_MIRROR: - if (memory->savedata.type == SAVEDATA_SRAM) { + if (memory->savedata.type == GBA_SAVEDATA_SRAM) { LOAD_16(oldValue, address & (GBA_SIZE_SRAM - 2), memory->savedata.data); STORE_16(value, address & (GBA_SIZE_SRAM - 2), memory->savedata.data); } else { @@ -1391,7 +1391,7 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) break; case GBA_REGION_SRAM: case GBA_REGION_SRAM_MIRROR: - if (memory->savedata.type == SAVEDATA_SRAM) { + if (memory->savedata.type == GBA_SAVEDATA_SRAM) { oldValue = ((int8_t*) memory->savedata.data)[address & (GBA_SIZE_SRAM - 1)]; ((int8_t*) memory->savedata.data)[address & (GBA_SIZE_SRAM - 1)] = value; } else { diff --git a/src/gba/overrides.c b/src/gba/overrides.c index ccc871e62..44a47efb5 100644 --- a/src/gba/overrides.c +++ b/src/gba/overrides.c @@ -13,210 +13,210 @@ static const struct GBACartridgeOverride _overrides[] = { // Advance Wars - { "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, - { "AWRP", SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, + { "AWRE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, + { "AWRP", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, // Advance Wars 2: Black Hole Rising - { "AW2E", SAVEDATA_FLASH512, HW_NONE, 0x8036E08, false }, - { "AW2P", SAVEDATA_FLASH512, HW_NONE, 0x803719C, false }, + { "AW2E", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8036E08, false }, + { "AW2P", GBA_SAVEDATA_FLASH512, HW_NONE, 0x803719C, false }, // Boktai: The Sun is in Your Hand - { "U3IJ", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U3IE", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U3IP", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U3IJ", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U3IE", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U3IP", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, // Boktai 2: Solar Boy Django - { "U32J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U32E", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U32P", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U32J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U32E", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U32P", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, // Crash Bandicoot 2 - N-Tranced - { "AC8J", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "AC8E", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "AC8P", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "AC8J", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "AC8E", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "AC8P", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // DigiCommunication Nyo - Datou! Black Gemagema Dan - { "BDKJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "BDKJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Dragon Ball Z - The Legacy of Goku - { "ALGP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALGP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Dragon Ball Z - The Legacy of Goku II - { "ALFJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "ALFE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "ALFP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALFJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALFE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALFP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Dragon Ball Z - Taiketsu - { "BDBE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "BDBP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "BDBE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "BDBP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Drill Dozer - { "V49J", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, - { "V49E", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, - { "V49P", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, + { "V49J", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, + { "V49E", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, + { "V49P", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, // e-Reader - { "PEAJ", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, - { "PSAJ", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, - { "PSAE", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, + { "PEAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, + { "PSAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, + { "PSAE", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, // Final Fantasy Tactics Advance - { "AFXE", SAVEDATA_FLASH512, HW_NONE, 0x8000428, false }, + { "AFXE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8000428, false }, // F-Zero - Climax - { "BFTJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BFTJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, // Goodboy Galaxy - { "2GBP", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, + { "2GBP", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, // Iridion II - { "AI2E", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, - { "AI2P", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "AI2E", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "AI2P", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, // Game Boy Wars Advance 1+2 - { "BGWJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BGWJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, // Golden Sun: The Lost Age - { "AGFE", SAVEDATA_FLASH512, HW_NONE, 0x801353A, false }, + { "AGFE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x801353A, false }, // Koro Koro Puzzle - Happy Panechu! - { "KHPJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, + { "KHPJ", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, // Legendz - Yomigaeru Shiren no Shima - { "BLJJ", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, - { "BLJK", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, + { "BLJJ", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, + { "BLJK", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, // Legendz - Sign of Nekuromu - { "BLVJ", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, + { "BLVJ", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, // Mega Man Battle Network - { "AREE", SAVEDATA_SRAM, HW_NONE, 0x800032E, false }, + { "AREE", GBA_SAVEDATA_SRAM, HW_NONE, 0x800032E, false }, // Mega Man Zero - { "AZCE", SAVEDATA_SRAM, HW_NONE, 0x80004E8, false }, + { "AZCE", GBA_SAVEDATA_SRAM, HW_NONE, 0x80004E8, false }, // Metal Slug Advance - { "BSME", SAVEDATA_EEPROM, HW_NONE, 0x8000290, false }, + { "BSME", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8000290, false }, // Pokemon Ruby - { "AXVJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVE", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVP", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVI", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVS", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVD", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVF", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, // Pokemon Sapphire - { "AXPJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPE", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPP", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPI", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPS", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPD", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPF", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, // Pokemon Emerald - { "BPEJ", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEE", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEP", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEI", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPES", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPED", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEF", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPEJ", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPEE", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPEP", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPEI", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPES", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPED", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPEF", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, // Pokemon Mystery Dungeon - { "B24E", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "B24P", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "B24E", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "B24P", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, // Pokemon FireRed - { "BPRJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRE", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRP", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRI", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRS", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRD", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRF", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, // Pokemon LeafGreen - { "BPGJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGE", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGP", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGI", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGS", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGD", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGF", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, // RockMan EXE 4.5 - Real Operation - { "BR4J", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, + { "BR4J", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, // Rocky - { "AR8E", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "AROP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "AR8E", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "AROP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Sennen Kazoku - { "BKAJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "BKAJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, // Shin Bokura no Taiyou: Gyakushuu no Sabata - { "U33J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U33J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, // Stuart Little 2 - { "ASLE", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, - { "ASLF", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "ASLE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "ASLF", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, // Super Mario Advance 2 - { "AA2J", SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, - { "AA2E", SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, - { "AA2P", SAVEDATA_AUTODETECT, HW_NONE, 0x800052E, false }, + { "AA2J", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, + { "AA2E", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, + { "AA2P", GBA_SAVEDATA_AUTODETECT, HW_NONE, 0x800052E, false }, // Super Mario Advance 3 - { "A3AJ", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, - { "A3AE", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, - { "A3AP", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, + { "A3AJ", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, + { "A3AE", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, + { "A3AP", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, // Super Mario Advance 4 - { "AX4J", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, - { "AX4E", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, - { "AX4P", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, + { "AX4J", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, + { "AX4E", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, + { "AX4P", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, // Super Monkey Ball Jr. - { "ALUE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "ALUP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALUE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALUP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Top Gun - Combat Zones - { "A2YE", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "A2YE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, // Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle - { "BUHJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "BUHJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Wario Ware Twisted - { "RZWJ", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, - { "RZWE", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, - { "RZWP", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, + { "RZWJ", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, + { "RZWE", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, + { "RZWP", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, // Yoshi's Universal Gravitation - { "KYGJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, - { "KYGE", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, - { "KYGP", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, + { "KYGJ", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, + { "KYGE", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, + { "KYGP", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, // Aging cartridge - { "TCHK", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "TCHK", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, // Famicom Mini series 3 (FDS), some aren't mirrored (22 - 28) // See https://forum.no-intro.org/viewtopic.php?f=2&t=4221 for discussion - { "FNMJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FMRJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FPTJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FLBJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FFMJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FTKJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FTUJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FNMJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FMRJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FPTJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FLBJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FFMJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FTKJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FTUJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { { 0, 0, 0, 0 }, 0, 0, IDLE_LOOP_NONE, false } }; bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOverride* override) { - override->savetype = SAVEDATA_AUTODETECT; + override->savetype = GBA_SAVEDATA_AUTODETECT; override->hardware = HW_NONE; override->idleLoop = IDLE_LOOP_NONE; override->mirroring = false; @@ -233,7 +233,7 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver } if (!found && override->id[0] == 'F') { // Classic NES Series - override->savetype = SAVEDATA_EEPROM; + override->savetype = GBA_SAVEDATA_EEPROM; found = true; } @@ -247,25 +247,25 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver if (savetype) { if (strcasecmp(savetype, "SRAM") == 0) { found = true; - override->savetype = SAVEDATA_SRAM; + override->savetype = GBA_SAVEDATA_SRAM; } else if (strcasecmp(savetype, "SRAM512") == 0) { found = true; - override->savetype = SAVEDATA_SRAM512; + override->savetype = GBA_SAVEDATA_SRAM512; } else if (strcasecmp(savetype, "EEPROM") == 0) { found = true; - override->savetype = SAVEDATA_EEPROM; + override->savetype = GBA_SAVEDATA_EEPROM; } else if (strcasecmp(savetype, "EEPROM512") == 0) { found = true; - override->savetype = SAVEDATA_EEPROM512; + override->savetype = GBA_SAVEDATA_EEPROM512; } else if (strcasecmp(savetype, "FLASH512") == 0) { found = true; - override->savetype = SAVEDATA_FLASH512; + override->savetype = GBA_SAVEDATA_FLASH512; } else if (strcasecmp(savetype, "FLASH1M") == 0) { found = true; - override->savetype = SAVEDATA_FLASH1M; + override->savetype = GBA_SAVEDATA_FLASH1M; } else if (strcasecmp(savetype, "NONE") == 0) { found = true; - override->savetype = SAVEDATA_FORCE_NONE; + override->savetype = GBA_SAVEDATA_FORCE_NONE; } } @@ -295,28 +295,28 @@ void GBAOverrideSave(struct Configuration* config, const struct GBACartridgeOver snprintf(sectionName, sizeof(sectionName), "override.%c%c%c%c", override->id[0], override->id[1], override->id[2], override->id[3]); const char* savetype = 0; switch (override->savetype) { - case SAVEDATA_SRAM: + case GBA_SAVEDATA_SRAM: savetype = "SRAM"; break; - case SAVEDATA_SRAM512: + case GBA_SAVEDATA_SRAM512: savetype = "SRAM512"; break; - case SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM: savetype = "EEPROM"; break; - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM512: savetype = "EEPROM512"; break; - case SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH512: savetype = "FLASH512"; break; - case SAVEDATA_FLASH1M: + case GBA_SAVEDATA_FLASH1M: savetype = "FLASH1M"; break; - case SAVEDATA_FORCE_NONE: + case GBA_SAVEDATA_FORCE_NONE: savetype = "NONE"; break; - case SAVEDATA_AUTODETECT: + case GBA_SAVEDATA_AUTODETECT: break; } ConfigurationSetValue(config, sectionName, "savetype", savetype); @@ -335,7 +335,7 @@ void GBAOverrideSave(struct Configuration* config, const struct GBACartridgeOver } void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* override) { - if (override->savetype != SAVEDATA_AUTODETECT) { + if (override->savetype != GBA_SAVEDATA_AUTODETECT) { GBASavedataForceType(&gba->memory.savedata, override->savetype); } @@ -429,7 +429,7 @@ void GBAOverrideApplyDefaults(struct GBA* gba, const struct Configuration* overr if (isPokemon && !isKnownPokemon) { // Enable FLASH1M and RTC on Pokémon ROM hacks - override.savetype = SAVEDATA_FLASH1M; + override.savetype = GBA_SAVEDATA_FLASH1M; override.hardware = HW_RTC; override.vbaBugCompat = true; GBAOverrideApply(gba, &override); diff --git a/src/gba/savedata.c b/src/gba/savedata.c index e7176650b..11be3e0ab 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -44,7 +44,7 @@ static void _ashesToAshes(struct mTiming* timing, void* user, uint32_t cyclesLat } void GBASavedataInit(struct GBASavedata* savedata, struct VFile* vf) { - savedata->type = SAVEDATA_AUTODETECT; + savedata->type = GBA_SAVEDATA_AUTODETECT; savedata->data = 0; savedata->command = EEPROM_COMMAND_NULL; savedata->flashState = FLASH_STATE_RAW; @@ -72,35 +72,35 @@ void GBASavedataDeinit(struct GBASavedata* savedata) { savedata->vf = NULL; } else { switch (savedata->type) { - case SAVEDATA_SRAM: + case GBA_SAVEDATA_SRAM: mappedMemoryFree(savedata->data, GBA_SIZE_SRAM); break; - case SAVEDATA_SRAM512: + case GBA_SAVEDATA_SRAM512: mappedMemoryFree(savedata->data, GBA_SIZE_SRAM512); break; - case SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH512: mappedMemoryFree(savedata->data, GBA_SIZE_FLASH512); break; - case SAVEDATA_FLASH1M: + case GBA_SAVEDATA_FLASH1M: mappedMemoryFree(savedata->data, GBA_SIZE_FLASH1M); break; - case SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM: mappedMemoryFree(savedata->data, GBA_SIZE_EEPROM); break; - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM512: mappedMemoryFree(savedata->data, GBA_SIZE_EEPROM512); break; - case SAVEDATA_FORCE_NONE: - case SAVEDATA_AUTODETECT: + case GBA_SAVEDATA_FORCE_NONE: + case GBA_SAVEDATA_AUTODETECT: break; } } savedata->data = 0; - savedata->type = SAVEDATA_AUTODETECT; + savedata->type = GBA_SAVEDATA_AUTODETECT; } void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf, bool writeback) { - enum SavedataType type = savedata->type; + enum GBASavedataType type = savedata->type; struct VFile* oldVf = savedata->vf; GBASavedataDeinit(savedata); if (oldVf && oldVf != savedata->realVf) { @@ -116,7 +116,7 @@ void GBASavedataUnmask(struct GBASavedata* savedata) { if (!savedata->realVf || savedata->vf == savedata->realVf) { return; } - enum SavedataType type = savedata->type; + enum GBASavedataType type = savedata->type; struct VFile* vf = savedata->vf; GBASavedataDeinit(savedata); savedata->vf = savedata->realVf; @@ -132,20 +132,20 @@ void GBASavedataUnmask(struct GBASavedata* savedata) { bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) { if (savedata->data) { switch (savedata->type) { - case SAVEDATA_SRAM: + case GBA_SAVEDATA_SRAM: return out->write(out, savedata->data, GBA_SIZE_SRAM) == GBA_SIZE_SRAM; - case SAVEDATA_SRAM512: + case GBA_SAVEDATA_SRAM512: return out->write(out, savedata->data, GBA_SIZE_SRAM512) == GBA_SIZE_SRAM512; - case SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH512: return out->write(out, savedata->data, GBA_SIZE_FLASH512) == GBA_SIZE_FLASH512; - case SAVEDATA_FLASH1M: + case GBA_SAVEDATA_FLASH1M: return out->write(out, savedata->data, GBA_SIZE_FLASH1M) == GBA_SIZE_FLASH1M; - case SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM: return out->write(out, savedata->data, GBA_SIZE_EEPROM) == GBA_SIZE_EEPROM; - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM512: return out->write(out, savedata->data, GBA_SIZE_EEPROM512) == GBA_SIZE_EEPROM512; - case SAVEDATA_AUTODETECT: - case SAVEDATA_FORCE_NONE: + case GBA_SAVEDATA_AUTODETECT: + case GBA_SAVEDATA_FORCE_NONE: return true; } } else if (savedata->vf) { @@ -163,21 +163,21 @@ bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) { size_t GBASavedataSize(const struct GBASavedata* savedata) { switch (savedata->type) { - case SAVEDATA_SRAM: + case GBA_SAVEDATA_SRAM: return GBA_SIZE_SRAM; - case SAVEDATA_SRAM512: + case GBA_SAVEDATA_SRAM512: return GBA_SIZE_SRAM512; - case SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH512: return GBA_SIZE_FLASH512; - case SAVEDATA_FLASH1M: + case GBA_SAVEDATA_FLASH1M: return GBA_SIZE_FLASH1M; - case SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM: return GBA_SIZE_EEPROM; - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM512: return GBA_SIZE_EEPROM512; - case SAVEDATA_FORCE_NONE: + case GBA_SAVEDATA_FORCE_NONE: return 0; - case SAVEDATA_AUTODETECT: + case GBA_SAVEDATA_AUTODETECT: default: if (savedata->vf) { return savedata->vf->size(savedata->vf); @@ -188,7 +188,7 @@ size_t GBASavedataSize(const struct GBASavedata* savedata) { bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in) { if (savedata->data) { - if (!in || savedata->type == SAVEDATA_FORCE_NONE) { + if (!in || savedata->type == GBA_SAVEDATA_FORCE_NONE) { return false; } ssize_t size = GBASavedataSize(savedata); @@ -220,11 +220,11 @@ bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in) { return true; } -void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) { +void GBASavedataForceType(struct GBASavedata* savedata, enum GBASavedataType type) { if (savedata->type == type) { return; } - if (savedata->type != SAVEDATA_AUTODETECT) { + if (savedata->type != GBA_SAVEDATA_AUTODETECT) { struct VFile* vf = savedata->vf; int mapMode = savedata->mapMode; bool maskWriteback = savedata->maskWriteback; @@ -234,40 +234,40 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) savedata->maskWriteback = maskWriteback; } switch (type) { - case SAVEDATA_FLASH512: - case SAVEDATA_FLASH1M: + case GBA_SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH1M: savedata->type = type; GBASavedataInitFlash(savedata); break; - case SAVEDATA_EEPROM: - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM512: savedata->type = type; GBASavedataInitEEPROM(savedata); break; - case SAVEDATA_SRAM: + case GBA_SAVEDATA_SRAM: GBASavedataInitSRAM(savedata); break; - case SAVEDATA_SRAM512: + case GBA_SAVEDATA_SRAM512: GBASavedataInitSRAM512(savedata); break; - case SAVEDATA_FORCE_NONE: - savedata->type = SAVEDATA_FORCE_NONE; + case GBA_SAVEDATA_FORCE_NONE: + savedata->type = GBA_SAVEDATA_FORCE_NONE; break; - case SAVEDATA_AUTODETECT: + case GBA_SAVEDATA_AUTODETECT: break; } } void GBASavedataInitFlash(struct GBASavedata* savedata) { - if (savedata->type == SAVEDATA_AUTODETECT) { - savedata->type = SAVEDATA_FLASH512; + if (savedata->type == GBA_SAVEDATA_AUTODETECT) { + savedata->type = GBA_SAVEDATA_FLASH512; } - if (savedata->type != SAVEDATA_FLASH512 && savedata->type != SAVEDATA_FLASH1M) { + if (savedata->type != GBA_SAVEDATA_FLASH512 && savedata->type != GBA_SAVEDATA_FLASH1M) { mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); return; } int32_t flashSize = GBA_SIZE_FLASH512; - if (savedata->type == SAVEDATA_FLASH1M) { + if (savedata->type == GBA_SAVEDATA_FLASH1M) { flashSize = GBA_SIZE_FLASH1M; } off_t end; @@ -289,14 +289,14 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { } void GBASavedataInitEEPROM(struct GBASavedata* savedata) { - if (savedata->type == SAVEDATA_AUTODETECT) { - savedata->type = SAVEDATA_EEPROM512; - } else if (savedata->type != SAVEDATA_EEPROM512 && savedata->type != SAVEDATA_EEPROM) { + if (savedata->type == GBA_SAVEDATA_AUTODETECT) { + savedata->type = GBA_SAVEDATA_EEPROM512; + } else if (savedata->type != GBA_SAVEDATA_EEPROM512 && savedata->type != GBA_SAVEDATA_EEPROM) { mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); return; } int32_t eepromSize = GBA_SIZE_EEPROM512; - if (savedata->type == SAVEDATA_EEPROM) { + if (savedata->type == GBA_SAVEDATA_EEPROM) { eepromSize = GBA_SIZE_EEPROM; } off_t end; @@ -316,8 +316,8 @@ void GBASavedataInitEEPROM(struct GBASavedata* savedata) { } void GBASavedataInitSRAM(struct GBASavedata* savedata) { - if (savedata->type == SAVEDATA_AUTODETECT) { - savedata->type = SAVEDATA_SRAM; + if (savedata->type == GBA_SAVEDATA_AUTODETECT) { + savedata->type = GBA_SAVEDATA_SRAM; } else { mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); return; @@ -340,8 +340,8 @@ void GBASavedataInitSRAM(struct GBASavedata* savedata) { } void GBASavedataInitSRAM512(struct GBASavedata* savedata) { - if (savedata->type == SAVEDATA_AUTODETECT) { - savedata->type = SAVEDATA_SRAM512; + if (savedata->type == GBA_SAVEDATA_AUTODETECT) { + savedata->type = GBA_SAVEDATA_SRAM512; } else { mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); return; @@ -365,11 +365,11 @@ void GBASavedataInitSRAM512(struct GBASavedata* savedata) { uint8_t GBASavedataReadFlash(struct GBASavedata* savedata, uint16_t address) { if (savedata->command == FLASH_COMMAND_ID) { - if (savedata->type == SAVEDATA_FLASH512) { + if (savedata->type == GBA_SAVEDATA_FLASH512) { if (address < 2) { return FLASH_MFG_PANASONIC >> (address * 8); } - } else if (savedata->type == SAVEDATA_FLASH1M) { + } else if (savedata->type == GBA_SAVEDATA_FLASH1M) { if (address < 2) { return FLASH_MFG_SANYO >> (address * 8); } @@ -472,10 +472,10 @@ static void _ensureEeprom(struct GBASavedata* savedata, uint32_t size) { if (size < GBA_SIZE_EEPROM512) { return; } - if (savedata->type == SAVEDATA_EEPROM) { + if (savedata->type == GBA_SAVEDATA_EEPROM) { return; } - savedata->type = SAVEDATA_EEPROM; + savedata->type = GBA_SAVEDATA_EEPROM; if (!savedata->vf) { return; } @@ -605,7 +605,7 @@ void GBASavedataRTCWrite(struct GBASavedata* savedata) { int bank = 0; if ((savedata->vf->size(savedata->vf) & 0xFF) != sizeof(buffer)) { // Writing past the end of the file can invalidate the file mapping - if (savedata->type == SAVEDATA_FLASH1M) { + if (savedata->type == GBA_SAVEDATA_FLASH1M) { bank = savedata->currentBank == &savedata->data[0x10000]; } savedata->vf->unmap(savedata->vf, savedata->data, size); @@ -614,9 +614,9 @@ void GBASavedataRTCWrite(struct GBASavedata* savedata) { savedata->vf->write(savedata->vf, &buffer, sizeof(buffer)); if (!savedata->data) { savedata->data = savedata->vf->map(savedata->vf, size, MAP_WRITE); - if (savedata->type == SAVEDATA_FLASH1M) { + if (savedata->type == GBA_SAVEDATA_FLASH1M) { savedata->currentBank = &savedata->data[bank << 16]; - } else if (savedata->type == SAVEDATA_FLASH512) { + } else if (savedata->type == GBA_SAVEDATA_FLASH512) { savedata->currentBank = savedata->data; } } @@ -730,7 +730,7 @@ void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerial LOAD_32(savedata->writeAddress, 0, &state->savedata.writeAddress); LOAD_16(savedata->settling, 0, &state->savedata.settlingSector); - if (savedata->type == SAVEDATA_FLASH1M) { + if (savedata->type == GBA_SAVEDATA_FLASH1M) { _flashSwitchBank(savedata, GBASerializedSavedataFlagsGetFlashBank(flags)); } @@ -743,9 +743,9 @@ void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerial void _flashSwitchBank(struct GBASavedata* savedata, int bank) { mLOG(GBA_SAVE, DEBUG, "Performing flash bank switch to bank %i", bank); - if (bank > 0 && savedata->type == SAVEDATA_FLASH512) { + if (bank > 0 && savedata->type == GBA_SAVEDATA_FLASH512) { mLOG(GBA_SAVE, INFO, "Updating flash chip from 512kb to 1Mb"); - savedata->type = SAVEDATA_FLASH1M; + savedata->type = GBA_SAVEDATA_FLASH1M; if (savedata->vf) { savedata->vf->unmap(savedata->vf, savedata->data, GBA_SIZE_FLASH512); if (savedata->vf->size(savedata->vf) < GBA_SIZE_FLASH1M) { @@ -764,7 +764,7 @@ void _flashErase(struct GBASavedata* savedata) { mLOG(GBA_SAVE, DEBUG, "Performing flash chip erase"); savedata->dirty |= mSAVEDATA_DIRT_NEW; size_t size = GBA_SIZE_FLASH512; - if (savedata->type == SAVEDATA_FLASH1M) { + if (savedata->type == GBA_SAVEDATA_FLASH1M) { size = GBA_SIZE_FLASH1M; } memset(savedata->data, 0xFF, size); @@ -774,7 +774,7 @@ void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart) { mLOG(GBA_SAVE, DEBUG, "Performing flash sector erase at 0x%04x", sectorStart); savedata->dirty |= mSAVEDATA_DIRT_NEW; size_t size = 0x1000; - if (savedata->type == SAVEDATA_FLASH1M) { + if (savedata->type == GBA_SAVEDATA_FLASH1M) { mLOG(GBA_SAVE, DEBUG, "Performing unknown sector-size erase at 0x%04x", sectorStart); } savedata->settling = sectorStart >> 12; diff --git a/src/gba/sharkport.c b/src/gba/sharkport.c index 9e1e64518..2f33e3d41 100644 --- a/src/gba/sharkport.c +++ b/src/gba/sharkport.c @@ -18,9 +18,9 @@ static const int GSV_PAYLOAD_OFFSET = 0x430; static bool _importSavedata(struct GBA* gba, void* payload, size_t size) { bool success = false; switch (gba->memory.savedata.type) { - case SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH512: if (size > GBA_SIZE_FLASH512) { - GBASavedataForceType(&gba->memory.savedata, SAVEDATA_FLASH1M); + GBASavedataForceType(&gba->memory.savedata, GBA_SAVEDATA_FLASH1M); } // Fall through default: @@ -28,8 +28,8 @@ static bool _importSavedata(struct GBA* gba, void* payload, size_t size) { size = GBASavedataSize(&gba->memory.savedata); } break; - case SAVEDATA_FORCE_NONE: - case SAVEDATA_AUTODETECT: + case GBA_SAVEDATA_FORCE_NONE: + case GBA_SAVEDATA_AUTODETECT: goto cleanup; } @@ -276,7 +276,7 @@ bool GBASavedataExportSharkPort(const struct GBA* gba, struct VFile* vf) { checksum += buffer.c[i] << (checksum % 24); } - if (gba->memory.savedata.type == SAVEDATA_EEPROM) { + if (gba->memory.savedata.type == GBA_SAVEDATA_EEPROM) { for (i = 0; i < size; ++i) { char byte = gba->memory.savedata.data[i ^ 7]; checksum += byte << (checksum % 24); diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 8c08e7bb6..bea9f6273 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -1156,7 +1156,7 @@ size_t retro_get_memory_size(unsigned id) { #ifdef M_CORE_GBA case mPLATFORM_GBA: switch (((struct GBA*) core->board)->memory.savedata.type) { - case SAVEDATA_AUTODETECT: + case GBA_SAVEDATA_AUTODETECT: return GBA_SIZE_FLASH1M; default: return GBASavedataSize(&((struct GBA*) core->board)->memory.savedata); diff --git a/src/platform/qt/OverrideView.cpp b/src/platform/qt/OverrideView.cpp index 07e114c1c..9e51fab4a 100644 --- a/src/platform/qt/OverrideView.cpp +++ b/src/platform/qt/OverrideView.cpp @@ -153,14 +153,14 @@ void OverrideView::updateOverrides() { if (m_ui.tabWidget->currentWidget() == m_ui.tabGBA) { auto gba = std::make_unique(); memset(gba->override.id, 0, 4); - gba->override.savetype = static_cast(m_ui.savetype->currentIndex() - 1); + gba->override.savetype = static_cast(m_ui.savetype->currentIndex() - 1); gba->override.hardware = HW_NO_OVERRIDE; gba->override.idleLoop = IDLE_LOOP_NONE; gba->override.mirroring = false; gba->override.vbaBugCompat = false; gba->vbaBugCompatSet = false; - if (gba->override.savetype != SAVEDATA_AUTODETECT) { + if (gba->override.savetype != GBA_SAVEDATA_AUTODETECT) { hasOverride = true; } if (!m_ui.hwAutodetect->isChecked()) { diff --git a/src/platform/qt/SaveConverter.cpp b/src/platform/qt/SaveConverter.cpp index 44e061c8f..d16eeeea4 100644 --- a/src/platform/qt/SaveConverter.cpp +++ b/src/platform/qt/SaveConverter.cpp @@ -170,8 +170,8 @@ void SaveConverter::detectFromSavestate(VFile* vf) { switch (platform) { #ifdef M_CORE_GBA case mPLATFORM_GBA: - save.gba.type = static_cast(state.at(offsetof(GBASerializedState, savedata.type))); - if (save.gba.type == SAVEDATA_EEPROM || save.gba.type == SAVEDATA_EEPROM512) { + save.gba.type = static_cast(state.at(offsetof(GBASerializedState, savedata.type))); + if (save.gba.type == GBA_SAVEDATA_EEPROM || save.gba.type == GBA_SAVEDATA_EEPROM512) { save.endianness = Endian::LITTLE; } break; @@ -198,25 +198,25 @@ void SaveConverter::detectFromSize(std::shared_ptr vf) { switch (vf->size()) { case GBA_SIZE_SRAM: case GBA_SIZE_SRAM + 16: - m_validSaves.append(AnnotatedSave{SAVEDATA_SRAM, vf}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_SRAM, vf}); break; case GBA_SIZE_FLASH512: case GBA_SIZE_FLASH512 + 16: - m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH512, vf}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH512, vf}); break; case GBA_SIZE_FLASH1M: case GBA_SIZE_FLASH1M + 16: - m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, vf}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, vf}); break; case GBA_SIZE_EEPROM: case GBA_SIZE_EEPROM + 16: - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, vf, Endian::LITTLE}); - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, vf, Endian::BIG}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, vf, Endian::LITTLE}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, vf, Endian::BIG}); break; case GBA_SIZE_EEPROM512: case GBA_SIZE_EEPROM512 + 16: - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, vf, Endian::LITTLE}); - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, vf, Endian::BIG}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, vf, Endian::LITTLE}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, vf, Endian::BIG}); break; } #endif @@ -272,12 +272,12 @@ void SaveConverter::detectFromHeaders(std::shared_ptr vf) { QByteArray bytes = QByteArray::fromRawData(static_cast(data), size); bytes.data(); // Trigger a deep copy before we delete the backing if (size == GBA_SIZE_FLASH1M) { - m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, std::make_shared(bytes), Endian::NONE, Container::SHARKPORT}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, std::make_shared(bytes), Endian::NONE, Container::SHARKPORT}); } else { - m_validSaves.append(AnnotatedSave{SAVEDATA_SRAM, std::make_shared(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::SHARKPORT}); - m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH512, std::make_shared(bytes.left(GBA_SIZE_FLASH512)), Endian::NONE, Container::SHARKPORT}); - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, std::make_shared(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::SHARKPORT}); - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, std::make_shared(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::SHARKPORT}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_SRAM, std::make_shared(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::SHARKPORT}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH512, std::make_shared(bytes.left(GBA_SIZE_FLASH512)), Endian::NONE, Container::SHARKPORT}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, std::make_shared(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::SHARKPORT}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, std::make_shared(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::SHARKPORT}); } free(data); } @@ -289,20 +289,20 @@ void SaveConverter::detectFromHeaders(std::shared_ptr vf) { bytes.data(); // Trigger a deep copy before we delete the backing switch (size) { case GBA_SIZE_FLASH1M: - m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, std::make_shared(bytes), Endian::NONE, Container::GSV}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, std::make_shared(bytes), Endian::NONE, Container::GSV}); break; case GBA_SIZE_FLASH512: - m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH512, std::make_shared(bytes), Endian::NONE, Container::GSV}); - m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, std::make_shared(bytes), Endian::NONE, Container::GSV}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH512, std::make_shared(bytes), Endian::NONE, Container::GSV}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, std::make_shared(bytes), Endian::NONE, Container::GSV}); break; case GBA_SIZE_SRAM: - m_validSaves.append(AnnotatedSave{SAVEDATA_SRAM, std::make_shared(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::GSV}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_SRAM, std::make_shared(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::GSV}); break; case GBA_SIZE_EEPROM: - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, std::make_shared(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::GSV}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, std::make_shared(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::GSV}); break; case GBA_SIZE_EEPROM512: - m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, std::make_shared(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::GSV}); + m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, std::make_shared(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::GSV}); break; } free(data); @@ -401,7 +401,7 @@ SaveConverter::AnnotatedSave::AnnotatedSave(mPlatform platform, std::shared_ptr< } #ifdef M_CORE_GBA -SaveConverter::AnnotatedSave::AnnotatedSave(SavedataType type, std::shared_ptr vf, Endian endianness, Container container) +SaveConverter::AnnotatedSave::AnnotatedSave(GBASavedataType type, std::shared_ptr vf, Endian endianness, Container container) : container(container) , platform(mPLATFORM_GBA) , size(vf->size()) @@ -468,15 +468,15 @@ SaveConverter::AnnotatedSave::operator QString() const { #ifdef M_CORE_GBA case mPLATFORM_GBA: switch (gba.type) { - case SAVEDATA_SRAM: + case GBA_SAVEDATA_SRAM: typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "SRAM"); break; - case SAVEDATA_FLASH512: - case SAVEDATA_FLASH1M: + case GBA_SAVEDATA_FLASH512: + case GBA_SAVEDATA_FLASH1M: typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 flash"); break; - case SAVEDATA_EEPROM: - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM512: typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 EEPROM"); break; default: @@ -664,8 +664,8 @@ QByteArray SaveConverter::AnnotatedSave::convertTo(const SaveConverter::Annotate #ifdef M_CORE_GBA case mPLATFORM_GBA: switch (gba.type) { - case SAVEDATA_EEPROM: - case SAVEDATA_EEPROM512: + case GBA_SAVEDATA_EEPROM: + case GBA_SAVEDATA_EEPROM512: if (endianness == target.endianness) { break; } diff --git a/src/platform/qt/SaveConverter.h b/src/platform/qt/SaveConverter.h index 2fa133071..764e13d9c 100644 --- a/src/platform/qt/SaveConverter.h +++ b/src/platform/qt/SaveConverter.h @@ -48,7 +48,7 @@ private slots: private: #ifdef M_CORE_GBA struct GBASave { - SavedataType type; + GBASavedataType type; }; #endif #ifdef M_CORE_GB @@ -66,7 +66,7 @@ private: AnnotatedSave(); AnnotatedSave(mPlatform, std::shared_ptr, Endian = Endian::NONE, Container = Container::NONE); #ifdef M_CORE_GBA - AnnotatedSave(SavedataType, std::shared_ptr, Endian = Endian::NONE, Container = Container::NONE); + AnnotatedSave(GBASavedataType, std::shared_ptr, Endian = Endian::NONE, Container = Container::NONE); #endif #ifdef M_CORE_GB AnnotatedSave(GBMemoryBankControllerType, std::shared_ptr, Endian = Endian::NONE, Container = Container::NONE); From e48acb6b97fa59b8f317eff55f59a21b0fc6bd1c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2024 23:03:59 -0700 Subject: [PATCH 094/336] GB, GBA: Move override structs to public API --- include/mgba/gb/interface.h | 15 +++ include/mgba/gba/interface.h | 22 ++++ include/mgba/internal/gb/overrides.h | 15 --- include/mgba/internal/gba/overrides.h | 13 +- include/mgba/internal/gba/savedata.h | 12 +- src/gba/core.c | 2 +- src/gba/overrides.c | 182 +++++++++++++------------- src/platform/qt/OverrideView.cpp | 4 +- 8 files changed, 133 insertions(+), 132 deletions(-) diff --git a/include/mgba/gb/interface.h b/include/mgba/gb/interface.h index ecd99e2f9..485111b41 100644 --- a/include/mgba/gb/interface.h +++ b/include/mgba/gb/interface.h @@ -58,6 +58,13 @@ enum GBVideoLayer { GB_LAYER_OBJ }; +enum GBColorLookup { + GB_COLORS_NONE = 0, + GB_COLORS_CGB = 1, + GB_COLORS_SGB = 2, + GB_COLORS_SGB_CGB_FALLBACK = GB_COLORS_CGB | GB_COLORS_SGB +}; + struct GBSIODriver { struct GBSIO* p; @@ -67,6 +74,14 @@ struct GBSIODriver { uint8_t (*writeSC)(struct GBSIODriver* driver, uint8_t value); }; +struct GBCartridgeOverride { + int headerCrc32; + enum GBModel model; + enum GBMemoryBankControllerType mbc; + + uint32_t gbColors[12]; +}; + struct VFile; bool GBIsROM(struct VFile* vf); diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index bf10c59ba..f2f05064d 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -13,6 +13,8 @@ CXX_GUARD_START #include #include +#define GBA_IDLE_LOOP_NONE 0xFFFFFFFF + enum { GBA_VIDEO_HORIZONTAL_PIXELS = 240, GBA_VIDEO_VERTICAL_PIXELS = 160, @@ -45,6 +47,17 @@ enum GBAVideoLayer { GBA_LAYER_OBJWIN, }; +enum GBASavedataType { + GBA_SAVEDATA_AUTODETECT = -1, + GBA_SAVEDATA_FORCE_NONE = 0, + GBA_SAVEDATA_SRAM = 1, + GBA_SAVEDATA_FLASH512 = 2, + GBA_SAVEDATA_FLASH1M = 3, + GBA_SAVEDATA_EEPROM = 4, + GBA_SAVEDATA_EEPROM512 = 5, + GBA_SAVEDATA_SRAM512 = 6, +}; + struct GBA; struct GBAAudio; struct GBASIO; @@ -78,6 +91,15 @@ struct GBASIODriver { uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value); }; +struct GBACartridgeOverride { + char id[4]; + enum GBASavedataType savetype; + int hardware; + uint32_t idleLoop; + bool mirroring; + bool vbaBugCompat; +}; + void GBASIOJOYCreate(struct GBASIODriver* sio); enum GBASIOBattleChipGateFlavor { diff --git a/include/mgba/internal/gb/overrides.h b/include/mgba/internal/gb/overrides.h index 86cac0f9d..6e683f0de 100644 --- a/include/mgba/internal/gb/overrides.h +++ b/include/mgba/internal/gb/overrides.h @@ -12,21 +12,6 @@ CXX_GUARD_START #include -enum GBColorLookup { - GB_COLORS_NONE = 0, - GB_COLORS_CGB = 1, - GB_COLORS_SGB = 2, - GB_COLORS_SGB_CGB_FALLBACK = GB_COLORS_CGB | GB_COLORS_SGB -}; - -struct GBCartridgeOverride { - int headerCrc32; - enum GBModel model; - enum GBMemoryBankControllerType mbc; - - uint32_t gbColors[12]; -}; - struct GBColorPreset { const char* name; uint32_t colors[12]; diff --git a/include/mgba/internal/gba/overrides.h b/include/mgba/internal/gba/overrides.h index 83a63f0a4..b2eba2d7a 100644 --- a/include/mgba/internal/gba/overrides.h +++ b/include/mgba/internal/gba/overrides.h @@ -10,18 +10,7 @@ CXX_GUARD_START -#include - -#define IDLE_LOOP_NONE 0xFFFFFFFF - -struct GBACartridgeOverride { - char id[4]; - enum GBASavedataType savetype; - int hardware; - uint32_t idleLoop; - bool mirroring; - bool vbaBugCompat; -}; +#include struct Configuration; bool GBAOverrideFind(const struct Configuration*, struct GBACartridgeOverride* override); diff --git a/include/mgba/internal/gba/savedata.h b/include/mgba/internal/gba/savedata.h index a03f2960c..274241a76 100644 --- a/include/mgba/internal/gba/savedata.h +++ b/include/mgba/internal/gba/savedata.h @@ -12,22 +12,12 @@ CXX_GUARD_START #include #include +#include mLOG_DECLARE_CATEGORY(GBA_SAVE); struct VFile; -enum GBASavedataType { - GBA_SAVEDATA_AUTODETECT = -1, - GBA_SAVEDATA_FORCE_NONE = 0, - GBA_SAVEDATA_SRAM = 1, - GBA_SAVEDATA_FLASH512 = 2, - GBA_SAVEDATA_FLASH1M = 3, - GBA_SAVEDATA_EEPROM = 4, - GBA_SAVEDATA_EEPROM512 = 5, - GBA_SAVEDATA_SRAM512 = 6, -}; - enum SavedataCommand { EEPROM_COMMAND_NULL = 0, EEPROM_COMMAND_PENDING = 1, diff --git a/src/gba/core.c b/src/gba/core.c index 89bcaafc6..54c436b3a 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -374,7 +374,7 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con } else if (strcasecmp(idleOptimization, "remove") == 0) { gba->idleOptimization = IDLE_LOOP_REMOVE; } else if (strcasecmp(idleOptimization, "detect") == 0) { - if (gba->idleLoop == IDLE_LOOP_NONE) { + if (gba->idleLoop == GBA_IDLE_LOOP_NONE) { gba->idleOptimization = IDLE_LOOP_DETECT; } else { gba->idleOptimization = IDLE_LOOP_REMOVE; diff --git a/src/gba/overrides.c b/src/gba/overrides.c index 44a47efb5..a35830705 100644 --- a/src/gba/overrides.c +++ b/src/gba/overrides.c @@ -21,73 +21,73 @@ static const struct GBACartridgeOverride _overrides[] = { { "AW2P", GBA_SAVEDATA_FLASH512, HW_NONE, 0x803719C, false }, // Boktai: The Sun is in Your Hand - { "U3IJ", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U3IE", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U3IP", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U3IJ", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, + { "U3IE", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, + { "U3IP", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, // Boktai 2: Solar Boy Django - { "U32J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U32E", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, - { "U32P", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U32J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, + { "U32E", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, + { "U32P", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, // Crash Bandicoot 2 - N-Tranced - { "AC8J", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "AC8E", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "AC8P", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "AC8J", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "AC8E", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "AC8P", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // DigiCommunication Nyo - Datou! Black Gemagema Dan - { "BDKJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "BDKJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Dragon Ball Z - The Legacy of Goku - { "ALGP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALGP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Dragon Ball Z - The Legacy of Goku II - { "ALFJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "ALFE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "ALFP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALFJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ALFE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ALFP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Dragon Ball Z - Taiketsu - { "BDBE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "BDBP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "BDBE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BDBP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Drill Dozer - { "V49J", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, - { "V49E", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, - { "V49P", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, + { "V49J", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, + { "V49E", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, + { "V49P", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, // e-Reader - { "PEAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, - { "PSAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, - { "PSAE", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, + { "PEAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, GBA_IDLE_LOOP_NONE }, + { "PSAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, GBA_IDLE_LOOP_NONE }, + { "PSAE", GBA_SAVEDATA_FLASH1M, HW_EREADER, GBA_IDLE_LOOP_NONE }, // Final Fantasy Tactics Advance { "AFXE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8000428, false }, // F-Zero - Climax - { "BFTJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BFTJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Goodboy Galaxy - { "2GBP", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, + { "2GBP", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, // Iridion II - { "AI2E", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, - { "AI2P", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "AI2E", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "AI2P", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Game Boy Wars Advance 1+2 - { "BGWJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BGWJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Golden Sun: The Lost Age { "AGFE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x801353A, false }, // Koro Koro Puzzle - Happy Panechu! - { "KHPJ", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, + { "KHPJ", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, // Legendz - Yomigaeru Shiren no Shima - { "BLJJ", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, - { "BLJK", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, + { "BLJJ", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "BLJK", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, // Legendz - Sign of Nekuromu - { "BLVJ", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, + { "BLVJ", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, // Mega Man Battle Network { "AREE", GBA_SAVEDATA_SRAM, HW_NONE, 0x800032E, false }, @@ -99,22 +99,22 @@ static const struct GBACartridgeOverride _overrides[] = { { "BSME", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8000290, false }, // Pokemon Ruby - { "AXVJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVE", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVP", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVI", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVS", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVD", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXVF", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXVJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXVE", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXVP", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXVI", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXVS", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXVD", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXVF", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, // Pokemon Sapphire - { "AXPJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPE", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPP", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPI", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPS", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPD", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, - { "AXPF", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "AXPJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXPE", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXPP", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXPI", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXPS", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXPD", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXPF", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, // Pokemon Emerald { "BPEJ", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, @@ -126,43 +126,43 @@ static const struct GBACartridgeOverride _overrides[] = { { "BPEF", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, // Pokemon Mystery Dungeon - { "B24E", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "B24P", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "B24E", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "B24P", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Pokemon FireRed - { "BPRJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRE", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRP", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRI", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRS", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRD", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPRF", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPRJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPRE", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPRP", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPRI", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPRS", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPRD", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPRF", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Pokemon LeafGreen - { "BPGJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGE", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGP", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGI", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGS", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGD", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, - { "BPGF", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, + { "BPGJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPGE", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPGP", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPGI", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPGS", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPGD", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPGF", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // RockMan EXE 4.5 - Real Operation - { "BR4J", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, + { "BR4J", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, // Rocky - { "AR8E", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "AROP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "AR8E", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "AROP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Sennen Kazoku - { "BKAJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, + { "BKAJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, // Shin Bokura no Taiyou: Gyakushuu no Sabata - { "U33J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, + { "U33J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, // Stuart Little 2 - { "ASLE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, - { "ASLF", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "ASLE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ASLF", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Super Mario Advance 2 { "AA2J", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, @@ -180,45 +180,45 @@ static const struct GBACartridgeOverride _overrides[] = { { "AX4P", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, // Super Monkey Ball Jr. - { "ALUE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "ALUP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "ALUE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ALUP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Top Gun - Combat Zones - { "A2YE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, + { "A2YE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle - { "BUHJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "BUHJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Wario Ware Twisted - { "RZWJ", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, - { "RZWE", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, - { "RZWP", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, + { "RZWJ", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE, false }, + { "RZWE", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE, false }, + { "RZWP", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE, false }, // Yoshi's Universal Gravitation - { "KYGJ", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, - { "KYGE", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, - { "KYGP", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, + { "KYGJ", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, + { "KYGE", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, + { "KYGP", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, // Aging cartridge - { "TCHK", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "TCHK", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, // Famicom Mini series 3 (FDS), some aren't mirrored (22 - 28) // See https://forum.no-intro.org/viewtopic.php?f=2&t=4221 for discussion - { "FNMJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FMRJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FPTJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FLBJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FFMJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FTKJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, - { "FTUJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, + { "FNMJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "FMRJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "FPTJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "FLBJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "FFMJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "FTKJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "FTUJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { { 0, 0, 0, 0 }, 0, 0, IDLE_LOOP_NONE, false } + { { 0, 0, 0, 0 }, 0, 0, GBA_IDLE_LOOP_NONE, false } }; bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOverride* override) { override->savetype = GBA_SAVEDATA_AUTODETECT; override->hardware = HW_NONE; - override->idleLoop = IDLE_LOOP_NONE; + override->idleLoop = GBA_IDLE_LOOP_NONE; override->mirroring = false; override->vbaBugCompat = false; bool found = false; @@ -327,7 +327,7 @@ void GBAOverrideSave(struct Configuration* config, const struct GBACartridgeOver ConfigurationClearValue(config, sectionName, "hardware"); } - if (override->idleLoop != IDLE_LOOP_NONE) { + if (override->idleLoop != GBA_IDLE_LOOP_NONE) { ConfigurationSetUIntValue(config, sectionName, "idleLoop", override->idleLoop); } else { ConfigurationClearValue(config, sectionName, "idleLoop"); @@ -376,7 +376,7 @@ void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* overri } } - if (override->idleLoop != IDLE_LOOP_NONE) { + if (override->idleLoop != GBA_IDLE_LOOP_NONE) { gba->idleLoop = override->idleLoop; if (gba->idleOptimization == IDLE_LOOP_DETECT) { gba->idleOptimization = IDLE_LOOP_REMOVE; @@ -385,7 +385,7 @@ void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* overri } void GBAOverrideApplyDefaults(struct GBA* gba, const struct Configuration* overrides) { - struct GBACartridgeOverride override = { .idleLoop = IDLE_LOOP_NONE }; + struct GBACartridgeOverride override = { .idleLoop = GBA_IDLE_LOOP_NONE }; const struct GBACartridge* cart = (const struct GBACartridge*) gba->memory.rom; if (cart) { memcpy(override.id, &cart->id, sizeof(override.id)); diff --git a/src/platform/qt/OverrideView.cpp b/src/platform/qt/OverrideView.cpp index 9e51fab4a..1d2737521 100644 --- a/src/platform/qt/OverrideView.cpp +++ b/src/platform/qt/OverrideView.cpp @@ -155,7 +155,7 @@ void OverrideView::updateOverrides() { memset(gba->override.id, 0, 4); gba->override.savetype = static_cast(m_ui.savetype->currentIndex() - 1); gba->override.hardware = HW_NO_OVERRIDE; - gba->override.idleLoop = IDLE_LOOP_NONE; + gba->override.idleLoop = GBA_IDLE_LOOP_NONE; gba->override.mirroring = false; gba->override.vbaBugCompat = false; gba->vbaBugCompatSet = false; @@ -246,7 +246,7 @@ void OverrideView::gameStarted() { m_ui.hwGBPlayer->setChecked(gba->memory.hw.devices & HW_GB_PLAYER_DETECTION); m_ui.vbaBugCompat->setChecked(gba->vbaBugCompat); - if (gba->idleLoop != IDLE_LOOP_NONE) { + if (gba->idleLoop != GBA_IDLE_LOOP_NONE) { m_ui.idleLoop->setText(QString::number(gba->idleLoop, 16)); } else { m_ui.idleLoop->clear(); From abf484638e751e385abf52f23e8c5118ef2d2f4d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2024 01:23:14 -0700 Subject: [PATCH 095/336] GBA: Fix build --- src/gba/gba.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gba/gba.c b/src/gba/gba.c index 409bd2b3a..31008507c 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -111,7 +111,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) { gba->biosChecksum = GBAChecksum(gba->memory.bios, GBA_SIZE_BIOS); gba->idleOptimization = IDLE_LOOP_REMOVE; - gba->idleLoop = IDLE_LOOP_NONE; + gba->idleLoop = GBA_IDLE_LOOP_NONE; gba->vbaBugCompat = false; gba->hardCrash = true; @@ -165,7 +165,7 @@ void GBAUnloadROM(struct GBA* gba) { gba->memory.savedata.realVf->close(gba->memory.savedata.realVf); gba->memory.savedata.realVf = 0; } - gba->idleLoop = IDLE_LOOP_NONE; + gba->idleLoop = GBA_IDLE_LOOP_NONE; } void GBADestroy(struct GBA* gba) { From 4a17ed3b9cae7ce018a4f282b0299f5f58197f2e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2024 01:23:39 -0700 Subject: [PATCH 096/336] GBA: Remove legacy "mirroring" field from overrides --- include/mgba/gba/interface.h | 1 - include/mgba/internal/gba/memory.h | 2 - src/gba/overrides.c | 213 ++++++++++++++--------------- src/platform/qt/OverrideView.cpp | 1 - 4 files changed, 101 insertions(+), 116 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index f2f05064d..9d19a55c8 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -96,7 +96,6 @@ struct GBACartridgeOverride { enum GBASavedataType savetype; int hardware; uint32_t idleLoop; - bool mirroring; bool vbaBugCompat; }; diff --git a/include/mgba/internal/gba/memory.h b/include/mgba/internal/gba/memory.h index f9e963d76..c88e1d092 100644 --- a/include/mgba/internal/gba/memory.h +++ b/include/mgba/internal/gba/memory.h @@ -138,8 +138,6 @@ struct GBAMemory { struct GBAPrintContext agbPrintCtxBackup; uint32_t agbPrintFuncBackup; uint16_t* agbPrintBufferBackup; - - bool mirroring; }; struct GBA; diff --git a/src/gba/overrides.c b/src/gba/overrides.c index a35830705..a63616e61 100644 --- a/src/gba/overrides.c +++ b/src/gba/overrides.c @@ -13,47 +13,47 @@ static const struct GBACartridgeOverride _overrides[] = { // Advance Wars - { "AWRE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, - { "AWRP", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, + { "AWRE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, + { "AWRP", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, // Advance Wars 2: Black Hole Rising - { "AW2E", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8036E08, false }, - { "AW2P", GBA_SAVEDATA_FLASH512, HW_NONE, 0x803719C, false }, + { "AW2E", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8036E08 }, + { "AW2P", GBA_SAVEDATA_FLASH512, HW_NONE, 0x803719C }, // Boktai: The Sun is in Your Hand - { "U3IJ", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, - { "U3IE", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, - { "U3IP", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, + { "U3IJ", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE }, + { "U3IE", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE }, + { "U3IP", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE }, // Boktai 2: Solar Boy Django - { "U32J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, - { "U32E", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, - { "U32P", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, + { "U32J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE }, + { "U32E", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE }, + { "U32P", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE }, // Crash Bandicoot 2 - N-Tranced - { "AC8J", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "AC8E", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "AC8P", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "AC8J", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "AC8E", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "AC8P", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // DigiCommunication Nyo - Datou! Black Gemagema Dan - { "BDKJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BDKJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // Dragon Ball Z - The Legacy of Goku - { "ALGP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ALGP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // Dragon Ball Z - The Legacy of Goku II - { "ALFJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "ALFE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "ALFP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ALFJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "ALFE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "ALFP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // Dragon Ball Z - Taiketsu - { "BDBE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BDBP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BDBE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BDBP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // Drill Dozer - { "V49J", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, - { "V49E", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, - { "V49P", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, + { "V49J", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE }, + { "V49E", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE }, + { "V49P", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE }, // e-Reader { "PEAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, GBA_IDLE_LOOP_NONE }, @@ -61,156 +61,146 @@ static const struct GBACartridgeOverride _overrides[] = { { "PSAE", GBA_SAVEDATA_FLASH1M, HW_EREADER, GBA_IDLE_LOOP_NONE }, // Final Fantasy Tactics Advance - { "AFXE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8000428, false }, + { "AFXE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8000428 }, // F-Zero - Climax - { "BFTJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BFTJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, // Goodboy Galaxy - { "2GBP", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE, false }, + { "2GBP", GBA_SAVEDATA_SRAM, HW_RUMBLE, GBA_IDLE_LOOP_NONE }, // Iridion II - { "AI2E", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "AI2P", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "AI2E", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "AI2P", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE }, // Game Boy Wars Advance 1+2 - { "BGWJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BGWJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, // Golden Sun: The Lost Age - { "AGFE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x801353A, false }, + { "AGFE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x801353A }, // Koro Koro Puzzle - Happy Panechu! - { "KHPJ", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, + { "KHPJ", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE }, // Legendz - Yomigaeru Shiren no Shima - { "BLJJ", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "BLJK", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "BLJJ", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "BLJK", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE }, // Legendz - Sign of Nekuromu - { "BLVJ", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "BLVJ", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE }, // Mega Man Battle Network - { "AREE", GBA_SAVEDATA_SRAM, HW_NONE, 0x800032E, false }, + { "AREE", GBA_SAVEDATA_SRAM, HW_NONE, 0x800032E }, // Mega Man Zero - { "AZCE", GBA_SAVEDATA_SRAM, HW_NONE, 0x80004E8, false }, + { "AZCE", GBA_SAVEDATA_SRAM, HW_NONE, 0x80004E8 }, // Metal Slug Advance - { "BSME", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8000290, false }, + { "BSME", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8000290 }, // Pokemon Ruby - { "AXVJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXVE", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXVP", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXVI", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXVS", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXVD", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXVF", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXVJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXVE", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXVP", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXVI", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXVS", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXVD", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXVF", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, // Pokemon Sapphire - { "AXPJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXPE", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXPP", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXPI", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXPS", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXPD", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, - { "AXPF", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "AXPJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXPE", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXPP", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXPI", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXPS", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXPD", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, + { "AXPF", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, // Pokemon Emerald - { "BPEJ", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEE", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEP", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEI", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPES", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPED", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, - { "BPEF", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, + { "BPEJ", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPEE", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPEP", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPEI", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPES", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPED", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPEF", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, // Pokemon Mystery Dungeon - { "B24E", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "B24P", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "B24E", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "B24P", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, // Pokemon FireRed - { "BPRJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPRE", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPRP", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPRI", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPRS", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPRD", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPRF", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPRJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPRE", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPRP", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPRI", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPRS", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPRD", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPRF", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, // Pokemon LeafGreen - { "BPGJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPGE", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPGP", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPGI", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPGS", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPGD", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "BPGF", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BPGJ", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPGE", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPGP", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPGI", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPGS", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPGD", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "BPGF", GBA_SAVEDATA_FLASH1M, HW_NONE, GBA_IDLE_LOOP_NONE }, // RockMan EXE 4.5 - Real Operation - { "BR4J", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "BR4J", GBA_SAVEDATA_FLASH512, HW_RTC, GBA_IDLE_LOOP_NONE }, // Rocky - { "AR8E", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "AROP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "AR8E", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "AROP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // Sennen Kazoku - { "BKAJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE, false }, + { "BKAJ", GBA_SAVEDATA_FLASH1M, HW_RTC, GBA_IDLE_LOOP_NONE }, // Shin Bokura no Taiyou: Gyakushuu no Sabata - { "U33J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE, false }, + { "U33J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, GBA_IDLE_LOOP_NONE }, // Stuart Little 2 - { "ASLE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "ASLF", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ASLE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "ASLF", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE }, // Super Mario Advance 2 - { "AA2J", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, - { "AA2E", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, - { "AA2P", GBA_SAVEDATA_AUTODETECT, HW_NONE, 0x800052E, false }, + { "AA2J", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E }, + { "AA2E", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E }, + { "AA2P", GBA_SAVEDATA_AUTODETECT, HW_NONE, 0x800052E }, // Super Mario Advance 3 - { "A3AJ", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, - { "A3AE", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, - { "A3AP", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, + { "A3AJ", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, + { "A3AE", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, + { "A3AP", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, // Super Mario Advance 4 - { "AX4J", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, - { "AX4E", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, - { "AX4P", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, + { "AX4J", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, + { "AX4E", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, + { "AX4P", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, // Super Monkey Ball Jr. - { "ALUE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "ALUP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "ALUE", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, + { "ALUP", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // Top Gun - Combat Zones - { "A2YE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "A2YE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, GBA_IDLE_LOOP_NONE }, // Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle - { "BUHJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "BUHJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE }, // Wario Ware Twisted - { "RZWJ", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE, false }, - { "RZWE", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE, false }, - { "RZWP", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE, false }, + { "RZWJ", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE }, + { "RZWE", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE }, + { "RZWP", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, GBA_IDLE_LOOP_NONE }, // Yoshi's Universal Gravitation - { "KYGJ", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, - { "KYGE", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, - { "KYGP", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE, false }, + { "KYGJ", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE }, + { "KYGE", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE }, + { "KYGP", GBA_SAVEDATA_EEPROM, HW_TILT, GBA_IDLE_LOOP_NONE }, // Aging cartridge - { "TCHK", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - - // Famicom Mini series 3 (FDS), some aren't mirrored (22 - 28) - // See https://forum.no-intro.org/viewtopic.php?f=2&t=4221 for discussion - { "FNMJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "FMRJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "FPTJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "FLBJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "FFMJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "FTKJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, - { "FTUJ", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, false }, + { "TCHK", GBA_SAVEDATA_EEPROM, HW_NONE, GBA_IDLE_LOOP_NONE, }, { { 0, 0, 0, 0 }, 0, 0, GBA_IDLE_LOOP_NONE, false } }; @@ -219,7 +209,6 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver override->savetype = GBA_SAVEDATA_AUTODETECT; override->hardware = HW_NONE; override->idleLoop = GBA_IDLE_LOOP_NONE; - override->mirroring = false; override->vbaBugCompat = false; bool found = false; diff --git a/src/platform/qt/OverrideView.cpp b/src/platform/qt/OverrideView.cpp index 1d2737521..bec404a00 100644 --- a/src/platform/qt/OverrideView.cpp +++ b/src/platform/qt/OverrideView.cpp @@ -156,7 +156,6 @@ void OverrideView::updateOverrides() { gba->override.savetype = static_cast(m_ui.savetype->currentIndex() - 1); gba->override.hardware = HW_NO_OVERRIDE; gba->override.idleLoop = GBA_IDLE_LOOP_NONE; - gba->override.mirroring = false; gba->override.vbaBugCompat = false; gba->vbaBugCompatSet = false; From 318c5d7435ccd45dca1926a75d3b55d8544feaf2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2024 01:24:50 -0700 Subject: [PATCH 097/336] GBA: Move GBAHardwareDevice to public API --- include/mgba/gba/interface.h | 13 +++++++++++++ include/mgba/internal/gba/cart/gpio.h | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 9d19a55c8..c54277e83 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -58,6 +58,19 @@ enum GBASavedataType { GBA_SAVEDATA_SRAM512 = 6, }; +enum GBAHardwareDevice { + HW_NO_OVERRIDE = 0x8000, + HW_NONE = 0, + HW_RTC = 1, + HW_RUMBLE = 2, + HW_LIGHT_SENSOR = 4, + HW_GYRO = 8, + HW_TILT = 16, + HW_GB_PLAYER = 32, + HW_GB_PLAYER_DETECTION = 64, + HW_EREADER = 128 +}; + struct GBA; struct GBAAudio; struct GBASIO; diff --git a/include/mgba/internal/gba/cart/gpio.h b/include/mgba/internal/gba/cart/gpio.h index 86ddc941f..77785e612 100644 --- a/include/mgba/internal/gba/cart/gpio.h +++ b/include/mgba/internal/gba/cart/gpio.h @@ -18,19 +18,6 @@ mLOG_DECLARE_CATEGORY(GBA_HW); #define IS_GPIO_REGISTER(reg) ((reg) == GPIO_REG_DATA || (reg) == GPIO_REG_DIRECTION || (reg) == GPIO_REG_CONTROL) -enum GBAHardwareDevice { - HW_NO_OVERRIDE = 0x8000, - HW_NONE = 0, - HW_RTC = 1, - HW_RUMBLE = 2, - HW_LIGHT_SENSOR = 4, - HW_GYRO = 8, - HW_TILT = 16, - HW_GB_PLAYER = 32, - HW_GB_PLAYER_DETECTION = 64, - HW_EREADER = 128 -}; - enum GPIORegister { GPIO_REG_DATA = 0xC4, GPIO_REG_DIRECTION = 0xC6, From a430f58c15d65d7daa04364fafa140dc486201be Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2024 01:47:32 -0700 Subject: [PATCH 098/336] GB, GBA: Move more override-adjacent stuff to public API --- include/mgba/gb/interface.h | 12 ++++++++++++ include/mgba/gba/interface.h | 28 +++++++++++++++------------ include/mgba/internal/gb/overrides.h | 12 ------------ include/mgba/internal/gba/overrides.h | 4 ---- src/feature/gui/gui-config.c | 2 +- src/platform/qt/ConfigController.cpp | 2 +- src/platform/qt/GBAOverride.h | 2 +- src/platform/qt/GBOverride.h | 2 +- src/platform/qt/SettingsView.cpp | 2 +- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/include/mgba/gb/interface.h b/include/mgba/gb/interface.h index 485111b41..de26ef731 100644 --- a/include/mgba/gb/interface.h +++ b/include/mgba/gb/interface.h @@ -82,6 +82,12 @@ struct GBCartridgeOverride { uint32_t gbColors[12]; }; +struct GBColorPreset { + const char* name; + uint32_t colors[12]; +}; + +struct Configuration; struct VFile; bool GBIsROM(struct VFile* vf); @@ -93,6 +99,12 @@ const char* GBModelToName(enum GBModel); int GBValidModels(const uint8_t* bank0); +bool GBOverrideFind(const struct Configuration*, struct GBCartridgeOverride* override); +bool GBOverrideColorFind(struct GBCartridgeOverride* override, enum GBColorLookup); +void GBOverrideSave(struct Configuration*, const struct GBCartridgeOverride* override); + +size_t GBColorPresetList(const struct GBColorPreset** presets); + CXX_GUARD_END #endif diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index c54277e83..c64d00391 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -71,7 +71,7 @@ enum GBAHardwareDevice { HW_EREADER = 128 }; -struct GBA; +struct Configuration; struct GBAAudio; struct GBASIO; struct GBAVideoRenderer; @@ -84,9 +84,13 @@ enum { mPERIPH_GBA_BATTLECHIP_GATE, }; -bool GBAIsROM(struct VFile* vf); -bool GBAIsMB(struct VFile* vf); -bool GBAIsBIOS(struct VFile* vf); +struct GBACartridgeOverride { + char id[4]; + enum GBASavedataType savetype; + int hardware; + uint32_t idleLoop; + bool vbaBugCompat; +}; struct GBALuminanceSource { void (*sample)(struct GBALuminanceSource*); @@ -94,6 +98,13 @@ struct GBALuminanceSource { uint8_t (*readLuminance)(struct GBALuminanceSource*); }; +bool GBAIsROM(struct VFile* vf); +bool GBAIsMB(struct VFile* vf); +bool GBAIsBIOS(struct VFile* vf); + +bool GBAOverrideFind(const struct Configuration*, struct GBACartridgeOverride* override); +void GBAOverrideSave(struct Configuration*, const struct GBACartridgeOverride* override); + struct GBASIODriver { struct GBASIO* p; @@ -104,14 +115,6 @@ struct GBASIODriver { uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value); }; -struct GBACartridgeOverride { - char id[4]; - enum GBASavedataType savetype; - int hardware; - uint32_t idleLoop; - bool vbaBugCompat; -}; - void GBASIOJOYCreate(struct GBASIODriver* sio); enum GBASIOBattleChipGateFlavor { @@ -132,6 +135,7 @@ struct GBASIOBattlechipGate { void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*); +struct GBA; void GBACartEReaderQueueCard(struct GBA* gba, const void* data, size_t size); struct EReaderScan; diff --git a/include/mgba/internal/gb/overrides.h b/include/mgba/internal/gb/overrides.h index 6e683f0de..9d16ce65c 100644 --- a/include/mgba/internal/gb/overrides.h +++ b/include/mgba/internal/gb/overrides.h @@ -12,18 +12,6 @@ CXX_GUARD_START #include -struct GBColorPreset { - const char* name; - uint32_t colors[12]; -}; - -struct Configuration; -bool GBOverrideFind(const struct Configuration*, struct GBCartridgeOverride* override); -bool GBOverrideColorFind(struct GBCartridgeOverride* override, enum GBColorLookup); -void GBOverrideSave(struct Configuration*, const struct GBCartridgeOverride* override); - -size_t GBColorPresetList(const struct GBColorPreset** presets); - struct GB; void GBOverrideApply(struct GB*, const struct GBCartridgeOverride*); void GBOverrideApplyDefaults(struct GB*); diff --git a/include/mgba/internal/gba/overrides.h b/include/mgba/internal/gba/overrides.h index b2eba2d7a..4bec8bf15 100644 --- a/include/mgba/internal/gba/overrides.h +++ b/include/mgba/internal/gba/overrides.h @@ -12,10 +12,6 @@ CXX_GUARD_START #include -struct Configuration; -bool GBAOverrideFind(const struct Configuration*, struct GBACartridgeOverride* override); -void GBAOverrideSave(struct Configuration*, const struct GBACartridgeOverride* override); - struct GBA; void GBAOverrideApply(struct GBA*, const struct GBACartridgeOverride*); void GBAOverrideApplyDefaults(struct GBA*, const struct Configuration*); diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index 4a6c79871..e110ef768 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -12,7 +12,7 @@ #include #ifdef M_CORE_GB #include -#include +#include #endif #include #include diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index e1bf35408..91ecf8e7a 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -13,7 +13,7 @@ #include #ifdef M_CORE_GB -#include +#include #endif static const mOption s_frontendOptions[] = { diff --git a/src/platform/qt/GBAOverride.h b/src/platform/qt/GBAOverride.h index 477af0014..b93cb1953 100644 --- a/src/platform/qt/GBAOverride.h +++ b/src/platform/qt/GBAOverride.h @@ -7,7 +7,7 @@ #include "Override.h" -#include +#include namespace QGBA { diff --git a/src/platform/qt/GBOverride.h b/src/platform/qt/GBOverride.h index e967211de..fc1a7d2c9 100644 --- a/src/platform/qt/GBOverride.h +++ b/src/platform/qt/GBOverride.h @@ -7,7 +7,7 @@ #include "Override.h" -#include +#include namespace QGBA { diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 04d7d1649..7c41cb4a4 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -18,7 +18,7 @@ #ifdef M_CORE_GB #include "GameBoy.h" -#include +#include #endif #include From 1179d218e7094b40ce5666df0a7c2d083cb96504 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2024 02:35:03 -0700 Subject: [PATCH 099/336] Qt: Fix Qt6 build --- src/platform/qt/VideoDumper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/qt/VideoDumper.h b/src/platform/qt/VideoDumper.h index 65433462c..2dcceac0f 100644 --- a/src/platform/qt/VideoDumper.h +++ b/src/platform/qt/VideoDumper.h @@ -6,6 +6,7 @@ #pragma once #include +#include #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #include #include From ae8b88a4a318044a946e1806540a45ec66ae4505 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2024 21:16:09 -0700 Subject: [PATCH 100/336] Qt: Fix underrun stalling with Qt6 --- src/platform/qt/AudioDevice.cpp | 10 ++++++++++ src/platform/qt/AudioDevice.h | 1 + src/platform/qt/AudioProcessorQt.cpp | 29 ++++++++++++++++++++++++++++ src/platform/qt/AudioProcessorQt.h | 8 +++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index 74f863444..d19fc20d3 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -62,3 +62,13 @@ qint64 AudioDevice::writeData(const char*, qint64) { LOG(QT, WARN) << tr("Writing data to read-only audio device"); return 0; } + +bool AudioDevice::atEnd() const { + if (!m_context->core) { + return true; + } + mCoreSyncLockAudio(&m_context->impl->sync); + bool available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)) == 0; + mCoreSyncUnlockAudio(&m_context->impl->sync); + return available; +} diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index 0794b3743..86c5b17a6 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -20,6 +20,7 @@ public: void setInput(mCoreThread* input); void setFormat(const QAudioFormat& format); + bool atEnd() const override; protected: virtual qint64 readData(char* data, qint64 maxSize) override; diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index 4b53c7bb7..3e4c5474e 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -21,6 +21,10 @@ using namespace QGBA; AudioProcessorQt::AudioProcessorQt(QObject* parent) : AudioProcessor(parent) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + m_recheckTimer.setInterval(1); + connect(&m_recheckTimer, &QTimer::timeout, this, &AudioProcessorQt::recheckUnderflow); +#endif } void AudioProcessorQt::setInput(std::shared_ptr controller) { @@ -34,6 +38,9 @@ void AudioProcessorQt::setInput(std::shared_ptr controller) { } void AudioProcessorQt::stop() { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + m_recheckTimer.stop(); +#endif if (m_audioOutput) { m_audioOutput->stop(); m_audioOutput.reset(); @@ -72,6 +79,12 @@ bool AudioProcessorQt::start() { QAudioDevice device(QMediaDevices::defaultAudioOutput()); m_audioOutput = std::make_unique(device, format); LOG(QT, INFO) << "Audio outputting to " << device.description(); + connect(m_audioOutput.get(), &QAudioSink::stateChanged, this, [this](QAudio::State state) { + if (state != QAudio::IdleState) { + return; + } + m_recheckTimer.start(); + }); #endif } @@ -86,6 +99,9 @@ bool AudioProcessorQt::start() { } void AudioProcessorQt::pause() { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + m_recheckTimer.stop(); +#endif if (m_audioOutput) { m_audioOutput->suspend(); } @@ -115,3 +131,16 @@ unsigned AudioProcessorQt::sampleRate() const { } return m_audioOutput->format().sampleRate(); } + +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +void AudioProcessorQt::recheckUnderflow() { + if (!m_device) { + m_recheckTimer.stop(); + return; + } + if (!m_device->atEnd()) { + start(); + m_recheckTimer.stop(); + } +} +#endif diff --git a/src/platform/qt/AudioProcessorQt.h b/src/platform/qt/AudioProcessorQt.h index 1648b967f..bdfa17a77 100644 --- a/src/platform/qt/AudioProcessorQt.h +++ b/src/platform/qt/AudioProcessorQt.h @@ -11,6 +11,7 @@ #include #else #include +#include #endif class QAudioOutput; @@ -38,10 +39,15 @@ public slots: virtual void requestSampleRate(unsigned) override; -private: #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +private slots: + void recheckUnderflow(); + +private: + QTimer m_recheckTimer; std::unique_ptr m_audioOutput; #else +private: std::unique_ptr m_audioOutput; #endif std::unique_ptr m_device; From 86551614d9b0d6c0aeb9c0e03e58d4266acdae2c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2024 21:27:58 -0700 Subject: [PATCH 101/336] Qt: Enable building against Qt6 by default --- src/platform/qt/CMakeLists.txt | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 19d4293d0..fe898be1e 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -25,12 +25,19 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(QT_LIBRARIES) -set(QT_V 5) -find_package(Qt${QT_V} COMPONENTS Core Widgets Network OPTIONAL_COMPONENTS Multimedia) -if(QT_V GREATER_EQUAL 6) - find_package(Qt${QT_V} COMPONENTS OpenGL OpenGLWidgets) -endif() -set(QT Qt${QT_V}) +set(QT_VERSIONS 6 5) +foreach(V ${QT_VERSIONS}) + set(QT Qt${V}) + set(QT_V ${V}) + message("${V} ${QT} ${QT_V}") + find_package(${QT} COMPONENTS Core Widgets Network OPTIONAL_COMPONENTS Multimedia) + if(QT_V GREATER_EQUAL 6) + find_package(${QT} COMPONENTS OpenGL OpenGLWidgets) + endif() + if(${${QT}Widgets_FOUND}) + break() + endif() +endforeach() if(NOT BUILD_GL AND NOT BUILD_GLES2 AND NOT BUILD_GLES3) message(WARNING "OpenGL is recommended to build the Qt port") From e3edca1f4168c1eee36cd213ef8d5e91fd35e400 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 26 Mar 2024 22:24:14 -0700 Subject: [PATCH 102/336] Scripting: Attempt to shake out single-lua_State requirement --- src/script/engines/lua.c | 270 +++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 137 deletions(-) diff --git a/src/script/engines/lua.c b/src/script/engines/lua.c index 32ed0d13e..f6bdabea2 100644 --- a/src/script/engines/lua.c +++ b/src/script/engines/lua.c @@ -40,12 +40,12 @@ static void _freeFrame(struct mScriptList* frame); static void _autofreeFrame(struct mScriptContext* context, struct mScriptList* frame); struct mScriptEngineContextLua; -static bool _luaPushFrame(struct mScriptEngineContextLua*, struct mScriptList*); -static bool _luaPopFrame(struct mScriptEngineContextLua*, struct mScriptList*); +static bool _luaPushFrame(struct mScriptEngineContextLua*, lua_State*, struct mScriptList*); +static bool _luaPopFrame(struct mScriptEngineContextLua*, lua_State*, struct mScriptList*); static bool _luaInvoke(struct mScriptEngineContextLua*, struct mScriptFrame*); -static struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, bool pop); -static bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue*); +static struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, lua_State*, bool pop); +static bool _luaWrap(struct mScriptEngineContextLua* luaContext, lua_State*, struct mScriptValue*); static void _luaDeref(struct mScriptValue*); @@ -516,14 +516,14 @@ bool _luaIsScript(struct mScriptEngineContext* ctx, const char* name, struct VFi struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext* ctx, const char* name) { struct mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx; lua_getglobal(luaContext->lua, name); - return _luaCoerce(luaContext, true); + return _luaCoerce(luaContext, luaContext->lua, true); } bool _luaSetGlobal(struct mScriptEngineContext* ctx, const char* name, struct mScriptValue* value) { struct mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx; if (!value) { lua_pushnil(luaContext->lua); - } else if (!_luaWrap(luaContext, value)) { + } else if (!_luaWrap(luaContext, luaContext->lua, value)) { return false; } lua_setglobal(luaContext->lua, name); @@ -540,7 +540,7 @@ struct mScriptValue* _luaRootScope(struct mScriptEngineContext* ctx) { struct mScriptValue* key; lua_pop(luaContext->lua, 1); - key = _luaCoerce(luaContext, false); + key = _luaCoerce(luaContext, luaContext->lua, false); mScriptValueWrap(key, mScriptListAppend(list->value.list)); mScriptValueRef(key); mScriptContextFillPool(luaContext->d.context, key); @@ -550,60 +550,60 @@ struct mScriptValue* _luaRootScope(struct mScriptEngineContext* ctx) { return list; } -struct mScriptValue* _luaCoerceFunction(struct mScriptEngineContextLua* luaContext) { +struct mScriptValue* _luaCoerceFunction(struct mScriptEngineContextLua* luaContext, lua_State* lua) { struct mScriptValue* value = mScriptValueAlloc(&mSTLuaFunc); struct mScriptFunction* fn = calloc(1, sizeof(*fn)); struct mScriptEngineContextLuaRef* ref = calloc(1, sizeof(*ref)); fn->call = _luaCall; fn->context = ref; ref->context = luaContext; - ref->ref = luaL_ref(luaContext->lua, LUA_REGISTRYINDEX); + ref->ref = luaL_ref(lua, LUA_REGISTRYINDEX); value->value.opaque = fn; return value; } -struct mScriptValue* _luaCoerceTable(struct mScriptEngineContextLua* luaContext, struct Table* markedObjects) { +struct mScriptValue* _luaCoerceTable(struct mScriptEngineContextLua* luaContext, lua_State* lua, struct Table* markedObjects) { struct mScriptValue* table = mScriptValueAlloc(mSCRIPT_TYPE_MS_TABLE); bool isList = true; - lua_pushnil(luaContext->lua); + lua_pushnil(lua); const void* tablePointer; - while (lua_next(luaContext->lua, -2) != 0) { + while (lua_next(lua, -2) != 0) { struct mScriptValue* value = NULL; - int type = lua_type(luaContext->lua, -1); + int type = lua_type(lua, -1); switch (type) { case LUA_TNUMBER: case LUA_TBOOLEAN: case LUA_TSTRING: case LUA_TFUNCTION: - value = _luaCoerce(luaContext, true); + value = _luaCoerce(luaContext, lua, true); break; case LUA_TTABLE: - tablePointer = lua_topointer(luaContext->lua, -1); + tablePointer = lua_topointer(lua, -1); // Ensure this table doesn't contain any cycles if (!HashTableLookupBinary(markedObjects, &tablePointer, sizeof(tablePointer))) { HashTableInsertBinary(markedObjects, &tablePointer, sizeof(tablePointer), (void*) tablePointer); - value = _luaCoerceTable(luaContext, markedObjects); + value = _luaCoerceTable(luaContext, lua, markedObjects); } default: break; } if (!value) { - lua_pop(luaContext->lua, type == LUA_TTABLE ? 2 : 3); + lua_pop(lua, type == LUA_TTABLE ? 2 : 3); mScriptValueDeref(table); return NULL; } struct mScriptValue* key = NULL; - type = lua_type(luaContext->lua, -1); + type = lua_type(lua, -1); switch (type) { case LUA_TBOOLEAN: case LUA_TSTRING: isList = false; // Fall through case LUA_TNUMBER: - key = _luaCoerce(luaContext, false); + key = _luaCoerce(luaContext, lua, false); break; default: // Limit keys to hashable types @@ -611,7 +611,7 @@ struct mScriptValue* _luaCoerceTable(struct mScriptEngineContextLua* luaContext, } if (!key) { - lua_pop(luaContext->lua, 2); + lua_pop(lua, 2); mScriptValueDeref(table); return false; } @@ -619,7 +619,7 @@ struct mScriptValue* _luaCoerceTable(struct mScriptEngineContextLua* luaContext, mScriptValueDeref(key); mScriptValueDeref(value); } - lua_pop(luaContext->lua, 1); + lua_pop(lua, 1); size_t len = mScriptTableSize(table); if (!isList || !len) { @@ -652,9 +652,9 @@ struct mScriptValue* _luaCoerceTable(struct mScriptEngineContextLua* luaContext, return list; } -struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, bool pop) { - if (lua_isnone(luaContext->lua, -1)) { - lua_pop(luaContext->lua, 1); +struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, lua_State* lua, bool pop) { + if (lua_isnone(lua, -1)) { + lua_pop(lua, 1); return NULL; } @@ -662,27 +662,27 @@ struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, bool const void* buffer; struct Table markedObjects; struct mScriptValue* value = NULL; - switch (lua_type(luaContext->lua, -1)) { + switch (lua_type(lua, -1)) { case LUA_TNIL: value = &mScriptValueNull; break; case LUA_TNUMBER: #if LUA_VERSION_NUM >= 503 - if (lua_isinteger(luaContext->lua, -1)) { + if (lua_isinteger(lua, -1)) { value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S64); - value->value.s64 = lua_tointeger(luaContext->lua, -1); + value->value.s64 = lua_tointeger(lua, -1); break; } #endif value = mScriptValueAlloc(mSCRIPT_TYPE_MS_F64); - value->value.f64 = lua_tonumber(luaContext->lua, -1); + value->value.f64 = lua_tonumber(lua, -1); break; case LUA_TBOOLEAN: value = mScriptValueAlloc(mSCRIPT_TYPE_MS_BOOL); - value->value.u32 = lua_toboolean(luaContext->lua, -1); + value->value.u32 = lua_toboolean(lua, -1); break; case LUA_TSTRING: - buffer = lua_tolstring(luaContext->lua, -1, &size); + buffer = lua_tolstring(lua, -1, &size); value = mScriptStringCreateFromBytes(buffer, size); break; case LUA_TFUNCTION: @@ -690,35 +690,35 @@ struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, bool if (!pop) { break; } - return _luaCoerceFunction(luaContext); + return _luaCoerceFunction(luaContext, lua); case LUA_TTABLE: // This function pops the value internally if (!pop) { break; } HashTableInit(&markedObjects, 0, NULL); - value = _luaCoerceTable(luaContext, &markedObjects); + value = _luaCoerceTable(luaContext, lua, &markedObjects); HashTableDeinit(&markedObjects); return value; case LUA_TUSERDATA: - if (!lua_getmetatable(luaContext->lua, -1)) { + if (!lua_getmetatable(lua, -1)) { break; } - luaL_getmetatable(luaContext->lua, "mSTStruct"); - if (!lua_rawequal(luaContext->lua, -1, -2)) { - lua_pop(luaContext->lua, 1); - luaL_getmetatable(luaContext->lua, "mSTList"); - if (!lua_rawequal(luaContext->lua, -1, -2)) { - lua_pop(luaContext->lua, 1); - luaL_getmetatable(luaContext->lua, "mSTTable"); - if (!lua_rawequal(luaContext->lua, -1, -2)) { - lua_pop(luaContext->lua, 2); + luaL_getmetatable(lua, "mSTStruct"); + if (!lua_rawequal(lua, -1, -2)) { + lua_pop(lua, 1); + luaL_getmetatable(lua, "mSTList"); + if (!lua_rawequal(lua, -1, -2)) { + lua_pop(lua, 1); + luaL_getmetatable(lua, "mSTTable"); + if (!lua_rawequal(lua, -1, -2)) { + lua_pop(lua, 2); break; } } } - lua_pop(luaContext->lua, 2); - value = lua_touserdata(luaContext->lua, -1); + lua_pop(lua, 2); + value = lua_touserdata(lua, -1); value = mScriptContextAccessWeakref(luaContext->d.context, value); if (value->type->base == mSCRIPT_TYPE_WRAPPER) { value = mScriptValueUnwrap(value); @@ -729,14 +729,14 @@ struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, bool break; } if (pop) { - lua_pop(luaContext->lua, 1); + lua_pop(lua, 1); } return value; } -bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* value) { +bool _luaWrap(struct mScriptEngineContextLua* luaContext, lua_State* lua, struct mScriptValue* value) { if (!value) { - lua_pushnil(luaContext->lua); + lua_pushnil(lua); return true; } uint32_t weakref; @@ -744,7 +744,7 @@ bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* v if (value->type->base == mSCRIPT_TYPE_WRAPPER) { value = mScriptValueUnwrap(value); if (!value) { - lua_pushnil(luaContext->lua); + lua_pushnil(lua); return true; } mScriptContextFillPool(luaContext->d.context, value); @@ -778,7 +778,7 @@ bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* v weakref = value->value.u32; value = mScriptContextAccessWeakref(luaContext->d.context, value); if (!value) { - lua_pushnil(luaContext->lua); + lua_pushnil(lua); return true; } needsWeakref = true; @@ -787,95 +787,95 @@ bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* v struct mScriptValue* newValue; switch (value->type->base) { case mSCRIPT_TYPE_VOID: - lua_pushnil(luaContext->lua); + lua_pushnil(lua); break; case mSCRIPT_TYPE_SINT: if (value->type->size <= 4) { - lua_pushinteger(luaContext->lua, value->value.s32); + lua_pushinteger(lua, value->value.s32); } else if (value->type->size == 8) { - lua_pushinteger(luaContext->lua, value->value.s64); + lua_pushinteger(lua, value->value.s64); } else { ok = false; } break; case mSCRIPT_TYPE_UINT: if (value->type == mSCRIPT_TYPE_MS_BOOL) { - lua_pushboolean(luaContext->lua, !!value->value.u32); + lua_pushboolean(lua, !!value->value.u32); } else if (value->type->size <= 4) { - lua_pushinteger(luaContext->lua, value->value.u32); + lua_pushinteger(lua, value->value.u32); } else if (value->type->size == 8) { - lua_pushinteger(luaContext->lua, value->value.u64); + lua_pushinteger(lua, value->value.u64); } else { ok = false; } break; case mSCRIPT_TYPE_FLOAT: if (value->type->size == 4) { - lua_pushnumber(luaContext->lua, value->value.f32); + lua_pushnumber(lua, value->value.f32); } else if (value->type->size == 8) { - lua_pushnumber(luaContext->lua, value->value.f64); + lua_pushnumber(lua, value->value.f64); } else { ok = false; } break; case mSCRIPT_TYPE_STRING: if (!value->value.string) { - lua_pushnil(luaContext->lua); + lua_pushnil(lua); break; } if (value->type == mSCRIPT_TYPE_MS_STR) { - lua_pushlstring(luaContext->lua, value->value.string->buffer, value->value.string->size); + lua_pushlstring(lua, value->value.string->buffer, value->value.string->size); break; } if (value->type == mSCRIPT_TYPE_MS_CHARP) { - lua_pushstring(luaContext->lua, value->value.copaque); + lua_pushstring(lua, value->value.copaque); break; } ok = false; break; case mSCRIPT_TYPE_LIST: - newValue = lua_newuserdata(luaContext->lua, sizeof(*newValue)); + newValue = lua_newuserdata(lua, sizeof(*newValue)); if (needsWeakref) { *newValue = mSCRIPT_MAKE(WEAKREF, weakref); } else { mScriptValueRef(value); mScriptValueWrap(value, newValue); } - lua_getfield(luaContext->lua, LUA_REGISTRYINDEX, "mSTList"); - lua_setmetatable(luaContext->lua, -2); + lua_getfield(lua, LUA_REGISTRYINDEX, "mSTList"); + lua_setmetatable(lua, -2); break; case mSCRIPT_TYPE_TABLE: - newValue = lua_newuserdata(luaContext->lua, sizeof(*newValue)); + newValue = lua_newuserdata(lua, sizeof(*newValue)); if (needsWeakref) { *newValue = mSCRIPT_MAKE(WEAKREF, weakref); } else { mScriptValueRef(value); mScriptValueWrap(value, newValue); } - lua_getfield(luaContext->lua, LUA_REGISTRYINDEX, "mSTTable"); - lua_setmetatable(luaContext->lua, -2); + lua_getfield(lua, LUA_REGISTRYINDEX, "mSTTable"); + lua_setmetatable(lua, -2); break; case mSCRIPT_TYPE_FUNCTION: - newValue = lua_newuserdata(luaContext->lua, sizeof(*newValue)); + newValue = lua_newuserdata(lua, sizeof(*newValue)); newValue->type = value->type; newValue->refs = mSCRIPT_VALUE_UNREF; newValue->type->alloc(newValue); - lua_pushcclosure(luaContext->lua, _luaThunk, 1); + lua_pushcclosure(lua, _luaThunk, 1); break; case mSCRIPT_TYPE_OBJECT: if (!value->value.opaque) { - lua_pushnil(luaContext->lua); + lua_pushnil(lua); break; } - newValue = lua_newuserdata(luaContext->lua, sizeof(*newValue)); + newValue = lua_newuserdata(lua, sizeof(*newValue)); if (needsWeakref) { *newValue = mSCRIPT_MAKE(WEAKREF, weakref); } else { mScriptValueRef(value); mScriptValueWrap(value, newValue); } - lua_getfield(luaContext->lua, LUA_REGISTRYINDEX, "mSTStruct"); - lua_setmetatable(luaContext->lua, -2); + lua_getfield(lua, LUA_REGISTRYINDEX, "mSTStruct"); + lua_setmetatable(lua, -2); break; default: ok = false; @@ -1032,31 +1032,31 @@ const char* _luaGetError(struct mScriptEngineContext* context) { return luaContext->lastError; } -bool _luaPushFrame(struct mScriptEngineContextLua* luaContext, struct mScriptList* frame) { +bool _luaPushFrame(struct mScriptEngineContextLua* luaContext, lua_State* lua, struct mScriptList* frame) { bool ok = true; if (frame) { size_t i; for (i = 0; i < mScriptListSize(frame); ++i) { struct mScriptValue* value = mScriptListGetPointer(frame, i); - if (!_luaWrap(luaContext, value)) { + if (!_luaWrap(luaContext, lua, value)) { ok = false; break; } } } if (!ok) { - lua_pop(luaContext->lua, lua_gettop(luaContext->lua)); + lua_pop(lua, lua_gettop(lua)); } return ok; } -bool _luaPopFrame(struct mScriptEngineContextLua* luaContext, struct mScriptList* frame) { - int count = lua_gettop(luaContext->lua); +bool _luaPopFrame(struct mScriptEngineContextLua* luaContext, lua_State* lua, struct mScriptList* frame) { + int count = lua_gettop(lua); bool ok = true; if (frame) { int i; for (i = 0; i < count; ++i) { - struct mScriptValue* value = _luaCoerce(luaContext, true); + struct mScriptValue* value = _luaCoerce(luaContext, lua, true); if (!value) { ok = false; break; @@ -1068,7 +1068,7 @@ bool _luaPopFrame(struct mScriptEngineContextLua* luaContext, struct mScriptList } } if (count > i) { - lua_pop(luaContext->lua, count - i); + lua_pop(lua, count - i); } if (ok) { @@ -1127,7 +1127,7 @@ bool _luaInvoke(struct mScriptEngineContextLua* luaContext, struct mScriptFrame* return false; } - if (frame && !_luaPushFrame(luaContext, &frame->arguments)) { + if (frame && !_luaPushFrame(luaContext, luaContext->lua, &frame->arguments)) { mScriptContextDeactivate(luaContext->d.context); return false; } @@ -1151,7 +1151,7 @@ bool _luaInvoke(struct mScriptEngineContextLua* luaContext, struct mScriptFrame* return false; } - if (frame && !_luaPopFrame(luaContext, &frame->returnValues)) { + if (frame && !_luaPopFrame(luaContext, luaContext->lua, &frame->returnValues)) { mScriptContextDrainPool(luaContext->d.context); return false; } @@ -1184,10 +1184,6 @@ static struct mScriptEngineContextLua* _luaGetContext(lua_State* lua) { struct mScriptEngineContextLua* luaContext = lua_touserdata(lua, -1); lua_pop(lua, 1); - if (luaContext->lua != lua) { - lua_pushliteral(lua, "Function called from invalid context"); - lua_error(lua); - } return luaContext; } @@ -1195,7 +1191,7 @@ int _luaThunk(lua_State* lua) { struct mScriptEngineContextLua* luaContext = _luaGetContext(lua); struct mScriptFrame frame; mScriptFrameInit(&frame); - if (!_luaPopFrame(luaContext, &frame.arguments)) { + if (!_luaPopFrame(luaContext, lua, &frame.arguments)) { _freeFrame(&frame.arguments); mScriptContextDrainPool(luaContext->d.context); mScriptFrameDeinit(&frame); @@ -1212,7 +1208,7 @@ int _luaThunk(lua_State* lua) { return lua_error(lua); } - bool ok = _luaPushFrame(luaContext, &frame.returnValues); + bool ok = _luaPushFrame(luaContext, lua, &frame.returnValues); mScriptContextDrainPool(luaContext->d.context); mScriptFrameDeinit(&frame); if (!ok) { @@ -1220,7 +1216,7 @@ int _luaThunk(lua_State* lua) { return lua_error(lua); } - return lua_gettop(luaContext->lua); + return lua_gettop(lua); } int _luaGetObject(lua_State* lua) { @@ -1251,7 +1247,7 @@ int _luaGetObject(lua_State* lua) { return lua_error(lua); } - if (!_luaWrap(luaContext, &val)) { + if (!_luaWrap(luaContext, lua, &val)) { luaL_traceback(lua, lua, "Error translating value from runtime", 1); return lua_error(lua); } @@ -1263,7 +1259,7 @@ int _luaSetObject(lua_State* lua) { char key[MAX_KEY_SIZE]; const char* keyPtr = lua_tostring(lua, -2); struct mScriptValue* obj = lua_touserdata(lua, -3); - struct mScriptValue* val = _luaCoerce(luaContext, true); + struct mScriptValue* val = _luaCoerce(luaContext, lua, true); if (!keyPtr) { lua_pop(lua, 2); @@ -1312,12 +1308,12 @@ static int _luaGcObject(lua_State* lua) { int _luaGetTable(lua_State* lua) { struct mScriptEngineContextLua* luaContext = _luaGetContext(lua); char key[MAX_KEY_SIZE]; - int type = lua_type(luaContext->lua, -1); + int type = lua_type(lua, -1); const char* keyPtr = NULL; int64_t intKey; switch (type) { case LUA_TNUMBER: - intKey = lua_tointeger(luaContext->lua, -1); + intKey = lua_tointeger(lua, -1); break; case LUA_TSTRING: keyPtr = lua_tostring(lua, -1); @@ -1355,7 +1351,7 @@ int _luaGetTable(lua_State* lua) { return 0; } - if (!_luaWrap(luaContext, val)) { + if (!_luaWrap(luaContext, lua, val)) { luaL_traceback(lua, lua, "Error translating value from runtime", 1); return lua_error(lua); } @@ -1378,7 +1374,7 @@ int _luaLenTable(lua_State* lua) { struct mScriptValue val = mSCRIPT_MAKE_U64(mScriptTableSize(obj)); - if (!_luaWrap(luaContext, &val)) { + if (!_luaWrap(luaContext, lua, &val)) { luaL_traceback(lua, lua, "Error translating value from runtime", 1); return lua_error(lua); } @@ -1388,12 +1384,12 @@ int _luaLenTable(lua_State* lua) { static int _luaNextTable(lua_State* lua) { struct mScriptEngineContextLua* luaContext = _luaGetContext(lua); char key[MAX_KEY_SIZE]; - int type = lua_type(luaContext->lua, -1); + int type = lua_type(lua, -1); const char* keyPtr = NULL; struct mScriptValue keyVal = {0}; switch (type) { case LUA_TNUMBER: - keyVal = mSCRIPT_MAKE_S64(lua_tointeger(luaContext->lua, -1)); + keyVal = mSCRIPT_MAKE_S64(lua_tointeger(lua, -1)); break; case LUA_TSTRING: keyPtr = lua_tostring(lua, -1); @@ -1429,12 +1425,12 @@ static int _luaNextTable(lua_State* lua) { } } - if (!_luaWrap(luaContext, mScriptTableIteratorGetKey(table, &iter))) { + if (!_luaWrap(luaContext, lua, mScriptTableIteratorGetKey(table, &iter))) { luaL_traceback(lua, lua, "Iteration error", 1); return lua_error(lua); } - if (!_luaWrap(luaContext, mScriptTableIteratorGetValue(table, &iter))) { + if (!_luaWrap(luaContext, lua, mScriptTableIteratorGetValue(table, &iter))) { luaL_traceback(lua, lua, "Iteration error", 1); return lua_error(lua); } @@ -1453,9 +1449,9 @@ int _luaGetList(lua_State* lua) { struct mScriptEngineContextLua* luaContext = _luaGetContext(lua); ssize_t index; #if LUA_VERSION_NUM >= 503 - index = lua_tointeger(luaContext->lua, -1); + index = lua_tointeger(lua, -1); #else - index = lua_tonumber(luaContext->lua, -1); + index = lua_tonumber(lua, -1); #endif struct mScriptValue* obj = lua_touserdata(lua, -2); lua_pop(lua, 2); @@ -1481,7 +1477,7 @@ int _luaGetList(lua_State* lua) { --index; struct mScriptValue* val = mScriptListGetPointer(list, index); - if (!_luaWrap(luaContext, val)) { + if (!_luaWrap(luaContext, lua, val)) { luaL_traceback(lua, lua, "Error translating value from runtime", 1); return lua_error(lua); } @@ -1509,21 +1505,21 @@ static int _luaLenList(lua_State* lua) { static int _luaRequireShim(lua_State* lua) { struct mScriptEngineContextLua* luaContext = _luaGetContext(lua); - int oldtop = lua_gettop(luaContext->lua); + int oldtop = lua_gettop(lua); const char* path = lua_tostring(lua, lua_upvalueindex(1)); - lua_getglobal(luaContext->lua, "package"); + lua_getglobal(lua, "package"); - lua_pushliteral(luaContext->lua, "path"); - lua_pushstring(luaContext->lua, path); - lua_pushliteral(luaContext->lua, "/?.lua;"); - lua_pushstring(luaContext->lua, path); - lua_pushliteral(luaContext->lua, "/?/init.lua;"); - lua_pushliteral(luaContext->lua, "path"); - lua_gettable(luaContext->lua, -7); - char* oldpath = strdup(lua_tostring(luaContext->lua, -1)); - lua_concat(luaContext->lua, 5); - lua_settable(luaContext->lua, -3); + lua_pushliteral(lua, "path"); + lua_pushstring(lua, path); + lua_pushliteral(lua, "/?.lua;"); + lua_pushstring(lua, path); + lua_pushliteral(lua, "/?/init.lua;"); + lua_pushliteral(lua, "path"); + lua_gettable(lua, -7); + char* oldpath = strdup(lua_tostring(lua, -1)); + lua_concat(lua, 5); + lua_settable(lua, -3); #ifdef _WIN32 #define DLL "dll" @@ -1532,42 +1528,42 @@ static int _luaRequireShim(lua_State* lua) { #else #define DLL "so" #endif - lua_pushliteral(luaContext->lua, "cpath"); - lua_pushstring(luaContext->lua, path); - lua_pushliteral(luaContext->lua, "/?." DLL ";"); - lua_pushstring(luaContext->lua, path); - lua_pushliteral(luaContext->lua, "/?/init." DLL ";"); - lua_pushliteral(luaContext->lua, "cpath"); - lua_gettable(luaContext->lua, -7); - char* oldcpath = strdup(lua_tostring(luaContext->lua, -1)); - lua_concat(luaContext->lua, 5); - lua_settable(luaContext->lua, -3); + lua_pushliteral(lua, "cpath"); + lua_pushstring(lua, path); + lua_pushliteral(lua, "/?." DLL ";"); + lua_pushstring(lua, path); + lua_pushliteral(lua, "/?/init." DLL ";"); + lua_pushliteral(lua, "cpath"); + lua_gettable(lua, -7); + char* oldcpath = strdup(lua_tostring(lua, -1)); + lua_concat(lua, 5); + lua_settable(lua, -3); - lua_pop(luaContext->lua, 1); + lua_pop(lua, 1); - lua_rawgeti(luaContext->lua, LUA_REGISTRYINDEX, luaContext->require); - lua_insert(luaContext->lua, -2); - int ret = lua_pcall(luaContext->lua, 1, LUA_MULTRET, 0); + lua_rawgeti(lua, LUA_REGISTRYINDEX, luaContext->require); + lua_insert(lua, -2); + int ret = lua_pcall(lua, 1, LUA_MULTRET, 0); - lua_getglobal(luaContext->lua, "package"); + lua_getglobal(lua, "package"); - lua_pushliteral(luaContext->lua, "path"); - lua_pushstring(luaContext->lua, oldpath); - lua_settable(luaContext->lua, -3); + lua_pushliteral(lua, "path"); + lua_pushstring(lua, oldpath); + lua_settable(lua, -3); - lua_pushliteral(luaContext->lua, "cpath"); - lua_pushstring(luaContext->lua, oldcpath); - lua_settable(luaContext->lua, -3); + lua_pushliteral(lua, "cpath"); + lua_pushstring(lua, oldcpath); + lua_settable(lua, -3); - lua_pop(luaContext->lua, 1); + lua_pop(lua, 1); free(oldpath); free(oldcpath); if (ret) { - return lua_error(luaContext->lua); + return lua_error(lua); } - int newtop = lua_gettop(luaContext->lua); + int newtop = lua_gettop(lua); return newtop - oldtop + 1; } From 5ff777d301d0d674b124eac0cf56021997078c3a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 2 Apr 2024 22:53:02 -0700 Subject: [PATCH 103/336] Scripting: Add overloads, overload isKeyActive --- include/mgba/script/macros.h | 82 +++++++++++++++++++++++++++++++----- include/mgba/script/types.h | 10 ++++- src/script/context.c | 2 +- src/script/input.c | 45 +++++++++----------- src/script/test/classes.c | 67 ++++++++++++++++++++++++++++- src/script/test/input.c | 38 +++++++++++++++++ src/script/test/types.c | 12 +++--- src/script/types.c | 46 +++++++++++++++----- src/tools/docgen.c | 8 ++++ 9 files changed, 255 insertions(+), 55 deletions(-) diff --git a/include/mgba/script/macros.h b/include/mgba/script/macros.h index 4acf7591a..7d2057d4e 100644 --- a/include/mgba/script/macros.h +++ b/include/mgba/script/macros.h @@ -254,7 +254,7 @@ CXX_GUARD_START return false; \ } -#define _mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, NRET, RETURN, NPARAMS, DEFAULTS, ...) \ +#define _mSCRIPT_DECLARE_STRUCT_METHOD_HEAD(TYPE, NAME) \ static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx); \ static const struct mScriptFunction _mSTStructBindingFunction_ ## TYPE ## _ ## NAME = { \ .call = &_mSTStructBinding_ ## TYPE ## _ ## NAME \ @@ -269,6 +269,9 @@ CXX_GUARD_START .alloc = _mSTStructBindingAlloc_ ## TYPE ## _ ## NAME, \ .details = { \ .function = { \ + +#define _mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, NRET, RETURN, NPARAMS, DEFAULTS, ...) \ + _mSCRIPT_DECLARE_STRUCT_METHOD_HEAD(TYPE, NAME) \ .parameters = { \ .count = _mSUCC_ ## NPARAMS, \ .entries = { mSCRIPT_TYPE_MS_ ## S(TYPE), _mCALL(mSCRIPT_PREFIX_ ## NPARAMS, mSCRIPT_TYPE_MS_, _mEVEN_ ## NPARAMS(__VA_ARGS__)) }, \ @@ -283,6 +286,23 @@ CXX_GUARD_START } \ }; +#define _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD(TYPE, NAME, S, NRET, RETURN) \ + _mSCRIPT_DECLARE_STRUCT_METHOD_HEAD(TYPE, NAME) \ + .parameters = { \ + .count = 1, \ + .entries = { mSCRIPT_TYPE_MS_ ## S(TYPE) }, \ + .names = { "this" }, \ + .defaults = NULL, \ + .variable = true, \ + }, \ + .returnType = { \ + .count = NRET, \ + .entries = { RETURN } \ + }, \ + }, \ + } \ + }; + #define _mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, RETURN, NAME, CONST, NPARAMS, ...) \ typedef RETURN (*_mSTStructFunctionType_ ## TYPE ## _ ## NAME)(_mCOMMA_ ## NPARAMS(CONST struct TYPE* , mSCRIPT_PREFIX_ ## NPARAMS(mSCRIPT_TYPE_C_, __VA_ARGS__))) @@ -302,6 +322,20 @@ CXX_GUARD_START return true; \ } \ +#define _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD_BINDING(TYPE, NAME, T) \ + static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## TYPE ## _ ## NAME[]; \ + static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \ + UNUSED(ctx); \ + const struct mScriptFunctionOverload* overload = mScriptFunctionFindOverload(_mSTStructBindingOverloads_ ## TYPE ## _ ## NAME, &frame->arguments); \ + if (!overload) { \ + return false; \ + } \ + if (!mScriptCoerceFrame(&overload->type->details.function.parameters, &frame->arguments, &frame->arguments)) { \ + return false; \ + } \ + return overload->function->call(frame, overload->function->context); \ + } + #define mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, RETURN, NAME, FUNCTION, NPARAMS, ...) \ _mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, mSCRIPT_TYPE_C_ ## RETURN, NAME, , NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \ _mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, 1, mSCRIPT_TYPE_MS_ ## RETURN, NPARAMS, NULL, __VA_ARGS__) \ @@ -346,6 +380,22 @@ CXX_GUARD_START _mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, CS, 0, 0, NPARAMS, _mIDENT(_mSTStructBindingDefaults_ ## TYPE ## _ ## NAME, __VA_ARGS__) \ _mSCRIPT_DECLARE_STRUCT_VOID_METHOD_BINDING(TYPE, NAME, FUNCTION, CS, NPARAMS, __VA_ARGS__) +#define mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD(TYPE, RETURN, NAME) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD(TYPE, NAME, S, 1, mSCRIPT_TYPE_MS_ ## RETURN) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD_BINDING(TYPE, NAME, S) + +#define mSCRIPT_DECLARE_STRUCT_OVERLOADED_VOID_METHOD(TYPE, NAME) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD(TYPE, NAME, S, 0, 0) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD_BINDING(TYPE, NAME, S) + +#define mSCRIPT_DECLARE_STRUCT_OVERLOADED_C_METHOD(TYPE, RETURN, NAME) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD(TYPE, NAME, CS, 1, mSCRIPT_TYPE_MS_ ## RETURN) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD_BINDING(TYPE, NAME, CS) + +#define mSCRIPT_DECLARE_STRUCT_OVERLOADED_VOID_C_METHOD(TYPE, NAME) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD(TYPE, NAME, CS, 0, 0) \ + _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD_BINDING(TYPE, NAME, CS) + #define mSCRIPT_DECLARE_STRUCT_D_METHOD(TYPE, RETURN, NAME, NPARAMS, ...) \ mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, RETURN, NAME, p0->NAME, NPARAMS, __VA_ARGS__) @@ -417,27 +467,39 @@ CXX_GUARD_START #define mSCRIPT_DEFINE_DEFAULTS_END } -#define _mSCRIPT_DEFINE_STRUCT_BINDING(INIT_TYPE, TYPE, EXPORTED_NAME, NAME) { \ +#define mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOADS(STRUCT, METHOD) \ + static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## STRUCT ## _ ## METHOD[] = { \ + +#define mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOAD(TYPE, FUNCTION) { \ + .type = &_mSTStructBindingType_ ## TYPE ## _ ## FUNCTION, \ + .function = &_mSTStructBindingFunction_ ## TYPE ## _ ## FUNCTION \ +}, + +#define mSCRIPT_DEFINE_OVERLOADS_END { NULL, NULL } } + +#define _mSCRIPT_DEFINE_STRUCT_BINDING(INIT_TYPE, TYPE, EXPORTED_NAME, NAME, OVERLOADS) { \ .type = mSCRIPT_CLASS_INIT_ ## INIT_TYPE, \ .info = { \ .member = { \ .name = #EXPORTED_NAME, \ - .type = &_mSTStructBindingType_ ## TYPE ## _ ## NAME \ + .type = &_mSTStructBindingType_ ## TYPE ## _ ## NAME, \ + .overloads = OVERLOADS, \ } \ }, \ }, #define mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(TYPE, EXPORTED_NAME, NAME) \ - _mSCRIPT_DEFINE_STRUCT_BINDING(INSTANCE_MEMBER, TYPE, EXPORTED_NAME, NAME) + _mSCRIPT_DEFINE_STRUCT_BINDING(INSTANCE_MEMBER, TYPE, EXPORTED_NAME, NAME, NULL) #define mSCRIPT_DEFINE_STRUCT_METHOD(TYPE, NAME) mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(TYPE, NAME, NAME) +#define mSCRIPT_DEFINE_STRUCT_OVERLOADED_METHOD(TYPE, NAME) _mSCRIPT_DEFINE_STRUCT_BINDING(INSTANCE_MEMBER, TYPE, NAME, NAME, _mSTStructBindingOverloads_ ## TYPE ## _ ## NAME) -#define mSCRIPT_DEFINE_STRUCT_INIT(TYPE) _mSCRIPT_DEFINE_STRUCT_BINDING(INIT, TYPE, _init, _init) -#define mSCRIPT_DEFINE_STRUCT_INIT_NAMED(TYPE, NAME) _mSCRIPT_DEFINE_STRUCT_BINDING(INIT, TYPE, _init, NAME) -#define mSCRIPT_DEFINE_STRUCT_DEINIT(TYPE) _mSCRIPT_DEFINE_STRUCT_BINDING(DEINIT, TYPE, _deinit, _deinit) -#define mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(TYPE, NAME) _mSCRIPT_DEFINE_STRUCT_BINDING(DEINIT, TYPE, _deinit, NAME) -#define mSCRIPT_DEFINE_STRUCT_DEFAULT_GET(TYPE) _mSCRIPT_DEFINE_STRUCT_BINDING(GET, TYPE, _get, _get) -#define mSCRIPT_DEFINE_STRUCT_DEFAULT_SET(TYPE, SETTER) _mSCRIPT_DEFINE_STRUCT_BINDING(SET, TYPE, SETTER, SETTER) +#define mSCRIPT_DEFINE_STRUCT_INIT(TYPE) _mSCRIPT_DEFINE_STRUCT_BINDING(INIT, TYPE, _init, _init, NULL) +#define mSCRIPT_DEFINE_STRUCT_INIT_NAMED(TYPE, NAME) _mSCRIPT_DEFINE_STRUCT_BINDING(INIT, TYPE, _init, NAME, NULL) +#define mSCRIPT_DEFINE_STRUCT_DEINIT(TYPE) _mSCRIPT_DEFINE_STRUCT_BINDING(DEINIT, TYPE, _deinit, _deinit, NULL) +#define mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(TYPE, NAME) _mSCRIPT_DEFINE_STRUCT_BINDING(DEINIT, TYPE, _deinit, NAME, NULL) +#define mSCRIPT_DEFINE_STRUCT_DEFAULT_GET(TYPE) _mSCRIPT_DEFINE_STRUCT_BINDING(GET, TYPE, _get, _get, NULL) +#define mSCRIPT_DEFINE_STRUCT_DEFAULT_SET(TYPE, SETTER) _mSCRIPT_DEFINE_STRUCT_BINDING(SET, TYPE, SETTER, SETTER, NULL) #define mSCRIPT_DEFINE_DOC_STRUCT_METHOD(SCOPE, TYPE, NAME) mSCRIPT_DEFINE_STRUCT_METHOD_NAMED(doc_ ## TYPE, NAME, NAME) diff --git a/include/mgba/script/types.h b/include/mgba/script/types.h index 1475f1a6e..5770456e6 100644 --- a/include/mgba/script/types.h +++ b/include/mgba/script/types.h @@ -259,6 +259,7 @@ struct mScriptClassMember { const char* name; const char* docstring; const struct mScriptType* type; + const struct mScriptFunctionOverload* overloads; size_t offset; bool readonly; }; @@ -275,6 +276,7 @@ struct mScriptClassInitDetails { const struct mScriptType* parent; struct mScriptClassMember member; struct mScriptClassCastMember castMember; + const struct mScriptFunctionOverload* overload; } info; }; @@ -332,6 +334,11 @@ struct mScriptFunction { void* context; }; +struct mScriptFunctionOverload { + const struct mScriptType* type; + const struct mScriptFunction* function; +}; + struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type); void mScriptValueRef(struct mScriptValue* val); void mScriptValueDeref(struct mScriptValue* val); @@ -385,7 +392,8 @@ bool mScriptPopBool(struct mScriptList* list, bool* out); bool mScriptPopPointer(struct mScriptList* list, void** out); bool mScriptCast(const struct mScriptType* type, const struct mScriptValue* input, struct mScriptValue* output); -bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList* frame); +bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, const struct mScriptList* input, struct mScriptList* output); +const struct mScriptFunctionOverload* mScriptFunctionFindOverload(const struct mScriptFunctionOverload* overloads, struct mScriptList* frame); CXX_GUARD_END diff --git a/src/script/context.c b/src/script/context.c index 090daf66d..47a4460f6 100644 --- a/src/script/context.c +++ b/src/script/context.c @@ -481,7 +481,7 @@ bool mScriptInvoke(const struct mScriptValue* val, struct mScriptFrame* frame) { return false; } const struct mScriptTypeFunction* signature = &val->type->details.function; - if (!mScriptCoerceFrame(&signature->parameters, &frame->arguments)) { + if (!mScriptCoerceFrame(&signature->parameters, &frame->arguments, &frame->arguments)) { return false; } const struct mScriptFunction* fn = val->value.opaque; diff --git a/src/script/input.c b/src/script/input.c index c103fa82c..1cb9f488b 100644 --- a/src/script/input.c +++ b/src/script/input.c @@ -35,20 +35,28 @@ struct mScriptInputContext { }; static void _mScriptInputDeinit(struct mScriptInputContext*); -static bool _mScriptInputIsKeyActive(const struct mScriptInputContext*, struct mScriptValue*); +static bool _mScriptInputIsKeyActiveStr(const struct mScriptInputContext*, const char*); +static bool _mScriptInputIsKeyActiveNum(const struct mScriptInputContext*, uint32_t); static struct mScriptValue* _mScriptInputActiveKeys(const struct mScriptInputContext*); mSCRIPT_DECLARE_STRUCT(mScriptInputContext); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptInputContext, _deinit, _mScriptInputDeinit, 0); -mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, BOOL, isKeyActive, _mScriptInputIsKeyActive, 1, WRAPPER, key); +mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, BOOL, isKeyActiveStr, _mScriptInputIsKeyActiveStr, 1, CHARP, key); +mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, BOOL, isKeyActiveNum, _mScriptInputIsKeyActiveNum, 1, U32, key); +mSCRIPT_DECLARE_STRUCT_OVERLOADED_C_METHOD(mScriptInputContext, BOOL, isKeyActive); mSCRIPT_DECLARE_STRUCT_C_METHOD(mScriptInputContext, WLIST, activeKeys, _mScriptInputActiveKeys, 0); +mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOADS(mScriptInputContext, isKeyActive) + mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOAD(mScriptInputContext, isKeyActiveStr) + mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOAD(mScriptInputContext, isKeyActiveNum) +mSCRIPT_DEFINE_OVERLOADS_END; + mSCRIPT_DEFINE_STRUCT(mScriptInputContext) mSCRIPT_DEFINE_STRUCT_DEINIT(mScriptInputContext) mSCRIPT_DEFINE_DOCSTRING("Sequence number of the next event to be emitted") mSCRIPT_DEFINE_STRUCT_MEMBER(mScriptInputContext, U64, seq) mSCRIPT_DEFINE_DOCSTRING("Check if a given keyboard key is currently held. The input can be either the printable character for a key, the numerical Unicode codepoint, or a special value from C.KEY") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptInputContext, isKeyActive) + mSCRIPT_DEFINE_STRUCT_OVERLOADED_METHOD(mScriptInputContext, isKeyActive) mSCRIPT_DEFINE_DOCSTRING("Get a list of the currently active keys. The values are Unicode codepoints or special key values from C.KEY, not strings, so make sure to convert as needed") mSCRIPT_DEFINE_STRUCT_METHOD(mScriptInputContext, activeKeys) mSCRIPT_DEFINE_DOCSTRING("The currently active gamepad, if any") @@ -319,33 +327,18 @@ void _mScriptInputDeinit(struct mScriptInputContext* context) { TableDeinit(&context->activeKeys); } -bool _mScriptInputIsKeyActive(const struct mScriptInputContext* context, struct mScriptValue* value) { +bool _mScriptInputIsKeyActiveStr(const struct mScriptInputContext* context, const char* value) { uint32_t key; - struct mScriptValue intValue; - size_t length; - const char* strbuf; - - switch (value->type->base) { - case mSCRIPT_TYPE_SINT: - case mSCRIPT_TYPE_UINT: - case mSCRIPT_TYPE_FLOAT: - if (!mScriptCast(mSCRIPT_TYPE_MS_U32, value, &intValue)) { - return false; - } - key = intValue.value.u32; - break; - case mSCRIPT_TYPE_STRING: - if (value->value.string->length > 1) { - return false; - } - strbuf = value->value.string->buffer; - length = value->value.string->size; - key = utf8Char(&strbuf, &length); - break; - default: + size_t length = strlen(value); + key = utf8Char(&value, &length); + if (length > 0) { return false; } + void* down = TableLookup(&context->activeKeys, key); + return down != NULL; +} +bool _mScriptInputIsKeyActiveNum(const struct mScriptInputContext* context, uint32_t key) { void* down = TableLookup(&context->activeKeys, key); return down != NULL; } diff --git a/src/script/test/classes.c b/src/script/test/classes.c index f7c5eb128..e0ce39d47 100644 --- a/src/script/test/classes.c +++ b/src/script/test/classes.c @@ -57,6 +57,11 @@ struct TestH { int32_t j; }; +struct TestI { + uint32_t num; + const char* str; +}; + static int32_t testAi0(struct TestA* a) { return a->i; } @@ -114,6 +119,14 @@ static void testSetC(struct TestG* g, const char* name, const char* val) { g->c = val; } +static void callNum(struct TestI* i, uint32_t num) { + i->num = num; +} + +static void callStr(struct TestI* i, const char* str) { + i->str = str; +} + #define MEMBER_A_DOCSTRING "Member a" mSCRIPT_DECLARE_STRUCT(TestA); @@ -201,12 +214,25 @@ mSCRIPT_DEFINE_STRUCT(TestG) mSCRIPT_DEFINE_STRUCT_DEFAULT_SET(TestG, setC) mSCRIPT_DEFINE_END; - mSCRIPT_DEFINE_STRUCT(TestH) mSCRIPT_DEFINE_STRUCT_MEMBER(TestH, S32, i) mSCRIPT_DEFINE_STRUCT_CONST_MEMBER(TestH, S32, j) mSCRIPT_DEFINE_END; +mSCRIPT_DECLARE_STRUCT(TestI); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(TestI, callStr, callStr, 1, CHARP, value); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(TestI, callNum, callNum, 1, U32, value); +mSCRIPT_DECLARE_STRUCT_OVERLOADED_VOID_METHOD(TestI, call); + +mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOADS(TestI, call) + mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOAD(TestI, callStr) + mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOAD(TestI, callNum) +mSCRIPT_DEFINE_OVERLOADS_END; + +mSCRIPT_DEFINE_STRUCT(TestI) + mSCRIPT_DEFINE_STRUCT_OVERLOADED_METHOD(TestI, call) +mSCRIPT_DEFINE_END; + M_TEST_DEFINE(testALayout) { struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestA)->details.cls; assert_false(cls->init); @@ -1184,6 +1210,44 @@ M_TEST_DEFINE(testHSet) { assert_false(cls->init); } +M_TEST_DEFINE(testOverloadsBasic) { + struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestI)->details.cls; + assert_false(cls->init); + mScriptClassInit(cls); + assert_true(cls->init); + + struct TestI s = { + .num = 0, + .str = NULL, + }; + + struct mScriptValue sval = mSCRIPT_MAKE_S(TestI, &s); + struct mScriptValue fn; + struct mScriptFrame frame; + + assert_true(mScriptObjectGet(&sval, "call", &fn)); + + mScriptFrameInit(&frame); + mSCRIPT_PUSH(&frame.arguments, S(TestI), &s); + mSCRIPT_PUSH(&frame.arguments, U32, 1); + assert_true(mScriptInvoke(&fn, &frame)); + mScriptFrameDeinit(&frame); + assert_int_equal(s.num, 1); + assert_null(s.str); + + mScriptFrameInit(&frame); + mSCRIPT_PUSH(&frame.arguments, S(TestI), &s); + mSCRIPT_PUSH(&frame.arguments, CHARP, "called"); + assert_true(mScriptInvoke(&fn, &frame)); + mScriptFrameDeinit(&frame); + assert_int_equal(s.num, 1); + assert_string_equal(s.str, "called"); + + assert_true(cls->init); + mScriptClassDeinit(cls); + assert_false(cls->init); +} + M_TEST_SUITE_DEFINE(mScriptClasses, cmocka_unit_test(testALayout), cmocka_unit_test(testASignatures), @@ -1201,4 +1265,5 @@ M_TEST_SUITE_DEFINE(mScriptClasses, cmocka_unit_test(testFDeinit), cmocka_unit_test(testGSet), cmocka_unit_test(testHSet), + cmocka_unit_test(testOverloadsBasic), ) diff --git a/src/script/test/input.c b/src/script/test/input.c index 4c689a6ef..641e1c6ab 100644 --- a/src/script/test/input.c +++ b/src/script/test/input.c @@ -172,6 +172,43 @@ M_TEST_DEFINE(clearKeys) { mScriptContextDeinit(&context); } +M_TEST_DEFINE(numericKeys) { + SETUP_LUA; + + TEST_PROGRAM("assert(not input:isKeyActive(C.KEY.F1))"); + + TEST_PROGRAM( + "activeKey = false\n" + "state = nil\n" + "function cb(ev)\n" + " assert(ev.type == C.EV_TYPE.KEY)\n" + " activeKey = ev.key\n" + " state = ev.state\n" + "end\n" + "id = callbacks:add('key', cb)\n" + "assert(id)\n" + "assert(not activeKey)\n" + ); + + struct mScriptKeyEvent keyEvent = { + .d = { .type = mSCRIPT_EV_TYPE_KEY }, + .state = mSCRIPT_INPUT_STATE_DOWN, + .key = mSCRIPT_KEY_F1 + }; + mScriptContextFireEvent(&context, &keyEvent.d); + + TEST_PROGRAM("assert(input:isKeyActive(C.KEY.F1))"); + TEST_PROGRAM("assert(activeKey == C.KEY.F1)"); + TEST_PROGRAM("assert(state == C.INPUT_STATE.DOWN)"); + + keyEvent.state = mSCRIPT_INPUT_STATE_UP; + mScriptContextFireEvent(&context, &keyEvent.d); + + TEST_PROGRAM("assert(not input:isKeyActive(C.KEY.F1))"); + TEST_PROGRAM("assert(state == C.INPUT_STATE.UP)"); + + mScriptContextDeinit(&context); +} M_TEST_DEFINE(gamepadExport) { SETUP_LUA; @@ -219,5 +256,6 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptInput, cmocka_unit_test(fireKey), cmocka_unit_test(activeKeys), cmocka_unit_test(clearKeys), + cmocka_unit_test(numericKeys), cmocka_unit_test(gamepadExport), ) diff --git a/src/script/test/types.c b/src/script/test/types.c index 5c66b3f76..67b6fba9a 100644 --- a/src/script/test/types.c +++ b/src/script/test/types.c @@ -372,25 +372,25 @@ M_TEST_DEFINE(wrongConst) { mScriptFrameInit(&frame); mSCRIPT_PUSH(&frame.arguments, S(Test), &a); signature.entries[0] = mSCRIPT_TYPE_MS_S(Test); - assert_true(mScriptCoerceFrame(&signature, &frame.arguments)); + assert_true(mScriptCoerceFrame(&signature, &frame.arguments, &frame.arguments)); mScriptFrameDeinit(&frame); mScriptFrameInit(&frame); mSCRIPT_PUSH(&frame.arguments, CS(Test), &a); signature.entries[0] = mSCRIPT_TYPE_MS_CS(Test); - assert_true(mScriptCoerceFrame(&signature, &frame.arguments)); + assert_true(mScriptCoerceFrame(&signature, &frame.arguments, &frame.arguments)); mScriptFrameDeinit(&frame); mScriptFrameInit(&frame); mSCRIPT_PUSH(&frame.arguments, S(Test), &a); signature.entries[0] = mSCRIPT_TYPE_MS_CS(Test); - assert_true(mScriptCoerceFrame(&signature, &frame.arguments)); + assert_true(mScriptCoerceFrame(&signature, &frame.arguments, &frame.arguments)); mScriptFrameDeinit(&frame); mScriptFrameInit(&frame); mSCRIPT_PUSH(&frame.arguments, CS(Test), &a); signature.entries[0] = mSCRIPT_TYPE_MS_S(Test); - assert_false(mScriptCoerceFrame(&signature, &frame.arguments)); + assert_false(mScriptCoerceFrame(&signature, &frame.arguments, &frame.arguments)); mScriptFrameDeinit(&frame); mScriptFrameInit(&frame); @@ -402,7 +402,7 @@ M_TEST_DEFINE(wrongConst) { mSCRIPT_PUSH(&frame.arguments, S(Test), &a); assert_false(mScriptPopCSTest(&frame.arguments, &cb)); signature.entries[0] = mSCRIPT_TYPE_MS_CS(Test); - assert_true(mScriptCoerceFrame(&signature, &frame.arguments)); + assert_true(mScriptCoerceFrame(&signature, &frame.arguments, &frame.arguments)); assert_true(mScriptPopCSTest(&frame.arguments, &cb)); mScriptFrameDeinit(&frame); @@ -410,7 +410,7 @@ M_TEST_DEFINE(wrongConst) { mSCRIPT_PUSH(&frame.arguments, CS(Test), &a); assert_false(mScriptPopSTest(&frame.arguments, &b)); signature.entries[0] = mSCRIPT_TYPE_MS_S(Test); - assert_false(mScriptCoerceFrame(&signature, &frame.arguments)); + assert_false(mScriptCoerceFrame(&signature, &frame.arguments, &frame.arguments)); assert_false(mScriptPopSTest(&frame.arguments, &b)); mScriptFrameDeinit(&frame); diff --git a/src/script/types.c b/src/script/types.c index 20f945839..d860d40c0 100644 --- a/src/script/types.c +++ b/src/script/types.c @@ -1238,6 +1238,9 @@ static void _mScriptClassInit(struct mScriptTypeClass* cls, const struct mScript member->docstring = docstring; docstring = NULL; } + if (detail->info.member.type->base != mSCRIPT_TYPE_FUNCTION) { + abort(); + } if (detail->info.member.type->details.function.parameters.count != 3) { abort(); } @@ -1773,21 +1776,24 @@ bool mScriptCast(const struct mScriptType* type, const struct mScriptValue* inpu return false; } -bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList* frame) { - if (types->count < mScriptListSize(frame) && !types->variable) { +bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, const struct mScriptList* input, struct mScriptList* output) { + if (types->count < mScriptListSize(input) && !types->variable) { return false; } - if (types->count > mScriptListSize(frame) && !types->variable && !types->defaults) { + if (types->count > mScriptListSize(input) && !types->variable && !types->defaults) { return false; } + if (output) { + mScriptListResize(output, mScriptListSize(input) - mScriptListSize(output)); + } size_t i; - for (i = 0; i < mScriptListSize(frame) && i < types->count; ++i) { - if (types->entries[i] == mScriptListGetPointer(frame, i)->type) { + for (i = 0; i < mScriptListSize(input) && i < types->count; ++i) { + if (types->entries[i] == mScriptListGetConstPointer(input, i)->type) { continue; } - struct mScriptValue* unwrapped = NULL; - if (mScriptListGetPointer(frame, i)->type->base == mSCRIPT_TYPE_WRAPPER) { - unwrapped = mScriptValueUnwrap(mScriptListGetPointer(frame, i)); + const struct mScriptValue* unwrapped = NULL; + if (mScriptListGetConstPointer(input, i)->type->base == mSCRIPT_TYPE_WRAPPER) { + unwrapped = mScriptValueUnwrapConst(mScriptListGetConstPointer(input, i)); if (types->entries[i]->base == mSCRIPT_TYPE_WRAPPER) { if (types->entries[i]->details.type == unwrapped->type) { continue; @@ -1796,7 +1802,12 @@ bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList continue; } } - if (!mScriptCast(types->entries[i], mScriptListGetPointer(frame, i), mScriptListGetPointer(frame, i))) { + struct mScriptValue fakeVal; + struct mScriptValue* castTo = &fakeVal; + if (output) { + castTo = mScriptListGetPointer(output, i); + } + if (!mScriptCast(types->entries[i], mScriptListGetConstPointer(input, i), castTo)) { return false; } } @@ -1808,11 +1819,26 @@ bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList if (!types->defaults[i].type) { return false; } - memcpy(mScriptListAppend(frame), &types->defaults[i], sizeof(struct mScriptValue)); + if (output) { + memcpy(mScriptListAppend(output), &types->defaults[i], sizeof(struct mScriptValue)); + } } return true; } +const struct mScriptFunctionOverload* mScriptFunctionFindOverload(const struct mScriptFunctionOverload* overloads, struct mScriptList* frame) { + size_t i; + for (i = 0; overloads[i].type; ++i) { + if (overloads[i].type->base != mSCRIPT_TYPE_FUNCTION) { + continue; + } + if (mScriptCoerceFrame(&overloads[i].type->details.function.parameters, frame, NULL)) { + return &overloads[i]; + } + } + return NULL; +} + static void addTypesFromTuple(struct Table* types, const struct mScriptTypeTuple* tuple) { size_t i; for (i = 0; i < tuple->count; ++i) { diff --git a/src/tools/docgen.c b/src/tools/docgen.c index f57fb8d44..cdabb472c 100644 --- a/src/tools/docgen.c +++ b/src/tools/docgen.c @@ -190,6 +190,14 @@ void explainClass(struct mScriptTypeClass* cls, int level) { fprintf(out, "%s readonly: true\n", indent); } fprintf(out, "%s type: %s\n", indent, details->info.member.type->name); + if (details->info.member.overloads) { + fprintf(out, "%s overloads:\n", indent); + size_t i; + for (i = 0; details->info.member.overloads[i].type; ++i) { + mScriptTypeAdd(&types, details->info.member.overloads[i].type); + fprintf(out, "%s - %s\n", indent, details->info.member.overloads[i].type->name); + } + } break; case mSCRIPT_CLASS_INIT_END: break; From fb7ad7dbfb281478e362e944bb07f453740b7eb2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 3 Apr 2024 02:55:59 -0700 Subject: [PATCH 104/336] Qt: Actually load defaults again --- src/platform/qt/InputController.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index d5e799b5a..3deca07f3 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -172,15 +172,16 @@ void InputController::setConfiguration(ConfigController* config) { } bool InputController::loadConfiguration(uint32_t type) { - if (!mInputMapLoad(&m_inputMap, type, m_config->input())) { - return false; - } + bool loaded = mInputMapLoad(&m_inputMap, type, m_config->input()); auto driver = m_inputDrivers.value(type); if (!driver) { return false; } + if (!loaded) { + driver->bindDefaults(this); + } driver->loadConfiguration(m_config); - return true; + return loaded; } bool InputController::loadProfile(uint32_t type, const QString& profile) { From 68d120ec5571fedfe43f0150b13221d6c87ce81a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 3 Apr 2024 02:56:29 -0700 Subject: [PATCH 105/336] SDL: Start actually using SDL_GameController for its intended purpose --- src/platform/qt/GBAKeyEditor.cpp | 6 +- src/platform/qt/SettingsView.cpp | 5 ++ src/platform/qt/Window.cpp | 5 ++ src/platform/qt/input/SDLInputDriver.h | 4 ++ src/platform/sdl/sdl-events.c | 94 ++++++++++++++++++++------ src/platform/sdl/sdl-events.h | 1 + 6 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/platform/qt/GBAKeyEditor.cpp b/src/platform/qt/GBAKeyEditor.cpp index 4536bda2a..2afb546ad 100644 --- a/src/platform/qt/GBAKeyEditor.cpp +++ b/src/platform/qt/GBAKeyEditor.cpp @@ -54,7 +54,7 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, const QString& refresh(); #ifdef BUILD_SDL - if (type == SDL_BINDING_BUTTON) { + if (type == SDL_BINDING_BUTTON || type == SDL_BINDING_CONTROLLER) { m_profileSelect = new QComboBox(this); connect(m_profileSelect, static_cast(&QComboBox::currentIndexChanged), this, &GBAKeyEditor::selectGamepad); @@ -265,7 +265,7 @@ void GBAKeyEditor::refresh() { void GBAKeyEditor::lookupBinding(const mInputMap* map, KeyEditor* keyEditor, int key) { #ifdef BUILD_SDL - if (m_type == SDL_BINDING_BUTTON) { + if (m_type == SDL_BINDING_BUTTON || m_type == SDL_BINDING_CONTROLLER) { int value = mInputQueryBinding(map, m_type, key); keyEditor->setValueButton(value); return; @@ -329,7 +329,7 @@ void GBAKeyEditor::lookupHats(const mInputMap* map) { void GBAKeyEditor::bindKey(const KeyEditor* keyEditor, int key) { InputMapper mapper = m_controller->mapper(m_type); #ifdef BUILD_SDL - if (m_type == SDL_BINDING_BUTTON && keyEditor->axis() >= 0) { + if ((m_type == SDL_BINDING_BUTTON || m_type == SDL_BINDING_CONTROLLER) && keyEditor->axis() >= 0) { mapper.bindAxis(keyEditor->axis(), keyEditor->direction(), key); } if (m_type == SDL_BINDING_BUTTON && keyEditor->hat() >= 0) { diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 7c41cb4a4..e95da696c 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -334,8 +334,13 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC GBAKeyEditor* buttonEditor = nullptr; #ifdef BUILD_SDL +#if SDL_VERSION_ATLEAST(2, 0, 0) + QString profile = inputController->profileForType(SDL_BINDING_CONTROLLER); + buttonEditor = new GBAKeyEditor(inputController, SDL_BINDING_CONTROLLER, profile); +#else QString profile = inputController->profileForType(SDL_BINDING_BUTTON); buttonEditor = new GBAKeyEditor(inputController, SDL_BINDING_BUTTON, profile); +#endif addPage(tr("Controllers"), buttonEditor, Page::CONTROLLERS); connect(m_ui.buttonBox, &QDialogButtonBox::accepted, buttonEditor, &GBAKeyEditor::save); #endif diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index cc439f60f..6216e2247 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -177,8 +177,13 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi #ifdef BUILD_SDL m_inputController.addInputDriver(std::make_shared(&m_inputController)); +#if SDL_VERSION_ATLEAST(2, 0, 0) + m_inputController.setGamepadDriver(SDL_BINDING_CONTROLLER); + m_inputController.setSensorDriver(SDL_BINDING_CONTROLLER); +#else m_inputController.setGamepadDriver(SDL_BINDING_BUTTON); m_inputController.setSensorDriver(SDL_BINDING_BUTTON); +#endif #endif m_shortcutController->setConfigController(m_config); diff --git a/src/platform/qt/input/SDLInputDriver.h b/src/platform/qt/input/SDLInputDriver.h index 4a4916ad3..d10661ed7 100644 --- a/src/platform/qt/input/SDLInputDriver.h +++ b/src/platform/qt/input/SDLInputDriver.h @@ -31,7 +31,11 @@ public: SDLInputDriver(InputController*, QObject* parent = nullptr); ~SDLInputDriver(); +#if SDL_VERSION_ATLEAST(2, 0, 0) + uint32_t type() const override { return SDL_BINDING_CONTROLLER; } +#else uint32_t type() const override { return SDL_BINDING_BUTTON; } +#endif QString visibleName() const override { return QLatin1String("SDL"); } QString currentProfile() const override; diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 41783b3c3..e146bfd90 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -167,12 +167,30 @@ void mSDLInitBindingsGBA(struct mInputMap* inputMap) { mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT); #endif +#if SDL_VERSION_ATLEAST(2, 0, 0) + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_A, GBA_KEY_A); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_B, GBA_KEY_B); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, GBA_KEY_L); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, GBA_KEY_R); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_START, GBA_KEY_START); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_BACK, GBA_KEY_SELECT); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_UP, GBA_KEY_UP); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_DOWN, GBA_KEY_DOWN); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_LEFT, GBA_KEY_LEFT); + mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, GBA_KEY_RIGHT); + + struct mInputAxis description = (struct mInputAxis) { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x4000, -0x4000 }; + mInputBindAxis(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_AXIS_LEFTX, &description); + description = (struct mInputAxis) { GBA_KEY_DOWN, GBA_KEY_UP, 0x4000, -0x4000 }; + mInputBindAxis(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_AXIS_LEFTY, &description); +#else struct mInputAxis description = { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x4000, -0x4000 }; mInputBindAxis(inputMap, SDL_BINDING_BUTTON, 0, &description); description = (struct mInputAxis) { GBA_KEY_DOWN, GBA_KEY_UP, 0x4000, -0x4000 }; mInputBindAxis(inputMap, SDL_BINDING_BUTTON, 1, &description); mInputBindHat(inputMap, SDL_BINDING_BUTTON, 0, &GBAInputInfo.hat); +#endif } bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { @@ -284,17 +302,19 @@ void mSDLDetachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration* config) { mInputMapLoad(context->bindings, SDL_BINDING_KEY, config); if (context->joystick) { - mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config); #if SDL_VERSION_ATLEAST(2, 0, 0) + mInputMapLoad(context->bindings, SDL_BINDING_CONTROLLER, config); char name[34] = {0}; SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(context->joystick->joystick), name, sizeof(name)); + mInputProfileLoad(context->bindings, SDL_BINDING_CONTROLLER, config, name); #else + mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config); const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick)); if (!name) { return; } -#endif mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name); +#endif const char* value; char* end; @@ -410,7 +430,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration* if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) { events->players[i]->joystick = joystick; if (config) { - mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName); + mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_CONTROLLER, config, joystickName); } return; } @@ -421,7 +441,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration* } events->players[i]->joystick = joystick; if (config && joystickName[0]) { - mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName); + mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_CONTROLLER, config, joystickName); } break; } @@ -574,6 +594,45 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer* } } +#if SDL_VERSION_ATLEAST(2, 0, 0) +static void _mSDLHandleControllerButton(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const struct SDL_ControllerButtonEvent* event) { + int key = 0; + key = mInputMapKey(sdlContext->bindings, SDL_BINDING_CONTROLLER, event->button); + if (key == -1) { + return; + } + + mCoreThreadInterrupt(context); + if (event->type == SDL_CONTROLLERBUTTONDOWN) { + context->core->addKeys(context->core, 1 << key); + } else { + context->core->clearKeys(context->core, 1 << key); + } + mCoreThreadContinue(context); +} + +static void _mSDLHandleControllerAxis(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const struct SDL_ControllerAxisEvent* event) { + int clearKeys = ~mInputClearAxis(sdlContext->bindings, SDL_BINDING_CONTROLLER, event->axis, -1); + int newKeys = 0; + int key = mInputMapAxis(sdlContext->bindings, SDL_BINDING_CONTROLLER, event->axis, event->value); + if (key != -1) { + newKeys |= 1 << key; + } + clearKeys &= ~newKeys; + mCoreThreadInterrupt(context); + context->core->clearKeys(context->core, clearKeys); + context->core->addKeys(context->core, newKeys); + mCoreThreadContinue(context); +} + +static void _mSDLHandleWindowEvent(struct mSDLPlayer* sdlContext, const struct SDL_WindowEvent* event) { + switch (event->event) { + case SDL_WINDOWEVENT_SIZE_CHANGED: + sdlContext->windowUpdated = 1; + break; + } +} +#else static void _mSDLHandleJoyButton(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const struct SDL_JoyButtonEvent* event) { int key = 0; key = mInputMapKey(sdlContext->bindings, SDL_BINDING_BUTTON, event->button); @@ -616,16 +675,6 @@ static void _mSDLHandleJoyAxis(struct mCoreThread* context, struct mSDLPlayer* s context->core->clearKeys(context->core, clearKeys); context->core->addKeys(context->core, newKeys); mCoreThreadContinue(context); - -} - -#if SDL_VERSION_ATLEAST(2, 0, 0) -static void _mSDLHandleWindowEvent(struct mSDLPlayer* sdlContext, const struct SDL_WindowEvent* event) { - switch (event->event) { - case SDL_WINDOWEVENT_SIZE_CHANGED: - sdlContext->windowUpdated = 1; - break; - } } #endif @@ -638,17 +687,19 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, case SDL_WINDOWEVENT: _mSDLHandleWindowEvent(sdlContext, &event->window); break; + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + _mSDLHandleControllerButton(context, sdlContext, &event->cbutton); + break; + case SDL_CONTROLLERAXISMOTION: + _mSDLHandleControllerAxis(context, sdlContext, &event->caxis); + break; #else case SDL_VIDEORESIZE: sdlContext->newWidth = event->resize.w; sdlContext->newHeight = event->resize.h; sdlContext->windowUpdated = 1; break; -#endif - case SDL_KEYDOWN: - case SDL_KEYUP: - _mSDLHandleKeypress(context, sdlContext, &event->key); - break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: _mSDLHandleJoyButton(context, sdlContext, &event->jbutton); @@ -659,6 +710,11 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, case SDL_JOYAXISMOTION: _mSDLHandleJoyAxis(context, sdlContext, &event->jaxis); break; +#endif + case SDL_KEYDOWN: + case SDL_KEYUP: + _mSDLHandleKeypress(context, sdlContext, &event->key); + break; } } diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index 8bdbd7c0b..e49613932 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -29,6 +29,7 @@ mLOG_DECLARE_CATEGORY(SDL_EVENTS); #define SDL_BINDING_KEY 0x53444C4BU #define SDL_BINDING_BUTTON 0x53444C42U +#define SDL_BINDING_CONTROLLER 0x53444C43U #define MAX_PLAYERS 4 From 9320588e45ab0c71f27dc7f6d570bda27082a8b9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 3 Apr 2024 04:41:54 -0700 Subject: [PATCH 106/336] Qt: Switch SDL controller usage from Joystick to GameController --- CMakeLists.txt | 2 +- src/platform/qt/GBAKeyEditor.cpp | 1 + src/platform/qt/KeyEditor.cpp | 32 +++- src/platform/qt/KeyEditor.h | 5 + src/platform/qt/ShortcutView.cpp | 1 + src/platform/qt/input/Gamepad.h | 3 + src/platform/qt/input/SDLInputDriver.cpp | 56 +++++- src/platform/qt/input/SDLInputDriver.h | 3 + src/platform/sdl/sdl-events.c | 207 +++++++++++++++++++++++ src/platform/sdl/sdl-events.h | 3 + 10 files changed, 307 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bf160665..3f2ff4686 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ if(NOT MSVC) # TODO: Remove this once mScript KV pairs support const correctness set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=incompatible-pointer-types") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -Woverloaded-virtual") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -Woverloaded-virtual -Werror=reorder") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267 /Zc:preprocessor-") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267 /Zc:preprocessor-") diff --git a/src/platform/qt/GBAKeyEditor.cpp b/src/platform/qt/GBAKeyEditor.cpp index 2afb546ad..8a8427973 100644 --- a/src/platform/qt/GBAKeyEditor.cpp +++ b/src/platform/qt/GBAKeyEditor.cpp @@ -122,6 +122,7 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, const QString& connect(key, &KeyEditor::valueChanged, this, &GBAKeyEditor::setNext); connect(key, &KeyEditor::axisChanged, this, &GBAKeyEditor::setNext); connect(key, &KeyEditor::hatChanged, this, &GBAKeyEditor::setNext); + key->setInputController(m_controller); key->installEventFilter(this); } diff --git a/src/platform/qt/KeyEditor.cpp b/src/platform/qt/KeyEditor.cpp index 7d3ba1990..50702da73 100644 --- a/src/platform/qt/KeyEditor.cpp +++ b/src/platform/qt/KeyEditor.cpp @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "KeyEditor.h" +#include "InputController.h" +#include "input/Gamepad.h" #include "input/GamepadAxisEvent.h" #include "input/GamepadButtonEvent.h" #include "ShortcutController.h" @@ -18,6 +20,7 @@ using namespace QGBA; KeyEditor::KeyEditor(QWidget* parent) : QLineEdit(parent) + , m_controller(nullptr) , m_direction(GamepadAxisEvent::NEUTRAL) , m_hatDirection(GamepadHatEvent::CENTER) { @@ -26,6 +29,13 @@ KeyEditor::KeyEditor(QWidget* parent) m_lastKey.setSingleShot(true); } +void KeyEditor::setInputController(InputController* controller) { + m_controller = controller; + if (m_button) { + updateButtonText(); + } +} + void KeyEditor::setValue(int key) { m_key = key; if (m_button) { @@ -204,10 +214,28 @@ void KeyEditor::updateButtonText() { } } if (m_key >= 0) { - text.append(QString::number(m_key)); + std::shared_ptr gamepad; + if (m_controller && m_controller->gamepadDriver()) { + gamepad = m_controller->gamepadDriver()->activeGamepad(); + } + if (!gamepad) { + text.append(QString::number(m_key)); + } else { + text.append(gamepad->buttonHumanName(m_key)); + } } if (m_direction != GamepadAxisEvent::NEUTRAL) { - text.append((m_direction == GamepadAxisEvent::NEGATIVE ? "-" : "+") + QString::number(m_axis)); + QString name; + std::shared_ptr gamepad; + if (m_controller && m_controller->gamepadDriver()) { + gamepad = m_controller->gamepadDriver()->activeGamepad(); + } + if (!gamepad) { + name = QString::number(m_axis); + } else { + name = gamepad->axisHumanName(m_axis); + } + text.append((m_direction == GamepadAxisEvent::NEGATIVE ? "-" : "+") + name); } if (text.isEmpty()) { setText(tr("---")); diff --git a/src/platform/qt/KeyEditor.h b/src/platform/qt/KeyEditor.h index c1bb56fae..93af927ac 100644 --- a/src/platform/qt/KeyEditor.h +++ b/src/platform/qt/KeyEditor.h @@ -13,12 +13,16 @@ namespace QGBA { +class InputController; + class KeyEditor : public QLineEdit { Q_OBJECT public: KeyEditor(QWidget* parent = nullptr); + void setInputController(InputController* controller); + int value() const { return m_key; } GamepadAxisEvent::Direction direction() const { return m_direction; } @@ -57,6 +61,7 @@ private: int m_axis = -1; int m_hat = -1; bool m_button = false; + InputController* m_controller; GamepadAxisEvent::Direction m_direction; GamepadHatEvent::Direction m_hatDirection; QTimer m_lastKey; diff --git a/src/platform/qt/ShortcutView.cpp b/src/platform/qt/ShortcutView.cpp index 5efbc4d62..f457263c5 100644 --- a/src/platform/qt/ShortcutView.cpp +++ b/src/platform/qt/ShortcutView.cpp @@ -54,6 +54,7 @@ void ShortcutView::setInputController(InputController* controller) { } m_input = controller; m_input->stealFocus(this); + m_ui.keyEdit->setInputController(controller); } void ShortcutView::load(const QModelIndex& index) { diff --git a/src/platform/qt/input/Gamepad.h b/src/platform/qt/input/Gamepad.h index 1781885cd..9a1cf19ec 100644 --- a/src/platform/qt/input/Gamepad.h +++ b/src/platform/qt/input/Gamepad.h @@ -22,6 +22,9 @@ public: virtual QList currentAxes() = 0; virtual QList currentHats() = 0; + virtual QString buttonHumanName(int) const = 0; + virtual QString axisHumanName(int) const = 0; + virtual int buttonCount() const = 0; virtual int axisCount() const = 0; virtual int hatCount() const = 0; diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index e3a77094f..72d148057 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -257,13 +257,20 @@ QList SDLGamepad::currentButtons() { return {}; } - SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; QList buttons; +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller; + for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) { + buttons.append(SDL_GameControllerGetButton(controller, static_cast(i))); + } +#else + SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; int numButtons = SDL_JoystickNumButtons(joystick); for (int i = 0; i < numButtons; ++i) { buttons.append(SDL_JoystickGetButton(joystick, i)); } +#endif return buttons; } @@ -273,13 +280,20 @@ QList SDLGamepad::currentAxes() { return {}; } - SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; QList axes; +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller; + for (int i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) { + axes.append(SDL_GameControllerGetAxis(controller, static_cast(i))); + } +#else + SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; int numAxes = SDL_JoystickNumAxes(joystick); for (int i = 0; i < numAxes; ++i) { axes.append(SDL_JoystickGetAxis(joystick, i)); } +#endif return axes; } @@ -289,24 +303,52 @@ QList SDLGamepad::currentHats() { return {}; } - SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; QList hats; +#if !SDL_VERSION_ATLEAST(2, 0, 0) + SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; int numHats = SDL_JoystickNumHats(joystick); for (int i = 0; i < numHats; ++i) { hats.append(static_cast(SDL_JoystickGetHat(joystick, i))); } +#endif return hats; } +QString SDLGamepad::buttonHumanName(int button) const { +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller; + const char* name = mSDLButtonName(controller, static_cast(button)); + if (name) { + return QString::fromUtf8(name); + } +#endif + return QString::number(button); +} + +QString SDLGamepad::axisHumanName(int axis) const { +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller; + const char* name = mSDLAxisName(controller, static_cast(axis)); + if (name) { + return QString::fromUtf8(name); + } +#endif + return QString::number(axis); +} + int SDLGamepad::buttonCount() const { if (!verify()) { return -1; } +#if SDL_VERSION_ATLEAST(2, 0, 0) + return SDL_CONTROLLER_BUTTON_MAX; +#else SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; return SDL_JoystickNumButtons(joystick); +#endif } int SDLGamepad::axisCount() const { @@ -314,8 +356,12 @@ int SDLGamepad::axisCount() const { return -1; } +#if SDL_VERSION_ATLEAST(2, 0, 0) + return SDL_CONTROLLER_AXIS_MAX; +#else SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; return SDL_JoystickNumAxes(joystick); +#endif } int SDLGamepad::hatCount() const { @@ -323,8 +369,12 @@ int SDLGamepad::hatCount() const { return -1; } +#if SDL_VERSION_ATLEAST(2, 0, 0) + return 0; +#else SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; return SDL_JoystickNumHats(joystick); +#endif } QString SDLGamepad::name() const { diff --git a/src/platform/qt/input/SDLInputDriver.h b/src/platform/qt/input/SDLInputDriver.h index d10661ed7..217dc40a7 100644 --- a/src/platform/qt/input/SDLInputDriver.h +++ b/src/platform/qt/input/SDLInputDriver.h @@ -93,6 +93,9 @@ public: int axisCount() const override; int hatCount() const override; + QString buttonHumanName(int) const override; + QString axisHumanName(int) const override; + QString name() const override; QString visibleName() const override; diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index e146bfd90..383775636 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -886,4 +886,211 @@ void mSDLSetScreensaverSuspendable(struct mSDLEvents* events, bool suspendable) SDL_EnableScreenSaver(); } } + +static const char* const buttonNamesXbox360[SDL_CONTROLLER_BUTTON_MAX] = { + [SDL_CONTROLLER_BUTTON_A] = "A", + [SDL_CONTROLLER_BUTTON_B] = "B", + [SDL_CONTROLLER_BUTTON_X] = "X", + [SDL_CONTROLLER_BUTTON_Y] = "Y", + [SDL_CONTROLLER_BUTTON_BACK] = "Back", + [SDL_CONTROLLER_BUTTON_GUIDE] = "Xbox", + [SDL_CONTROLLER_BUTTON_START] = "Start", + [SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS", + [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", + [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", + [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", + [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", + [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", + [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", + [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", + [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", + [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +}; + +#if SDL_VERSION_ATLEAST(2, 0, 12) +static const char* const buttonNamesXboxOne[SDL_CONTROLLER_BUTTON_MAX] = { + [SDL_CONTROLLER_BUTTON_A] = "A", + [SDL_CONTROLLER_BUTTON_B] = "B", + [SDL_CONTROLLER_BUTTON_X] = "X", + [SDL_CONTROLLER_BUTTON_Y] = "Y", + [SDL_CONTROLLER_BUTTON_BACK] = "View", + [SDL_CONTROLLER_BUTTON_GUIDE] = "Xbox", + [SDL_CONTROLLER_BUTTON_START] = "Menu", + [SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS", + [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", + [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", + [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", + [SDL_CONTROLLER_BUTTON_MISC1] = "Share", + [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", + [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", + [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", + [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", + [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +}; + +static const char* const buttonNamesPlayStation[SDL_CONTROLLER_BUTTON_MAX] = { + [SDL_CONTROLLER_BUTTON_A] = "×", + [SDL_CONTROLLER_BUTTON_B] = "â—‹", + [SDL_CONTROLLER_BUTTON_X] = "â–¡", + [SDL_CONTROLLER_BUTTON_Y] = "â–³", + [SDL_CONTROLLER_BUTTON_BACK] = "Share", + [SDL_CONTROLLER_BUTTON_GUIDE] = "PS", + [SDL_CONTROLLER_BUTTON_START] = "Options", + [SDL_CONTROLLER_BUTTON_LEFTSTICK] = "L3", + [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "R3", + [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L1", + [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R1", + [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", + [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", + [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", + [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", + [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", + [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +}; + +static const char* const buttonNamesNintedo[SDL_CONTROLLER_BUTTON_MAX] = { + [SDL_CONTROLLER_BUTTON_A] = "A", + [SDL_CONTROLLER_BUTTON_B] = "B", + [SDL_CONTROLLER_BUTTON_X] = "X", + [SDL_CONTROLLER_BUTTON_Y] = "Y", + [SDL_CONTROLLER_BUTTON_BACK] = "-", + [SDL_CONTROLLER_BUTTON_GUIDE] = "Home", + [SDL_CONTROLLER_BUTTON_START] = "+", + [SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS", + [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", + [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L", + [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R", + [SDL_CONTROLLER_BUTTON_MISC1] = "Share", + [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", + [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", + [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", + [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", + [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +}; + +static const char* const buttonNamesGeneric[SDL_CONTROLLER_BUTTON_MAX] = { + [SDL_CONTROLLER_BUTTON_A] = "A", + [SDL_CONTROLLER_BUTTON_B] = "B", + [SDL_CONTROLLER_BUTTON_X] = "X", + [SDL_CONTROLLER_BUTTON_Y] = "Y", + [SDL_CONTROLLER_BUTTON_BACK] = "Select", + [SDL_CONTROLLER_BUTTON_GUIDE] = "Guide", + [SDL_CONTROLLER_BUTTON_START] = "Start", + [SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS", + [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", + [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", + [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", + [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", + [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", + [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", + [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", + [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", + [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +}; +#endif + +const char* mSDLButtonName(SDL_GameController* controller, SDL_GameControllerButton button) { + const char* const* buttonNames = buttonNamesXbox360; + +#if SDL_VERSION_ATLEAST(2, 0, 12) + switch (SDL_GameControllerGetType(controller)) { + case SDL_CONTROLLER_TYPE_XBOX360: + buttonNames = buttonNamesXbox360; + break; + case SDL_CONTROLLER_TYPE_XBOXONE: + buttonNames = buttonNamesXboxOne; + break; + case SDL_CONTROLLER_TYPE_PS3: + case SDL_CONTROLLER_TYPE_PS4: +#if SDL_VERSION_ATLEAST(2, 0, 14) + case SDL_CONTROLLER_TYPE_PS5: +#endif + buttonNames = buttonNamesPlayStation; + break; + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + buttonNames = buttonNamesNintedo; + break; + default: + buttonNames = buttonNamesGeneric; + break; + } +#endif + + switch (button) { + case SDL_CONTROLLER_BUTTON_DPAD_UP: + return "D↑"; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + return "D↓"; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + return "Dâ†"; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + return "D→"; + default: + return buttonNames[button]; + case SDL_CONTROLLER_BUTTON_INVALID: + case SDL_CONTROLLER_BUTTON_MAX: + break; + } + return NULL; +} + +static const char* const axisNamesXbox[SDL_CONTROLLER_AXIS_MAX] = { + [SDL_CONTROLLER_AXIS_TRIGGERLEFT] = "LT", + [SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = "RT", +}; + +#if SDL_VERSION_ATLEAST(2, 0, 12) +static const char* const axisNamesPlayStation[SDL_CONTROLLER_AXIS_MAX] = { + [SDL_CONTROLLER_AXIS_TRIGGERLEFT] = "L3", + [SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = "R3", +}; + +static const char* const axisNamesNintendo[SDL_CONTROLLER_AXIS_MAX] = { + [SDL_CONTROLLER_AXIS_TRIGGERLEFT] = "ZL", + [SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = "ZR", +}; +#endif + +const char* mSDLAxisName(SDL_GameController* controller, SDL_GameControllerAxis axis) { + const char* const* axisNames = axisNamesXbox; + +#if SDL_VERSION_ATLEAST(2, 0, 12) + switch (SDL_GameControllerGetType(controller)) { + case SDL_CONTROLLER_TYPE_XBOX360: + case SDL_CONTROLLER_TYPE_XBOXONE: + default: + axisNames = axisNamesXbox; + break; + case SDL_CONTROLLER_TYPE_PS3: + case SDL_CONTROLLER_TYPE_PS4: +#if SDL_VERSION_ATLEAST(2, 0, 14) + case SDL_CONTROLLER_TYPE_PS5: +#endif + axisNames = axisNamesPlayStation; + break; + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + axisNames = axisNamesNintendo; + break; + } +#endif + + switch (axis) { + case SDL_CONTROLLER_AXIS_LEFTX: + return "X"; + case SDL_CONTROLLER_AXIS_LEFTY: + return "Y"; + case SDL_CONTROLLER_AXIS_RIGHTX: + return "RX"; + case SDL_CONTROLLER_AXIS_RIGHTY: + return "RY"; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + return axisNames[axis]; + case SDL_CONTROLLER_AXIS_INVALID: + case SDL_CONTROLLER_AXIS_MAX: + break; + } + return NULL; +} + #endif diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index e49613932..741503be4 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -126,6 +126,9 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, void mSDLSuspendScreensaver(struct mSDLEvents*); void mSDLResumeScreensaver(struct mSDLEvents*); void mSDLSetScreensaverSuspendable(struct mSDLEvents*, bool suspendable); + +const char* mSDLButtonName(SDL_GameController*, SDL_GameControllerButton); +const char* mSDLAxisName(SDL_GameController*, SDL_GameControllerAxis); #endif CXX_GUARD_END From 6e39eb37f6db51f893410117f45dcdd3a6128eb6 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Sat, 29 Jul 2023 11:45:37 +0000 Subject: [PATCH 107/336] Qt: Update translation (Spanish) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/es/ --- src/platform/qt/ts/mgba-es.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/platform/qt/ts/mgba-es.ts b/src/platform/qt/ts/mgba-es.ts index 83c4d5d98..16238357b 100644 --- a/src/platform/qt/ts/mgba-es.ts +++ b/src/platform/qt/ts/mgba-es.ts @@ -716,7 +716,7 @@ Tamaño de descarga: %3 Image files (*.png *.jpg *.bmp) - + Archivos de imagen (*.png *.jpg *.bmp) @@ -3752,17 +3752,17 @@ Tamaño de descarga: %3 Trying to detach a multiplayer player that's not attached - + Intentando desvincular a un multijugador que no está conectado Trying to get player ID for a multiplayer player that's not attached - + Intentando obtener el ID de un multijugador que no está conectado Trying to get save ID for a multiplayer player that's not attached - + Intentando obtener el ID de guardado de un multijugador que no está conectado @@ -4310,7 +4310,7 @@ Tamaño de descarga: %3 Save file: - + Guarda el archivo: @@ -4477,7 +4477,7 @@ Tamaño de descarga: %3 + RTC - + + RTC @@ -4759,12 +4759,12 @@ Tamaño de descarga: %3 Select image - Seleccionar imagen + Seleccionar una imagen Image file (*.png *.jpg *.jpeg) - Archivo de imagen (*.png *.jpg *.jpeg) + Archivo de imagen (*.png *.jpg *.jpeg) @@ -5089,7 +5089,7 @@ Tamaño de descarga: %3 Custom border: - + Borde personalizado: @@ -5134,7 +5134,7 @@ Tamaño de descarga: %3 Rewind speed: - + Velocidad del rebobinado: @@ -6388,12 +6388,12 @@ Tamaño de descarga: %3 Increase fast forward speed - + Aumentar la velocidad del avance rápido Decrease fast forward speed - + Reducir la velocidad del avance rápido @@ -6771,17 +6771,17 @@ Tamaño de descarga: %3 Super (L) - Super (L) + Súper (L) Super (R) - Super (R) + Súper (R) Menu - Menú + Menú From 5acef1c454dac84d54458896547cc937b20e0589 Mon Sep 17 00:00:00 2001 From: Momo cao Date: Fri, 22 Sep 2023 00:52:19 +0000 Subject: [PATCH 108/336] Qt: Update translation (Spanish) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/es/ --- src/platform/qt/ts/mgba-es.ts | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/platform/qt/ts/mgba-es.ts b/src/platform/qt/ts/mgba-es.ts index 16238357b..7dfe054c7 100644 --- a/src/platform/qt/ts/mgba-es.ts +++ b/src/platform/qt/ts/mgba-es.ts @@ -656,7 +656,7 @@ Tamaño de descarga: %3 Use default image - Utilizar la imagen por defecto + Utilizar imagen por defecto @@ -686,17 +686,17 @@ Tamaño de descarga: %3 Build finished - Construcción finalizada + Compilación finalizada Forwarder finished building - Transmisor terminado de construir + Transmisor terminado de compilar Build failed - Falló la construcción + Falló la compilación @@ -3762,7 +3762,7 @@ Tamaño de descarga: %3 Trying to get save ID for a multiplayer player that's not attached - Intentando obtener el ID de guardado de un multijugador que no está conectado + Intentando obtener ID de guardado para un jugador multijugador que no está conectado @@ -3780,7 +3780,7 @@ Tamaño de descarga: %3 Export - Esportar + Exportar @@ -4228,7 +4228,7 @@ Tamaño de descarga: %3 Hurry up! - ¡Apúrate! + ¡Apresúrate! @@ -4310,7 +4310,7 @@ Tamaño de descarga: %3 Save file: - Guarda el archivo: + Guardar: @@ -4759,7 +4759,7 @@ Tamaño de descarga: %3 Select image - Seleccionar una imagen + Seleccionar imagen @@ -4792,14 +4792,16 @@ Tamaño de descarga: %3 Hace %n hora Hace %n horas + Hace %n horas %n day(s) ago - Hace %n dia - Hace %n dias + Hace %n día + Hace %n días + Hace %n días @@ -5134,7 +5136,7 @@ Tamaño de descarga: %3 Rewind speed: - Velocidad del rebobinado: + Velocidad de rebobinado: @@ -6106,7 +6108,7 @@ Tamaño de descarga: %3 Load ROM in archive... - Cargar ROM desde contenedor... + Cargar ROM desde archivo comprimido... @@ -6151,7 +6153,7 @@ Tamaño de descarga: %3 Recent - Cargar reciente + Reciente @@ -6388,12 +6390,12 @@ Tamaño de descarga: %3 Increase fast forward speed - Aumentar la velocidad del avance rápido + Aumentar la velocidad de avance rápido Decrease fast forward speed - Reducir la velocidad del avance rápido + Disminuir velocidad de avance rápido From dcb07f6e3363151f8267f9279071c03a7f4e81b4 Mon Sep 17 00:00:00 2001 From: Hoseok Seo Date: Fri, 4 Aug 2023 02:23:05 +0000 Subject: [PATCH 109/336] Qt: Update translation (Korean) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/ko/ --- src/platform/qt/ts/mgba-ko.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/platform/qt/ts/mgba-ko.ts b/src/platform/qt/ts/mgba-ko.ts index a0955e500..05a8dc604 100644 --- a/src/platform/qt/ts/mgba-ko.ts +++ b/src/platform/qt/ts/mgba-ko.ts @@ -716,7 +716,7 @@ Download size: %3 Image files (*.png *.jpg *.bmp) - + ì´ë¯¸ì§€ íŒŒì¼ (*.png *.jpg *.bmp) @@ -3752,17 +3752,17 @@ Download size: %3 Trying to detach a multiplayer player that's not attached - + ì—°ê²°ë˜ì§€ ì•Šì€ ë©€í‹°í”Œë ˆì´ì–´ 플레ì´ì–´ë¥¼ 분리하려고 함 Trying to get player ID for a multiplayer player that's not attached - + ì—°ê²°ë˜ì§€ ì•Šì€ ë©€í‹°í”Œë ˆì´ì–´ 플레ì´ì–´ì˜ 플레ì´ì–´ ID를 가져오려고 함 Trying to get save ID for a multiplayer player that's not attached - + ì—°ê²°ë˜ì§€ ì•Šì€ ë©€í‹°í”Œë ˆì´ì–´ 플레ì´ì–´ì˜ 저장 ID를 얻으려고 함 @@ -4310,7 +4310,7 @@ Download size: %3 Save file: - + 저장 파ì¼: @@ -4477,7 +4477,7 @@ Download size: %3 + RTC - + + RTC @@ -4759,12 +4759,12 @@ Download size: %3 Select image - ì´ë¯¸ì§€ ì„ íƒ + ì´ë¯¸ì§€ ì„ íƒ Image file (*.png *.jpg *.jpeg) - ì´ë¯¸ì§€ íŒŒì¼ (*.png *.jpg *.jpeg) + ì´ë¯¸ì§€ íŒŒì¼ (*.png *.jpg *.jpeg) @@ -5067,7 +5067,7 @@ Download size: %3 Custom border: - + 커스텀 í…Œë‘리: @@ -5112,7 +5112,7 @@ Download size: %3 Rewind speed: - + ë˜ê°ê¸° ì†ë„: @@ -6325,12 +6325,12 @@ Download size: %3 Increase fast forward speed - + 빨리 ê°ê¸° ì†ë„ í–¥ìƒ Decrease fast forward speed - + 빨리 ê°ê¸° ì†ë„ 줄ì´ê¸° @@ -6769,17 +6769,17 @@ Download size: %3 Super (L) - ìŠˆí¼ (L) + ìŠˆí¼ (L) Super (R) - ìŠˆí¼ (R) + ìŠˆí¼ (R) Menu - 메뉴 + 메뉴 From 424ef6ff745a5fea974705d74d4a79315ae9afe6 Mon Sep 17 00:00:00 2001 From: Felipe Date: Tue, 1 Aug 2023 13:33:20 +0000 Subject: [PATCH 110/336] Qt: Update translation (Portuguese (Brazil)) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/pt_BR/ --- src/platform/qt/ts/mgba-pt_BR.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/platform/qt/ts/mgba-pt_BR.ts b/src/platform/qt/ts/mgba-pt_BR.ts index 2cbfde528..77573eb1b 100644 --- a/src/platform/qt/ts/mgba-pt_BR.ts +++ b/src/platform/qt/ts/mgba-pt_BR.ts @@ -716,7 +716,7 @@ Tamanho do download: %3 Image files (*.png *.jpg *.bmp) - + Arquivo da imagem (*.png *.jpg *.bmp) @@ -3752,17 +3752,17 @@ Tamanho do download: %3 Trying to detach a multiplayer player that's not attached - + Tentando desconectar um jogador multiplayer que não está conectado Trying to get player ID for a multiplayer player that's not attached - + Tentando obter a ID do jogador pra um jogador multiplayer que não está conectado Trying to get save ID for a multiplayer player that's not attached - + Tentando obter a ID salva pra um jogador multiplayer que não está conectado @@ -4310,7 +4310,7 @@ Tamanho do download: %3 Save file: - + Arquivo do save: @@ -4477,7 +4477,7 @@ Tamanho do download: %3 + RTC - + + RTC @@ -4759,12 +4759,12 @@ Tamanho do download: %3 Select image - Selecionar imagem + Selecionar imagem Image file (*.png *.jpg *.jpeg) - Arquivo da imagem (*.png *.jpg *.jpeg) + Arquivo da imagem (*.png *.jpg *.jpeg) @@ -4792,6 +4792,7 @@ Tamanho do download: %3 %n hora atrás %n horas atrás + @@ -4800,6 +4801,7 @@ Tamanho do download: %3 %n dia atrás %n dias atrás + @@ -5089,7 +5091,7 @@ Tamanho do download: %3 Custom border: - + Borda personalizada: @@ -5134,7 +5136,7 @@ Tamanho do download: %3 Rewind speed: - + Velocidade do retrocesso: @@ -6388,12 +6390,12 @@ Tamanho do download: %3 Increase fast forward speed - + Aumentar a velocidade do avanço rápido Decrease fast forward speed - + Diminuir a velocidade do avanço rápido @@ -6771,17 +6773,17 @@ Tamanho do download: %3 Super (L) - Super (E) + Super (E) Super (R) - Super (D) + Super (D) Menu - Menu + Menu From 7af70a69bb4b8f74257bacbc7310769788b1f8f4 Mon Sep 17 00:00:00 2001 From: Eryk Michalak Date: Sat, 30 Sep 2023 10:54:29 +0000 Subject: [PATCH 111/336] Qt: Update translation (Polish) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/pl/ --- src/platform/qt/ts/mgba-pl.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/platform/qt/ts/mgba-pl.ts b/src/platform/qt/ts/mgba-pl.ts index 180b32630..650563e2e 100644 --- a/src/platform/qt/ts/mgba-pl.ts +++ b/src/platform/qt/ts/mgba-pl.ts @@ -716,7 +716,7 @@ Rozmiar pobierania: %3 Image files (*.png *.jpg *.bmp) - + Obrazy (*.png *.jpg *.bmp) @@ -3752,17 +3752,17 @@ Rozmiar pobierania: %3 Trying to detach a multiplayer player that's not attached - + Próba odÅ‚Ä…czenia gracza multiplayer, który nie jest doÅ‚Ä…czony Trying to get player ID for a multiplayer player that's not attached - + Próba uzyskania ID gracza w trybie wieloosobowym, który nie jest poÅ‚Ä…czony Trying to get save ID for a multiplayer player that's not attached - + Próba uzyskania identyfikatora zapisu dla gracza multiplayer, który nie jest poÅ‚Ä…czony @@ -4310,7 +4310,7 @@ Rozmiar pobierania: %3 Save file: - + Zapisz plik: @@ -4477,7 +4477,7 @@ Rozmiar pobierania: %3 + RTC - + + RTC @@ -4759,12 +4759,12 @@ Rozmiar pobierania: %3 Select image - Wybierz obraz + Wybierz obraz Image file (*.png *.jpg *.jpeg) - Plik graficzny (*.png *.jpg *.jpeg) + Plik graficzny (*.png *.jpg *.jpeg) @@ -5251,7 +5251,7 @@ Rozmiar pobierania: %3 Custom border: - + Niestandardowa ramka: @@ -5287,7 +5287,7 @@ Rozmiar pobierania: %3 Rewind speed: - + PrÄ™dkość przewijania: @@ -6405,12 +6405,12 @@ Rozmiar pobierania: %3 Increase fast forward speed - + ZwiÄ™kszenie prÄ™dkoÅ›ci przewijania do przodu Decrease fast forward speed - + Zmiejszenie prÄ™dkoÅ›ci przewijania do przodu @@ -6773,17 +6773,17 @@ Rozmiar pobierania: %3 Super (L) - Super (L) + Super (L) Super (R) - Super (R) + Super (R) Menu - Menu + Menu From 3a37c1d3ff1c2725af7c96bfbd6e90ce2ff8e578 Mon Sep 17 00:00:00 2001 From: Ensar Melih Bulut Date: Tue, 17 Oct 2023 20:39:46 +0000 Subject: [PATCH 112/336] Qt: Update translation (Turkish) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/tr/ --- src/platform/qt/ts/mgba-tr.ts | 47 +++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/platform/qt/ts/mgba-tr.ts b/src/platform/qt/ts/mgba-tr.ts index d239b59c2..73ab0b7ca 100644 --- a/src/platform/qt/ts/mgba-tr.ts +++ b/src/platform/qt/ts/mgba-tr.ts @@ -6,22 +6,22 @@ Game Boy Advance ROMs (%1) - Game Boy Advance ROMları (%1) + Game Boy Advance ROM'ları (%1) Game Boy ROMs (%1) - Game Boy ROMları (%1) + Game Boy ROM'ları (%1) All ROMs (%1) - Bütün ROMlar (%1) + Bütün ROM'lar (%1) %1 Video Logs (*.mvl) - + %1 Video Günlükleri (*.mvl) @@ -64,47 +64,52 @@ Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. An update is available - + Bir güncelleme mevcut An update to %1 is available. - + %1 için bir güncelleme mevcut. + Do you want to download and install it now? You will need to restart the emulator when the download is complete. - + +Åžimdi indirip yüklemek istiyor musunuz? Ä°ndirme iÅŸlemi tamamlandığında öykünücüyü yeniden baÅŸlatmanız gerekecektir. Auto-update is not available on this platform. If you wish to update you will need to do it manually. - + +Otomatik güncelleme bu platformda mevcut deÄŸildir. Güncellemek istiyorsanız bunu manuel olarak yapmanız gerekecektir. Current version: %1 New version: %2 Download size: %3 - + Güncel sürüm: %1 +Yeni sürüm: %2 +Ä°ndirme boyutu: %3 Downloading update... - + Güncelleme indiriliyor... Downloading failed. Please update manually. - + Ä°ndirme baÅŸarısız oldu. Lütfen manuel olarak güncelleyin. Downloading done. Press OK to restart %1 and install the update. - + Ä°ndirme tamamlandı. %1 yeniden baÅŸlatmak ve güncellemeyi yüklemek için Tamam'a basın. @@ -112,22 +117,22 @@ Download size: %3 Stable - + Kararlı Development - + GeliÅŸtirme Unknown - Bilinmeyen + Bilinmeyen (None) - + (Yok) @@ -188,17 +193,17 @@ Download size: %3 Can't set format of context-less audio device - + BaÄŸlamdan bağımsız ses cihazının formatı ayarlanamıyor Audio device is missing its core - + Ses cihazının çekirdeÄŸi eksik Writing data to read-only audio device - + Salt okunur ses cihazına veri yazma @@ -6074,7 +6079,7 @@ Download size: %3 This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - Emülatörün yapılandırmasını yürütülebilir dosya ile aynı dizinden yüklemesini saÄŸlar. Devam etmek istiyor musun? + Öyküncünün yapılandırmasını yürütülebilir dosya ile aynı dizinden yüklemesini saÄŸlar. Devam etmek istiyor musunuz? @@ -6084,7 +6089,7 @@ Download size: %3 Some changes will not take effect until the emulator is restarted. - Bazı deÄŸiÅŸiklikler emülatör yeniden baÅŸlatılıncaya kadar etkili olmaz. + Bazı deÄŸiÅŸiklikler öyküncü yeniden baÅŸlatılıncaya kadar etkili olmaz. From 0a8470a6d0f6491ee6dab2b14e752738baf98f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enes=20=C3=87etinkal?= Date: Sat, 27 Jan 2024 19:42:44 +0000 Subject: [PATCH 113/336] Qt: Update translation (Turkish) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/tr/ --- src/platform/qt/ts/mgba-tr.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/platform/qt/ts/mgba-tr.ts b/src/platform/qt/ts/mgba-tr.ts index 73ab0b7ca..a98e0639b 100644 --- a/src/platform/qt/ts/mgba-tr.ts +++ b/src/platform/qt/ts/mgba-tr.ts @@ -211,7 +211,7 @@ Yeni sürüm: %2 Can't start an audio processor without input - + GiriÅŸsiz ses iÅŸlemcisi baÅŸlatılamaz @@ -219,7 +219,7 @@ Yeni sürüm: %2 Can't start an audio processor without input - + GiriÅŸsiz ses iÅŸlemcisi baÅŸlatılamaz @@ -287,28 +287,28 @@ Yeni sürüm: %2 BattleChip data missing - + BattleChip verisi yok BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - + BattleChip verisi yok. Bazı grafikler olmadan BattleChip Gates hala çalışır. Verileri ÅŸimdi indirmek istermisin? Select deck file - + Deste dosyası seç Incompatible deck - + Uyumsuz deste The selected deck is not compatible with this Chip Gate - + Seçilen deste bu Chip Gate ile uyumlu deÄŸildir @@ -334,7 +334,7 @@ Yeni sürüm: %2 Add New Code - + Yeni Kod Ekle @@ -344,12 +344,12 @@ Yeni sürüm: %2 Add Lines - + Satır ekle Code type - + Kod tipi @@ -370,7 +370,7 @@ Yeni sürüm: %2 Autodetect (recommended) - + Otoseç (tavsiye edilir) @@ -381,7 +381,7 @@ Yeni sürüm: %2 Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. - + Bazı hileler eklenemedi. Lütfen onların doÄŸru formatlandığından emin ol ve/yada baÅŸa hile tiplerini dene. @@ -400,7 +400,7 @@ Yeni sürüm: %2 Reset the game? - + Oyun sıfırlansım mı? From b78d230ba984c514babc33877acdf5e06a0647e0 Mon Sep 17 00:00:00 2001 From: Guih48 Date: Fri, 20 Oct 2023 16:42:39 +0000 Subject: [PATCH 114/336] Qt: Update translation (Hungarian) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/hu/ --- src/platform/qt/ts/mgba-hu.ts | 72 +++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/src/platform/qt/ts/mgba-hu.ts b/src/platform/qt/ts/mgba-hu.ts index 4e5f7e1f0..6db9b2da9 100644 --- a/src/platform/qt/ts/mgba-hu.ts +++ b/src/platform/qt/ts/mgba-hu.ts @@ -21,7 +21,7 @@ %1 Video Logs (*.mvl) - + %1 Videonaplók (*.mvl) @@ -50,8 +50,9 @@ © 2013 – {year} Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - © 2013 – {year} Jeffrey Pfau, a Mozilla Public License 2.0 alatt licencelve -A Game Boy Advance a Nintendo Co., Ltd. bejegyzett védjegye + © 2013 – {year} Jeffrey Pfau, a Mozilla Public License 2.0 alatt licencelve. + +A Game Boy Advance a Nintendo Co., Ltd. bejegyzett védjegye. @@ -64,47 +65,52 @@ A Game Boy Advance a Nintendo Co., Ltd. bejegyzett védjegye An update is available - + Egy frissítés érhetÅ‘ el An update to %1 is available. - + Egy frissítés elérhetÅ‘ %1 verzióra. + Do you want to download and install it now? You will need to restart the emulator when the download is complete. - + +Szeretné most letöleni és telepíteni? Az emulátor újraindítására lesz szükség a letöltés befejezésekor. Auto-update is not available on this platform. If you wish to update you will need to do it manually. - + +Az automatikus frisítés ezen platformon nem elérhetÅ‘, a frissítéseket manuálisan telepíthetÅ‘k. Current version: %1 New version: %2 Download size: %3 - + Jelenlegi verzió: %1 +Új verzió: %2 +LetöltendÅ‘ adat: %3 Downloading update... - + Frissítés letöltése... Downloading failed. Please update manually. - + A letöltés meghiúsult. Próbálja meg manuálisan frissíteni aprogramot. Downloading done. Press OK to restart %1 and install the update. - + A letöltés kész. Nyomja meg az OK gombot %1 újraindításához és a frissítés telepítéséhez. @@ -112,22 +118,22 @@ Download size: %3 Stable - + Stabil Development - + Fejlesztési Unknown - + Nem ismert (None) - + (nincs) @@ -148,7 +154,7 @@ Download size: %3 Tile # - + Cím # @@ -232,7 +238,7 @@ Download size: %3 Insert - + Beszúrás @@ -329,7 +335,7 @@ Download size: %3 Add New Code - + Új kód hozzáadása @@ -339,12 +345,12 @@ Download size: %3 Add Lines - + Sorok hozzáadása Code type - + Kód típusa @@ -365,7 +371,7 @@ Download size: %3 Autodetect (recommended) - + Automatikus felisnerés (javasolt) @@ -376,7 +382,7 @@ Download size: %3 Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. - + Néhány csalást nem sikerült betölteni. EllenÅ‘rizze, hogy helyesen formázottak-e és/vagy próbáljon ki más csalástípust! @@ -390,7 +396,7 @@ Download size: %3 Rewinding not currently enabled - + Visszatekerés jelenleg nem engedélyezett @@ -451,7 +457,7 @@ Download size: %3 Debugger - HibakeresÅ‘ + HibakeresÅ‘ @@ -477,7 +483,7 @@ Download size: %3 Connect to Dolphin - Csatlakozás Dolphin emulátorhoz + Csatlakozás Dolphin emulátorhoz @@ -512,12 +518,12 @@ Download size: %3 Couldn't Connect - + Nem sikerült csatlakozni Could not connect to Dolphin. - + Nem sikerült csatlakozni Dolphin emulátorhoz. @@ -719,7 +725,7 @@ Download size: %3 Inspect frame - Képkocka vizsgáló + Képkocka vizsgálata @@ -965,22 +971,22 @@ Download size: %3 Autodetect - Automatikus észlelés + Automatikus észlelés Game Boy (DMG) - + Game Boy (DMG) Game Boy Pocket (MGB) - + Game Boy Pocket (MGB) Super Game Boy (SGB) - + Super Game Boy (SGB) @@ -1138,7 +1144,7 @@ Download size: %3 0x0000 - + 0x0000 From af2e2fd517c712a08a5a501dc710580f06e3b3b6 Mon Sep 17 00:00:00 2001 From: Anatolij Vasilev Date: Fri, 3 Nov 2023 10:39:49 +0000 Subject: [PATCH 115/336] Qt: Update translation (German) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/de/ --- src/platform/qt/ts/mgba-de.ts | 48 +++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index a1d1b2e15..ce7f38c30 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -70,7 +70,7 @@ Game Boy Advance ist eine eingetragene Marke von Nintendo Co., Ltd. An update to %1 is available. - Ein Update für %1 ist verfügbar. + Ein Update auf %1 ist verfügbar. @@ -132,7 +132,7 @@ Download-Größe: %3 (None) - (keiner) + (Nichts) @@ -145,7 +145,7 @@ Download-Größe: %3 Loading... - Laden â€¦ + Lädt â€¦ @@ -198,7 +198,7 @@ Download-Größe: %3 Audio device is missing its core - Dem Audio-Gerät fehlt ein Core + Dem Audio-Gerät fehlt sein Core @@ -395,7 +395,7 @@ Download-Größe: %3 Rewinding not currently enabled - Rücklauf ist derzeit nicht aktiviert + Zurückspulen ist derzeit nicht aktiviert @@ -716,7 +716,7 @@ Download-Größe: %3 Image files (*.png *.jpg *.bmp) - + Bilddateien (*.png *.jpg *.bmp) @@ -724,7 +724,7 @@ Download-Größe: %3 Inspect frame - Bild beobachten + Frame untersuchen @@ -734,7 +734,7 @@ Download-Größe: %3 Freeze frame - Bild einfrieren + Frame einfrieren @@ -3752,17 +3752,17 @@ Download-Größe: %3 Trying to detach a multiplayer player that's not attached - + Versuch Multiplayer-Spieler zu trennen der nicht verbunden ist Trying to get player ID for a multiplayer player that's not attached - + Versuch Spieler-ID festzustellen von einem Multiplayer-Spieler der nicht verbunden ist Trying to get save ID for a multiplayer player that's not attached - + Versuch Speicherstand-ID festzustellen von einem Multiplayer-Spieler der nicht verbunden ist @@ -4310,7 +4310,7 @@ Download-Größe: %3 Save file: - + Speicherstand: @@ -4477,7 +4477,7 @@ Download-Größe: %3 + RTC - + + RTC @@ -4759,12 +4759,12 @@ Download-Größe: %3 Select image - Bild auswählen + Bild auswählen Image file (*.png *.jpg *.jpeg) - Bilddatei (*.png *.jpg *.jpeg) + Bilddatei (*.png *.jpg *.jpeg) @@ -5074,7 +5074,7 @@ Download-Größe: %3 Custom border: - + Benutzerdefinierter Rand: @@ -5119,7 +5119,7 @@ Download-Größe: %3 Rewind speed: - + Zurückspulgeschwindigkeit: @@ -5457,7 +5457,7 @@ Download-Größe: %3 Enable rewind - Rücklauf aktivieren + Zurückspulen aktivieren @@ -5467,7 +5467,7 @@ Download-Größe: %3 Rewind history: - Rücklauf-Verlauf: + Zurückspulverlauf: @@ -6317,12 +6317,12 @@ Download-Größe: %3 Increase fast forward speed - + Vorspulgeschwindigkeit erhöhen Decrease fast forward speed - + Vorspulgeschwindigkeit senken @@ -6771,17 +6771,17 @@ Download-Größe: %3 Super (L) - Super (L) + Super (L) Super (R) - Super (R) + Super (R) Menu - Menü + Menü From 33bfd7f752e0c035a811b4c2487397bb268e6871 Mon Sep 17 00:00:00 2001 From: ssantos Date: Mon, 18 Dec 2023 15:26:35 +0000 Subject: [PATCH 116/336] Qt: Update translation (Portuguese) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/pt/ --- src/platform/qt/ts/mgba-pt.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/platform/qt/ts/mgba-pt.ts b/src/platform/qt/ts/mgba-pt.ts index 72af03abe..cddb1dd8c 100644 --- a/src/platform/qt/ts/mgba-pt.ts +++ b/src/platform/qt/ts/mgba-pt.ts @@ -716,7 +716,7 @@ Tamanho da descarga: %3 Image files (*.png *.jpg *.bmp) - + Ficheiro da imagem (*.png *.jpg *.bmp) @@ -3752,17 +3752,17 @@ Tamanho da descarga: %3 Trying to detach a multiplayer player that's not attached - + A tentar desconectar um jogador multiplayer que não está conectado Trying to get player ID for a multiplayer player that's not attached - + A tentar obter a ID do jogador para um jogador multiplayer que não está conectado Trying to get save ID for a multiplayer player that's not attached - + A tentar obter a ID gravada para um jogador multiplayer que não está conectado @@ -4310,7 +4310,7 @@ Tamanho da descarga: %3 Save file: - + Ficheiro do save: @@ -4477,7 +4477,7 @@ Tamanho da descarga: %3 + RTC - + + RTC @@ -4759,12 +4759,12 @@ Tamanho da descarga: %3 Select image - Selecionar imagem + Selecionar imagem Image file (*.png *.jpg *.jpeg) - Ficheiro da imagem (*.png *.jpg *.jpeg) + Ficheiro da imagem (*.png *.jpg *.jpeg) @@ -4792,6 +4792,7 @@ Tamanho da descarga: %3 %n hora atrás %n horas atrás + %n horas atrás @@ -4800,6 +4801,7 @@ Tamanho da descarga: %3 %n dia atrás %n dias atrás + %n dias atrás @@ -5249,7 +5251,7 @@ Tamanho da descarga: %3 Custom border: - + Borda personalizada: @@ -5285,7 +5287,7 @@ Tamanho da descarga: %3 Rewind speed: - + Velocidade do retrocesso: @@ -6403,12 +6405,12 @@ Tamanho da descarga: %3 Increase fast forward speed - + Aumentar a velocidade do avanço rápido Decrease fast forward speed - + Diminuir a velocidade do avanço rápido @@ -6771,17 +6773,17 @@ Tamanho da descarga: %3 Super (L) - Super (E) + Super (E) Super (R) - Super (D) + Super (D) Menu - Menu + Menu From 910326f29d3d29b941f61d659f812bc35ade1b51 Mon Sep 17 00:00:00 2001 From: Imre Kristoffer Eilertsen Date: Thu, 22 Feb 2024 01:36:33 +0000 Subject: [PATCH 117/336] =?UTF-8?q?Qt:=20Update=20translation=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/nb_NO/ --- src/platform/qt/ts/mgba-nb_NO.ts | 764 +++++++++++++++---------------- 1 file changed, 382 insertions(+), 382 deletions(-) diff --git a/src/platform/qt/ts/mgba-nb_NO.ts b/src/platform/qt/ts/mgba-nb_NO.ts index 128bee3ac..4a97f0c60 100644 --- a/src/platform/qt/ts/mgba-nb_NO.ts +++ b/src/platform/qt/ts/mgba-nb_NO.ts @@ -16,7 +16,7 @@ All ROMs (%1) - + Alle ROM-filer (%1) @@ -64,7 +64,7 @@ Game Boy Advance er et registrert varemerke tilhørende Nintendo Co., Ltd. An update is available - + En oppdatering er tilgjengelig @@ -96,7 +96,7 @@ Nedlastningsstørrelse: %3 Downloading update... - Laster ned ny versjon … + Laster ned oppdatering … @@ -114,22 +114,22 @@ Nedlastningsstørrelse: %3 Stable - + Stabil Development - + Utvikling Unknown - Ukjent + Ukjent (None) - + (Ingen) @@ -142,7 +142,7 @@ Nedlastningsstørrelse: %3 Loading... - Laster inn … + Laster inn ... @@ -264,7 +264,7 @@ Nedlastningsstørrelse: %3 Inserted - + Satt inn @@ -331,7 +331,7 @@ Nedlastningsstørrelse: %3 Add New Code - + Legg til ny kode @@ -341,7 +341,7 @@ Nedlastningsstørrelse: %3 Add Lines - + Legg til linjer @@ -367,7 +367,7 @@ Nedlastningsstørrelse: %3 Autodetect (recommended) - + Auto-oppdag (anbefales) @@ -463,7 +463,7 @@ Nedlastningsstørrelse: %3 Break - + Stopp @@ -514,12 +514,12 @@ Nedlastningsstørrelse: %3 Couldn't Connect - + Kunne ikke koble til Could not connect to Dolphin. - + Klarte ikke Ã¥ koble til Dolphin. @@ -527,7 +527,7 @@ Nedlastningsstørrelse: %3 3DS - + 3DS @@ -540,7 +540,7 @@ Nedlastningsstørrelse: %3 Icon - + Ikon @@ -553,17 +553,17 @@ Nedlastningsstørrelse: %3 Bubble - + Boble Background - Bakgrunn + Bakgrunn Startup - + Oppstart @@ -576,12 +576,12 @@ Nedlastningsstørrelse: %3 Files - + Filer ROM file: - + ROM-fil: @@ -593,7 +593,7 @@ Nedlastningsstørrelse: %3 Output filename: - + Utdata-filnavn: @@ -603,7 +603,7 @@ Nedlastningsstørrelse: %3 Latest stable version - + Nyeste stabile versjon @@ -613,42 +613,42 @@ Nedlastningsstørrelse: %3 Specific file - + Spesifikk fil Base file: - + Grunnfil: System - + System 3DS - + 3DS Vita - + Vita Presentation - + Presentasjon Title: - + Tittel: Images: - + Bilder: @@ -658,17 +658,17 @@ Nedlastningsstørrelse: %3 Preferred size: - + Ønsket størrelse: Select image file - + Velg bildefil Select ROM file - + Velg ROM-fil @@ -678,7 +678,7 @@ Nedlastningsstørrelse: %3 Select base file - + Velg grunnfil @@ -708,12 +708,12 @@ Nedlastningsstørrelse: %3 Select an image - + Velg et bilde Image files (*.png *.jpg *.bmp) - + Bildefiler (*.png *.jpg *.bmp) @@ -736,7 +736,7 @@ Nedlastningsstørrelse: %3 Backdrop color - + Bakgrunnsfarge @@ -791,12 +791,12 @@ Nedlastningsstørrelse: %3 Backdrop - + Bakgrunn Frame - + Ramme @@ -850,7 +850,7 @@ Nedlastningsstørrelse: %3 Bind address - + Bindingsadresse @@ -875,7 +875,7 @@ Nedlastningsstørrelse: %3 Break - + Stopp @@ -967,7 +967,7 @@ Nedlastningsstørrelse: %3 Autodetect - + Auto-oppdag @@ -1037,7 +1037,7 @@ Nedlastningsstørrelse: %3 MBC5 + Rumble - + MBC5 + risting @@ -1047,7 +1047,7 @@ Nedlastningsstørrelse: %3 MBC7 (Tilt) - + MBC7 (Tilt) @@ -1112,12 +1112,12 @@ Nedlastningsstørrelse: %3 GGB-81 - + GGB-81 Li Cheng - + Li Cheng @@ -1135,12 +1135,12 @@ Nedlastningsstørrelse: %3 I/O Viewer - + I/O-visning 0x0000 - + 0x0000 @@ -1232,7 +1232,7 @@ Nedlastningsstørrelse: %3 Enable OBJ - + Skru pÃ¥ OBJ @@ -1252,17 +1252,17 @@ Nedlastningsstørrelse: %3 Currently in VBlank - + For øyeblikket i VBlank Currently in HBlank - + For øyeblikket i HBlank Currently in VCounter - + For øyeblikket i VCounter @@ -1319,7 +1319,7 @@ Nedlastningsstørrelse: %3 Enable 256-color - + Skru pÃ¥ 256-fargemodus @@ -1742,7 +1742,7 @@ Nedlastningsstørrelse: %3 Initial volume - + Volum ved begynnelse @@ -1801,28 +1801,28 @@ Nedlastningsstørrelse: %3 0% - 0% + 0 % 100% - 100% + 100% 50% - 50% + 50% 25% - 25% + 25% @@ -1830,7 +1830,7 @@ Nedlastningsstørrelse: %3 75% - 75% + 75% @@ -1848,13 +1848,13 @@ Nedlastningsstørrelse: %3 15 - 15 + 15 7 - 7 + 7 @@ -1954,7 +1954,7 @@ Nedlastningsstørrelse: %3 0 - 0 + 0 @@ -1967,7 +1967,7 @@ Nedlastningsstørrelse: %3 1 - 1 + 1 @@ -2137,22 +2137,22 @@ Nedlastningsstørrelse: %3 Right/A - + Høyre/A Left/B - + Venstre/B Up/Select - + Opp/Select Down/Start - + Ned/Start @@ -2162,7 +2162,7 @@ Nedlastningsstørrelse: %3 Active face buttons - + Skru pÃ¥ hovedknappene @@ -2182,12 +2182,12 @@ Nedlastningsstørrelse: %3 Divider - + Skillelinje 1/16 - 1/16 + 1/16 @@ -2479,7 +2479,7 @@ Nedlastningsstørrelse: %3 Red - Rød + Rød @@ -2618,7 +2618,7 @@ Nedlastningsstørrelse: %3 Immediate - + Umiddelbart @@ -2681,7 +2681,7 @@ Nedlastningsstørrelse: %3 Video Capture - + Videoopptak @@ -2715,7 +2715,7 @@ Nedlastningsstørrelse: %3 1/64 - 1/64 + 1/64 @@ -2724,7 +2724,7 @@ Nedlastningsstørrelse: %3 1/256 - 1/256 + 1/256 @@ -2733,14 +2733,14 @@ Nedlastningsstørrelse: %3 1/1024 - 1/1024 + 1/1024 Cascade - + Cascade @@ -2891,7 +2891,7 @@ Nedlastningsstørrelse: %3 Gamepak - + Spillkassett @@ -2905,7 +2905,7 @@ Nedlastningsstørrelse: %3 4 - 4 + 4 @@ -2913,7 +2913,7 @@ Nedlastningsstørrelse: %3 3 - 3 + 3 @@ -2922,7 +2922,7 @@ Nedlastningsstørrelse: %3 2 - 2 + 2 @@ -2931,7 +2931,7 @@ Nedlastningsstørrelse: %3 8 - 8 + 8 @@ -2966,7 +2966,7 @@ Nedlastningsstørrelse: %3 PHI terminal - + PHI-terminal @@ -2977,17 +2977,17 @@ Nedlastningsstørrelse: %3 4.19MHz - + 4,19MHz 8.38MHz - + 8,38MHz 16.78MHz - + 16,78MHz @@ -3006,7 +3006,7 @@ Nedlastningsstørrelse: %3 --- - + --- @@ -3019,7 +3019,7 @@ Nedlastningsstørrelse: %3 Location - + Sted @@ -3034,7 +3034,7 @@ Nedlastningsstørrelse: %3 CRC32 - + CRC32 @@ -3111,12 +3111,12 @@ Nedlastningsstørrelse: %3 Load State - + Last inn tilstand Save State - + Lagre tilstand @@ -3170,12 +3170,12 @@ Nedlastningsstørrelse: %3 Stub - + Stump Game Error - Spillfeil + Spillfeil @@ -3183,7 +3183,7 @@ Nedlastningsstørrelse: %3 [%1] %2: %3 - + [%1] %2: %3 @@ -3208,7 +3208,7 @@ Nedlastningsstørrelse: %3 WARN - + ADVARSEL @@ -3246,7 +3246,7 @@ Nedlastningsstørrelse: %3 Stub - + Stump @@ -3304,7 +3304,7 @@ Nedlastningsstørrelse: %3 Export - Eksporter + Eksporter @@ -3352,12 +3352,12 @@ Nedlastningsstørrelse: %3 Mirror - + Speilvend None - Ingen + Ingen @@ -3367,12 +3367,12 @@ Nedlastningsstørrelse: %3 Horizontal - + Horisontal Vertical - + Vertikal @@ -3389,7 +3389,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -3440,7 +3440,7 @@ Nedlastningsstørrelse: %3 Paste - Lim inn + Lim inn @@ -3450,7 +3450,7 @@ Nedlastningsstørrelse: %3 All - + Alle @@ -3480,12 +3480,12 @@ Nedlastningsstørrelse: %3 TBL - + TBL ISO-8859-1 - + ISO-8859-1 @@ -3519,7 +3519,7 @@ Nedlastningsstørrelse: %3 Numeric - + Numerisk @@ -3535,7 +3535,7 @@ Nedlastningsstørrelse: %3 Guess - + Gjett @@ -3555,17 +3555,17 @@ Nedlastningsstørrelse: %3 Number type - + Nummertype Decimal - + Desimal Hexadecimal - + Heksadesimal @@ -3640,17 +3640,17 @@ Nedlastningsstørrelse: %3 (%0/%1×) - + (%0/%1×) (â…Ÿ%0×) - + (â…Ÿ%0×) (%0×) - + (%0×) @@ -3741,7 +3741,7 @@ Nedlastningsstørrelse: %3 Frame %1 - + Bilde %1 @@ -3807,17 +3807,17 @@ Nedlastningsstørrelse: %3 Export - Eksporter + Eksporter Attributes - + Attributter Transform - + Transformer @@ -3851,13 +3851,13 @@ Nedlastningsstørrelse: %3 H Short for horizontal - + H V Short for vertical - + V @@ -3878,7 +3878,7 @@ Nedlastningsstørrelse: %3 Enabled - + Skrudd pÃ¥ @@ -3894,7 +3894,7 @@ Nedlastningsstørrelse: %3 0x%0 - + 0x%0 @@ -3906,7 +3906,7 @@ Nedlastningsstørrelse: %3 --- - + --- @@ -3916,12 +3916,12 @@ Nedlastningsstørrelse: %3 OBJWIN - + OBJWIN Invalid - + Ugyldig @@ -3945,7 +3945,7 @@ Nedlastningsstørrelse: %3 Game Overrides - + Overstyringer for spill @@ -3958,7 +3958,7 @@ Nedlastningsstørrelse: %3 Autodetect - + Auto-oppdag @@ -3973,7 +3973,7 @@ Nedlastningsstørrelse: %3 Tilt - + Tilt @@ -4013,7 +4013,7 @@ Nedlastningsstørrelse: %3 EEPROM 8kB - + EEPROM 8kB @@ -4033,7 +4033,7 @@ Nedlastningsstørrelse: %3 Game Boy Player features - + Game Boy Player-funksjoner @@ -4043,12 +4043,12 @@ Nedlastningsstørrelse: %3 Game Boy - + Game Boy Game Boy model - + Game Boy-modell @@ -4073,7 +4073,7 @@ Nedlastningsstørrelse: %3 Palette preset - + ForhÃ¥ndsvalgt fargepalett @@ -4096,7 +4096,7 @@ Nedlastningsstørrelse: %3 Palette - Palett + Palett @@ -4151,17 +4151,17 @@ Nedlastningsstørrelse: %3 Export OBJ - + Eksporter OBJ #%0 - + #%0 0x%0 - + 0x%0 @@ -4169,7 +4169,7 @@ Nedlastningsstørrelse: %3 0x%0 (%1) - 0x%0 (%1) + 0x%0 (%1) @@ -4197,7 +4197,7 @@ Nedlastningsstørrelse: %3 All - + Alle @@ -4207,12 +4207,12 @@ Nedlastningsstørrelse: %3 X - + X Y - + Y @@ -4277,32 +4277,32 @@ Nedlastningsstørrelse: %3 ROM Info - + ROM-info Game name: - + Spillets navn: Internal name: - + Internt navn: Game ID: - + Spill-ID: File size: - + Filstørrelse: CRC32: - + CRC32: @@ -4340,7 +4340,7 @@ Nedlastningsstørrelse: %3 Save - Lagre + Lagre @@ -4350,7 +4350,7 @@ Nedlastningsstørrelse: %3 Include save file - + Inkluder lagrefilen @@ -4378,7 +4378,7 @@ Nedlastningsstørrelse: %3 Select save game - + Velg lagrefil @@ -4439,7 +4439,7 @@ Nedlastningsstørrelse: %3 Output file - + Utdatafil @@ -4459,7 +4459,7 @@ Nedlastningsstørrelse: %3 SRAM - SRAM + SRAM @@ -4469,7 +4469,7 @@ Nedlastningsstørrelse: %3 %1 EEPROM - + %1 EEPROM @@ -4509,17 +4509,17 @@ Nedlastningsstørrelse: %3 MBC6 SRAM - + MBC6-SRAM TAMA5 - TAMA5 + TAMA5 %1 (%2) - + %1 (%2) @@ -4555,12 +4555,12 @@ Nedlastningsstørrelse: %3 Run - + Kjør File - + Fil @@ -4570,17 +4570,17 @@ Nedlastningsstørrelse: %3 Load script... - + Last inn skript... &Reset - + &Omstart 0 - 0 + 0 @@ -4595,7 +4595,7 @@ Nedlastningsstørrelse: %3 All files (*.*) - + Alle filer (*.*) @@ -4603,12 +4603,12 @@ Nedlastningsstørrelse: %3 Sensors - + Sensorer Realtime clock - Sanntidsklokke + Sanntidsklokke @@ -4618,7 +4618,7 @@ Nedlastningsstørrelse: %3 System time - + Systemtid @@ -4628,7 +4628,7 @@ Nedlastningsstørrelse: %3 Now - + NÃ¥ @@ -4638,27 +4638,27 @@ Nedlastningsstørrelse: %3 sec - + sek MM/dd/yy hh:mm:ss AP - + dd/mm/YYYY hh:mm:ss AP Light sensor - Lyssensor + Lyssensor Brightness - + Lysstyrke Tilt sensor - + Tiltsensor @@ -4675,12 +4675,12 @@ Nedlastningsstørrelse: %3 Gyroscope - Gyroskop + Gyroskop Sensitivity - + Følsomhet @@ -4715,12 +4715,12 @@ Nedlastningsstørrelse: %3 None - Ingen + Ingen None (Still Image) - + Ingen (stillbilde) @@ -4756,32 +4756,32 @@ Nedlastningsstørrelse: %3 Select image - Velg bilde + Velg bilde Image file (*.png *.jpg *.jpeg) - + Bildefil (*.png *.jpg *.jpeg) (%1×%2) - + (%1×%2) Never - + Aldri Just now - + Akkurat nÃ¥ Less than an hour ago - + Mindre enn én time siden @@ -4802,12 +4802,12 @@ Nedlastningsstørrelse: %3 Settings - + Innstillinger Audio/Video - + Lyd/Video @@ -4817,93 +4817,93 @@ Nedlastningsstørrelse: %3 Interface - + Grensesnitt Update - + Oppdater Emulation - + Emulering Enhancements - + Forbedringer BIOS - + BIOS Paths - + Filbaner Logging - + Loggføring Game Boy - + Game Boy Audio driver: - + Lyddriver: Audio buffer: - + Lydbuffer: 1536 - 1536 + 1536 512 - 512 + 512 768 - 768 + 768 1024 - 1024 + 1024 2048 - 2048 + 2048 3072 - 3072 + 3072 4096 - 4096 + 4096 samples - + datapunkter @@ -4914,32 +4914,32 @@ Nedlastningsstørrelse: %3 44100 - 44100 + 44100 22050 - 22050 + 22050 32000 - 32000 + 32000 48000 - 48000 + 48000 Hz - + Hz Volume: - + Volum: @@ -4947,7 +4947,7 @@ Nedlastningsstørrelse: %3 Mute - + Demp lyd @@ -4962,7 +4962,7 @@ Nedlastningsstørrelse: %3 All windows - + Alle vinduer @@ -4977,7 +4977,7 @@ Nedlastningsstørrelse: %3 Display driver: - + Skjermdriver: @@ -4987,45 +4987,45 @@ Nedlastningsstørrelse: %3 Skip every - + Hopp over hver frames - + bilder FPS target: - + SiktemÃ¥l for bildefrekvens: frames per second - + bilder per sekund Sync: - + Synkroniser: Video - + Video Audio - + Lyd Lock aspect ratio - + LÃ¥s visningsforhold @@ -5035,7 +5035,7 @@ Nedlastningsstørrelse: %3 Bilinear filtering - + Bilineær filtrering @@ -5046,7 +5046,7 @@ Nedlastningsstørrelse: %3 Pause - + Pause @@ -5056,7 +5056,7 @@ Nedlastningsstørrelse: %3 On loading a game: - + NÃ¥r det lastes inn et spill: @@ -5081,32 +5081,32 @@ Nedlastningsstørrelse: %3 Current channel: - + NÃ¥værende kanal: Current version: - + NÃ¥værende versjon: Update channel: - + Oppdateringskanal: Available version: - + Tilgjengelig versjon: (Unknown) - + (Ukjent) Last checked: - + Sist sjekket: @@ -5116,7 +5116,7 @@ Nedlastningsstørrelse: %3 Check now - + Sjekk nÃ¥ @@ -5126,37 +5126,37 @@ Nedlastningsstørrelse: %3 SGB color palette if available - + SGB-fargepalett hvis tilgjengelig GBC color palette if available - + GBC-fargepalett hvis tilgjengelig SGB (preferred) or GBC color palette if available - + SGB (foretrukket) eller GBC-fargepalett hvis tilgjengelig Game Boy Camera - + Game Boy Camera Driver: - + Driver: Source: - + Kilde: Native (59.7275) - + Systemstandard (59.7275) @@ -5166,32 +5166,32 @@ Nedlastningsstørrelse: %3 Language - + SprÃ¥k Library: - + Bibliotek: List view - + Listevisning Tree view - + Tre-visning Show when no game open - + Vis nÃ¥r ingen spill er Ã¥pne Clear cache - + Tøm mellomlageret @@ -5231,7 +5231,7 @@ Nedlastningsstørrelse: %3 Show FPS in title bar - + Vis bildefrekvensen i tittellinjen @@ -5272,7 +5272,7 @@ Nedlastningsstørrelse: %3 Enable rewind - + Skru pÃ¥ tilbakespoling @@ -5292,12 +5292,12 @@ Nedlastningsstørrelse: %3 Run all - + Kjør alle Remove known - + Fjern kjente @@ -5328,54 +5328,54 @@ Nedlastningsstørrelse: %3 Models - + Modeller GB only: - + Kun GB: SGB compatible: - + SGB-kompatibel: GBC only: - + Kun GBC: GBC compatible: - + GBC-kompatibel: SGB and GBC compatible: - + SGB- og GBC-kompatible: Game Boy palette - + Game Boy-fargepalett Preset: - + ForhÃ¥ndsinnstilling: Screenshot - + Skjermbilde Cheat codes - + Juksekoder @@ -5395,7 +5395,7 @@ Nedlastningsstørrelse: %3 Software - + Programvare @@ -5410,7 +5410,7 @@ Nedlastningsstørrelse: %3 (240×160) - + (240×160) @@ -5444,22 +5444,22 @@ Nedlastningsstørrelse: %3 Skip BIOS intro - + Hopp over BIOS-introen GBA BIOS file: - + GBA-BIOS-fil: GBC BIOS file: - + GBC-BIOS-fil: SGB BIOS file: - + SGB-BIOS-fil: @@ -5488,7 +5488,7 @@ Nedlastningsstørrelse: %3 Patches - + Patcher @@ -5498,7 +5498,7 @@ Nedlastningsstørrelse: %3 Log to file - + Loggfør til en fil @@ -5528,7 +5528,7 @@ Nedlastningsstørrelse: %3 Super Game Boy borders - + Super Game Boy-kanter @@ -5567,7 +5567,7 @@ Nedlastningsstørrelse: %3 Shaders - Skyggeleggere + Skygger @@ -5577,17 +5577,17 @@ Nedlastningsstørrelse: %3 Name - Navn + Navn Author - + Skaper Description - + Beskrivelse @@ -5615,7 +5615,7 @@ Nedlastningsstørrelse: %3 Gamepad - + Kontroller @@ -5628,17 +5628,17 @@ Nedlastningsstørrelse: %3 Keyboard - Tastatur + Tastatur Gamepad - + Kontroller Clear - Tøm + Tøm @@ -5672,17 +5672,17 @@ Nedlastningsstørrelse: %3 Export All - + Eksporter alle 256 colors - + 256 farger Palette - Palett + Palett @@ -5697,7 +5697,7 @@ Nedlastningsstørrelse: %3 Fit to window - + Tilpass til vinduet @@ -5717,7 +5717,7 @@ Nedlastningsstørrelse: %3 Both - Begge + Begge @@ -5727,7 +5727,7 @@ Nedlastningsstørrelse: %3 Copy All - + Kopier alle @@ -5755,44 +5755,44 @@ Nedlastningsstørrelse: %3 Start - Start + Begynn Stop - Stopp + Stopp Select File - Velg fil + Velg fil Presets - + ForhÃ¥ndsinnstillinger High &Quality - + Høy &kvalitet &YouTube - + &YouTube WebM - + WebM MP4 - + MP4 @@ -5802,22 +5802,22 @@ Nedlastningsstørrelse: %3 4K - 4K + 4K &1080p - + &1080p &720p - + &720p &480p - + &480p @@ -5827,47 +5827,47 @@ Nedlastningsstørrelse: %3 Format - + Format MKV - + MKV AVI - + AVI H.264 - + H.264 H.264 (NVENC) - + H.264 (NVENC) HEVC - + HEVC HEVC (NVENC) - + HEVC (NVENC) VP8 - + VP8 VP9 - + VP9 @@ -5878,12 +5878,12 @@ Nedlastningsstørrelse: %3 None - Ingen + Ingen FLAC - + FLAC @@ -5893,27 +5893,27 @@ Nedlastningsstørrelse: %3 Opus - + Opus Vorbis - + Vorbis MP3 - + MP3 AAC - + AAC Uncompressed - + Ukomprimert @@ -5923,32 +5923,32 @@ Nedlastningsstørrelse: %3 ABR - + ABR VBR - + VBR CRF - + CRF Dimensions - Dimensjoner + Dimensjoner Lock aspect ratio - + LÃ¥s visningsforhold Show advanced - Vis avanserte innstillinger + Vis avansert @@ -5974,7 +5974,7 @@ Nedlastningsstørrelse: %3 Select save - + Velg lagrefil @@ -5989,12 +5989,12 @@ Nedlastningsstørrelse: %3 Select e-Reader dotcode - + Velg e-Reader-punktkode e-Reader card (*.raw *.bin *.bmp) - + e-Reader-kort (*.raw *.bin *.bmp) @@ -6019,7 +6019,7 @@ Nedlastningsstørrelse: %3 Video logs (*.mvl) - + Videologgføringer (*.mvl) @@ -6036,12 +6036,12 @@ Nedlastningsstørrelse: %3 Couldn't Start - + Klarte ikke Ã¥ starte opp Could not start game. - + Klarte ikke Ã¥ starte opp spillet. @@ -6071,7 +6071,7 @@ Nedlastningsstørrelse: %3 Restart needed - + Gjennomfør omstart @@ -6086,12 +6086,12 @@ Nedlastningsstørrelse: %3 %1 - %2 - + %1 - %2 %1 - %2 - %3 - + %1 - %2 - %3 @@ -6101,12 +6101,12 @@ Nedlastningsstørrelse: %3 &File - + &Fil Load &ROM... - + Last inn &ROM... @@ -6126,7 +6126,7 @@ Nedlastningsstørrelse: %3 Select save game - + Velg lagrefil @@ -6142,12 +6142,12 @@ Nedlastningsstørrelse: %3 Select e-Reader card images - + Velg e-Reader-kortavbildninger Image file (*.png *.jpg *.jpeg) - + Bildefil (*.png *.jpg *.jpeg) @@ -6177,17 +6177,17 @@ Nedlastningsstørrelse: %3 Boot BIOS - + Oppstarts-BIOS Replace ROM... - + Bytt ROM.... Scan e-Reader dotcodes... - + Skann e-Reader-punktkoder... @@ -6202,7 +6202,7 @@ Nedlastningsstørrelse: %3 Recent - + Nylig @@ -6212,7 +6212,7 @@ Nedlastningsstørrelse: %3 &Load state - + &Last inn tilstand @@ -6222,7 +6222,7 @@ Nedlastningsstørrelse: %3 &Save state - + &Lagre en tilstand @@ -6323,47 +6323,47 @@ Nedlastningsstørrelse: %3 Connect to Dolphin... - + Koble til Dolphin... Report bug... - + Rapporter inn feil... About... - + Om … E&xit - + A&vslutt &Emulation - + &Emulering &Reset - + &Omstart Sh&utdown - + Skr&u av Yank game pak - + Dra ut spillkassetten &Pause - + &Pause @@ -6393,7 +6393,7 @@ Nedlastningsstørrelse: %3 %0x - %0x + %0x @@ -6408,7 +6408,7 @@ Nedlastningsstørrelse: %3 Rewind (held) - + Spol tilbake (holdt) @@ -6423,37 +6423,37 @@ Nedlastningsstørrelse: %3 Solar sensor - + Solsensor Increase solar level - + Øke solnivÃ¥et Decrease solar level - + Reduser solnivÃ¥et Brightest solar level - + Lyseste solnivÃ¥ Darkest solar level - + Mørkeste solnivÃ¥ Brightness %1 - + Lysstyrke %1 Game Boy Printer... - + Game Boy Printer... @@ -6468,22 +6468,22 @@ Nedlastningsstørrelse: %3 Frame size - + Rammestørrelse %1× - %1× + %1× Toggle fullscreen - + Skru pÃ¥/av fullskjerm Lock aspect ratio - + LÃ¥s visningsforhold @@ -6498,7 +6498,7 @@ Nedlastningsstørrelse: %3 Bilinear filtering - + Bilineær filtrering @@ -6508,7 +6508,7 @@ Nedlastningsstørrelse: %3 Mute - + Demp lyd @@ -6518,17 +6518,17 @@ Nedlastningsstørrelse: %3 Native (59.7275) - + Systemstandard (59.7275) Take &screenshot - + Ta &skjermbilde F12 - + F12 @@ -6548,7 +6548,7 @@ Nedlastningsstørrelse: %3 Audio channels - + Lydkanaler @@ -6558,7 +6558,7 @@ Nedlastningsstørrelse: %3 &Tools - + Verk&tøy @@ -6573,7 +6573,7 @@ Nedlastningsstørrelse: %3 Game Pak sensors... - + Game Pak-sensorer ... @@ -6588,7 +6588,7 @@ Nedlastningsstørrelse: %3 Settings... - + Innstillinger… @@ -6613,7 +6613,7 @@ Nedlastningsstørrelse: %3 View &palette... - + Vis &palett ... @@ -6628,7 +6628,7 @@ Nedlastningsstørrelse: %3 View &map... - + Vis &kart … @@ -6663,7 +6663,7 @@ Nedlastningsstørrelse: %3 Exit fullscreen - + GÃ¥ ut av fullskjerm @@ -6728,7 +6728,7 @@ Nedlastningsstørrelse: %3 Clear - Tøm + Tøm @@ -6736,47 +6736,47 @@ Nedlastningsstørrelse: %3 %1 byte - + %1 byte %1 kiB - + %1 kiB %1 MiB - + %1 MiB GBA - + GBA GB - + GB ? - + ? Super (L) - + Super (L) Super (R) - + Super (R) Menu - Meny + Meny @@ -6784,22 +6784,22 @@ Nedlastningsstørrelse: %3 Shift - + Shift Control - + Kontroll Alt - + Alt Meta - + Meta From 890713124414cc03fca28bb3e6b87e2183db2732 Mon Sep 17 00:00:00 2001 From: Hexaae Date: Sun, 25 Feb 2024 22:41:33 +0000 Subject: [PATCH 118/336] Qt: Update translation (Italian) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/it/ --- src/platform/qt/ts/mgba-it.ts | 102 +++++++++++++++++----------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/platform/qt/ts/mgba-it.ts b/src/platform/qt/ts/mgba-it.ts index a0a0deb5e..12a018db7 100644 --- a/src/platform/qt/ts/mgba-it.ts +++ b/src/platform/qt/ts/mgba-it.ts @@ -530,12 +530,12 @@ Dimensione del download: %3 3DS - + 3DS Vita - + Vita @@ -543,12 +543,12 @@ Dimensione del download: %3 Icon - + Icona Banner - + Striscia @@ -556,7 +556,7 @@ Dimensione del download: %3 Bubble - + Bolla @@ -566,7 +566,7 @@ Dimensione del download: %3 Startup - + Avvio @@ -574,17 +574,17 @@ Dimensione del download: %3 Create forwarder - + Crea Icona di avvio Files - + File ROM file: - + File ROM: @@ -596,127 +596,127 @@ Dimensione del download: %3 Output filename: - + Nome file in uscita: Forwarder base: - + Base dell'Icona di avvio: Latest stable version - + Ultima versione stabile Latest development build - + Ultima development build Specific file - + File specifico Base file: - + File base: System - + Sistema 3DS - + 3DS Vita - + Vita Presentation - + Presentazione Title: - + Titolo: Images: - + Immagini: Use default image - + Usa immagine predefinita Preferred size: - + Dimensione preferita: Select image file - + Seleziona file immagine Select ROM file - + Seleziona file ROM Select output filename - + Selezione nome file in uscita Select base file - + Selezione file base Build finished - + Build completata Forwarder finished building - + Icona di avvio compilazione completata Build failed - + Build fallita Failed to build forwarder - + Impossibile compilare Icona di avvio %1 installable package (*.%2) - + %1 pacchetto installabile (*.%2) Select an image - + Seleziona una immagine Image files (*.png *.jpg *.bmp) - + File immagine (*.png *.jpg *.bmp) @@ -1085,12 +1085,12 @@ Dimensione del download: %3 NT (old 1) - + NT (vec. 1) NT (old 2) - + NT (vec. 2) @@ -1115,12 +1115,12 @@ Dimensione del download: %3 GGB-81 - + GGB-81 Li Cheng - + Li Cheng @@ -3752,17 +3752,17 @@ Dimensione del download: %3 Trying to detach a multiplayer player that's not attached - + Tentativo di scollegare un giocatore in multi che non è collegato Trying to get player ID for a multiplayer player that's not attached - + Cerco di ottenere l'ID giocatore per un giocatore in multi non collegato Trying to get save ID for a multiplayer player that's not attached - + Cerco di ottenere l'ID di salvataggio per un giocatore in multi non collegato @@ -4310,7 +4310,7 @@ Dimensione del download: %3 Save file: - + Salva file: @@ -4477,7 +4477,7 @@ Dimensione del download: %3 + RTC - + + RTC @@ -4779,7 +4779,7 @@ Dimensione del download: %3 Just now - Solo adesso + Proprio adesso @@ -5079,7 +5079,7 @@ Dimensione del download: %3 Custom border: - + Bordo personalizzato: @@ -5109,7 +5109,7 @@ Dimensione del download: %3 Last checked: - Vista l'ultima volta: + Ultimo controllo: @@ -5124,7 +5124,7 @@ Dimensione del download: %3 Rewind speed: - + Velocità riavvolgimento: @@ -5891,7 +5891,7 @@ Dimensione del download: %3 WavPack - + WavPack @@ -6312,12 +6312,12 @@ Dimensione del download: %3 Increase fast forward speed - + Aumenta la velocità di avvolgimento veloce Decrease fast forward speed - + Diminuisci la velocità di avvolgimento veloce @@ -6447,7 +6447,7 @@ Dimensione del download: %3 Create forwarder... - + Crea Icona di avvio... From ee1a860ac4e944e8c450bf182baa5587621d926a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 3 Apr 2024 04:57:19 -0700 Subject: [PATCH 119/336] SDL: Fix build on SDL 2.0.12 --- src/platform/sdl/sdl-events.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 383775636..cd34a7781 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -920,12 +920,14 @@ static const char* const buttonNamesXboxOne[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Share", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; static const char* const buttonNamesPlayStation[SDL_CONTROLLER_BUTTON_MAX] = { @@ -940,12 +942,14 @@ static const char* const buttonNamesPlayStation[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "R3", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L1", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R1", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; static const char* const buttonNamesNintedo[SDL_CONTROLLER_BUTTON_MAX] = { @@ -960,12 +964,14 @@ static const char* const buttonNamesNintedo[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Share", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; static const char* const buttonNamesGeneric[SDL_CONTROLLER_BUTTON_MAX] = { From b5a2f62c88957217d4b0b1a18806b3f602947684 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 3 Apr 2024 04:59:04 -0700 Subject: [PATCH 120/336] SDL: Really fix the build this time --- src/platform/sdl/sdl-events.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index cd34a7781..08a369c73 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -899,12 +899,14 @@ static const char* const buttonNamesXbox360[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; #if SDL_VERSION_ATLEAST(2, 0, 12) @@ -986,12 +988,14 @@ static const char* const buttonNamesGeneric[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; #endif From 104d746c1ead326f9499abe443c131f9bf701a98 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 4 Apr 2024 00:28:58 -0700 Subject: [PATCH 121/336] Core: Fix some mutex ordering --- src/core/thread.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/thread.c b/src/core/thread.c index 4b470777d..11465e232 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -433,13 +433,13 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { threadContext->run(threadContext); } } + MutexLock(&impl->stateMutex); } - while (impl->state < mTHREAD_SHUTDOWN) { - MutexLock(&impl->stateMutex); + if (impl->state < mTHREAD_SHUTDOWN) { impl->state = mTHREAD_SHUTDOWN; - MutexUnlock(&impl->stateMutex); } + MutexUnlock(&impl->stateMutex); if (core->opts.rewindEnable) { mCoreRewindContextDeinit(&impl->rewind); From 008a6f3f237bb7cb86b43386cc5c160e97053704 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 4 Apr 2024 00:31:47 -0700 Subject: [PATCH 122/336] Scripting: Attempt to fix MSVC build --- include/mgba/script/macros.h | 4 ++-- include/mgba/script/types.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/mgba/script/macros.h b/include/mgba/script/macros.h index 7d2057d4e..70eed0af5 100644 --- a/include/mgba/script/macros.h +++ b/include/mgba/script/macros.h @@ -323,7 +323,7 @@ CXX_GUARD_START } \ #define _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD_BINDING(TYPE, NAME, T) \ - static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## TYPE ## _ ## NAME[]; \ + static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## TYPE ## _ ## NAME[mSCRIPT_OVERLOADS_MAX]; \ static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \ UNUSED(ctx); \ const struct mScriptFunctionOverload* overload = mScriptFunctionFindOverload(_mSTStructBindingOverloads_ ## TYPE ## _ ## NAME, &frame->arguments); \ @@ -468,7 +468,7 @@ CXX_GUARD_START #define mSCRIPT_DEFINE_DEFAULTS_END } #define mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOADS(STRUCT, METHOD) \ - static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## STRUCT ## _ ## METHOD[] = { \ + static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## STRUCT ## _ ## METHOD[mSCRIPT_OVERLOADS_MAX] = { \ #define mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOAD(TYPE, FUNCTION) { \ .type = &_mSTStructBindingType_ ## TYPE ## _ ## FUNCTION, \ diff --git a/include/mgba/script/types.h b/include/mgba/script/types.h index 5770456e6..5b07abe3b 100644 --- a/include/mgba/script/types.h +++ b/include/mgba/script/types.h @@ -16,6 +16,7 @@ CXX_GUARD_START #define mSCRIPT_VALUE_UNREF -1 #define mSCRIPT_PARAMS_MAX 8 +#define mSCRIPT_OVERLOADS_MAX 8 #define mSCRIPT_VALUE_DOC_FUNCTION(NAME) (&_mScriptDoc_ ## NAME) From e61a324df28d250c67e6bec3f37ca6de1b9b119d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 4 Apr 2024 22:49:48 -0700 Subject: [PATCH 123/336] Core: More threading cleanup --- include/mgba/core/thread.h | 3 ++- src/core/thread.c | 42 +++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/mgba/core/thread.h b/include/mgba/core/thread.h index d3d8a9e92..9f2c229be 100644 --- a/include/mgba/core/thread.h +++ b/include/mgba/core/thread.h @@ -87,7 +87,8 @@ struct mCoreThreadInternal { int requested; Mutex stateMutex; - Condition stateCond; + Condition stateOnThreadCond; + Condition stateOffThreadCond; int interruptDepth; bool frameWasOn; diff --git a/src/core/thread.c b/src/core/thread.c index 11465e232..e0ace6240 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -44,12 +44,12 @@ static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level static void _changeState(struct mCoreThreadInternal* threadContext, enum mCoreThreadState newState) { threadContext->state = newState; - ConditionWake(&threadContext->stateCond); + ConditionWake(&threadContext->stateOffThreadCond); } static void _waitOnInterrupt(struct mCoreThreadInternal* threadContext) { while (threadContext->state == mTHREAD_INTERRUPTED || threadContext->state == mTHREAD_INTERRUPTING) { - ConditionWait(&threadContext->stateCond, &threadContext->stateMutex); + ConditionWait(&threadContext->stateOnThreadCond, &threadContext->stateMutex); } } @@ -110,7 +110,7 @@ static void _wait(struct mCoreThreadInternal* threadContext) { #endif MutexLock(&threadContext->stateMutex); - ConditionWake(&threadContext->stateCond); + ConditionWake(&threadContext->stateOnThreadCond); } static void _waitOnRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) { @@ -140,7 +140,7 @@ static void _sendRequest(struct mCoreThreadInternal* threadContext, enum mCoreTh static void _cancelRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) { threadContext->requested &= ~request; _pokeRequest(threadContext); - ConditionWake(&threadContext->stateCond); + ConditionWake(&threadContext->stateOffThreadCond); } void _frameStarted(void* context) { @@ -351,19 +351,18 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { while (impl->state >= mTHREAD_MIN_WAITING && impl->state < mTHREAD_EXITING) { if (impl->state == mTHREAD_INTERRUPTING) { - impl->state = mTHREAD_INTERRUPTED; - ConditionWake(&impl->stateCond); + _changeState(impl, mTHREAD_INTERRUPTED); } while (impl->state >= mTHREAD_MIN_WAITING && impl->state <= mTHREAD_MAX_WAITING) { #ifdef USE_DEBUGGERS if (debugger && debugger->state != DEBUGGER_SHUTDOWN) { mDebuggerUpdate(debugger); - ConditionWaitTimed(&impl->stateCond, &impl->stateMutex, 10); + ConditionWaitTimed(&impl->stateOnThreadCond, &impl->stateMutex, 10); } else #endif { - ConditionWait(&impl->stateCond, &impl->stateMutex); + ConditionWait(&impl->stateOnThreadCond, &impl->stateMutex); } if (impl->sync.audioWait) { @@ -392,14 +391,13 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { if (impl->state == mTHREAD_REQUEST) { if (pendingRequests) { if (pendingRequests & mTHREAD_REQ_PAUSE) { - impl->state = mTHREAD_PAUSED; + _changeState(impl, mTHREAD_PAUSED); } if (pendingRequests & mTHREAD_REQ_WAIT) { - impl->state = mTHREAD_PAUSED; + _changeState(impl, mTHREAD_PAUSED); } } else { - impl->state = mTHREAD_RUNNING; - ConditionWake(&threadContext->impl->stateCond); + _changeState(impl, mTHREAD_RUNNING); } } MutexUnlock(&impl->stateMutex); @@ -439,6 +437,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { if (impl->state < mTHREAD_SHUTDOWN) { impl->state = mTHREAD_SHUTDOWN; } + ConditionWake(&threadContext->impl->stateOffThreadCond); MutexUnlock(&impl->stateMutex); if (core->opts.rewindEnable) { @@ -477,7 +476,8 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { } MutexInit(&threadContext->impl->stateMutex); - ConditionInit(&threadContext->impl->stateCond); + ConditionInit(&threadContext->impl->stateOnThreadCond); + ConditionInit(&threadContext->impl->stateOffThreadCond); MutexInit(&threadContext->impl->sync.videoFrameMutex); ConditionInit(&threadContext->impl->sync.videoFrameAvailableCond); @@ -502,7 +502,7 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); ThreadCreate(&threadContext->impl->thread, _mCoreThreadRun, threadContext); while (threadContext->impl->state < mTHREAD_RUNNING) { - ConditionWait(&threadContext->impl->stateCond, &threadContext->impl->stateMutex); + ConditionWait(&threadContext->impl->stateOffThreadCond, &threadContext->impl->stateMutex); } MutexUnlock(&threadContext->impl->stateMutex); @@ -544,7 +544,7 @@ bool mCoreThreadHasCrashed(struct mCoreThread* threadContext) { void mCoreThreadMarkCrashed(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); - threadContext->impl->state = mTHREAD_CRASHED; + _changeState(threadContext->impl, mTHREAD_CRASHED); MutexUnlock(&threadContext->impl->stateMutex); } @@ -552,7 +552,7 @@ void mCoreThreadClearCrashed(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); if (threadContext->impl->state == mTHREAD_CRASHED) { threadContext->impl->state = mTHREAD_REQUEST; - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); } MutexUnlock(&threadContext->impl->stateMutex); } @@ -561,7 +561,7 @@ void mCoreThreadEnd(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); _waitOnInterrupt(threadContext->impl); threadContext->impl->state = mTHREAD_EXITING; - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); MutexUnlock(&threadContext->impl->stateMutex); MutexLock(&threadContext->impl->sync.audioBufferMutex); threadContext->impl->sync.audioWait = 0; @@ -590,7 +590,8 @@ void mCoreThreadJoin(struct mCoreThread* threadContext) { ThreadJoin(&threadContext->impl->thread); MutexDeinit(&threadContext->impl->stateMutex); - ConditionDeinit(&threadContext->impl->stateCond); + ConditionDeinit(&threadContext->impl->stateOnThreadCond); + ConditionDeinit(&threadContext->impl->stateOffThreadCond); MutexDeinit(&threadContext->impl->sync.videoFrameMutex); ConditionWake(&threadContext->impl->sync.videoFrameAvailableCond); @@ -642,7 +643,6 @@ void mCoreThreadInterruptFromThread(struct mCoreThread* threadContext) { return; } threadContext->impl->state = mTHREAD_INTERRUPTING; - ConditionWake(&threadContext->impl->stateCond); MutexUnlock(&threadContext->impl->stateMutex); } @@ -658,7 +658,7 @@ void mCoreThreadContinue(struct mCoreThread* threadContext) { } else { threadContext->impl->state = mTHREAD_RUNNING; } - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); } MutexUnlock(&threadContext->impl->stateMutex); } @@ -718,7 +718,7 @@ void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool rewinding) threadContext->impl->rewinding = rewinding; if (rewinding && threadContext->impl->state == mTHREAD_CRASHED) { threadContext->impl->state = mTHREAD_REQUEST; - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); } MutexUnlock(&threadContext->impl->stateMutex); } From 1f2d0d505625414eacbd38f426b94e274ea18aa6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 5 Apr 2024 00:10:09 -0700 Subject: [PATCH 124/336] GBA GPIO: Fix gyro read-out start (fixes #3141) --- CHANGES | 1 + src/gba/cart/gpio.c | 10 ++++++---- src/platform/3ds/main.c | 2 +- src/platform/libretro/libretro.c | 2 +- src/platform/psp2/psp2-context.c | 2 +- src/platform/sdl/sdl-events.c | 4 ++-- src/platform/switch/main.c | 2 +- src/platform/wii/main.c | 2 +- 8 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index efb7d494e..5abed6a7e 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Emulation fixes: - GB Video: Implement DMG-style sprite ordering - GBA: Unhandled bkpt should be treated as an undefined exception - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) + - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index 53c14dafd..811dc1e8a 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -320,18 +320,20 @@ void _gyroReadPins(struct GBACartridgeHardware* hw) { return; } + // Write bit on falling edge + bool doOutput = hw->gyroEdge && !(hw->pinState & 2); if (hw->pinState & 1) { if (gyro->sample) { gyro->sample(gyro); } int32_t sample = gyro->readGyroZ(gyro); - // Normalize to ~12 bits, focused on 0x6C0 - hw->gyroSample = (sample >> 21) + 0x6C0; // Crop off an extra bit so that we can't go negative + // Normalize to ~12 bits, focused on 0x700 + hw->gyroSample = (sample >> 21) + 0x700; // Crop off an extra bit so that we can't go negative + doOutput = true; } - if (hw->gyroEdge && !(hw->pinState & 2)) { - // Write bit on falling edge + if (doOutput) { unsigned bit = hw->gyroSample >> 15; hw->gyroSample <<= 1; _outputPins(hw, bit << 2); diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 0f7bb27b9..36df49a9c 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -704,7 +704,7 @@ static int32_t _readTiltY(struct mRotationSource* source) { static int32_t _readGyroZ(struct mRotationSource* source) { struct m3DSRotationSource* rotation = (struct m3DSRotationSource*) source; - return rotation->gyro.y << 18L; // Yes, y + return rotation->gyro.y << 17L; // Yes, y } static void _startRequestImage(struct mImageSource* source, unsigned w, unsigned h, int colorFormats) { diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index bea9f6273..69c547b57 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -1390,7 +1390,7 @@ static void _updateRotation(struct mRotationSource* source) { tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * 2e8f; } if (gyroEnabled) { - gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -1.1e9f; + gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -5.5e8f; } } diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index a7504f7cc..1e48c2f24 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -149,7 +149,7 @@ static int32_t _readTiltY(struct mRotationSource* source) { static int32_t _readGyroZ(struct mRotationSource* source) { struct mSceRotationSource* rotation = (struct mSceRotationSource*) source; - return rotation->state.gyro.z * -0x10000000; + return rotation->state.gyro.z * -0x8000000; } static void _setRumble(struct mRumble* source, int enable) { diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 08a369c73..46807cae1 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -823,14 +823,14 @@ static void _mSDLRotationSample(struct mRotationSource* source) { float theta[3]; int count = SDL_GameControllerGetSensorData(controller, SDL_SENSOR_GYRO, theta, 3); if (count >= 0) { - rotation->zDelta = theta[1] / -10.f; + rotation->zDelta = theta[1] / -20.f; } return; } } #endif if (rotation->gyroZ >= 0) { - rotation->zDelta = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroZ) / 1.e5f; + rotation->zDelta = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroZ) / 2.e5f; return; } diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index ef3e12164..15196aaec 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -644,7 +644,7 @@ void _sampleRotation(struct mRotationSource* source) { } tiltX = sixaxis.acceleration.x * 3e8f; tiltY = sixaxis.acceleration.y * -3e8f; - gyroZ = sixaxis.angular_velocity.z * -1.1e9f; + gyroZ = sixaxis.angular_velocity.z * -5.5e8f; } int32_t _readTiltX(struct mRotationSource* source) { diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index db3ed7242..60d4e95ae 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -1731,7 +1731,7 @@ void _sampleRotation(struct mRotationSource* source) { return; } gyroZ = exp.mp.rz - 0x1FA0; - gyroZ <<= 18; + gyroZ <<= 17; } int32_t _readTiltX(struct mRotationSource* source) { From 04a95a5445b2617a0015a268bd3e36577c521214 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:10:58 -0700 Subject: [PATCH 125/336] CHANGES: Remove duplicate entry --- CHANGES | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGES b/CHANGES index 5abed6a7e..e08179d72 100644 --- a/CHANGES +++ b/CHANGES @@ -11,7 +11,6 @@ Emulation fixes: - GB Serialize: Add missing Pocket Cam state to savestates - GB Video: Implement DMG-style sprite ordering - GBA: Unhandled bkpt should be treated as an undefined exception - - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) From 47ec447dd0902661c3e21766b60788a43778d401 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:11:14 -0700 Subject: [PATCH 126/336] CMakeLists: Fix strtof_l detection logic --- CMakeLists.txt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f2ff4686..aee8ac512 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -345,18 +345,14 @@ find_function(popcount32) find_function(futimens) find_function(futimes) +find_function(localtime_r) find_function(realpath) if(ANDROID AND ANDROID_NDK_MAJOR GREATER 13) - find_function(localtime_r) - set(HAVE_STRTOF_L ON) -elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - find_function(localtime_r) + list(APPEND FUNCTION_DEFINES HAVE_STRTOF_L) +elseif(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") # The strtof_l on Linux not actually exposed nor actually strtof_l - set(HAVE_STRTOF_L OFF) -else() - find_function(localtime_r) find_function(strtof_l) endif() From 02b2f5a98a7f430c60d66948d8ab57102261c302 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:52:47 -0700 Subject: [PATCH 127/336] flags.h: Add missing flags --- src/core/flags.h.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/flags.h.in b/src/core/flags.h.in index 3bd142a44..5a9e4e6ef 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -59,6 +59,10 @@ #cmakedefine USE_DEBUGGERS #endif +#ifndef USE_DISCORD_RPC +#cmakedefine USE_DISCORD_RPC +#endif + #ifndef USE_EDITLINE #cmakedefine USE_EDITLINE #endif @@ -133,6 +137,10 @@ #cmakedefine HAVE_CRC32 #endif +#ifndef HAVE_LOCALE +#cmakedefine HAVE_LOCALE +#endif + #ifndef HAVE_LOCALTIME_R #cmakedefine HAVE_LOCALTIME_R #endif @@ -149,6 +157,10 @@ #cmakedefine HAVE_PTHREAD_SETNAME_NP #endif +#ifndef HAVE_SNPRINTF_L +#cmakedefine HAVE_SNPRINTF_L +#endif + #ifndef HAVE_STRDUP #cmakedefine HAVE_STRDUP #endif From 4652bbb4271af4054acfbf779df8720e424ad80b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:53:00 -0700 Subject: [PATCH 128/336] Util: Fix #if into #ifdef --- src/util/formatting.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/formatting.c b/src/util/formatting.c index e1e1c0bf0..2506ddc9c 100644 --- a/src/util/formatting.c +++ b/src/util/formatting.c @@ -46,26 +46,26 @@ float strtof_l(const char* restrict str, char** restrict end, locale_t locale) { #endif int ftostr_u(char* restrict str, size_t size, float f) { -#if HAVE_LOCALE +#ifdef HAVE_LOCALE locale_t l = newlocale(LC_NUMERIC_MASK, "C", 0); #else locale_t l = "C"; #endif int res = ftostr_l(str, size, f, l); -#if HAVE_LOCALE +#ifdef HAVE_LOCALE freelocale(l); #endif return res; } float strtof_u(const char* restrict str, char** restrict end) { -#if HAVE_LOCALE +#ifdef HAVE_LOCALE locale_t l = newlocale(LC_NUMERIC_MASK, "C", 0); #else locale_t l = "C"; #endif float res = strtof_l(str, end, l); -#if HAVE_LOCALE +#ifdef HAVE_LOCALE freelocale(l); #endif return res; From 0e441527c896022ff7a558529618f2a28036f6b2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 03:08:10 -0700 Subject: [PATCH 129/336] CMake: Rename USE_DEBUGGERS and USE_GDB_STUB to ENABLE_DEBUGGERS and ENABLE_GDB_STUB ENABLE flags are for optional features, USE flags are for optional dependencies --- CMakeLists.txt | 26 +++++++++---------- include/mgba/core/core.h | 6 ++--- include/mgba/core/scripting.h | 6 ++--- include/mgba/internal/arm/decoder.h | 2 +- include/mgba/internal/gba/gba.h | 2 +- src/arm/decoder.c | 2 +- src/core/core.c | 2 +- src/core/flags.h.in | 16 ++++++------ src/core/scripting.c | 16 ++++++------ src/core/test/scripting.c | 4 +-- src/core/thread.c | 6 ++--- src/debugger/CMakeLists.txt | 2 +- src/debugger/cli-debugger.c | 2 +- src/debugger/debugger.c | 6 ++--- src/feature/commandline.c | 12 ++++----- src/gb/core.c | 6 ++--- src/gb/gb.c | 4 +-- src/gba/core.c | 8 +++--- src/gba/gba.c | 14 +++++----- src/platform/python/_builder.h | 2 +- src/platform/python/engine.c | 10 +++---- src/platform/python/lib.h | 2 +- src/platform/qt/CMakeLists.txt | 4 +-- src/platform/qt/CoreController.cpp | 8 +++--- src/platform/qt/CoreController.h | 4 +-- src/platform/qt/GDBController.h | 2 +- src/platform/qt/Window.cpp | 20 +++++++------- src/platform/qt/Window.h | 8 +++--- .../qt/scripting/ScriptingController.cpp | 2 +- src/platform/sdl/main.c | 6 ++--- src/platform/sdl/sdl-events.c | 2 +- src/platform/test/rom-test-main.c | 6 ++--- src/script/stdlib.c | 2 +- 33 files changed, 110 insertions(+), 110 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aee8ac512..24caaaf9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,11 +46,11 @@ else() endif() if(NOT LIBMGBA_ONLY) - set(USE_DEBUGGERS ON CACHE BOOL "Whether or not to enable the debugging infrastructure") + set(ENABLE_DEBUGGERS ON CACHE BOOL "Whether or not to enable the debugging infrastructure") if (NOT WIN32) set(USE_EDITLINE ON CACHE BOOL "Whether or not to enable the CLI-mode debugger") endif() - set(USE_GDB_STUB ON CACHE BOOL "Whether or not to enable the GDB stub ARM debugger") + set(ENABLE_GDB_STUB ON CACHE BOOL "Whether or not to enable the GDB stub ARM debugger") set(USE_FFMPEG ON CACHE BOOL "Whether or not to enable FFmpeg support") set(USE_ZLIB ON CACHE BOOL "Whether or not to enable zlib support") set(USE_MINIZIP ON CACHE BOOL "Whether or not to enable external minizip support") @@ -301,7 +301,7 @@ endif() if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII OR DEFINED SWITCH) set(IS_EMBEDDED ON) - set(USE_DEBUGGERS OFF) + set(ENABLE_DEBUGGERS OFF) set(USE_SQLITE3 OFF) set(USE_DISCORD_RPC OFF) set(USE_LIBZIP OFF CACHE BOOL "") @@ -313,12 +313,12 @@ if(DEFINED SWITCH) endif() if(NOT M_CORE_GBA) - set(USE_GDB_STUB OFF) + set(ENABLE_GDB_STUB OFF) endif() -if(NOT USE_DEBUGGERS) +if(NOT ENABLE_DEBUGGERS) set(USE_EDITLINE OFF) - set(USE_GDB_STUB OFF) + set(ENABLE_GDB_STUB OFF) endif() if(WII) @@ -489,7 +489,7 @@ if(NOT BUILD_GLES2 AND NOT BUILD_GLES3 AND NOT LIBMGBA_ONLY) endif() if(DISABLE_DEPS) - set(USE_GDB_STUB OFF) + set(ENABLE_GDB_STUB OFF) set(USE_DISCORD_RPC OFF) set(USE_JSON_C OFF) set(USE_SQLITE3 OFF) @@ -541,8 +541,8 @@ else() set(DEBUGGER_LIB "") endif() -if(USE_GDB_STUB) - list(APPEND FEATURES GDB_STUB) +if(ENABLE_GDB_STUB) + list(APPEND ENABLES GDB_STUB) endif() source_group("Debugger" FILES ${DEBUGGER_SRC}) @@ -851,10 +851,10 @@ if(M_CORE_GBA) list(APPEND TEST_SRC ${ARM_TEST_SRC} ${GBA_TEST_SRC}) endif() -if(USE_DEBUGGERS) +if(ENABLE_DEBUGGERS) list(APPEND FEATURE_SRC ${DEBUGGER_SRC}) list(APPEND TEST_SRC ${DEBUGGER_TEST_SRC}) - list(APPEND FEATURES DEBUGGERS) + list(APPEND ENABLES DEBUGGERS) endif() if(ENABLE_SCRIPTING) @@ -1312,11 +1312,11 @@ if(NOT QUIET AND NOT LIBMGBA_ONLY) message(STATUS " Game Boy Advance: ${M_CORE_GBA}") message(STATUS " Game Boy: ${M_CORE_GB}") message(STATUS "Features:") - message(STATUS " Debuggers: ${USE_DEBUGGERS}") + message(STATUS " Debuggers: ${ENABLE_DEBUGGERS}") if(NOT WIN32) message(STATUS " CLI debugger: ${USE_EDITLINE}") endif() - message(STATUS " GDB stub: ${USE_GDB_STUB}") + message(STATUS " GDB stub: ${ENABLE_GDB_STUB}") message(STATUS " GIF/Video recording: ${USE_FFMPEG}") message(STATUS " Screenshot/advanced savestate support: ${USE_PNG}") message(STATUS " ZIP support: ${SUMMARY_ZIP}") diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 052e36795..99bfd0e83 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -18,7 +18,7 @@ CXX_GUARD_START #include #endif #include -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #endif @@ -146,7 +146,7 @@ struct mCore { bool (*readRegister)(const struct mCore*, const char* name, void* out); bool (*writeRegister)(struct mCore*, const char* name, const void* in); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS bool (*supportsDebuggerType)(struct mCore*, enum mDebuggerType); struct mDebuggerPlatform* (*debuggerPlatform)(struct mCore*); struct CLIDebuggerSystem* (*cliDebuggerSystem)(struct mCore*); @@ -219,7 +219,7 @@ const struct mCoreMemoryBlock* mCoreGetMemoryBlockInfo(struct mCore* core, uint3 #ifdef USE_ELF struct ELF; bool mCoreLoadELF(struct mCore* core, struct ELF* elf); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF*); #endif #endif diff --git a/include/mgba/core/scripting.h b/include/mgba/core/scripting.h index 645874883..a8fdbc425 100644 --- a/include/mgba/core/scripting.h +++ b/include/mgba/core/scripting.h @@ -10,7 +10,7 @@ CXX_GUARD_START -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #endif #include @@ -35,7 +35,7 @@ struct mScriptEngine { void (*run)(struct mScriptEngine*); bool (*lookupSymbol)(struct mScriptEngine*, const char* name, int32_t* out); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void (*debuggerEntered)(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); #endif }; @@ -63,7 +63,7 @@ void mScriptBridgeDestroy(struct mScriptBridge*); void mScriptBridgeInstallEngine(struct mScriptBridge*, struct mScriptEngine*); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mScriptBridgeSetDebugger(struct mScriptBridge*, struct mDebugger*); struct mDebugger* mScriptBridgeGetDebugger(struct mScriptBridge*); void mScriptBridgeDebuggerEntered(struct mScriptBridge*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); diff --git a/include/mgba/internal/arm/decoder.h b/include/mgba/internal/arm/decoder.h index c0efb22e8..f6e197698 100644 --- a/include/mgba/internal/arm/decoder.h +++ b/include/mgba/internal/arm/decoder.h @@ -221,7 +221,7 @@ bool ARMDecodeThumbCombine(struct ARMInstructionInfo* info1, struct ARMInstructi struct ARMInstructionInfo* out); uint32_t ARMResolveMemoryAccess(struct ARMInstructionInfo* info, struct ARMRegisterFile* regs, uint32_t pc); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebuggerSymbols; int ARMDisassemble(const struct ARMInstructionInfo* info, struct ARMCore* core, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen); #endif diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index 020dd2ab5..e66ac47f3 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -160,7 +160,7 @@ struct ELF; bool GBAVerifyELFEntry(struct ELF* elf, uint32_t target); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger; void GBAAttachDebugger(struct GBA* gba, struct mDebugger* debugger); void GBADetachDebugger(struct GBA* gba); diff --git a/src/arm/decoder.c b/src/arm/decoder.c index 01622cc9d..21ea0e872 100644 --- a/src/arm/decoder.c +++ b/src/arm/decoder.c @@ -9,7 +9,7 @@ #include #include -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #define ADVANCE(AMOUNT) \ if (AMOUNT >= blen) { \ buffer[blen - 1] = '\0'; \ diff --git a/src/core/core.c b/src/core/core.c index a7de23943..bc68fd5d2 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -467,7 +467,7 @@ bool mCoreLoadELF(struct mCore* core, struct ELF* elf) { return true; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF* elf) { size_t symIndex = ELFFindSection(elf, ".symtab"); size_t names = ELFFindSection(elf, ".strtab"); diff --git a/src/core/flags.h.in b/src/core/flags.h.in index 5a9e4e6ef..ebfd67ed9 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -49,16 +49,20 @@ // ENABLE flags +#ifndef ENABLE_DEBUGGERS +#cmakedefine ENABLE_DEBUGGERS +#endif + +#ifndef ENABLE_GDB_STUB +#cmakedefine ENABLE_GDB_STUB +#endif + #ifndef ENABLE_SCRIPTING #cmakedefine ENABLE_SCRIPTING #endif // USE flags -#ifndef USE_DEBUGGERS -#cmakedefine USE_DEBUGGERS -#endif - #ifndef USE_DISCORD_RPC #cmakedefine USE_DISCORD_RPC #endif @@ -79,10 +83,6 @@ #cmakedefine USE_FFMPEG #endif -#ifndef USE_GDB_STUB -#cmakedefine USE_GDB_STUB -#endif - #ifndef USE_JSON_C #cmakedefine USE_JSON_C #endif diff --git a/src/core/scripting.c b/src/core/scripting.c index 5b1f39a63..1fd37aeb9 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -64,7 +64,7 @@ static void _seRun(const char* key, void* value, void* user) { se->run(se); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mScriptDebuggerEntry { enum mDebuggerEntryReason reason; struct mDebuggerEntryInfo* info; @@ -98,7 +98,7 @@ void mScriptBridgeInstallEngine(struct mScriptBridge* sb, struct mScriptEngine* HashTableInsert(&sb->engines, name, se); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mScriptBridgeSetDebugger(struct mScriptBridge* sb, struct mDebugger* debugger) { if (sb->debugger == debugger) { return; @@ -159,7 +159,7 @@ struct mScriptMemoryDomain { struct mCoreMemoryBlock block; }; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mScriptBreakpointName { uint32_t address; uint32_t maxAddress; @@ -189,7 +189,7 @@ struct mScriptCoreAdapter { struct mCore* core; struct mScriptContext* context; struct mScriptValue memory; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mScriptDebugger debugger; #endif struct mRumble rumble; @@ -701,7 +701,7 @@ static void _rebuildMemoryMap(struct mScriptContext* context, struct mScriptCore } } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static void _freeBreakpoint(void* bp) { struct mScriptBreakpoint* point = bp; HashTableDeinit(&point->callbacks); @@ -929,7 +929,7 @@ static bool _mScriptCoreAdapterClearBreakpoint(struct mScriptCoreAdapter* adapte static void _mScriptCoreAdapterDeinit(struct mScriptCoreAdapter* adapter) { _clearMemoryMap(adapter->context, adapter, false); adapter->memory.type->free(&adapter->memory); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (adapter->core->debugger) { mDebuggerDetachModule(adapter->core->debugger, &adapter->debugger.d); } @@ -982,7 +982,7 @@ mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, _deinit, _mScriptCoreAdap mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, reset, _mScriptCoreAdapterReset, 0); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, WTABLE, setRotationCallbacks, _mScriptCoreAdapterSetRotationCbTable, 1, WTABLE, cbTable); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, setSolarSensorCallback, _mScriptCoreAdapterSetLuminanceCb, 1, WRAPPER, callback); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setBreakpoint, _mScriptCoreAdapterSetBreakpoint, 3, WRAPPER, callback, U32, address, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setWatchpoint, _mScriptCoreAdapterSetWatchpoint, 4, WRAPPER, callback, U32, address, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setRangeWatchpoint, _mScriptCoreAdapterSetRangeWatchpoint, 5, WRAPPER, callback, U32, minAddress, U32, maxAddress, S32, type, S32, segment); @@ -1040,7 +1040,7 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) "Note that the full range of values is not used by games, and the exact range depends on the calibration done by the game itself." ) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setSolarSensorCallback) -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mSCRIPT_DEFINE_DOCSTRING("Set a breakpoint at a given address") mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setBreakpoint) mSCRIPT_DEFINE_DOCSTRING("Clear a breakpoint or watchpoint for a given id returned by a previous call") diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index c2593bf14..d2f0f0a00 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -327,7 +327,7 @@ M_TEST_DEFINE(screenshot) { TEARDOWN_CORE; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void _setupBp(struct mCore* core) { switch (core->platform(core)) { #ifdef M_CORE_GBA @@ -727,7 +727,7 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptCore, cmocka_unit_test(memoryWrite), cmocka_unit_test(logging), cmocka_unit_test(screenshot), -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #ifdef M_CORE_GBA cmocka_unit_test(basicBreakpointGBA), #endif diff --git a/src/core/thread.c b/src/core/thread.c index e0ace6240..43a569d4f 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -103,7 +103,7 @@ static void _wait(struct mCoreThreadInternal* threadContext) { MutexUnlock(&threadContext->sync.audioBufferMutex); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (threadContext->core && threadContext->core->debugger) { mDebuggerInterrupt(threadContext->core->debugger); } @@ -330,7 +330,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { MutexLock(&impl->stateMutex); while (impl->state < mTHREAD_EXITING) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger* debugger = core->debugger; if (debugger) { MutexUnlock(&impl->stateMutex); @@ -355,7 +355,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { } while (impl->state >= mTHREAD_MIN_WAITING && impl->state <= mTHREAD_MAX_WAITING) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (debugger && debugger->state != DEBUGGER_SHUTDOWN) { mDebuggerUpdate(debugger); ConditionWaitTimed(&impl->stateOnThreadCond, &impl->stateMutex, 10); diff --git a/src/debugger/CMakeLists.txt b/src/debugger/CMakeLists.txt index ce2ade635..976f88c93 100644 --- a/src/debugger/CMakeLists.txt +++ b/src/debugger/CMakeLists.txt @@ -15,7 +15,7 @@ if(USE_EDITLINE) list(APPEND SOURCE_FILES cli-el-backend.c) endif() -if(USE_GDB_STUB) +if(ENABLE_GDB_STUB) list(APPEND SOURCE_FILES gdb-stub.c) endif() diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 9c9696f9f..6d5b70e97 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -1420,7 +1420,7 @@ static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv #ifdef USE_ELF struct ELF* elf = ELFOpen(vf); if (elf) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mCoreLoadELFSymbols(symbolTable, elf); #endif ELFClose(elf); diff --git a/src/debugger/debugger.c b/src/debugger/debugger.c index 7de4772d7..a03f106d9 100644 --- a/src/debugger/debugger.c +++ b/src/debugger/debugger.c @@ -10,7 +10,7 @@ #include #include -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB #include #endif @@ -37,7 +37,7 @@ struct mDebuggerModule* mDebuggerCreateModule(enum mDebuggerType type, struct mC union DebugUnion { struct mDebuggerModule d; struct CLIDebugger cli; -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB struct GDBStub gdb; #endif }; @@ -52,7 +52,7 @@ struct mDebuggerModule* mDebuggerCreateModule(enum mDebuggerType type, struct mC CLIDebuggerAttachSystem(&debugger->cli, sys); break; case DEBUGGER_GDB: -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB GDBStubCreate(&debugger->gdb); struct Address localHost = { .version = IPV4, diff --git a/src/feature/commandline.c b/src/feature/commandline.c index 7e720886d..cdf788b19 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -12,7 +12,7 @@ #include #include -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB #include #endif #ifdef USE_EDITLINE @@ -40,7 +40,7 @@ static const struct option _options[] = { #ifdef USE_EDITLINE { "debug", no_argument, 0, 'd' }, #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB { "gdb", no_argument, 0, 'g' }, #endif { "help", no_argument, 0, 'h' }, @@ -85,7 +85,7 @@ bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struc #ifdef USE_EDITLINE "d" #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB "g" #endif ; @@ -151,7 +151,7 @@ bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struc args->debugCli = true; break; #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB case 'g': args->debugAtStart = true; args->debugGdb = true; @@ -231,7 +231,7 @@ bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, } #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB if (args->debugGdb) { struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_GDB, core); if (module) { @@ -355,7 +355,7 @@ void usage(const char* arg0, const char* prologue, const char* epilogue, const s #ifdef USE_EDITLINE " -d, --debug Use command-line debugger\n" #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB " -g, --gdb Start GDB session (default port 2345)\n" #endif " -l, --log-level N Log level mask\n" diff --git a/src/gb/core.c b/src/gb/core.c index 9154221d6..1018b9f82 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -164,7 +164,7 @@ static void _GBCoreDeinit(struct mCore* core) { #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 mDirectorySetDeinit(&core->dirs); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (core->symbolTable) { mDebuggerSymbolTableDestroy(core->symbolTable); } @@ -1060,7 +1060,7 @@ static bool _GBCoreWriteRegister(struct mCore* core, const char* name, const voi return false; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _GBCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) { UNUSED(core); switch (type) { @@ -1352,7 +1352,7 @@ struct mCore* GBCoreCreate(void) { core->listRegisters = _GBCoreListRegisters; core->readRegister = _GBCoreReadRegister; core->writeRegister = _GBCoreWriteRegister; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS core->supportsDebuggerType = _GBCoreSupportsDebuggerType; core->debuggerPlatform = _GBCoreDebuggerPlatform; core->cliDebuggerSystem = _GBCoreCliDebuggerSystem; diff --git a/src/gb/gb.c b/src/gb/gb.c index b3bb62a80..c0e966c27 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -940,7 +940,7 @@ void GBProcessEvents(struct SM83Core* cpu) { nextEvent = cycles; do { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS gb->timing.globalCycles += nextEvent; #endif nextEvent = mTimingTick(&gb->timing, nextEvent); @@ -1057,7 +1057,7 @@ void GBStop(struct SM83Core* cpu) { void GBIllegal(struct SM83Core* cpu) { struct GB* gb = (struct GB*) cpu->master; mLOG(GB, GAME_ERROR, "Hit illegal opcode at address %04X:%02X", cpu->pc, cpu->bus); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (cpu->components && cpu->components[CPU_COMPONENT_DEBUGGER]) { struct mDebuggerEntryInfo info = { .address = cpu->pc, diff --git a/src/gba/core.c b/src/gba/core.c index 54c436b3a..dd5df523b 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -313,7 +313,7 @@ static void _GBACoreDeinit(struct mCore* core) { #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 mDirectorySetDeinit(&core->dirs); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (core->symbolTable) { mDebuggerSymbolTableDestroy(core->symbolTable); } @@ -1218,7 +1218,7 @@ static bool _GBACoreWriteRegister(struct mCore* core, const char* name, const vo return true; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _GBACoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) { UNUSED(core); switch (type) { @@ -1280,7 +1280,7 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { #ifdef USE_ELF struct ELF* elf = ELFOpen(vf); if (elf) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mCoreLoadELFSymbols(core->symbolTable, elf); #endif ELFClose(elf); @@ -1565,7 +1565,7 @@ struct mCore* GBACoreCreate(void) { core->listRegisters = _GBACoreListRegisters; core->readRegister = _GBACoreReadRegister; core->writeRegister = _GBACoreWriteRegister; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS core->supportsDebuggerType = _GBACoreSupportsDebuggerType; core->debuggerPlatform = _GBACoreDebuggerPlatform; core->cliDebuggerSystem = _GBACoreCliDebuggerSystem; diff --git a/src/gba/gba.c b/src/gba/gba.c index 31008507c..41eee7435 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -49,7 +49,7 @@ static void GBATestIRQNoDelay(struct ARMCore* cpu); static void _triggerIRQ(struct mTiming*, void* user, uint32_t cyclesLate); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _setSoftwareBreakpoint(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode); static void _clearSoftwareBreakpoint(struct ARMDebugger*, const struct ARMDebugBreakpoint*); #endif @@ -305,7 +305,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { do { int32_t cycles = cpu->cycles; cpu->cycles = 0; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS gba->timing.globalCycles += cycles < nextEvent ? nextEvent : cycles; #endif #ifndef NDEBUG @@ -338,7 +338,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { } } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void GBAAttachDebugger(struct GBA* gba, struct mDebugger* debugger) { gba->debugger = (struct ARMDebugger*) debugger->platform; gba->debugger->setSoftwareBreakpoint = _setSoftwareBreakpoint; @@ -850,7 +850,7 @@ void GBAGetGameTitle(const struct GBA* gba, char* out) { void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) { struct GBA* gba = (struct GBA*) cpu->master; UNUSED(gba); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (gba->debugger) { struct mDebuggerEntryInfo info = { .address = _ARMPCAddress(cpu), @@ -873,7 +873,7 @@ void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) { // TODO: More sensible category? mLOG(GBA, WARN, "Illegal opcode: %08x", opcode); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (gba->debugger) { struct mDebuggerEntryInfo info = { .address = _ARMPCAddress(cpu), @@ -888,7 +888,7 @@ void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) { void GBABreakpoint(struct ARMCore* cpu, int immediate) { struct GBA* gba = (struct GBA*) cpu->master; switch (immediate) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS case CPU_COMPONENT_DEBUGGER: if (gba->debugger) { struct mDebuggerEntryInfo info = { @@ -1053,7 +1053,7 @@ void GBAClearBreakpoint(struct GBA* gba, uint32_t address, enum ExecutionMode mo } } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _setSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) { GBASetBreakpoint((struct GBA*) debugger->cpu->master, &debugger->d.p->d, address, mode, opcode); return true; diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index eef4cf046..e06e4f5cc 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -67,7 +67,7 @@ void free(void*); #include #include #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #include #endif diff --git a/src/platform/python/engine.c b/src/platform/python/engine.c index 67d1d7b49..86ec2cf5c 100644 --- a/src/platform/python/engine.c +++ b/src/platform/python/engine.c @@ -9,7 +9,7 @@ #include #include -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #endif @@ -23,7 +23,7 @@ static bool mPythonScriptEngineLoadScript(struct mScriptEngine*, const char* nam static void mPythonScriptEngineRun(struct mScriptEngine*); static bool mPythonScriptEngineLookupSymbol(struct mScriptEngine*, const char* name, int32_t* out); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static void mPythonScriptDebuggerEntered(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); #endif @@ -41,7 +41,7 @@ struct mPythonScriptEngine* mPythonCreateScriptEngine(void) { engine->d.loadScript = mPythonScriptEngineLoadScript; engine->d.run = mPythonScriptEngineRun; engine->d.lookupSymbol = mPythonScriptEngineLookupSymbol; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS engine->d.debuggerEntered = mPythonScriptDebuggerEntered; #endif engine->sb = NULL; @@ -82,7 +82,7 @@ bool mPythonScriptEngineLoadScript(struct mScriptEngine* se, const char* name, s void mPythonScriptEngineRun(struct mScriptEngine* se) { struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger* debugger = mScriptBridgeGetDebugger(engine->sb); if (debugger) { mPythonSetDebugger(debugger); @@ -97,7 +97,7 @@ bool mPythonScriptEngineLookupSymbol(struct mScriptEngine* se, const char* name, return mPythonLookupSymbol(name, out); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mPythonScriptDebuggerEntered(struct mScriptEngine* se, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; diff --git a/src/platform/python/lib.h b/src/platform/python/lib.h index 0dd8754ed..d0893101f 100644 --- a/src/platform/python/lib.h +++ b/src/platform/python/lib.h @@ -6,7 +6,7 @@ extern bool mPythonLoadScript(const char*, struct VFile*); extern void mPythonRunPending(); extern bool mPythonLookupSymbol(const char* name, int32_t* out); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS extern void mPythonSetDebugger(struct mDebugger*); extern void mPythonDebuggerEntered(enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); #endif diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index fe898be1e..05f5add0a 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -249,7 +249,7 @@ if(NOT AUDIO_SRC) return() endif() -if(USE_DEBUGGERS) +if(ENABLE_DEBUGGERS) list(APPEND SOURCE_FILES DebuggerController.cpp DebuggerConsole.cpp @@ -257,7 +257,7 @@ if(USE_DEBUGGERS) MemoryAccessLogView.cpp) endif() -if(USE_GDB_STUB) +if(ENABLE_GDB_STUB) list(APPEND SOURCE_FILES GDBController.cpp GDBWindow.cpp) endif() diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index dd74cce78..660de1f57 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -49,7 +49,7 @@ CoreController::CoreController(mCore* core, QObject* parent) GBASIODolphinCreate(&m_dolphin); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mDebuggerInit(&m_debugger); #endif @@ -218,7 +218,7 @@ CoreController::~CoreController() { mCoreThreadJoin(&m_threadContext); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mDebuggerDeinit(&m_debugger); #endif @@ -331,7 +331,7 @@ void CoreController::loadConfig(ConfigController* config) { #endif } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void CoreController::attachDebugger(bool interrupt) { Interrupter interrupter(this); if (!m_threadContext.core->debugger) { @@ -478,7 +478,7 @@ void CoreController::start() { void CoreController::stop() { setSync(false); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS detachDebugger(); #endif setPaused(false); diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index c46b4d6e9..684d864d0 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -107,7 +107,7 @@ public: mCheatDevice* cheatDevice() { return m_threadContext.core->cheatDevice(m_threadContext.core); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mDebugger* debugger() { return &m_debugger; } void attachDebugger(bool interrupt = true); void detachDebugger(); @@ -305,7 +305,7 @@ private: bool m_autoload; int m_autosaveCounter = 0; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger m_debugger; #endif diff --git a/src/platform/qt/GDBController.h b/src/platform/qt/GDBController.h index 6bf0a7132..50c0fb927 100644 --- a/src/platform/qt/GDBController.h +++ b/src/platform/qt/GDBController.h @@ -7,7 +7,7 @@ #include "DebuggerController.h" -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB #include diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 6216e2247..117da820d 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -211,7 +211,7 @@ void Window::argumentsPassed() { m_pendingState = args->savestate; } -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB if (args->debugGdb) { if (!m_gdbController) { m_gdbController = new GDBController(this); @@ -224,7 +224,7 @@ void Window::argumentsPassed() { } #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (args->debugCli) { consoleOpen(); } @@ -607,7 +607,7 @@ std::function Window::openNamedControllerTView(std::unique_ptr* name, }; } -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB void Window::gdbOpen() { if (!m_gdbController) { m_gdbController = new GDBController(this); @@ -619,7 +619,7 @@ void Window::gdbOpen() { } #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void Window::consoleOpen() { if (!m_console) { m_console = new DebuggerConsoleController(this); @@ -1677,14 +1677,14 @@ void Window::setupMenu(QMenuBar* menubar) { m_actions.addAction(tr("Make portable"), "makePortable", this, &Window::tryMakePortable, "tools"); m_actions.addSeparator("tools"); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS m_actions.addAction(tr("Open debugger console..."), "debuggerWindow", this, &Window::consoleOpen, "tools"); -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB auto gdbWindow = addGameAction(tr("Start &GDB server..."), "gdbWindow", this, &Window::gdbOpen, "tools"); m_platformActions.insert(mPLATFORM_GBA, gdbWindow); #endif #endif -#if defined(USE_DEBUGGERS) || defined(ENABLE_SCRIPTING) +#if defined(ENABLE_DEBUGGERS) || defined(ENABLE_SCRIPTING) m_actions.addSeparator("tools"); #endif @@ -1714,7 +1714,7 @@ void Window::setupMenu(QMenuBar* menubar) { addGameAction(tr("Search memory..."), "memorySearch", openControllerTView(), "stateViews"); addGameAction(tr("View &I/O registers..."), "ioViewer", openControllerTView(), "stateViews"); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS addGameAction(tr("Log memory &accesses..."), "memoryAccessView", openControllerTView(), "tools"); #endif @@ -2132,13 +2132,13 @@ void Window::setController(CoreController* controller, const QString& fname) { } #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB if (m_gdbController) { m_gdbController->setController(m_controller); } #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (m_console) { m_console->setController(m_controller); } diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index b2e8de82b..4bcb6b7f9 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -108,11 +108,11 @@ public slots: void startVideoLog(); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void consoleOpen(); #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB void gdbOpen(); #endif @@ -206,7 +206,7 @@ private: LogController m_log{0}; LogView* m_logView; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS DebuggerConsoleController* m_console = nullptr; #endif LoadSaveState* m_stateWindow = nullptr; @@ -249,7 +249,7 @@ private: std::unique_ptr m_gifView; #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB GDBController* m_gdbController = nullptr; #endif diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index 79b46e9d0..b1d68e22a 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -302,7 +302,7 @@ void ScriptingController::updateGamepad() { void ScriptingController::attach() { CoreController::Interrupter interrupter(m_controller); mScriptContextAttachCore(&m_scriptContext, m_controller->thread()->core); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS m_controller->attachDebugger(false); #endif } diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index d6a41f611..1a1d3f6fc 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -217,12 +217,12 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { #ifdef ENABLE_PYTHON mPythonSetup(bridge); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS CLIDebuggerScriptEngineInstall(bridge); #endif #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger debugger; mDebuggerInit(&debugger); bool hasDebugger = mArgumentsApplyDebugger(args, renderer->core, &debugger); @@ -292,7 +292,7 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { mScriptBridgeDestroy(bridge); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (hasDebugger) { renderer->core->detachDebugger(renderer->core); mDebuggerDeinit(&debugger); diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 46807cae1..eceaf1808 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -505,7 +505,7 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer* } if (event->type == SDL_KEYDOWN) { switch (event->keysym.sym) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS case SDLK_F11: if (context->core->debugger) { mDebuggerEnter(context->core->debugger, DEBUGGER_ENTER_MANUAL, NULL); diff --git a/src/platform/test/rom-test-main.c b/src/platform/test/rom-test-main.c index 8c0d4fd3d..8524a852f 100644 --- a/src/platform/test/rom-test-main.c +++ b/src/platform/test/rom-test-main.c @@ -139,7 +139,7 @@ int main(int argc, char * argv[]) { goto loadError; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger debugger; mDebuggerInit(&debugger); bool hasDebugger = mArgumentsApplyDebugger(&args, core, &debugger); @@ -165,7 +165,7 @@ int main(int argc, char * argv[]) { savestate->close(savestate); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (hasDebugger) { do { mDebuggerRun(&debugger); @@ -178,7 +178,7 @@ int main(int argc, char * argv[]) { core->unloadROM(core); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (hasDebugger) { core->detachDebugger(core); mDebuggerDeinit(&debugger); diff --git a/src/script/stdlib.c b/src/script/stdlib.c index 33ec0b751..6e81cfd86 100644 --- a/src/script/stdlib.c +++ b/src/script/stdlib.c @@ -160,7 +160,7 @@ void mScriptContextAttachStdlib(struct mScriptContext* context) { mSCRIPT_KV_SENTINEL }); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mScriptContextExportConstants(context, "WATCHPOINT_TYPE", (struct mScriptKVPair[]) { mSCRIPT_CONSTANT_PAIR(WATCHPOINT, WRITE), mSCRIPT_CONSTANT_PAIR(WATCHPOINT, READ), From 2037e97fc9e4d58ed9565dd4f6b0b25f813841ef Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 22:42:18 +0000 Subject: [PATCH 130/336] Qt: Update translation (Chinese (Simplified)) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/zh_Hans/ --- src/platform/qt/ts/mgba-zh_CN.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index 150ad5404..6992a6280 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -4366,7 +4366,7 @@ Download size: %3 Save games and save states (%1) - ä¿å­˜æ¸¸æˆå’Œå³æ—¶å­˜æ¡£ï¼ˆ%1) + ä¿å­˜æ¸¸æˆå’Œå³æ—¶å­˜æ¡£ (%1) @@ -4376,7 +4376,7 @@ Download size: %3 Save games (%1) - ä¿å­˜æ¸¸æˆï¼ˆ%1) + ä¿å­˜æ¸¸æˆ (%1) @@ -6124,7 +6124,7 @@ Download size: %3 Save games (%1) - ä¿å­˜æ¸¸æˆï¼ˆ%1) + ä¿å­˜æ¸¸æˆ (%1) @@ -6134,7 +6134,7 @@ Download size: %3 mGBA save state files (%1) - mGBA å³æ—¶å­˜æ¡£æ–‡ä»¶ï¼ˆ%1) + mGBA å³æ—¶å­˜æ¡£æ–‡ä»¶ (%1) From 61172d837fc22dfb715f0bb1aec2e41cadb8fd76 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 19:59:11 -0700 Subject: [PATCH 131/336] Core: Fix thread not waking up properly on canceling request --- src/core/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/thread.c b/src/core/thread.c index 43a569d4f..18c1c20e1 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -140,7 +140,7 @@ static void _sendRequest(struct mCoreThreadInternal* threadContext, enum mCoreTh static void _cancelRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) { threadContext->requested &= ~request; _pokeRequest(threadContext); - ConditionWake(&threadContext->stateOffThreadCond); + ConditionWake(&threadContext->stateOnThreadCond); } void _frameStarted(void* context) { From 72202544bb0dcc444a4ef6ff5f52cf22c34f1da4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 9 Apr 2024 00:50:23 -0700 Subject: [PATCH 132/336] Core: Don't trigger watchpoints with access inside of a script (fixes #3050) --- src/core/scripting.c | 104 +++++++++++++++++++++++++++++++++++++- src/core/test/scripting.c | 35 +++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/core/scripting.c b/src/core/scripting.c index 1fd37aeb9..acf324e1f 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -182,6 +182,7 @@ struct mScriptDebugger { struct Table cbidMap; struct Table bpidMap; int64_t nextBreakpoint; + bool reentered; }; #endif @@ -779,6 +780,7 @@ static void _scriptDebuggerInit(struct mDebuggerModule* debugger) { struct mScriptDebugger* scriptDebugger = (struct mScriptDebugger*) debugger; debugger->isPaused = false; debugger->needsCallback = false; + scriptDebugger->reentered = false; HashTableInit(&scriptDebugger->breakpoints, 0, _freeBreakpoint); HashTableInit(&scriptDebugger->cbidMap, 0, NULL); @@ -812,6 +814,11 @@ static void _scriptDebuggerEntered(struct mDebuggerModule* debugger, enum mDebug default: return; } + + if (scriptDebugger->reentered) { + return; + } + _runCallbacks(scriptDebugger, point); debugger->isPaused = false; } @@ -976,18 +983,105 @@ static void _mScriptCoreAdapterSetLuminanceCb(struct mScriptCoreAdapter* adapter adapter->luminanceCb = callback; } +static uint32_t _mScriptCoreAdapterRead8(struct mScriptCoreAdapter* adapter, uint32_t address) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + uint32_t value = adapter->core->busRead8(adapter->core, address); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static uint32_t _mScriptCoreAdapterRead16(struct mScriptCoreAdapter* adapter, uint32_t address) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + uint32_t value = adapter->core->busRead16(adapter->core, address); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static uint32_t _mScriptCoreAdapterRead32(struct mScriptCoreAdapter* adapter, uint32_t address) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + uint32_t value = adapter->core->busRead32(adapter->core, address); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static struct mScriptValue* _mScriptCoreAdapterReadRange(struct mScriptCoreAdapter* adapter, uint32_t address, uint32_t length) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + struct mScriptValue* value = mScriptStringCreateEmpty(length); + char* buffer = value->value.string->buffer; + uint32_t i; + for (i = 0; i < length; ++i, ++address) { + buffer[i] = adapter->core->busRead8(adapter->core, address); + } +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static void _mScriptCoreAdapterWrite8(struct mScriptCoreAdapter* adapter, uint32_t address, uint8_t value) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + adapter->core->busWrite8(adapter->core, address, value); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif +} + +static void _mScriptCoreAdapterWrite16(struct mScriptCoreAdapter* adapter, uint32_t address, uint16_t value) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + adapter->core->busWrite16(adapter->core, address, value); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif +} + +static void _mScriptCoreAdapterWrite32(struct mScriptCoreAdapter* adapter, uint32_t address, uint32_t value) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + adapter->core->busWrite32(adapter->core, address, value); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif +} + mSCRIPT_DECLARE_STRUCT(mScriptCoreAdapter); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, W(mCore), _get, _mScriptCoreAdapterGet, 1, CHARP, name); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, _deinit, _mScriptCoreAdapterDeinit, 0); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, reset, _mScriptCoreAdapterReset, 0); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, WTABLE, setRotationCallbacks, _mScriptCoreAdapterSetRotationCbTable, 1, WTABLE, cbTable); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, setSolarSensorCallback, _mScriptCoreAdapterSetLuminanceCb, 1, WRAPPER, callback); + +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U32, read8, _mScriptCoreAdapterRead8, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U32, read16, _mScriptCoreAdapterRead16, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U32, read32, _mScriptCoreAdapterRead32, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, WSTR, readRange, _mScriptCoreAdapterReadRange, 2, U32, address, U32, length); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write8, _mScriptCoreAdapterWrite8, 2, U32, address, U8, value); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write16, _mScriptCoreAdapterWrite16, 2, U32, address, U16, value); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write32, _mScriptCoreAdapterWrite32, 2, U32, address, U32, value); + #ifdef ENABLE_DEBUGGERS mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setBreakpoint, _mScriptCoreAdapterSetBreakpoint, 3, WRAPPER, callback, U32, address, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setWatchpoint, _mScriptCoreAdapterSetWatchpoint, 4, WRAPPER, callback, U32, address, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setRangeWatchpoint, _mScriptCoreAdapterSetRangeWatchpoint, 5, WRAPPER, callback, U32, minAddress, U32, maxAddress, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, BOOL, clearBreakpoint, _mScriptCoreAdapterClearBreakpoint, 1, S64, cbid); -#endif mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptCoreAdapter, setBreakpoint) mSCRIPT_NO_DEFAULT, @@ -1009,6 +1103,7 @@ mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptCoreAdapter, setRangeWatchpoint) mSCRIPT_NO_DEFAULT, mSCRIPT_S32(-1) mSCRIPT_DEFINE_DEFAULTS_END; +#endif mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) mSCRIPT_DEFINE_CLASS_DOCSTRING( @@ -1040,6 +1135,13 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) "Note that the full range of values is not used by games, and the exact range depends on the calibration done by the game itself." ) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setSolarSensorCallback) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, read8) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, read16) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, read32) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, readRange) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write8) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write16) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write32) #ifdef ENABLE_DEBUGGERS mSCRIPT_DEFINE_DOCSTRING("Set a breakpoint at a given address") mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setBreakpoint) diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index d2f0f0a00..e66f2a722 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -547,6 +547,40 @@ M_TEST_DEFINE(basicWatchpoint) { mDebuggerDeinit(&debugger); } +M_TEST_DEFINE(watchpointReentrant) { + SETUP_LUA; + mScriptContextAttachStdlib(&context); + CREATE_CORE; + struct mDebugger debugger; + core->reset(core); + mScriptContextAttachCore(&context, core); + + mDebuggerInit(&debugger); + mDebuggerAttach(&debugger, core); + + TEST_PROGRAM( + "hit = 0\n" + "function bkpt()\n" + " hit = hit + 1\n" + "end" + ); + struct mScriptValue base = mSCRIPT_MAKE_S32(RAM_BASE); + lua->setGlobal(lua, "base", &base); + TEST_PROGRAM("assert(0 < emu:setWatchpoint(bkpt, base, C.WATCHPOINT_TYPE.READ))"); + + TEST_PROGRAM("hit = 0"); + core->busRead8(core, RAM_BASE); + TEST_PROGRAM("assert(hit == 1)"); + TEST_PROGRAM("emu:read8(base)"); + TEST_PROGRAM("assert(hit == 1)"); + core->busRead8(core, RAM_BASE); + TEST_PROGRAM("assert(hit == 2)"); + + mScriptContextDeinit(&context); + TEARDOWN_CORE; + mDebuggerDeinit(&debugger); +} + M_TEST_DEFINE(removeBreakpoint) { SETUP_LUA; mScriptContextAttachStdlib(&context); @@ -736,6 +770,7 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptCore, #endif cmocka_unit_test(multipleBreakpoint), cmocka_unit_test(basicWatchpoint), + cmocka_unit_test(watchpointReentrant), cmocka_unit_test(removeBreakpoint), cmocka_unit_test(overlappingBreakpoint), cmocka_unit_test(overlappingWatchpoint), From cbd117eb3a9eba367e58b9139f46f29294fe7ebe Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 10 Apr 2024 23:54:40 -0700 Subject: [PATCH 133/336] Util: Start bringing up better audio resampling --- include/mgba-util/interpolator.h | 33 +++++++++++++ src/util/CMakeLists.txt | 1 + src/util/interpolator.c | 83 ++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 include/mgba-util/interpolator.h create mode 100644 src/util/interpolator.c diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h new file mode 100644 index 000000000..4cb7231fd --- /dev/null +++ b/include/mgba-util/interpolator.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef M_INTERPOLATOR_H +#define M_INTERPOLATOR_H + +#include + +struct mSampleBuffer { + int16_t* data; + size_t samples; + int channels; +}; + +struct mInterpolator { + int16_t (*interpolate)(const struct mInterpolator* interp, const struct mSampleBuffer* data, double time, double sampleStep); +}; + +struct mInterpolatorSinc { + struct mInterpolator d; + + unsigned resolution; + unsigned width; + double* sincLut; + double* windowLut; +}; + +void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width); +void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp); + +#endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index eb82215d7..820a178d5 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCE_FILES image.c image/export.c image/png-io.c + interpolator.c patch.c patch-fast.c patch-ips.c diff --git a/src/util/interpolator.c b/src/util/interpolator.c new file mode 100644 index 000000000..2fceee898 --- /dev/null +++ b/src/util/interpolator.c @@ -0,0 +1,83 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +enum { + mSINC_RESOLUTION = 8192, + mSINC_WIDTH = 8, +}; + +static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mSampleBuffer* data, double time, double sampleStep); + +void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { + interp->d.interpolate = mInterpolatorSincInterpolate; + + if (!resolution) { + resolution = mSINC_RESOLUTION; + } + if (!width) { + width = mSINC_WIDTH; + } + unsigned samples = resolution * width; + double dy = M_PI / samples; + double y = dy; + double dx = dy * width; + double x = dx; + + interp->sincLut = calloc(samples + 1, sizeof(double)); + interp->windowLut = calloc(samples + 1, sizeof(double)); + + interp->sincLut[0] = 0; + interp->windowLut[0] = 1; + + unsigned i; + for (i = 1; i <= samples; ++i, x += dx, y += dy) { + interp->sincLut[i] = x < width ? sin(x) / x : 0.0; + // Three term Nuttall window with continuous first derivative + interp->windowLut[i] = 0.40897 + 0.5 * cos(y) + 0.09103 * cos(2 * y); + } +} + +void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp) { + free(interp->sincLut); + free(interp->windowLut); +} + +int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mSampleBuffer* data, double time, double sampleStep) { + struct mInterpolatorSinc* interp = (struct mInterpolatorSinc*) interpolator; + ssize_t index = (ssize_t) time; + double subsample = time - floor(time); + unsigned step = sampleStep > 1 ? interp->resolution * sampleStep : interp->resolution; + unsigned yShift = subsample * step; + unsigned xShift = subsample * interp->resolution; + double sum = 0.0; + double kernelSum = 0.0; + double kernel; + + ssize_t i; + for (i = 1 - (ssize_t) interp->width; i <= (ssize_t) interp->width; ++i) { + unsigned window = i * interp->resolution; + if (yShift > window) { + window = yShift - window; + } else { + window -= yShift; + } + + unsigned sinc = i * step; + if (xShift > sinc) { + sinc = xShift - sinc; + } else { + sinc -= xShift; + } + + kernel = interp->sincLut[sinc] * interp->windowLut[window]; + kernelSum += kernel; + if (index + i >= 0 && index + i < (ssize_t) data->samples) { + sum += data->data[(index + i) * data->channels] * kernel; + } + } + return sum / kernelSum; +} From 2d03ae64ba7b72a2d722cbc90b26b024d7006d02 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 11 Apr 2024 00:47:45 -0700 Subject: [PATCH 134/336] 3DS: Handle audio resampling in DSP --- src/platform/3ds/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 36df49a9c..fb4f63a56 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -343,9 +343,8 @@ static void _gameLoaded(struct mGUIRunner* runner) { } osSetSpeedupEnable(true); - double ratio = GBAAudioCalculateRatio(1, 268111856.f / 4481136.f, 1); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 32768 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 32768 * ratio); + blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 32768); + blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 32768); if (hasSound != NO_SOUND) { audioPos = 0; } @@ -858,7 +857,7 @@ int main(int argc, char* argv[]) { ndspChnReset(0); ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16); ndspChnSetInterp(0, NDSP_INTERP_NONE); - ndspChnSetRate(0, 0x8000); + ndspChnSetRate(0, 32822); ndspChnWaveBufClear(0); audioLeft = linearMemAlign(AUDIO_SAMPLES * DSP_BUFFERS * 2 * sizeof(int16_t), 0x80); memset(dspBuffer, 0, sizeof(dspBuffer)); From a8023e4f6a2614a77d445f03082825346789880e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 11 Apr 2024 20:33:51 -0700 Subject: [PATCH 135/336] Qt: Remove debug message from CMakeLists --- src/platform/qt/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 05f5add0a..673170f0f 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -29,7 +29,6 @@ set(QT_VERSIONS 6 5) foreach(V ${QT_VERSIONS}) set(QT Qt${V}) set(QT_V ${V}) - message("${V} ${QT} ${QT_V}") find_package(${QT} COMPONENTS Core Widgets Network OPTIONAL_COMPONENTS Multimedia) if(QT_V GREATER_EQUAL 6) find_package(${QT} COMPONENTS OpenGL OpenGLWidgets) From bc6a80137fcd96c8f3dcf33284906acf0ae64a2b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 00:46:12 -0700 Subject: [PATCH 136/336] Util: Start adding CircleBuffer tests --- src/util/CMakeLists.txt | 1 + src/util/test/circle-buffer.c | 163 ++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/util/test/circle-buffer.c diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 820a178d5..f0bc85a3d 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -36,6 +36,7 @@ set(GUI_FILES gui/menu.c) set(TEST_FILES + test/circle-buffer.c test/color.c test/geometry.c test/image.c diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c new file mode 100644 index 000000000..ff580e23e --- /dev/null +++ b/src/util/test/circle-buffer.c @@ -0,0 +1,163 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "util/test/suite.h" + +#include + +M_TEST_DEFINE(basicCircle) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i; + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + for (i = 0; i < 63; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } + + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + for (i = 0; i < 63; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } +} + +M_TEST_DEFINE(basicAlignment16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int16_t i; + for (i = 0; i < 29; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + for (i = 0; i < 29; ++i) { + int16_t value; + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } + + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 29; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + for (i = 0; i < 29; ++i) { + int16_t value; + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } +} + + +M_TEST_DEFINE(basicAlignment32) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int32_t i; + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } +} + +M_TEST_DEFINE(capacity) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i; + for (i = 0; i < 64; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + for (i = 0; i < 64; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } + + for (i = 0; i < 64; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + assert_int_equal(CircleBufferWrite8(&buffer, 64), 0); + + for (i = 0; i < 64; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } +} + +M_TEST_DEFINE(overCapacity16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i; + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + assert_int_equal(CircleBufferWrite16(&buffer, 0xFFFF), 0); +} + +M_TEST_SUITE_DEFINE(CircleBuffer, + cmocka_unit_test(basicCircle), + cmocka_unit_test(basicAlignment16), + cmocka_unit_test(basicAlignment32), + cmocka_unit_test(capacity), + cmocka_unit_test(overCapacity16), +) From cecb4543c328b5a8216d9665508946717d48d0f3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 00:54:54 -0700 Subject: [PATCH 137/336] Util: Remember to free memory in tests --- src/util/test/circle-buffer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index ff580e23e..0415f83a1 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -30,6 +30,8 @@ M_TEST_DEFINE(basicCircle) { assert_int_equal(CircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment16) { @@ -59,6 +61,8 @@ M_TEST_DEFINE(basicAlignment16) { assert_int_equal(CircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } @@ -113,6 +117,8 @@ M_TEST_DEFINE(basicAlignment32) { assert_int_equal(CircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } M_TEST_DEFINE(capacity) { @@ -140,6 +146,8 @@ M_TEST_DEFINE(capacity) { assert_int_equal(CircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } M_TEST_DEFINE(overCapacity16) { @@ -152,6 +160,8 @@ M_TEST_DEFINE(overCapacity16) { assert_int_equal(CircleBufferWrite8(&buffer, i), 1); } assert_int_equal(CircleBufferWrite16(&buffer, 0xFFFF), 0); + + CircleBufferDeinit(&buffer); } M_TEST_SUITE_DEFINE(CircleBuffer, From 042a66bb8040a1bb0c15d119130866cb86a1a764 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 20:52:16 -0700 Subject: [PATCH 138/336] Scripting: Fix leak when freeing painters --- src/script/image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/script/image.c b/src/script/image.c index 7705ebd9a..2bd5a8736 100644 --- a/src/script/image.c +++ b/src/script/image.c @@ -131,6 +131,7 @@ static struct mScriptValue* _mScriptPainterGet(struct mScriptPainter* painter, c void _mScriptPainterDeinit(struct mScriptPainter* painter) { mScriptValueDeref(painter->image); + free(painter); } mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mPainter, setBlend, _mPainterSetBlend, 1, BOOL, enable); From 6d2109dd48b784e44e173f84f41cc2cbfe0da045 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 21:27:35 -0700 Subject: [PATCH 139/336] Util: Add offset parameter to CircleBufferDump, more tests --- include/mgba-util/circle-buffer.h | 2 +- src/util/circle-buffer.c | 11 +-- src/util/test/circle-buffer.c | 116 ++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 6 deletions(-) diff --git a/include/mgba-util/circle-buffer.h b/include/mgba-util/circle-buffer.h index dee1f1f2a..995f2f32b 100644 --- a/include/mgba-util/circle-buffer.h +++ b/include/mgba-util/circle-buffer.h @@ -31,7 +31,7 @@ int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value); int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value); int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value); size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length); -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length); +size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset); CXX_GUARD_END diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index c77a71eba..d58ea0c44 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -264,15 +264,16 @@ size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length return length; } -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length) { +size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset) { int8_t* data = buffer->readPtr; - if (buffer->size == 0) { + if (buffer->size <= offset) { return 0; } - if (length > buffer->size) { - length = buffer->size; + if (length > buffer->size - offset) { + length = buffer->size - offset; } - size_t remaining = buffer->capacity - ((int8_t*) data - (int8_t*) buffer->data); + data += offset; + size_t remaining = buffer->capacity - ((uintptr_t) data - (uintptr_t) buffer->data); if (length <= remaining) { memcpy(output, data, length); } else { diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 0415f83a1..1bfb0c111 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -164,10 +164,126 @@ M_TEST_DEFINE(overCapacity16) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(writeLenCapacity) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 48); + assert_memory_equal(data, databuf, 48); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWrite(&buffer, data, 16), 16); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 48); + assert_memory_equal(data, &databuf[48], 16); + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(dumpBasic) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_memory_equal(data, databuf, 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_memory_equal(data, databuf, 48); + assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(CircleBufferSize(&buffer), 32); + assert_memory_equal(data, databuf, 16); + assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 32); + assert_int_equal(CircleBufferSize(&buffer), 32); + assert_memory_equal(&data[16], databuf, 32); + + assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_memory_equal(&data[16], databuf, 32); + assert_memory_equal(data, &databuf[32], 32); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_memory_equal(&data[16], databuf, 32); + assert_memory_equal(data, &databuf[32], 32); + assert_int_equal(CircleBufferSize(&buffer), 0); + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(dumpOffset) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_memory_equal(data, databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_memory_equal(&data[16], databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 16); + assert_memory_equal(&data[32], databuf, 16); + + assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(CircleBufferSize(&buffer), 32); + assert_memory_equal(data, databuf, 16); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_memory_equal(&data[16], databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 16); + assert_memory_equal(&data[32], databuf, 16); + + assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_memory_equal(&data[16], databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_memory_equal(&data[32], databuf, 16); + assert_memory_equal(data, &databuf[16], 16); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 32); + assert_memory_equal(data, databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 48), 16); + assert_memory_equal(&data[16], databuf, 16); + + CircleBufferDeinit(&buffer); +} + M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(basicCircle), cmocka_unit_test(basicAlignment16), cmocka_unit_test(basicAlignment32), cmocka_unit_test(capacity), cmocka_unit_test(overCapacity16), + cmocka_unit_test(writeLenCapacity), + cmocka_unit_test(dumpBasic), + cmocka_unit_test(dumpOffset), ) From c689a7fd48a5f66cc30898d487eafecab9bfc6da Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 21:31:06 -0700 Subject: [PATCH 140/336] Util: Add CircleBufferWriteTruncate --- include/mgba-util/circle-buffer.h | 1 + src/util/circle-buffer.c | 7 +++++++ src/util/test/circle-buffer.c | 27 +++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/include/mgba-util/circle-buffer.h b/include/mgba-util/circle-buffer.h index 995f2f32b..137b6a7f9 100644 --- a/include/mgba-util/circle-buffer.h +++ b/include/mgba-util/circle-buffer.h @@ -27,6 +27,7 @@ int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value); int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value); int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value); size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t length); +size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length); int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value); int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value); int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value); diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index d58ea0c44..12ead5033 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -153,6 +153,13 @@ size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t return length; } +size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length) { + if (buffer->size + length > buffer->capacity) { + length = buffer->capacity - buffer->size; + } + return CircleBufferWrite(buffer, input, length); +} + int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) { int8_t* data = buffer->readPtr; if (buffer->size < sizeof(int8_t)) { diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 1bfb0c111..b60f73a56 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -196,6 +196,32 @@ M_TEST_DEFINE(writeLenCapacity) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(writeTruncate) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 64); + + assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 16); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_memory_equal(data, databuf, 48); + assert_memory_equal(data, &databuf[48], 16); + + CircleBufferDeinit(&buffer); +} + M_TEST_DEFINE(dumpBasic) { struct CircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; @@ -284,6 +310,7 @@ M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(capacity), cmocka_unit_test(overCapacity16), cmocka_unit_test(writeLenCapacity), + cmocka_unit_test(writeTruncate), cmocka_unit_test(dumpBasic), cmocka_unit_test(dumpOffset), ) From ce46b6fe786a3dd31eeae05333b856ba45bebdbd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 22:20:12 -0700 Subject: [PATCH 141/336] Util: Fix overzealous CircleBufferRead/Write16, lots more tests --- src/util/circle-buffer.c | 4 +- src/util/test/circle-buffer.c | 216 +++++++++++++++++++++++++++++++--- 2 files changed, 199 insertions(+), 21 deletions(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 12ead5033..274720661 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -102,7 +102,7 @@ int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { if (buffer->size + sizeof(int16_t) > buffer->capacity) { return 0; } - if ((intptr_t) data & 0x3) { + if ((intptr_t) data & 0x1) { int written = 0; written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); @@ -187,7 +187,7 @@ int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { if (buffer->size < sizeof(int16_t)) { return 0; } - if ((intptr_t) data & 0x3) { + if ((intptr_t) data & 0x1) { int read = 0; read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index b60f73a56..0d8234d0c 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -22,41 +22,36 @@ M_TEST_DEFINE(basicCircle) { assert_int_equal(value, i); } - for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); - } - for (i = 0; i < 63; ++i) { - int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); - assert_int_equal(value, i); - } - CircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment16) { struct CircleBuffer buffer; + int8_t i8; CircleBufferInit(&buffer, 64); + // Aligned buffer int16_t i; - for (i = 0; i < 29; ++i) { + for (i = 0; i < 31; ++i) { assert_int_equal(CircleBufferWrite16(&buffer, i), 2); } - for (i = 0; i < 29; ++i) { + for (i = 0; i < 31; ++i) { int16_t value; assert_int_equal(CircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - int8_t i8; + // Misaligned buffer + CircleBufferClear(&buffer); assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - for (i = 0; i < 29; ++i) { + for (i = 0; i < 31; ++i) { assert_int_equal(CircleBufferWrite16(&buffer, i), 2); } - for (i = 0; i < 29; ++i) { + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 31; ++i) { int16_t value; assert_int_equal(CircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); @@ -65,12 +60,12 @@ M_TEST_DEFINE(basicAlignment16) { CircleBufferDeinit(&buffer); } - M_TEST_DEFINE(basicAlignment32) { struct CircleBuffer buffer; CircleBufferInit(&buffer, 64); + // Aligned buffer int32_t i; for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); @@ -81,37 +76,51 @@ M_TEST_DEFINE(basicAlignment32) { assert_int_equal(value, i); } + // Singly misaligned buffer int8_t i8; assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; assert_int_equal(CircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } + // Doubly misaligned buffer assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { int32_t value; assert_int_equal(CircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } + // Triply misaligned buffer assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 2), 1); for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { int32_t value; assert_int_equal(CircleBufferRead32(&buffer, &value), 4); @@ -150,6 +159,168 @@ M_TEST_DEFINE(capacity) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(overflowWrap8) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t value; + int8_t i; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int16_t value; + int16_t i; + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap16_1) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i8; + int16_t value; + int16_t i; + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32_1) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i8; + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32_2) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int16_t i16; + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead16(&buffer, &i16), 2); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32_3) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i8; + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + M_TEST_DEFINE(overCapacity16) { struct CircleBuffer buffer; @@ -308,6 +479,13 @@ M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(basicAlignment16), cmocka_unit_test(basicAlignment32), cmocka_unit_test(capacity), + cmocka_unit_test(overflowWrap8), + cmocka_unit_test(overflowWrap16), + cmocka_unit_test(overflowWrap16_1), + cmocka_unit_test(overflowWrap32), + cmocka_unit_test(overflowWrap32_1), + cmocka_unit_test(overflowWrap32_2), + cmocka_unit_test(overflowWrap32_3), cmocka_unit_test(overCapacity16), cmocka_unit_test(writeLenCapacity), cmocka_unit_test(writeTruncate), From e8c6613b12276ca439c5a3881f3ae93ab7efd861 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 22:59:08 -0700 Subject: [PATCH 142/336] Util: Fix misaligned end pointer case --- src/util/circle-buffer.c | 8 +- src/util/test/circle-buffer.c | 468 ++++++++++++++++++++++++++++++++++ 2 files changed, 472 insertions(+), 4 deletions(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 274720661..032418e16 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -72,7 +72,7 @@ int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) { if (buffer->size + sizeof(int32_t) > buffer->capacity) { return 0; } - if ((intptr_t) data & 0x3) { + if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int written = 0; written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); @@ -102,7 +102,7 @@ int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { if (buffer->size + sizeof(int16_t) > buffer->capacity) { return 0; } - if ((intptr_t) data & 0x1) { + if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int written = 0; written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); @@ -187,7 +187,7 @@ int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { if (buffer->size < sizeof(int16_t)) { return 0; } - if ((intptr_t) data & 0x1) { + if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int read = 0; read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); @@ -215,7 +215,7 @@ int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) { if (buffer->size < sizeof(int32_t)) { return 0; } - if ((intptr_t) data & 0x3) { + if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int read = 0; read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 0d8234d0c..545b7cffb 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -321,6 +321,470 @@ M_TEST_DEFINE(overflowWrap32_3) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(weirdSize16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 15); + + // Aligned, no overflow wrap + int16_t value; + int16_t i; + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + assert_int_equal(CircleBufferWrite16(&buffer, 7), 0); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + // Misaligned, no overflow wrap + CircleBufferClear(&buffer); + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 6; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + // Misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 6; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(weirdSize32_1) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 13); + + // Aligned, no overflow wrap + int32_t value; + int32_t i; + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Misaligned, no overflow wrap + CircleBufferClear(&buffer); + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(weirdSize32_2) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 14); + + // Aligned, no overflow wrap + int32_t value; + int8_t i8; + int32_t i; + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(weirdSize32_3) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 15); + + // Aligned, no overflow wrap + int32_t value; + int8_t i8; + int32_t i; + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Triply misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Triply misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + CircleBufferDeinit(&buffer); +} + M_TEST_DEFINE(overCapacity16) { struct CircleBuffer buffer; @@ -486,6 +950,10 @@ M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(overflowWrap32_1), cmocka_unit_test(overflowWrap32_2), cmocka_unit_test(overflowWrap32_3), + cmocka_unit_test(weirdSize16), + cmocka_unit_test(weirdSize32_1), + cmocka_unit_test(weirdSize32_2), + cmocka_unit_test(weirdSize32_3), cmocka_unit_test(overCapacity16), cmocka_unit_test(writeLenCapacity), cmocka_unit_test(writeTruncate), From b62ae33f38954df4acfc966117eb6cbc83f5ceb4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 23:17:07 -0700 Subject: [PATCH 143/336] Util: Change mInterpolator data API --- include/mgba-util/interpolator.h | 8 +++----- src/util/interpolator.c | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index 4cb7231fd..43b75da27 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -8,14 +8,12 @@ #include -struct mSampleBuffer { - int16_t* data; - size_t samples; - int channels; +struct mInterpData { + int16_t (*at)(const void* mInterpData, size_t index); }; struct mInterpolator { - int16_t (*interpolate)(const struct mInterpolator* interp, const struct mSampleBuffer* data, double time, double sampleStep); + int16_t (*interpolate)(const struct mInterpolator* interp, const struct mInterpData* data, double time, double sampleStep); }; struct mInterpolatorSinc { diff --git a/src/util/interpolator.c b/src/util/interpolator.c index 2fceee898..a9daaa539 100644 --- a/src/util/interpolator.c +++ b/src/util/interpolator.c @@ -10,7 +10,7 @@ enum { mSINC_WIDTH = 8, }; -static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mSampleBuffer* data, double time, double sampleStep); +static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpData*, double time, double sampleStep); void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { interp->d.interpolate = mInterpolatorSincInterpolate; @@ -46,7 +46,7 @@ void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp) { free(interp->windowLut); } -int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mSampleBuffer* data, double time, double sampleStep) { +int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mInterpData* data, double time, double sampleStep) { struct mInterpolatorSinc* interp = (struct mInterpolatorSinc*) interpolator; ssize_t index = (ssize_t) time; double subsample = time - floor(time); @@ -75,9 +75,7 @@ int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, c kernel = interp->sincLut[sinc] * interp->windowLut[window]; kernelSum += kernel; - if (index + i >= 0 && index + i < (ssize_t) data->samples) { - sum += data->data[(index + i) * data->channels] * kernel; - } + sum += data->at(data, index + i) * kernel; } return sum / kernelSum; } From fd4175ebf85ce589ddd0c6da95b41f8f8cdb7bf2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 23:27:37 -0700 Subject: [PATCH 144/336] Util: Rename CircleBuffer to mCircleBuffer --- include/mgba-util/circle-buffer.h | 32 +- include/mgba-util/vfs.h | 4 +- include/mgba/internal/gba/audio.h | 2 +- src/feature/gui/gui-runner.c | 16 +- src/feature/gui/gui-runner.h | 2 +- src/feature/video-logger.c | 64 +-- src/gba/extra/audio-mixer.c | 14 +- src/platform/psp2/psp2-context.c | 12 +- src/platform/sdl/sdl-events.c | 20 +- src/platform/sdl/sdl-events.h | 4 +- src/util/circle-buffer.c | 60 +-- src/util/patch-ups.c | 28 +- src/util/test/circle-buffer.c | 868 +++++++++++++++--------------- src/util/vfs/vfs-fifo.c | 12 +- 14 files changed, 569 insertions(+), 569 deletions(-) diff --git a/include/mgba-util/circle-buffer.h b/include/mgba-util/circle-buffer.h index 137b6a7f9..c93040c6a 100644 --- a/include/mgba-util/circle-buffer.h +++ b/include/mgba-util/circle-buffer.h @@ -10,7 +10,7 @@ CXX_GUARD_START -struct CircleBuffer { +struct mCircleBuffer { void* data; size_t capacity; size_t size; @@ -18,21 +18,21 @@ struct CircleBuffer { void* writePtr; }; -void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity); -void CircleBufferDeinit(struct CircleBuffer* buffer); -size_t CircleBufferSize(const struct CircleBuffer* buffer); -size_t CircleBufferCapacity(const struct CircleBuffer* buffer); -void CircleBufferClear(struct CircleBuffer* buffer); -int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value); -int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value); -int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value); -size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t length); -size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length); -int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value); -int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value); -int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value); -size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length); -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset); +void mCircleBufferInit(struct mCircleBuffer* buffer, unsigned capacity); +void mCircleBufferDeinit(struct mCircleBuffer* buffer); +size_t mCircleBufferSize(const struct mCircleBuffer* buffer); +size_t mCircleBufferCapacity(const struct mCircleBuffer* buffer); +void mCircleBufferClear(struct mCircleBuffer* buffer); +int mCircleBufferWrite8(struct mCircleBuffer* buffer, int8_t value); +int mCircleBufferWrite16(struct mCircleBuffer* buffer, int16_t value); +int mCircleBufferWrite32(struct mCircleBuffer* buffer, int32_t value); +size_t mCircleBufferWrite(struct mCircleBuffer* buffer, const void* input, size_t length); +size_t mCircleBufferWriteTruncate(struct mCircleBuffer* buffer, const void* input, size_t length); +int mCircleBufferRead8(struct mCircleBuffer* buffer, int8_t* value); +int mCircleBufferRead16(struct mCircleBuffer* buffer, int16_t* value); +int mCircleBufferRead32(struct mCircleBuffer* buffer, int32_t* value); +size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t length); +size_t mCircleBufferDump(const struct mCircleBuffer* buffer, void* output, size_t length, size_t offset); CXX_GUARD_END diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index eee68b99e..b9c4ca6b2 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -73,8 +73,8 @@ struct VFile* VFileFromMemory(void* mem, size_t size); struct VFile* VFileFromConstMemory(const void* mem, size_t size); struct VFile* VFileMemChunk(const void* mem, size_t size); -struct CircleBuffer; -struct VFile* VFileFIFO(struct CircleBuffer* backing); +struct mCircleBuffer; +struct VFile* VFileFIFO(struct mCircleBuffer* backing); struct VDir* VDirOpen(const char* path); struct VDir* VDirOpenArchive(const char* path); diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index 8b212dd6a..f2d878e4e 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -253,7 +253,7 @@ struct GBAMP2kTrack { struct GBAMP2kMusicPlayerTrack track; struct GBAMP2kSoundChannel* channel; uint8_t lastCommand; - struct CircleBuffer buffer; + struct mCircleBuffer buffer; uint32_t samplePlaying; float currentOffset; bool waiting; diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 8c25a79fb..b3ce21ad9 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -220,7 +220,7 @@ void mGUIInit(struct mGUIRunner* runner, const char* port) { runner->fps = 0; runner->lastFpsCheck = 0; runner->totalDelta = 0; - CircleBufferInit(&runner->fpsBuffer, FPS_BUFFER_SIZE * sizeof(uint32_t)); + mCircleBufferInit(&runner->fpsBuffer, FPS_BUFFER_SIZE * sizeof(uint32_t)); mInputMapInit(&runner->params.keyMap, &_mGUIKeyInfo); mCoreConfigInit(&runner->config, runner->port); @@ -284,7 +284,7 @@ void mGUIDeinit(struct mGUIRunner* runner) { if (runner->teardown) { runner->teardown(runner); } - CircleBufferDeinit(&runner->fpsBuffer); + mCircleBufferDeinit(&runner->fpsBuffer); mInputMapDeinit(&runner->params.keyMap); mCoreConfigDeinit(&runner->config); if (logger.vf) { @@ -502,7 +502,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { runner->fps = 0; bool fastForward = false; while (running) { - CircleBufferClear(&runner->fpsBuffer); + mCircleBufferClear(&runner->fpsBuffer); runner->totalDelta = 0; struct timeval tv; gettimeofday(&tv, 0); @@ -610,17 +610,17 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { uint64_t delta = t - runner->lastFpsCheck; runner->lastFpsCheck = t; if (delta > 0x7FFFFFFFLL) { - CircleBufferClear(&runner->fpsBuffer); + mCircleBufferClear(&runner->fpsBuffer); runner->fps = 0; } - if (CircleBufferSize(&runner->fpsBuffer) == CircleBufferCapacity(&runner->fpsBuffer)) { + if (mCircleBufferSize(&runner->fpsBuffer) == mCircleBufferCapacity(&runner->fpsBuffer)) { int32_t last; - CircleBufferRead32(&runner->fpsBuffer, &last); + mCircleBufferRead32(&runner->fpsBuffer, &last); runner->totalDelta -= last; } - CircleBufferWrite32(&runner->fpsBuffer, delta); + mCircleBufferWrite32(&runner->fpsBuffer, delta); runner->totalDelta += delta; - runner->fps = (CircleBufferSize(&runner->fpsBuffer) * FPS_GRANULARITY * 1000000.0f) / (runner->totalDelta * sizeof(uint32_t)); + runner->fps = (mCircleBufferSize(&runner->fpsBuffer) * FPS_GRANULARITY * 1000000.0f) / (runner->totalDelta * sizeof(uint32_t)); } } if (frame % (AUTOSAVE_GRANULARITY * (fastForwarding ? 2 : 1)) == 0) { diff --git a/src/feature/gui/gui-runner.h b/src/feature/gui/gui-runner.h index 0dc412838..334ef57d9 100644 --- a/src/feature/gui/gui-runner.h +++ b/src/feature/gui/gui-runner.h @@ -78,7 +78,7 @@ struct mGUIRunner { float fps; int64_t lastFpsCheck; int32_t totalDelta; - struct CircleBuffer fpsBuffer; + struct mCircleBuffer fpsBuffer; void (*setup)(struct mGUIRunner*); void (*teardown)(struct mGUIRunner*); diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index fb2065b42..978700864 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -87,8 +87,8 @@ struct mVideoLogChannel { enum mVideoLoggerInjectionPoint injectionPoint; uint32_t ignorePackets; - struct CircleBuffer injectedBuffer; - struct CircleBuffer buffer; + struct mCircleBuffer injectedBuffer; + struct mCircleBuffer buffer; }; struct mVideoLogContext { @@ -662,8 +662,8 @@ bool mVideoLogContextLoad(struct mVideoLogContext* context, struct VFile* vf) { size_t i; for (i = 0; i < context->nChannels; ++i) { - CircleBufferInit(&context->channels[i].injectedBuffer, BUFFER_BASE_SIZE); - CircleBufferInit(&context->channels[i].buffer, BUFFER_BASE_SIZE); + mCircleBufferInit(&context->channels[i].injectedBuffer, BUFFER_BASE_SIZE); + mCircleBufferInit(&context->channels[i].buffer, BUFFER_BASE_SIZE); context->channels[i].bufferRemaining = 0; context->channels[i].currentPointer = pointer; context->channels[i].p = context; @@ -676,8 +676,8 @@ bool mVideoLogContextLoad(struct mVideoLogContext* context, struct VFile* vf) { #ifdef USE_ZLIB static void _flushBufferCompressed(struct mVideoLogContext* context) { - struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer; - if (!CircleBufferSize(buffer)) { + struct mCircleBuffer* buffer = &context->channels[context->activeChannel].buffer; + if (!mCircleBufferSize(buffer)) { return; } struct VFile* vfm = VFileMemChunk(NULL, 0); @@ -707,20 +707,20 @@ static void _flushBuffer(struct mVideoLogContext* context) { } #endif - struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer; - if (!CircleBufferSize(buffer)) { + struct mCircleBuffer* buffer = &context->channels[context->activeChannel].buffer; + if (!mCircleBufferSize(buffer)) { return; } struct mVLBlockHeader header = { 0 }; STORE_32LE(mVL_BLOCK_DATA, 0, &header.blockType); - STORE_32LE(CircleBufferSize(buffer), 0, &header.length); + STORE_32LE(mCircleBufferSize(buffer), 0, &header.length); STORE_32LE(context->activeChannel, 0, &header.channelId); context->backing->write(context->backing, &header, sizeof(header)); uint8_t writeBuffer[0x800]; - while (CircleBufferSize(buffer)) { - size_t read = CircleBufferRead(buffer, writeBuffer, sizeof(writeBuffer)); + while (mCircleBufferSize(buffer)) { + size_t read = mCircleBufferRead(buffer, writeBuffer, sizeof(writeBuffer)); context->backing->write(context->backing, writeBuffer, read); } } @@ -743,8 +743,8 @@ void mVideoLogContextDestroy(struct mCore* core, struct mVideoLogContext* contex size_t i; for (i = 0; i < context->nChannels; ++i) { - CircleBufferDeinit(&context->channels[i].injectedBuffer); - CircleBufferDeinit(&context->channels[i].buffer); + mCircleBufferDeinit(&context->channels[i].injectedBuffer); + mCircleBufferDeinit(&context->channels[i].buffer); #ifdef USE_ZLIB if (context->channels[i].inflating) { inflateEnd(&context->channels[i].inflateStream); @@ -778,8 +778,8 @@ void mVideoLogContextRewind(struct mVideoLogContext* context, struct mCore* core size_t i; for (i = 0; i < context->nChannels; ++i) { - CircleBufferClear(&context->channels[i].injectedBuffer); - CircleBufferClear(&context->channels[i].buffer); + mCircleBufferClear(&context->channels[i].injectedBuffer); + mCircleBufferClear(&context->channels[i].buffer); context->channels[i].bufferRemaining = 0; context->channels[i].currentPointer = pointer; #ifdef USE_ZLIB @@ -805,8 +805,8 @@ int mVideoLoggerAddChannel(struct mVideoLogContext* context) { int chid = context->nChannels; ++context->nChannels; context->channels[chid].p = context; - CircleBufferInit(&context->channels[chid].injectedBuffer, BUFFER_BASE_SIZE); - CircleBufferInit(&context->channels[chid].buffer, BUFFER_BASE_SIZE); + mCircleBufferInit(&context->channels[chid].injectedBuffer, BUFFER_BASE_SIZE); + mCircleBufferInit(&context->channels[chid].buffer, BUFFER_BASE_SIZE); context->channels[chid].injecting = false; context->channels[chid].injectionPoint = LOGGER_INJECTION_IMMEDIATE; context->channels[chid].ignorePackets = 0; @@ -898,7 +898,7 @@ static size_t _readBufferCompressed(struct VFile* vf, struct mVideoLogChannel* c } } - thisWrite = CircleBufferWrite(&channel->buffer, zbuffer, thisWrite - channel->inflateStream.avail_out); + thisWrite = mCircleBufferWrite(&channel->buffer, zbuffer, thisWrite - channel->inflateStream.avail_out); length -= thisWrite; read += thisWrite; @@ -921,7 +921,7 @@ static void _readBuffer(struct VFile* vf, struct mVideoLogChannel* channel, size if (thisRead <= 0) { return; } - size_t thisWrite = CircleBufferWrite(&channel->buffer, buffer, thisRead); + size_t thisWrite = mCircleBufferWrite(&channel->buffer, buffer, thisRead); length -= thisWrite; channel->bufferRemaining -= thisWrite; channel->currentPointer += thisWrite; @@ -986,16 +986,16 @@ static ssize_t mVideoLoggerReadChannel(struct mVideoLogChannel* channel, void* d if (channelId >= mVL_MAX_CHANNELS) { return 0; } - struct CircleBuffer* buffer = &channel->buffer; + struct mCircleBuffer* buffer = &channel->buffer; if (channel->injecting) { buffer = &channel->injectedBuffer; } - if (CircleBufferSize(buffer) >= length) { - return CircleBufferRead(buffer, data, length); + if (mCircleBufferSize(buffer) >= length) { + return mCircleBufferRead(buffer, data, length); } ssize_t size = 0; - if (CircleBufferSize(buffer)) { - size = CircleBufferRead(buffer, data, CircleBufferSize(buffer)); + if (mCircleBufferSize(buffer)) { + size = mCircleBufferRead(buffer, data, mCircleBufferSize(buffer)); if (size <= 0) { return size; } @@ -1005,7 +1005,7 @@ static ssize_t mVideoLoggerReadChannel(struct mVideoLogChannel* channel, void* d if (channel->injecting || !_fillBuffer(context, channelId, BUFFER_BASE_SIZE)) { return size; } - size += CircleBufferRead(buffer, data, length); + size += mCircleBufferRead(buffer, data, length); return size; } @@ -1019,20 +1019,20 @@ static ssize_t mVideoLoggerWriteChannel(struct mVideoLogChannel* channel, const _flushBuffer(context); context->activeChannel = channelId; } - struct CircleBuffer* buffer = &channel->buffer; + struct mCircleBuffer* buffer = &channel->buffer; if (channel->injecting) { buffer = &channel->injectedBuffer; } - if (CircleBufferCapacity(buffer) - CircleBufferSize(buffer) < length) { + if (mCircleBufferCapacity(buffer) - mCircleBufferSize(buffer) < length) { _flushBuffer(context); - if (CircleBufferCapacity(buffer) < length) { - CircleBufferDeinit(buffer); - CircleBufferInit(buffer, toPow2(length << 1)); + if (mCircleBufferCapacity(buffer) < length) { + mCircleBufferDeinit(buffer); + mCircleBufferInit(buffer, toPow2(length << 1)); } } - ssize_t read = CircleBufferWrite(buffer, data, length); - if (CircleBufferCapacity(buffer) == CircleBufferSize(buffer)) { + ssize_t read = mCircleBufferWrite(buffer, data, length); + if (mCircleBufferCapacity(buffer) == mCircleBufferSize(buffer)) { _flushBuffer(context); } return read; diff --git a/src/gba/extra/audio-mixer.c b/src/gba/extra/audio-mixer.c index 2a14f1ce6..e01b609b4 100644 --- a/src/gba/extra/audio-mixer.c +++ b/src/gba/extra/audio-mixer.c @@ -43,7 +43,7 @@ void _mp2kInit(void* cpu, struct mCPUComponent* component) { size_t i; for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { mixer->activeTracks[i].channel = &mixer->context.chans[i]; - CircleBufferInit(&mixer->activeTracks[i].buffer, 0x10000); + mCircleBufferInit(&mixer->activeTracks[i].buffer, 0x10000); } } @@ -51,7 +51,7 @@ void _mp2kDeinit(struct mCPUComponent* component) { struct GBAAudioMixer* mixer = (struct GBAAudioMixer*) component; size_t i; for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { - CircleBufferDeinit(&mixer->activeTracks[i].buffer); + mCircleBufferDeinit(&mixer->activeTracks[i].buffer); } } @@ -130,8 +130,8 @@ static void _stepSample(struct GBAAudioMixer* mixer, struct GBAMP2kTrack* track) (sample * track->channel->rightVolume * track->channel->envelopeV) >> 9 }; - CircleBufferWrite16(&track->buffer, stereo.left); - CircleBufferWrite16(&track->buffer, stereo.right); + mCircleBufferWrite16(&track->buffer, stereo.left); + mCircleBufferWrite16(&track->buffer, stereo.right); sampleOffset += mixer->p->sampleInterval / OVERSAMPLE; while (sampleOffset > freq) { @@ -265,7 +265,7 @@ void _mp2kStep(struct GBAAudioMixer* mixer) { } else { track->currentOffset = 0; track->samplePlaying = 0; - CircleBufferClear(&track->buffer); + mCircleBufferClear(&track->buffer); } } mixer->frame -= VIDEO_TOTAL_LENGTH / mixer->tempo; @@ -281,9 +281,9 @@ void _mp2kStep(struct GBAAudioMixer* mixer) { continue; } int16_t value; - CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); + mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); sample.left += value; - CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); + mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); sample.right += value; } sample.left = (sample.left * mixer->p->masterVolume) >> 8; diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 1e48c2f24..34623a876 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -65,7 +65,7 @@ static struct mSceRotationSource { static struct mSceRumble { struct mRumble d; - struct CircleBuffer history; + struct mCircleBuffer history; int current; } rumble; @@ -155,12 +155,12 @@ static int32_t _readGyroZ(struct mRotationSource* source) { static void _setRumble(struct mRumble* source, int enable) { struct mSceRumble* rumble = (struct mSceRumble*) source; rumble->current += enable; - if (CircleBufferSize(&rumble->history) == RUMBLE_PWM) { + if (mCircleBufferSize(&rumble->history) == RUMBLE_PWM) { int8_t oldLevel; - CircleBufferRead8(&rumble->history, &oldLevel); + mCircleBufferRead8(&rumble->history, &oldLevel); rumble->current -= oldLevel; } - CircleBufferWrite8(&rumble->history, enable); + mCircleBufferWrite8(&rumble->history, enable); int small = (rumble->current << 21) / 65793; int big = ((rumble->current * rumble->current) << 18) / 65793; struct SceCtrlActuator state = { @@ -342,7 +342,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation.d); rumble.d.setRumble = _setRumble; - CircleBufferInit(&rumble.history, RUMBLE_PWM); + mCircleBufferInit(&rumble.history, RUMBLE_PWM); runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); camera.d.startRequestImage = _startRequestImage; @@ -482,7 +482,7 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { void mPSP2Teardown(struct mGUIRunner* runner) { UNUSED(runner); - CircleBufferDeinit(&rumble.history); + mCircleBufferDeinit(&rumble.history); vita2d_free_texture(tex[0]); vita2d_free_texture(tex[1]); vita2d_free_texture(screenshot); diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index eceaf1808..950bb94f3 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -202,7 +202,7 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { #if SDL_VERSION_ATLEAST(2, 0, 0) player->rumble.d.setRumble = _mSDLSetRumble; - CircleBufferInit(&player->rumble.history, RUMBLE_PWM); + mCircleBufferInit(&player->rumble.history, RUMBLE_PWM); player->rumble.level = 0; player->rumble.activeLevel = 0; player->rumble.p = player; @@ -219,7 +219,7 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { player->rotation.gyroY = 1; player->rotation.gyroZ = -1; player->rotation.zDelta = 0; - CircleBufferInit(&player->rotation.zHistory, sizeof(float) * GYRO_STEPS); + mCircleBufferInit(&player->rotation.zHistory, sizeof(float) * GYRO_STEPS); player->rotation.p = player; player->playerId = events->playersAttached; @@ -293,9 +293,9 @@ void mSDLDetachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { } } --events->playersAttached; - CircleBufferDeinit(&player->rotation.zHistory); + mCircleBufferDeinit(&player->rotation.zHistory); #if SDL_VERSION_ATLEAST(2, 0, 0) - CircleBufferDeinit(&player->rumble.history); + mCircleBufferDeinit(&player->rumble.history); #endif } @@ -739,12 +739,12 @@ static void _mSDLSetRumble(struct mRumble* rumble, int enable) { int8_t originalLevel = sdlRumble->level; sdlRumble->level += enable; - if (CircleBufferSize(&sdlRumble->history) == RUMBLE_PWM) { + if (mCircleBufferSize(&sdlRumble->history) == RUMBLE_PWM) { int8_t oldLevel; - CircleBufferRead8(&sdlRumble->history, &oldLevel); + mCircleBufferRead8(&sdlRumble->history, &oldLevel); sdlRumble->level -= oldLevel; } - CircleBufferWrite8(&sdlRumble->history, enable); + mCircleBufferWrite8(&sdlRumble->history, enable); if (sdlRumble->level == originalLevel) { return; } @@ -851,10 +851,10 @@ static void _mSDLRotationSample(struct mRotationSource* source) { rotation->oldY = y; float oldZ = 0; - if (CircleBufferSize(&rotation->zHistory) == GYRO_STEPS * sizeof(float)) { - CircleBufferRead32(&rotation->zHistory, (int32_t*) &oldZ); + if (mCircleBufferSize(&rotation->zHistory) == GYRO_STEPS * sizeof(float)) { + mCircleBufferRead32(&rotation->zHistory, (int32_t*) &oldZ); } - CircleBufferWrite32(&rotation->zHistory, theta.i); + mCircleBufferWrite32(&rotation->zHistory, theta.i); rotation->zDelta += theta.f - oldZ; } diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index 741503be4..877818a01 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -76,7 +76,7 @@ struct mSDLPlayer { int level; float activeLevel; - struct CircleBuffer history; + struct mCircleBuffer history; } rumble; #else int newWidth; @@ -98,7 +98,7 @@ struct mSDLPlayer { int gyroY; int gyroZ; float gyroSensitivity; - struct CircleBuffer zHistory; + struct mCircleBuffer zHistory; int oldX; int oldY; float zDelta; diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 032418e16..f0d074d36 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -6,7 +6,7 @@ #include #ifndef NDEBUG -static int _checkIntegrity(struct CircleBuffer* buffer) { +static int _checkIntegrity(struct mCircleBuffer* buffer) { if ((int8_t*) buffer->writePtr - (int8_t*) buffer->readPtr == (ssize_t) buffer->size) { return 1; } @@ -20,32 +20,32 @@ static int _checkIntegrity(struct CircleBuffer* buffer) { } #endif -void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) { +void mCircleBufferInit(struct mCircleBuffer* buffer, unsigned capacity) { buffer->data = malloc(capacity); buffer->capacity = capacity; - CircleBufferClear(buffer); + mCircleBufferClear(buffer); } -void CircleBufferDeinit(struct CircleBuffer* buffer) { +void mCircleBufferDeinit(struct mCircleBuffer* buffer) { free(buffer->data); buffer->data = 0; } -size_t CircleBufferSize(const struct CircleBuffer* buffer) { +size_t mCircleBufferSize(const struct mCircleBuffer* buffer) { return buffer->size; } -size_t CircleBufferCapacity(const struct CircleBuffer* buffer) { +size_t mCircleBufferCapacity(const struct mCircleBuffer* buffer) { return buffer->capacity; } -void CircleBufferClear(struct CircleBuffer* buffer) { +void mCircleBufferClear(struct mCircleBuffer* buffer) { buffer->size = 0; buffer->readPtr = buffer->data; buffer->writePtr = buffer->data; } -int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) { +int mCircleBufferWrite8(struct mCircleBuffer* buffer, int8_t value) { int8_t* data = buffer->writePtr; if (buffer->size + sizeof(int8_t) > buffer->capacity) { return 0; @@ -67,17 +67,17 @@ int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) { return 1; } -int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) { +int mCircleBufferWrite32(struct mCircleBuffer* buffer, int32_t value) { int32_t* data = buffer->writePtr; if (buffer->size + sizeof(int32_t) > buffer->capacity) { return 0; } if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int written = 0; - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[2]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[3]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[0]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[1]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[2]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[3]); return written; } *data = value; @@ -97,15 +97,15 @@ int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) { return 4; } -int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { +int mCircleBufferWrite16(struct mCircleBuffer* buffer, int16_t value) { int16_t* data = buffer->writePtr; if (buffer->size + sizeof(int16_t) > buffer->capacity) { return 0; } if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int written = 0; - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[0]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[1]); return written; } *data = value; @@ -125,7 +125,7 @@ int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { return 2; } -size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t length) { +size_t mCircleBufferWrite(struct mCircleBuffer* buffer, const void* input, size_t length) { int8_t* data = buffer->writePtr; if (buffer->size + length > buffer->capacity) { return 0; @@ -153,14 +153,14 @@ size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t return length; } -size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length) { +size_t mCircleBufferWriteTruncate(struct mCircleBuffer* buffer, const void* input, size_t length) { if (buffer->size + length > buffer->capacity) { length = buffer->capacity - buffer->size; } - return CircleBufferWrite(buffer, input, length); + return mCircleBufferWrite(buffer, input, length); } -int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) { +int mCircleBufferRead8(struct mCircleBuffer* buffer, int8_t* value) { int8_t* data = buffer->readPtr; if (buffer->size < sizeof(int8_t)) { return 0; @@ -182,15 +182,15 @@ int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) { return 1; } -int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { +int mCircleBufferRead16(struct mCircleBuffer* buffer, int16_t* value) { int16_t* data = buffer->readPtr; if (buffer->size < sizeof(int16_t)) { return 0; } if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int read = 0; - read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[0]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[1]); return read; } *value = *data; @@ -210,17 +210,17 @@ int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { return 2; } -int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) { +int mCircleBufferRead32(struct mCircleBuffer* buffer, int32_t* value) { int32_t* data = buffer->readPtr; if (buffer->size < sizeof(int32_t)) { return 0; } if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int read = 0; - read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[2]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[3]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[0]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[1]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[2]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[3]); return read; } *value = *data; @@ -240,7 +240,7 @@ int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) { return 4; } -size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) { +size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t length) { int8_t* data = buffer->readPtr; if (buffer->size == 0) { return 0; @@ -271,7 +271,7 @@ size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length return length; } -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset) { +size_t mCircleBufferDump(const struct mCircleBuffer* buffer, void* output, size_t length, size_t offset) { int8_t* data = buffer->readPtr; if (buffer->size <= offset) { return 0; diff --git a/src/util/patch-ups.c b/src/util/patch-ups.c index bce88e74d..72d0e14a8 100644 --- a/src/util/patch-ups.c +++ b/src/util/patch-ups.c @@ -23,7 +23,7 @@ static size_t _UPSOutputSize(struct Patch* patch, size_t inSize); static bool _UPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* out, size_t outSize); static bool _BPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* out, size_t outSize); -static size_t _decodeLength(struct VFile* vf, struct CircleBuffer* buffer); +static size_t _decodeLength(struct VFile* vf, struct mCircleBuffer* buffer); bool loadPatchUPS(struct Patch* patch) { patch->vf->seek(patch->vf, 0, SEEK_SET); @@ -77,42 +77,42 @@ bool _UPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* ou return false; } - struct CircleBuffer buffer; + struct mCircleBuffer buffer; memcpy(out, in, inSize > outSize ? outSize : inSize); size_t offset = 0; size_t alreadyRead = 0; uint8_t* buf = out; - CircleBufferInit(&buffer, BUFFER_SIZE); + mCircleBufferInit(&buffer, BUFFER_SIZE); while (alreadyRead < filesize + IN_CHECKSUM) { offset += _decodeLength(patch->vf, &buffer); int8_t byte; while (true) { - if (!CircleBufferSize(&buffer)) { + if (!mCircleBufferSize(&buffer)) { uint8_t block[BUFFER_SIZE]; ssize_t read = patch->vf->read(patch->vf, block, sizeof(block)); if (read < 1) { - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); return false; } - CircleBufferWrite(&buffer, block, read); + mCircleBufferWrite(&buffer, block, read); } - CircleBufferRead8(&buffer, &byte); + mCircleBufferRead8(&buffer, &byte); if (!byte) { break; } if (offset >= outSize) { - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); return false; } buf[offset] ^= byte; ++offset; } ++offset; - alreadyRead = patch->vf->seek(patch->vf, 0, SEEK_CUR) - CircleBufferSize(&buffer); + alreadyRead = patch->vf->seek(patch->vf, 0, SEEK_CUR) - mCircleBufferSize(&buffer); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); uint32_t goodCrc32; patch->vf->seek(patch->vf, OUT_CHECKSUM, SEEK_END); @@ -223,21 +223,21 @@ bool _BPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* ou return true; } -size_t _decodeLength(struct VFile* vf, struct CircleBuffer* buffer) { +size_t _decodeLength(struct VFile* vf, struct mCircleBuffer* buffer) { size_t shift = 1; size_t value = 0; uint8_t byte; while (true) { if (buffer) { - if (!CircleBufferSize(buffer)) { + if (!mCircleBufferSize(buffer)) { uint8_t block[BUFFER_SIZE]; ssize_t read = vf->read(vf, block, sizeof(block)); if (read < 1) { return false; } - CircleBufferWrite(buffer, block, read); + mCircleBufferWrite(buffer, block, read); } - CircleBufferRead8(buffer, (int8_t*) &byte); + mCircleBufferRead8(buffer, (int8_t*) &byte); } else { if (vf->read(vf, &byte, 1) != 1) { break; diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 545b7cffb..9ba383971 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -8,937 +8,937 @@ #include M_TEST_DEFINE(basicCircle) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i; for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } for (i = 0; i < 63; ++i) { int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; int8_t i8; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); // Aligned buffer int16_t i; for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } for (i = 0; i < 31; ++i) { int16_t value; - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } // Misaligned buffer - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 31; ++i) { int16_t value; - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment32) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); // Aligned buffer int32_t i; for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } // Singly misaligned buffer int8_t i8; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } // Doubly misaligned buffer - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 1), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } // Triply misaligned buffer - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 2), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 1), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 2), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(capacity) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i; for (i = 0; i < 64; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } for (i = 0; i < 64; ++i) { int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } for (i = 0; i < 64; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } - assert_int_equal(CircleBufferWrite8(&buffer, 64), 0); + assert_int_equal(mCircleBufferWrite8(&buffer, 64), 0); for (i = 0; i < 64; ++i) { int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap8) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t value; int8_t i; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int16_t value; int16_t i; - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap16_1) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i8; int16_t value; int16_t i; - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32_1) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i8; int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32_2) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int16_t i16; int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead16(&buffer, &i16), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &i16), 2); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32_3) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i8; int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 15); + mCircleBufferInit(&buffer, 15); // Aligned, no overflow wrap int16_t value; int16_t i; for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferWrite16(&buffer, 7), 0); + assert_int_equal(mCircleBufferWrite16(&buffer, 7), 0); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } // Misaligned, no overflow wrap - CircleBufferClear(&buffer); + mCircleBufferClear(&buffer); int8_t i8; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 6; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 2); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } // Misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 6; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 2); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize32_1) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 13); + mCircleBufferInit(&buffer, 13); // Aligned, no overflow wrap int32_t value; int32_t i; for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + assert_int_equal(mCircleBufferWrite32(&buffer, 3), 0); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Misaligned, no overflow wrap - CircleBufferClear(&buffer); + mCircleBufferClear(&buffer); int8_t i8; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize32_2) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 14); + mCircleBufferInit(&buffer, 14); // Aligned, no overflow wrap int32_t value; int8_t i8; int32_t i; for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + assert_int_equal(mCircleBufferWrite32(&buffer, 3), 0); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize32_3) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 15); + mCircleBufferInit(&buffer, 15); // Aligned, no overflow wrap int32_t value; int8_t i8; int32_t i; for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + assert_int_equal(mCircleBufferWrite32(&buffer, 3), 0); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Triply misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Triply misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overCapacity16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i; for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } - assert_int_equal(CircleBufferWrite16(&buffer, 0xFFFF), 0); + assert_int_equal(mCircleBufferWrite16(&buffer, 0xFFFF), 0); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(writeLenCapacity) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 48); assert_memory_equal(data, databuf, 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 16), 16); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 48); assert_memory_equal(data, &databuf[48], 16); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(writeTruncate) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferWriteTruncate(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 16); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferWriteTruncate(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWriteTruncate(&buffer, data, 48), 16); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); assert_memory_equal(data, databuf, 48); assert_memory_equal(data, &databuf[48], 16); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(dumpBasic) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 48, 0), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); assert_memory_equal(data, databuf, 48); - assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); - assert_int_equal(CircleBufferSize(&buffer), 32); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 32); assert_memory_equal(data, databuf, 16); - assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 32); - assert_int_equal(CircleBufferSize(&buffer), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 48, 0), 32); + assert_int_equal(mCircleBufferSize(&buffer), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); assert_memory_equal(&data[16], databuf, 32); assert_memory_equal(data, &databuf[32], 32); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); assert_memory_equal(&data[16], databuf, 32); assert_memory_equal(data, &databuf[32], 32); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferSize(&buffer), 0); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(dumpOffset) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 0), 32); assert_memory_equal(data, databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 16), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 16); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 32), 16); assert_memory_equal(&data[32], databuf, 16); - assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); - assert_int_equal(CircleBufferSize(&buffer), 32); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 32); assert_memory_equal(data, databuf, 16); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 0), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 16); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 16), 16); assert_memory_equal(&data[32], databuf, 16); - assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_int_equal(mCircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 0), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 16), 32); assert_memory_equal(&data[32], databuf, 16); assert_memory_equal(data, &databuf[16], 16); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 32), 32); assert_memory_equal(data, databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 48), 16); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 48), 16); assert_memory_equal(&data[16], databuf, 16); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } -M_TEST_SUITE_DEFINE(CircleBuffer, +M_TEST_SUITE_DEFINE(mCircleBuffer, cmocka_unit_test(basicCircle), cmocka_unit_test(basicAlignment16), cmocka_unit_test(basicAlignment32), diff --git a/src/util/vfs/vfs-fifo.c b/src/util/vfs/vfs-fifo.c index 5b6af5760..c7bb5be04 100644 --- a/src/util/vfs/vfs-fifo.c +++ b/src/util/vfs/vfs-fifo.c @@ -8,7 +8,7 @@ struct VFileFIFO { struct VFile d; - struct CircleBuffer* backing; + struct mCircleBuffer* backing; }; static bool _vffClose(struct VFile* vf); @@ -21,7 +21,7 @@ static void _vffTruncate(struct VFile* vf, size_t size); static ssize_t _vffSize(struct VFile* vf); static bool _vffSync(struct VFile* vf, void* buffer, size_t size); -struct VFile* VFileFIFO(struct CircleBuffer* backing) { +struct VFile* VFileFIFO(struct mCircleBuffer* backing) { if (!backing) { return NULL; } @@ -61,12 +61,12 @@ static off_t _vffSeek(struct VFile* vf, off_t offset, int whence) { static ssize_t _vffRead(struct VFile* vf, void* buffer, size_t size) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; - return CircleBufferRead(vff->backing, buffer, size); + return mCircleBufferRead(vff->backing, buffer, size); } static ssize_t _vffWrite(struct VFile* vf, const void* buffer, size_t size) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; - return CircleBufferWrite(vff->backing, buffer, size); + return mCircleBufferWrite(vff->backing, buffer, size); } static void* _vffMap(struct VFile* vf, size_t size, int flags) { @@ -85,13 +85,13 @@ static void _vffUnmap(struct VFile* vf, void* memory, size_t size) { static void _vffTruncate(struct VFile* vf, size_t size) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; if (!size) { - CircleBufferClear(vff->backing); + mCircleBufferClear(vff->backing); } } static ssize_t _vffSize(struct VFile* vf) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; - return CircleBufferSize(vff->backing); + return mCircleBufferSize(vff->backing); } static bool _vffSync(struct VFile* vf, void* buffer, size_t size) { From 237d502404632de326c9c467f8a2c691f89f25c2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 13 Apr 2024 00:48:37 -0700 Subject: [PATCH 145/336] Util: Add prototype mAudioBuffer wrapper --- include/mgba-util/audio-buffer.h | 34 ++++++++++++++++++ src/util/audio-buffer.c | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 include/mgba-util/audio-buffer.h create mode 100644 src/util/audio-buffer.c diff --git a/include/mgba-util/audio-buffer.h b/include/mgba-util/audio-buffer.h new file mode 100644 index 000000000..b6d760822 --- /dev/null +++ b/include/mgba-util/audio-buffer.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef M_AUDIO_BUFFER_H +#define M_AUDIO_BUFFER_H + +#include + +CXX_GUARD_START + +#include + +struct mAudioBuffer { + struct mCircleBuffer data; + unsigned channels; +}; + +void mAudioBufferInit(struct mAudioBuffer* buffer, size_t capacity, unsigned channels); +void mAudioBufferDeinit(struct mAudioBuffer* buffer); + +size_t mAudioBufferAvailable(const struct mAudioBuffer* buffer); +size_t mAudioBufferCapacity(const struct mAudioBuffer* buffer); + +void mAudioBufferClear(struct mAudioBuffer* buffer); +int16_t mAudioBufferPeek(const struct mAudioBuffer* buffer, unsigned channel, size_t offset); +size_t mAudioBufferDump(const struct mAudioBuffer* buffer, int16_t* samples, size_t count, size_t offset); +size_t mAudioBufferRead(struct mAudioBuffer* buffer, int16_t* samples, size_t count); +size_t mAudioBufferWrite(struct mAudioBuffer* buffer, const int16_t* samples, size_t count); + +CXX_GUARD_END + +#endif diff --git a/src/util/audio-buffer.c b/src/util/audio-buffer.c new file mode 100644 index 000000000..bb705b38c --- /dev/null +++ b/src/util/audio-buffer.c @@ -0,0 +1,59 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +#include + +void mAudioBufferInit(struct mAudioBuffer* buffer, size_t capacity, unsigned channels) { + mCircleBufferInit(&buffer->data, capacity * channels * sizeof(int16_t)); + buffer->channels = capacity; +} + +void mAudioBufferDeinit(struct mAudioBuffer* buffer) { + mCircleBufferDeinit(&buffer->data); +} + +size_t mAudioBufferAvailable(const struct mAudioBuffer* buffer) { + return mCircleBufferSize(&buffer->data) / (buffer->channels * sizeof(int16_t)); +} + +size_t mAudioBufferCapacity(const struct mAudioBuffer* buffer) { + return mCircleBufferCapacity(&buffer->data) / (buffer->channels * sizeof(int16_t)); +} + +void mAudioBufferClear(struct mAudioBuffer* buffer) { + mCircleBufferClear(&buffer->data); +} + +int16_t mAudioBufferPeek(const struct mAudioBuffer* buffer, unsigned channel, size_t offset) { + int16_t sample; + if (!mCircleBufferDump(&buffer->data, &sample, sizeof(int16_t), (offset * buffer->channels + channel) * sizeof(int16_t))) { + return 0; + } + return sample; +} + +size_t mAudioBufferDump(const struct mAudioBuffer* buffer, int16_t* samples, size_t count, size_t offset) { + return mCircleBufferDump(&buffer->data, + samples, + count * buffer->channels * sizeof(int16_t), + offset * buffer->channels * sizeof(int16_t)) / + (buffer->channels * sizeof(int16_t)); +} + +size_t mAudioBufferRead(struct mAudioBuffer* buffer, int16_t* samples, size_t count) { + return mCircleBufferRead(&buffer->data, samples, count * buffer->channels * sizeof(int16_t)) / + (buffer->channels * sizeof(int16_t)); +} + +size_t mAudioBufferWrite(struct mAudioBuffer* buffer, const int16_t* samples, size_t count) { + size_t free = mCircleBufferCapacity(&buffer->data) - mCircleBufferSize(&buffer->data); + if (count * buffer->channels * sizeof(int16_t) > free) { + count = free / (buffer->channels * sizeof(int16_t)); + } + return mCircleBufferWrite(&buffer->data, samples, count * buffer->channels * sizeof(int16_t)) / + (buffer->channels * sizeof(int16_t)); +} From f13a087b040e07a41f0ce61d5b5b0b1ab581e67b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 04:17:15 -0700 Subject: [PATCH 146/336] Feature: Fix (unused) mVideoProxyBackendRun with block=true --- src/feature/proxy-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/feature/proxy-backend.c b/src/feature/proxy-backend.c index fb6e555ed..3cfe7c39d 100644 --- a/src/feature/proxy-backend.c +++ b/src/feature/proxy-backend.c @@ -229,7 +229,7 @@ bool mVideoProxyBackendRun(struct mVideoProxyBackend* proxy, bool block) { } ok = true; } - } while (block); + } while (block && !ok); return ok; } From 2d7000c8ae4cf0c7da4d283fe1f711290f2847ab Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 04:18:43 -0700 Subject: [PATCH 147/336] Util: Remove unreachable code --- src/util/string.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/util/string.c b/src/util/string.c index b2bf376c6..4a9e35de5 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -285,9 +285,6 @@ char* latin1ToUtf8(const char* latin1, size_t length) { size_t utf8TotalBytes = 0; size_t utf8Length = 0; for (offset = 0; offset < length; ++offset) { - if (length == 0) { - break; - } uint8_t unichar = latin1[offset]; size_t bytes = toUtf8(unichar, buffer); utf8Length += bytes; From a999a8760733cd226741d5e9cc05557aeda3eee3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 04:22:40 -0700 Subject: [PATCH 148/336] Debugger: Actually handle parseLexedExpression returning false --- src/debugger/cli-debugger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 6d5b70e97..95b2037dc 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -615,7 +615,7 @@ static struct ParseTree* _parseTree(const char** string) { struct ParseTree* tree = NULL; if (!error) { tree = parseTreeCreate(); - parseLexedExpression(tree, &lv); + error = !parseLexedExpression(tree, &lv); } lexFree(&lv); LexVectorClear(&lv); From e8e6b803f25d0a873bcce75d71c4ff40ef4371ae Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 16:54:02 -0700 Subject: [PATCH 149/336] Qt: Fix window resizing when no game is loaded --- src/platform/qt/Window.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 117da820d..fe2253367 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1523,10 +1523,18 @@ void Window::setupMenu(QMenuBar* menubar) { auto setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() { auto setSize = m_frameSizes[i]; showNormal(); - QSize size(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); +#if defined(M_CORE_GBA) + QSize minimumSize = QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); +#elif defined(M_CORE_GB) + QSize minimumSize = QSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); +#endif + QSize size; if (m_display) { size = m_display->contentSize(); } + if (size.isNull()) { + size = minimumSize; + } size *= i; m_savedScale = i; m_config->setOption("scaleMultiplier", i); // TODO: Port to other From be85200b3e1eecd291dc93193a5594b104438653 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 20:22:11 -0700 Subject: [PATCH 150/336] Qt: Fix race condition in Qt display driver that could cause division by zero --- src/platform/qt/DisplayQt.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index 1d9efebec..db84c2689 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -130,6 +130,10 @@ void DisplayQt::paintEvent(QPaintEvent*) { struct mRectangle frame; VideoBackendGetFrame(&m_backend, &frame); QPoint origin(-frame.x, -frame.y); + QSize drawSize(contentSize()); + if (!drawSize.isValid() || drawSize.width() < 1 || drawSize.height() < 1) { + return; + } QRect full(clampSize(contentSize(), size(), isAspectRatioLocked(), isIntegerScalingLocked())); painter.save(); painter.translate(full.topLeft()); From d1a6e6b747990356754d988e65842eaa02ab9e0c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 20:39:58 -0700 Subject: [PATCH 151/336] Qt: Add option to lock the maximum frame size (closes #1493) --- CHANGES | 1 + include/mgba/feature/proxy-backend.h | 2 ++ include/mgba/feature/video-backend.h | 2 +- src/feature/proxy-backend.c | 10 +++++---- src/platform/opengl/gl.c | 23 ++++++++++++++------- src/platform/opengl/gles2.c | 20 ++++++++++++------ src/platform/qt/Display.h | 2 ++ src/platform/qt/DisplayGL.cpp | 15 +++++++++++++- src/platform/qt/DisplayGL.h | 3 +++ src/platform/qt/DisplayQt.cpp | 17 +++++++++++++-- src/platform/qt/DisplayQt.h | 5 ++++- src/platform/qt/Window.cpp | 31 +++++++++++++++++++++++++++- src/platform/qt/Window.h | 1 + src/platform/sdl/gl-common.c | 2 +- 14 files changed, 110 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index e08179d72..6249e67d8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ 0.11.0: (Future) Features: + - New option to lock the maximum frame size - Scripting: New `input` API for getting raw keyboard/mouse/controller state - Scripting: New `storage` API for saving data for a script, e.g. settings - Scripting: Debugger integration to allow for breakpoints and watchpoints diff --git a/include/mgba/feature/proxy-backend.h b/include/mgba/feature/proxy-backend.h index 8c0b9e427..ffd38eb47 100644 --- a/include/mgba/feature/proxy-backend.h +++ b/include/mgba/feature/proxy-backend.h @@ -38,6 +38,8 @@ union mVideoBackendCommandData { struct { unsigned width; unsigned height; + unsigned maxW; + unsigned maxH; } u; const void* image; }; diff --git a/include/mgba/feature/video-backend.h b/include/mgba/feature/video-backend.h index adf6f8395..f01e656c9 100644 --- a/include/mgba/feature/video-backend.h +++ b/include/mgba/feature/video-backend.h @@ -48,7 +48,7 @@ struct VideoBackend { void (*layerDimensions)(const struct VideoBackend*, enum VideoLayer, struct mRectangle*); void (*swap)(struct VideoBackend*); void (*clear)(struct VideoBackend*); - void (*contextResized)(struct VideoBackend*, unsigned w, unsigned h); + void (*contextResized)(struct VideoBackend*, unsigned w, unsigned h, unsigned maxW, unsigned maxH); void (*setImageSize)(struct VideoBackend*, enum VideoLayer, int w, int h); void (*imageSize)(struct VideoBackend*, enum VideoLayer, int* w, int* h); void (*setImage)(struct VideoBackend*, enum VideoLayer, const void* frame); diff --git a/src/feature/proxy-backend.c b/src/feature/proxy-backend.c index 3cfe7c39d..540034227 100644 --- a/src/feature/proxy-backend.c +++ b/src/feature/proxy-backend.c @@ -61,7 +61,7 @@ static void _mVideoProxyBackendClear(struct VideoBackend* v) { mVideoProxyBackendSubmit(proxy, &cmd, NULL); } -static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w, unsigned h) { +static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) { struct mVideoProxyBackend* proxy = (struct mVideoProxyBackend*) v; struct mVideoBackendCommand cmd = { .cmd = mVB_CMD_CONTEXT_RESIZED, @@ -69,6 +69,8 @@ static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w .u = { .width = w, .height = h, + .maxW = maxW, + .maxH = maxH, } } }; @@ -139,8 +141,8 @@ void mVideoProxyBackendInit(struct mVideoProxyBackend* proxy, struct VideoBacken proxy->d.drawFrame = _mVideoProxyBackendDrawFrame; proxy->backend = backend; - RingFIFOInit(&proxy->in, 0x400); - RingFIFOInit(&proxy->out, 0x400); + RingFIFOInit(&proxy->in, sizeof(union mVideoBackendCommandData) * 0x80); + RingFIFOInit(&proxy->out, sizeof(union mVideoBackendCommandData) * 0x80); MutexInit(&proxy->inLock); MutexInit(&proxy->outLock); ConditionInit(&proxy->inWait); @@ -209,7 +211,7 @@ bool mVideoProxyBackendRun(struct mVideoProxyBackend* proxy, bool block) { proxy->backend->clear(proxy->backend); break; case mVB_CMD_CONTEXT_RESIZED: - proxy->backend->contextResized(proxy->backend, cmd.data.u.width, cmd.data.u.height); + proxy->backend->contextResized(proxy->backend, cmd.data.u.width, cmd.data.u.height, cmd.data.u.maxW, cmd.data.u.maxH); break; case mVB_CMD_SET_IMAGE_SIZE: proxy->backend->setImageSize(proxy->backend, cmd.layer, cmd.data.s.width, cmd.data.s.height); diff --git a/src/platform/opengl/gl.c b/src/platform/opengl/gl.c index fe24d04cf..b0cef1f0d 100644 --- a/src/platform/opengl/gl.c +++ b/src/platform/opengl/gl.c @@ -103,20 +103,29 @@ static void mGLContextDeinit(struct VideoBackend* v) { glDeleteTextures(VIDEO_LAYER_MAX, context->layers); } -static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h) { +static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) { unsigned drawW = w; unsigned drawH = h; - unsigned maxW; - unsigned maxH; - VideoBackendGetFrameSize(v, &maxW, &maxH); + + if (maxW && drawW > maxW) { + drawW = maxW; + } + + if (maxH && drawH > maxH) { + drawH = maxH; + } + + unsigned lockW; + unsigned lockH; + VideoBackendGetFrameSize(v, &lockW, &lockH); if (v->lockAspectRatio) { - lockAspectRatioUInt(maxW, maxH, &drawW, &drawH); + lockAspectRatioUInt(lockW, lockH, &drawW, &drawH); } if (v->lockIntegerScaling) { - lockIntegerRatioUInt(maxW, &drawW); - lockIntegerRatioUInt(maxH, &drawH); + lockIntegerRatioUInt(lockW, &drawW); + lockIntegerRatioUInt(lockH, &drawH); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 51180813e..6350bd287 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -271,20 +271,28 @@ static void mGLES2ContextDeinit(struct VideoBackend* v) { free(context->initialShader.uniforms); } -static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h) { +static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) { struct mGLES2Context* context = (struct mGLES2Context*) v; unsigned drawW = w; unsigned drawH = h; - unsigned maxW = context->width; - unsigned maxH = context->height; + if (maxW && drawW > maxW) { + drawW = maxW; + } + + if (maxH && drawH > maxH) { + drawH = maxH; + } + + unsigned lockW = context->width; + unsigned lockH = context->height; if (v->lockAspectRatio) { - lockAspectRatioUInt(maxW, maxH, &drawW, &drawH); + lockAspectRatioUInt(lockW, lockH, &drawW, &drawH); } if (v->lockIntegerScaling) { - lockIntegerRatioUInt(maxW, &drawW); - lockIntegerRatioUInt(maxH, &drawH); + lockIntegerRatioUInt(lockW, &drawW); + lockIntegerRatioUInt(lockH, &drawH); } size_t n; for (n = 0; n < context->nShaders; ++n) { diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index ff6f0c23b..bb16b268e 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -57,6 +57,7 @@ public: virtual void setVideoScale(int) {} virtual void setBackgroundImage(const QImage&) = 0; virtual QSize contentSize() const = 0; + virtual void setMaximumSize(const QSize& size) = 0; virtual void setVideoProxy(std::shared_ptr proxy) { m_videoProxy = std::move(proxy); } std::shared_ptr videoProxy() { return m_videoProxy; } @@ -105,6 +106,7 @@ private: bool m_filter = false; QTimer m_mouseTimer; std::shared_ptr m_videoProxy; + QSize m_maxSize; }; } diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 3a4c3ffdd..5b60eb46e 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -524,6 +524,10 @@ int DisplayGL::framebufferHandle() { return m_painter->glTex(); } +void DisplayGL::setMaximumSize(const QSize& size) { + QMetaObject::invokeMethod(m_painter.get(), "setMaximumSize", Q_ARG(const QSize&, size)); +} + PainterGL::PainterGL(QWindow* window, mGLWidget* widget, const QSurfaceFormat& format) : m_window(window) , m_format(format) @@ -720,6 +724,11 @@ void PainterGL::resize(const QSize& size) { } } +void PainterGL::setMaximumSize(const QSize& size) { + m_maxSize = size; + resizeContext(); +} + void PainterGL::lockAspectRatio(bool lock) { m_backend->lockAspectRatio = lock; resize(m_size); @@ -911,7 +920,11 @@ void PainterGL::unpause() { void PainterGL::performDraw() { float r = m_window->devicePixelRatio(); - m_backend->contextResized(m_backend, m_size.width() * r, m_size.height() * r); + QSize maxSize = m_maxSize; + if (!maxSize.isValid()) { + maxSize = QSize(0, 0); + } + m_backend->contextResized(m_backend, m_size.width() * r, m_size.height() * r, maxSize.width() * r, maxSize.height() * r); if (m_buffer) { m_backend->setImage(m_backend, VIDEO_LAYER_IMAGE, m_buffer); } diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 71e2de597..5b0aab2cd 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -95,6 +95,7 @@ public: void setVideoProxy(std::shared_ptr) override; int framebufferHandle() override; QSize contentSize() const override { return m_cachedContentSize; } + void setMaximumSize(const QSize& size) override; static bool highestCompatible(QSurfaceFormat&); static bool supportsFormat(const QSurfaceFormat&); @@ -172,6 +173,7 @@ public slots: void pause(); void unpause(); void resize(const QSize& size); + void setMaximumSize(const QSize& size); void lockAspectRatio(bool lock); void lockIntegerScaling(bool lock); void interframeBlending(bool enable); @@ -230,6 +232,7 @@ private: VideoBackend* m_backend = nullptr; QSize m_size; QSize m_dims; + QSize m_maxSize; MessagePainter* m_messagePainter = nullptr; QElapsedTimer m_delayTimer; std::shared_ptr m_videoProxy; diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index db84c2689..3723a8445 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -134,7 +134,20 @@ void DisplayQt::paintEvent(QPaintEvent*) { if (!drawSize.isValid() || drawSize.width() < 1 || drawSize.height() < 1) { return; } - QRect full(clampSize(contentSize(), size(), isAspectRatioLocked(), isIntegerScalingLocked())); + QSize usedSize = size(); + QPoint screenOrigin(0, 0); + if (m_maxSize.isValid()) { + if (m_maxSize.width() < usedSize.width()) { + screenOrigin.setX((usedSize.width() - m_maxSize.width()) / 2); + usedSize.setWidth(m_maxSize.width()); + } + if (m_maxSize.height() < usedSize.height()) { + screenOrigin.setY((usedSize.height() - m_maxSize.height()) / 2); + usedSize.setHeight(m_maxSize.height()); + } + } + QRect full(clampSize(contentSize(), usedSize, isAspectRatioLocked(), isIntegerScalingLocked())); + full.translate(screenOrigin); painter.save(); painter.translate(full.topLeft()); painter.scale(full.width() / static_cast(frame.width), full.height() / static_cast(frame.height)); @@ -220,7 +233,7 @@ void DisplayQt::swap(struct VideoBackend*) { void DisplayQt::clear(struct VideoBackend*) { } -void DisplayQt::contextResized(struct VideoBackend*, unsigned, unsigned) { +void DisplayQt::contextResized(struct VideoBackend*, unsigned, unsigned, unsigned, unsigned) { } void DisplayQt::setImageSize(struct VideoBackend* v, enum VideoLayer layer, int w, int h) { diff --git a/src/platform/qt/DisplayQt.h b/src/platform/qt/DisplayQt.h index c1363dede..a6816a18b 100644 --- a/src/platform/qt/DisplayQt.h +++ b/src/platform/qt/DisplayQt.h @@ -27,6 +27,8 @@ public: VideoShader* shaders() override { return nullptr; } QSize contentSize() const override; VideoBackend* videoBackend() override { return &m_backend; } + void setMaximumSize(const QSize& size) override { m_maxSize = size; } + public slots: void stopDrawing() override; @@ -56,7 +58,7 @@ private: static void layerDimensions(const struct VideoBackend*, enum VideoLayer, struct mRectangle*); static void swap(struct VideoBackend*); static void clear(struct VideoBackend*); - static void contextResized(struct VideoBackend*, unsigned w, unsigned h); + static void contextResized(struct VideoBackend*, unsigned w, unsigned h, unsigned maxW, unsigned maxH); static void setImageSize(struct VideoBackend*, enum VideoLayer, int w, int h); static void imageSize(struct VideoBackend*, enum VideoLayer, int* w, int* h); static void setImage(struct VideoBackend*, enum VideoLayer, const void* frame); @@ -69,6 +71,7 @@ private: int m_width = -1; int m_height = -1; QImage m_oldBacking{nullptr}; + QSize m_maxSize; std::shared_ptr m_context = nullptr; }; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index fe2253367..bd52b0862 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -252,6 +252,9 @@ void Window::argumentsPassed() { void Window::resizeFrame(const QSize& size) { QSize newSize(size); + if (!m_config->getOption("lockFrameSize").toInt()) { + m_savedSize = size; + } if (windowHandle()) { QRect geom = windowHandle()->screen()->availableGeometry(); if (newSize.width() > geom.width()) { @@ -1522,7 +1525,10 @@ void Window::setupMenu(QMenuBar* menubar) { for (int i = 1; i <= 8; ++i) { auto setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() { auto setSize = m_frameSizes[i]; - showNormal(); + bool lockFrameSize = m_config->getOption("lockFrameSize").toInt(); + if (!lockFrameSize) { + showNormal(); + } #if defined(M_CORE_GBA) QSize minimumSize = QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); #elif defined(M_CORE_GB) @@ -1538,7 +1544,11 @@ void Window::setupMenu(QMenuBar* menubar) { size *= i; m_savedScale = i; m_config->setOption("scaleMultiplier", i); // TODO: Port to other + m_savedSize = size; resizeFrame(size); + if (lockFrameSize) { + m_display->setMaximumSize(size); + } setSize->setActive(true); }, "frame"); setSize->setExclusive(true); @@ -1553,8 +1563,22 @@ void Window::setupMenu(QMenuBar* menubar) { #else fullscreenKeys = QKeySequence("Ctrl+F"); #endif + m_actions.addSeparator("frame"); m_actions.addAction(tr("Toggle fullscreen"), "fullscreen", this, &Window::toggleFullScreen, "frame", fullscreenKeys); + ConfigOption* lockFrameSize = m_config->addOption("lockFrameSize"); + lockFrameSize->addBoolean(tr("&Lock frame size"), &m_actions, "frame"); + lockFrameSize->connect([this](const QVariant& value) { + if (m_display) { + if (value.toBool()) { + m_display->setMaximumSize(m_display->size()); + } else { + m_display->setMaximumSize({}); + } + } + }, this); + m_config->updateOption("lockFrameSize"); + ConfigOption* lockAspectRatio = m_config->addOption("lockAspectRatio"); lockAspectRatio->addBoolean(tr("Lock aspect ratio"), &m_actions, "av"); lockAspectRatio->connect([this](const QVariant& value) { @@ -2216,6 +2240,11 @@ void Window::setController(CoreController* controller, const QString& fname) { void Window::attachDisplay() { m_display->attach(m_controller); connect(m_display.get(), &QGBA::Display::drawingStarted, this, &Window::changeRenderer); + if (m_config->getOption("lockFrameSize").toInt()) { + m_display->setMaximumSize(m_savedSize); + } else { + m_display->setMaximumSize({}); + } m_display->startDrawing(m_controller); #ifdef ENABLE_SCRIPTING diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 4bcb6b7f9..f91e3ff30 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -194,6 +194,7 @@ private: std::unique_ptr m_display; QSize m_initialSize; + QSize m_savedSize; int m_savedScale; // TODO: Move these to a new class diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index 1ce9100e8..f2ccdd7e2 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -15,7 +15,7 @@ #endif void mSDLGLDoViewport(int w, int h, struct VideoBackend* v) { - v->contextResized(v, w, h); + v->contextResized(v, w, h, 0, 0); v->clear(v); v->swap(v); v->clear(v); From 4bd09bdac297571927469c5d5150a69260465ed5 Mon Sep 17 00:00:00 2001 From: oltolm Date: Thu, 28 Mar 2024 21:37:31 +0100 Subject: [PATCH 152/336] fix hang in AudioDevice --- src/platform/qt/AudioDevice.cpp | 8 ++++++-- src/platform/qt/AudioDevice.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index d19fc20d3..1ae71af19 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -64,11 +64,15 @@ qint64 AudioDevice::writeData(const char*, qint64) { } bool AudioDevice::atEnd() const { + return !bytesAvailable(); +} + +qint64 AudioDevice::bytesAvailable() const { if (!m_context->core) { return true; } mCoreSyncLockAudio(&m_context->impl->sync); - bool available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)) == 0; + int available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)); mCoreSyncUnlockAudio(&m_context->impl->sync); - return available; + return available * sizeof(mStereoSample); } diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index 86c5b17a6..e4386bda2 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -21,6 +21,7 @@ public: void setInput(mCoreThread* input); void setFormat(const QAudioFormat& format); bool atEnd() const override; + qint64 bytesAvailable() const override; protected: virtual qint64 readData(char* data, qint64 maxSize) override; From 9fa825e3360d9c553cda5f8f636ba547e68ca938 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 01:21:29 -0700 Subject: [PATCH 153/336] Util: Start bringing up new resampler --- include/mgba-util/audio-resampler.h | 37 ++++++++++++ include/mgba-util/interpolator.h | 11 +++- src/util/CMakeLists.txt | 2 + src/util/audio-buffer.c | 2 +- src/util/audio-resampler.c | 94 +++++++++++++++++++++++++++++ src/util/interpolator.c | 21 ++++--- 6 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 include/mgba-util/audio-resampler.h create mode 100644 src/util/audio-resampler.c diff --git a/include/mgba-util/audio-resampler.h b/include/mgba-util/audio-resampler.h new file mode 100644 index 000000000..50f298930 --- /dev/null +++ b/include/mgba-util/audio-resampler.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef M_AUDIO_RESAMPLER_H +#define M_AUDIO_RESAMPLER_H + +#include + +CXX_GUARD_START + +#include + +struct mAudioBuffer; +struct mAudioResampler { + struct mAudioBuffer* source; + struct mAudioBuffer* destination; + double sourceRate; + double destRate; + double timestamp; + double lowWaterMark; + double highWaterMark; + struct mInterpolatorSinc interp; + bool consume; +}; + +void mAudioResamplerInit(struct mAudioResampler*); +void mAudioResamplerDeinit(struct mAudioResampler*); +void mAudioResamplerSetSource(struct mAudioResampler*, struct mAudioBuffer* source, double rate, bool consume); +void mAudioResamplerSetDestination(struct mAudioResampler*, struct mAudioBuffer* destination, double rate); +size_t mAudioResamplerProcess(struct mAudioResampler*); + +CXX_GUARD_END + +#endif + diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index 43b75da27..f01048f34 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -8,12 +8,15 @@ #include -struct mInterpData { - int16_t (*at)(const void* mInterpData, size_t index); +CXX_GUARD_START + +struct mInterpolationData { + int16_t (*at)(int index, const void* context); + void* context; }; struct mInterpolator { - int16_t (*interpolate)(const struct mInterpolator* interp, const struct mInterpData* data, double time, double sampleStep); + int16_t (*interpolate)(const struct mInterpolator* interp, const struct mInterpolationData* data, double time, double sampleStep); }; struct mInterpolatorSinc { @@ -28,4 +31,6 @@ struct mInterpolatorSinc { void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width); void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp); +CXX_GUARD_END + #endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index f0bc85a3d..66cd6ca47 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -13,6 +13,8 @@ set(BASE_SOURCE_FILES set(SOURCE_FILES ${BASE_SOURCE_FILES} + audio-buffer.c + audio-resampler.c convolve.c elf-read.c geometry.c diff --git a/src/util/audio-buffer.c b/src/util/audio-buffer.c index bb705b38c..5d67827fb 100644 --- a/src/util/audio-buffer.c +++ b/src/util/audio-buffer.c @@ -9,7 +9,7 @@ void mAudioBufferInit(struct mAudioBuffer* buffer, size_t capacity, unsigned channels) { mCircleBufferInit(&buffer->data, capacity * channels * sizeof(int16_t)); - buffer->channels = capacity; + buffer->channels = channels; } void mAudioBufferDeinit(struct mAudioBuffer* buffer) { diff --git a/src/util/audio-resampler.c b/src/util/audio-resampler.c new file mode 100644 index 000000000..0f0147c34 --- /dev/null +++ b/src/util/audio-resampler.c @@ -0,0 +1,94 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +#include + +#define MAX_CHANNELS 2 + +struct mAudioResamplerData { + struct mAudioResampler* resampler; + unsigned channel; +}; + +static int16_t _sampleAt(int index, const void* context) { + const struct mAudioResamplerData* data = context; + if (index < 0) { + return 0; + } + return mAudioBufferPeek(data->resampler->source, data->channel, index); +} + +void mAudioResamplerInit(struct mAudioResampler* resampler) { + memset(resampler, 0, sizeof(*resampler)); + mInterpolatorSincInit(&resampler->interp, 0, 0); + resampler->lowWaterMark = resampler->interp.width; + resampler->highWaterMark = 0; +} + +void mAudioResamplerDeinit(struct mAudioResampler* resampler) { + mInterpolatorSincDeinit(&resampler->interp); + resampler->source = NULL; + resampler->destination = NULL; +} + +void mAudioResamplerSetSource(struct mAudioResampler* resampler, struct mAudioBuffer* source, double rate, bool consume) { + resampler->source = source; + resampler->sourceRate = rate; + resampler->consume = consume; +} + +void mAudioResamplerSetDestination(struct mAudioResampler* resampler, struct mAudioBuffer* destination, double rate) { + resampler->destination = destination; + resampler->destRate = rate; +} + +size_t mAudioResamplerProcess(struct mAudioResampler* resampler) { + int16_t sampleBuffer[MAX_CHANNELS] = {0}; + double timestep = resampler->sourceRate / resampler->destRate; + double timestamp = resampler->timestamp; + struct mInterpolator* interp = &resampler->interp.d; + struct mAudioResamplerData context = { + .resampler = resampler, + }; + struct mInterpolationData data = { + .at = _sampleAt, + .context = &context, + }; + + size_t read = 0; + if (resampler->source->channels > MAX_CHANNELS) { + abort(); + } + + while (true) { + if (timestamp + resampler->highWaterMark >= mAudioBufferAvailable(resampler->source)) { + break; + } + if (mAudioBufferAvailable(resampler->destination) == mAudioBufferCapacity(resampler->destination)) { + break; + } + + size_t channel; + for (channel = 0; channel < resampler->source->channels; ++channel) { + context.channel = channel; + sampleBuffer[channel] = interp->interpolate(interp, &data, timestamp, timestep); + } + if (!mAudioBufferWrite(resampler->destination, sampleBuffer, 1)) { + break; + } + timestamp += timestep; + ++read; + } + + if (resampler->consume && timestamp > resampler->lowWaterMark) { + size_t drop = timestamp - resampler->lowWaterMark; + drop = mAudioBufferRead(resampler->source, NULL, drop); + timestamp -= drop; + } + resampler->timestamp = timestamp; + return read; +} diff --git a/src/util/interpolator.c b/src/util/interpolator.c index a9daaa539..21dd91d2c 100644 --- a/src/util/interpolator.c +++ b/src/util/interpolator.c @@ -10,7 +10,7 @@ enum { mSINC_WIDTH = 8, }; -static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpData*, double time, double sampleStep); +static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep); void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { interp->d.interpolate = mInterpolatorSincInterpolate; @@ -33,6 +33,9 @@ void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution interp->sincLut[0] = 0; interp->windowLut[0] = 1; + interp->width = width; + interp->resolution = resolution; + unsigned i; for (i = 1; i <= samples; ++i, x += dx, y += dy) { interp->sincLut[i] = x < width ? sin(x) / x : 0.0; @@ -46,27 +49,27 @@ void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp) { free(interp->windowLut); } -int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mInterpData* data, double time, double sampleStep) { +int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mInterpolationData* data, double time, double sampleStep) { struct mInterpolatorSinc* interp = (struct mInterpolatorSinc*) interpolator; - ssize_t index = (ssize_t) time; + int index = time; double subsample = time - floor(time); - unsigned step = sampleStep > 1 ? interp->resolution * sampleStep : interp->resolution; + unsigned step = sampleStep < 1 ? interp->resolution * sampleStep : interp->resolution; unsigned yShift = subsample * step; unsigned xShift = subsample * interp->resolution; double sum = 0.0; double kernelSum = 0.0; double kernel; - ssize_t i; - for (i = 1 - (ssize_t) interp->width; i <= (ssize_t) interp->width; ++i) { - unsigned window = i * interp->resolution; + int i; + for (i = 1 - (int) interp->width; i <= (int) interp->width; ++i) { + unsigned window = (i >= 0 ? i : -i) * interp->resolution; if (yShift > window) { window = yShift - window; } else { window -= yShift; } - unsigned sinc = i * step; + unsigned sinc = (i >= 0 ? i : -i) * step; if (xShift > sinc) { sinc = xShift - sinc; } else { @@ -75,7 +78,7 @@ int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, c kernel = interp->sincLut[sinc] * interp->windowLut[window]; kernelSum += kernel; - sum += data->at(data, index + i) * kernel; + sum += data->at(index + i, data->context) * kernel; } return sum / kernelSum; } From 76169c669a70a278b480176deeb1bd5a5ddd639b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 02:54:30 -0700 Subject: [PATCH 154/336] Util: Fix circle buffer dump offset forcing an early wrap --- src/util/circle-buffer.c | 12 +++++++++++- src/util/test/circle-buffer.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index f0d074d36..037a23501 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -279,8 +279,18 @@ size_t mCircleBufferDump(const struct mCircleBuffer* buffer, void* output, size_ if (length > buffer->size - offset) { length = buffer->size - offset; } - data += offset; size_t remaining = buffer->capacity - ((uintptr_t) data - (uintptr_t) buffer->data); + if (offset) { + if (remaining >= offset) { + data += offset; + remaining -= offset; + } else { + offset -= remaining; + data = buffer->data; + data += offset; + } + } + if (length <= remaining) { memcpy(output, data, length); } else { diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 9ba383971..bff0c9485 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -938,6 +938,38 @@ M_TEST_DEFINE(dumpOffset) { mCircleBufferDeinit(&buffer); } +M_TEST_DEFINE(dumpOffsetWrap) { + struct mCircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + mCircleBufferInit(&buffer, 64); + + assert_int_equal(mCircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 48), 48); + assert_memory_equal(data, databuf, 48); + assert_int_equal(mCircleBufferSize(&buffer), 16); + assert_int_equal(mCircleBufferWrite(&buffer, data, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 32); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 0), 32); + assert_memory_equal(&data[48], databuf, 16); + assert_memory_equal(data, &databuf[16], 16); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 8), 24); + assert_memory_equal(&data[56], databuf, 8); + assert_memory_equal(data, &databuf[8], 16); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 16), 16); + assert_memory_equal(data, databuf, 16); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 24), 8); + assert_memory_equal(&data[8], databuf, 8); + + mCircleBufferDeinit(&buffer); +} + M_TEST_SUITE_DEFINE(mCircleBuffer, cmocka_unit_test(basicCircle), cmocka_unit_test(basicAlignment16), @@ -959,4 +991,5 @@ M_TEST_SUITE_DEFINE(mCircleBuffer, cmocka_unit_test(writeTruncate), cmocka_unit_test(dumpBasic), cmocka_unit_test(dumpOffset), + cmocka_unit_test(dumpOffsetWrap), ) From 96a2ef5f42a2a8f453bd71ed38bdead5d9c027c7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 02:54:48 -0700 Subject: [PATCH 155/336] Util: Enable dropping part of a circle buffer with a null read --- src/util/circle-buffer.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 037a23501..ec14bfc4f 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -250,15 +250,19 @@ size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t leng } size_t remaining = buffer->capacity - ((int8_t*) data - (int8_t*) buffer->data); if (length <= remaining) { - memcpy(output, data, length); + if (output) { + memcpy(output, data, length); + } if (length == remaining) { buffer->readPtr = buffer->data; } else { buffer->readPtr = (int8_t*) data + length; } } else { - memcpy(output, data, remaining); - memcpy((int8_t*) output + remaining, buffer->data, length - remaining); + if (output) { + memcpy(output, data, remaining); + memcpy((int8_t*) output + remaining, buffer->data, length - remaining); + } buffer->readPtr = (int8_t*) buffer->data + length - remaining; } From 73a39dea65cd90f2a36a7d2f1f87eb8cf204d8e0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 20:44:59 -0700 Subject: [PATCH 156/336] Core: Finally kill off GBAAudioCalculateRatio --- include/mgba/core/core.h | 2 ++ include/mgba/internal/gba/audio.h | 2 -- src/core/core.c | 6 ++++++ src/gba/audio.c | 4 ---- src/platform/psp2/psp2-context.c | 2 +- src/platform/qt/AudioDevice.cpp | 2 +- src/platform/sdl/sdl-audio.c | 5 ++--- src/platform/switch/main.c | 2 +- src/platform/wii/main.c | 4 ++-- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 99bfd0e83..b34a9451f 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -216,6 +216,8 @@ void* mCoreGetMemoryBlock(struct mCore* core, uint32_t start, size_t* size); void* mCoreGetMemoryBlockMasked(struct mCore* core, uint32_t start, size_t* size, uint32_t mask); const struct mCoreMemoryBlock* mCoreGetMemoryBlockInfo(struct mCore* core, uint32_t address); +double mCoreCalculateFramerateRatio(const struct mCore* core, double desiredFrameRate); + #ifdef USE_ELF struct ELF; bool mCoreLoadELF(struct mCore* core, struct ELF* elf); diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index f2d878e4e..6702f5ff4 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -313,8 +313,6 @@ struct GBASerializedState; void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state); void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state); -float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRatio); - CXX_GUARD_END #endif diff --git a/src/core/core.c b/src/core/core.c index bc68fd5d2..bcc72115a 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -442,6 +442,12 @@ const struct mCoreMemoryBlock* mCoreGetMemoryBlockInfo(struct mCore* core, uint3 return NULL; } +double mCoreCalculateFramerateRatio(const struct mCore* core, double desiredFrameRate) { + uint32_t clockRate = core->frequency(core); + uint32_t frameCycles = core->frameCycles(core); + return clockRate / (desiredFrameRate * frameCycles); +} + #ifdef USE_ELF bool mCoreLoadELF(struct mCore* core, struct ELF* elf) { struct ELFProgramHeaders ph; diff --git a/src/gba/audio.c b/src/gba/audio.c index fb0e1b62c..b25273f16 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -587,7 +587,3 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState } mTimingSchedule(&audio->p->timing, &audio->sampleEvent, when); } - -float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) { - return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate); -} diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 34623a876..755021f6f 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -376,7 +376,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { void mPSP2LoadROM(struct mGUIRunner* runner) { float rate = 60.0f / 1.001f; sceDisplayGetRefreshRate(&rate); - double ratio = GBAAudioCalculateRatio(1, rate, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, rate); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index 1ae71af19..ec6dd3133 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -26,7 +26,7 @@ void AudioDevice::setFormat(const QAudioFormat& format) { LOG(QT, INFO) << tr("Can't set format of context-less audio device"); return; } - double fauxClock = GBAAudioCalculateRatio(1, m_context->impl->sync.fpsTarget, 1); + double fauxClock = mCoreCalculateFramerateRatio(m_context->core, m_context->impl->sync.fpsTarget); mCoreSyncLockAudio(&m_context->impl->sync); blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); diff --git a/src/platform/sdl/sdl-audio.c b/src/platform/sdl/sdl-audio.c index f1666aa4e..2d1fc9f85 100644 --- a/src/platform/sdl/sdl-audio.c +++ b/src/platform/sdl/sdl-audio.c @@ -103,12 +103,11 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { if (audioContext->core) { left = audioContext->core->getAudioChannel(audioContext->core, 0); right = audioContext->core->getAudioChannel(audioContext->core, 1); - clockRate = audioContext->core->frequency(audioContext->core); } double fauxClock = 1; if (audioContext->sync) { - if (audioContext->sync->fpsTarget > 0) { - fauxClock = GBAAudioCalculateRatio(1, audioContext->sync->fpsTarget, 1); + if (audioContext->sync->fpsTarget > 0 && audioContext->core) { + fauxClock = mCoreCalculateFramerateRatio(audioContext->core, audioContext->sync->fpsTarget); } mCoreSyncLockAudio(audioContext->sync); } diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 15196aaec..7dd8dc742 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -330,7 +330,7 @@ static void _setup(struct mGUIRunner* runner) { static void _gameLoaded(struct mGUIRunner* runner) { u32 samplerate = audoutGetSampleRate(); - double ratio = GBAAudioCalculateRatio(1, 60.0, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate * ratio); diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 60d4e95ae..4e955a0ad 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -247,7 +247,7 @@ static void reconfigureScreen(struct mGUIRunner* runner) { runner->params.width = vmode->fbWidth * guiScale * wAdjust; runner->params.height = vmode->efbHeight * guiScale * hAdjust; if (runner->core) { - double ratio = GBAAudioCalculateRatio(1, audioSampleRate, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); } @@ -1422,7 +1422,7 @@ void _setup(struct mGUIRunner* runner) { } runner->core->setAudioBufferSize(runner->core, SAMPLES); - double ratio = GBAAudioCalculateRatio(1, audioSampleRate, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); From 7b2edbd1bdc26717f85f7b391936f7af18998489 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 21:01:58 -0700 Subject: [PATCH 157/336] Core: Add functions to get native sample rates --- include/mgba/core/core.h | 1 + src/gb/core.c | 6 ++++++ src/gba/core.c | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index b34a9451f..7eeb1d8fb 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -78,6 +78,7 @@ struct mCore { void (*getPixels)(struct mCore*, const void** buffer, size_t* stride); void (*putPixels)(struct mCore*, const void* buffer, size_t stride); + unsigned (*audioSampleRate)(const struct mCore*); struct blip_t* (*getAudioChannel)(struct mCore*, int ch); void (*setAudioBufferSize)(struct mCore*, size_t samples); size_t (*getAudioBufferSize)(struct mCore*); diff --git a/src/gb/core.c b/src/gb/core.c index 1018b9f82..9ee6d3f84 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -445,6 +445,11 @@ static void _GBCoreSetAudioBufferSize(struct mCore* core, size_t samples) { GBAudioResizeBuffer(&gb->audio, samples); } +static unsigned _GBCoreAudioSampleRate(const struct mCore* core) { + UNUSED(core); + return 131072; +} + static size_t _GBCoreGetAudioBufferSize(struct mCore* core) { struct GB* gb = core->board; return gb->audio.samples; @@ -1302,6 +1307,7 @@ struct mCore* GBCoreCreate(void) { core->setVideoGLTex = _GBCoreSetVideoGLTex; core->getPixels = _GBCoreGetPixels; core->putPixels = _GBCorePutPixels; + core->audioSampleRate = _GBCoreAudioSampleRate; core->getAudioChannel = _GBCoreGetAudioChannel; core->setAudioBufferSize = _GBCoreSetAudioBufferSize; core->getAudioBufferSize = _GBCoreGetAudioBufferSize; diff --git a/src/gba/core.c b/src/gba/core.c index dd5df523b..4fb801c4a 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -559,6 +559,11 @@ static void _GBACorePutPixels(struct mCore* core, const void* buffer, size_t str gba->video.renderer->putPixels(gba->video.renderer, stride, buffer); } +static unsigned _GBACoreAudioSampleRate(const struct mCore* core) { + UNUSED(core); + return 65536; +} + static struct blip_t* _GBACoreGetAudioChannel(struct mCore* core, int ch) { struct GBA* gba = core->board; switch (ch) { @@ -1515,6 +1520,7 @@ struct mCore* GBACoreCreate(void) { core->setVideoGLTex = _GBACoreSetVideoGLTex; core->getPixels = _GBACoreGetPixels; core->putPixels = _GBACorePutPixels; + core->audioSampleRate = _GBACoreAudioSampleRate; core->getAudioChannel = _GBACoreGetAudioChannel; core->setAudioBufferSize = _GBACoreSetAudioBufferSize; core->getAudioBufferSize = _GBACoreGetAudioBufferSize; From 5d92c3ca0a2b58db253b4296cdcd220335316040 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 22:38:49 -0700 Subject: [PATCH 158/336] SDL: Fix GB audio speed --- src/platform/sdl/sdl-audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/sdl/sdl-audio.c b/src/platform/sdl/sdl-audio.c index 2d1fc9f85..ff7ddd2da 100644 --- a/src/platform/sdl/sdl-audio.c +++ b/src/platform/sdl/sdl-audio.c @@ -99,8 +99,9 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { } blip_t* left = NULL; blip_t* right = NULL; - int32_t clockRate = GBA_ARM7TDMI_FREQUENCY; + int32_t clockRate = 1; if (audioContext->core) { + clockRate = audioContext->core->frequency(audioContext->core); left = audioContext->core->getAudioChannel(audioContext->core, 0); right = audioContext->core->getAudioChannel(audioContext->core, 1); } From b40cdd070c442030b347cb89ba4ce2dc0b01a84a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 02:39:36 -0700 Subject: [PATCH 159/336] Switch: Switch to resampling with audren --- src/platform/switch/main.c | 127 +++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 7dd8dc742..657941094 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -21,15 +22,9 @@ #define AUTO_INPUT 0x4E585031 #define SAMPLES 0x200 -#define N_BUFFERS 4 +#define N_BUFFERS 6 #define ANALOG_DEADZONE 0x4000 -#if (SAMPLES * 4) < 0x1000 -#define BUFFER_SIZE 0x1000 -#else -#define BUFFER_SIZE (SAMPLES * 4) -#endif - TimeType __nx_time_type = TimeType_UserSystemClock; static EGLDisplay s_display; @@ -94,9 +89,9 @@ static struct mSwitchRumble { HidVibrationValue value; } rumble; static struct mRotationSource rotation = {0}; -static int audioBufferActive; -static AudioOutBuffer audoutBuffer[N_BUFFERS]; -static int enqueuedBuffers; +static AudioDriver audrenDriver; +static AudioDriverWaveBuf audrvBuffer[N_BUFFERS]; +static struct mStereoSample* audioBuffer[N_BUFFERS]; static bool frameLimiter = true; static unsigned framecount = 0; static unsigned framecap = 10; @@ -116,8 +111,6 @@ static float gyroZ = 0; static float tiltX = 0; static float tiltY = 0; -static struct mStereoSample audioBuffer[N_BUFFERS][BUFFER_SIZE / 4] __attribute__((__aligned__(0x1000))); - static enum ScreenMode { SM_PA, SM_AF, @@ -274,22 +267,6 @@ static void _updateRenderer(struct mGUIRunner* runner, bool gl) { } } -static int _audioWait(u64 timeout) { - AudioOutBuffer* releasedBuffers; - u32 nReleasedBuffers = 0; - Result rc; - if (timeout) { - rc = audoutWaitPlayFinish(&releasedBuffers, &nReleasedBuffers, timeout); - } else { - rc = audoutGetReleasedAudioOutBuffer(&releasedBuffers, &nReleasedBuffers); - } - if (R_FAILED(rc)) { - return 0; - } - enqueuedBuffers -= nReleasedBuffers; - return nReleasedBuffers; -} - static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_A, GBA_KEY_A); _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_B, GBA_KEY_B); @@ -325,15 +302,22 @@ static void _setup(struct mGUIRunner* runner) { } runner->core->setAudioBufferSize(runner->core, SAMPLES); + + u32 samplerate = runner->core->audioSampleRate(runner->core); + double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); + blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate); + blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate); + + audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / ratio); + audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 0, 1); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 1, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 1, 1); + audrvUpdate(&audrenDriver); } static void _gameLoaded(struct mGUIRunner* runner) { - u32 samplerate = audoutGetSampleRate(); - - double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate * ratio); - mCoreConfigGetUIntValue(&runner->config, "fastForwardCap", &framecap); unsigned mode; @@ -388,6 +372,7 @@ static void _gameUnloaded(struct mGUIRunner* runner) { memcpy(&values[2], &vibrationStop, sizeof(rumble.value)); memcpy(&values[3], &vibrationStop, sizeof(rumble.value)); hidSendVibrationValues(vibrationDeviceHandles, values, 4); + audrvVoiceStop(&audrenDriver, 0); } static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded, bool blendTop) { @@ -565,9 +550,7 @@ static void _incrementScreenMode(struct mGUIRunner* runner) { static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { UNUSED(runner); if (!frameLimiter && limit) { - while (enqueuedBuffers > 2) { - _audioWait(100000000); - } + audrenWaitFrame(); } frameLimiter = limit; eglSwapInterval(s_surface, limit); @@ -593,27 +576,34 @@ static bool _running(struct mGUIRunner* runner) { static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { UNUSED(stream); - _audioWait(0); - while (enqueuedBuffers >= N_BUFFERS - 1) { + int i; + while (true) { + audrvUpdate(&audrenDriver); + for (i = 0; i < N_BUFFERS; ++i) { + if (audrvBuffer[i].state == AudioDriverWaveBufState_Free || audrvBuffer[i].state == AudioDriverWaveBufState_Done) { + break; + } + } + if (i < N_BUFFERS) { + break; + } if (!frameLimiter) { blip_clear(left); blip_clear(right); return; } - _audioWait(10000000); + audrenWaitFrame(); } - if (enqueuedBuffers >= N_BUFFERS) { - blip_clear(left); - blip_clear(right); - return; - } - struct mStereoSample* samples = audioBuffer[audioBufferActive]; + struct mStereoSample* samples = audioBuffer[i]; blip_read_samples(left, &samples[0].left, SAMPLES, true); blip_read_samples(right, &samples[0].right, SAMPLES, true); - audoutAppendAudioOutBuffer(&audoutBuffer[audioBufferActive]); - ++audioBufferActive; - audioBufferActive %= N_BUFFERS; - ++enqueuedBuffers; + armDCacheFlush(samples, SAMPLES * sizeof(struct mStereoSample)); + audrvVoiceAddWaveBuf(&audrenDriver, 0, &audrvBuffer[i]); + + if (!audrvVoiceIsPlaying(&audrenDriver, 0)) { + audrvVoiceStart(&audrenDriver, 0); + } + audrvUpdate(&audrenDriver); } void _setRumble(struct mRumble* rumble, int enable) { @@ -865,9 +855,26 @@ int main(int argc, char* argv[]) { nxlinkStdio(); eglInit(); romfsInit(); - audoutInitialize(); psmInitialize(); + const AudioRendererConfig audren = { + .output_rate = AudioRendererOutputRate_48kHz, + .num_voices = 24, + .num_effects = 0, + .num_sinks = 1, + .num_mix_objs = 1, + .num_mix_buffers = 2, + }; + const u8 channels[] = { 0, 1 }; + audrenInitialize(&audren); + audrvCreate(&audrenDriver, &audren, 2); + struct mStereoSample* buffers = memalign(AUDREN_MEMPOOL_ALIGNMENT, SAMPLES * N_BUFFERS * sizeof(struct mStereoSample)); + int mempool = audrvMemPoolAdd(&audrenDriver, buffers, SAMPLES * N_BUFFERS * sizeof(struct mStereoSample)); + audrvMemPoolAttach(&audrenDriver, mempool); + audrvDeviceSinkAdd(&audrenDriver, AUDREN_DEFAULT_DEVICE_NAME, 2, channels); + audrvUpdate(&audrenDriver); + audrenStartAudioRenderer(); + font = GUIFontCreate(); vmode = appletGetOperationMode(); @@ -888,16 +895,13 @@ int main(int argc, char* argv[]) { stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; - memset(audioBuffer, 0, sizeof(audioBuffer)); - audioBufferActive = 0; - enqueuedBuffers = 0; size_t i; for (i = 0; i < N_BUFFERS; ++i) { - audoutBuffer[i].next = NULL; - audoutBuffer[i].buffer = audioBuffer[i]; - audoutBuffer[i].buffer_size = BUFFER_SIZE; - audoutBuffer[i].data_size = SAMPLES * 4; - audoutBuffer[i].data_offset = 0; + audrvBuffer[i].data_raw = buffers; + audrvBuffer[i].size = SAMPLES * N_BUFFERS * sizeof(struct mStereoSample); + audrvBuffer[i].start_sample_offset = SAMPLES * i; + audrvBuffer[i].end_sample_offset = SAMPLES * (i + 1); + audioBuffer[i] = &buffers[SAMPLES * i]; } bool illuminanceAvailable = false; @@ -1074,8 +1078,6 @@ int main(int argc, char* argv[]) { _mapKey(&runner.params.keyMap, AUTO_INPUT, HidNpadButton_Left, GUI_INPUT_LEFT); _mapKey(&runner.params.keyMap, AUTO_INPUT, HidNpadButton_Right, GUI_INPUT_RIGHT); - audoutStartAudioOut(); - if (argc > 0) { struct VFile* vf = VFileOpen("romfs:/fileassoc.cfg.in", O_RDONLY); if (vf) { @@ -1108,7 +1110,8 @@ int main(int argc, char* argv[]) { mGUIDeinit(&runner); - audoutStopAudioOut(); + audrvClose(&audrenDriver); + audrenExit(); GUIFontDestroy(font); glDeinit(); From 61791c91cb41eaafd4a710f8c6229840e5a343b4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 02:41:59 -0700 Subject: [PATCH 160/336] Switch: Fix warnings --- src/platform/switch/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 657941094..0dc866dfd 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -366,6 +366,7 @@ static void _gameLoaded(struct mGUIRunner* runner) { } static void _gameUnloaded(struct mGUIRunner* runner) { + UNUSED(runner); HidVibrationValue values[4]; memcpy(&values[0], &vibrationStop, sizeof(rumble.value)); memcpy(&values[1], &vibrationStop, sizeof(rumble.value)); @@ -392,6 +393,7 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, float aspectY = inheight / vheight; float max = 1.f; switch (screenMode) { + case SM_MAX: // This should never get hit, so just fall through to silence warning case SM_PA: if (aspectX > aspectY) { max = floor(1.f / aspectX); @@ -616,6 +618,7 @@ void _setRumble(struct mRumble* rumble, int enable) { } void _sampleRotation(struct mRotationSource* source) { + UNUSED(source); HidSixAxisSensorState sixaxis = {0}; u64 styles = padGetStyleSet(&pad); if (styles & HidNpadStyleTag_NpadHandheld) { From f298c0185ec0e7186991128b99c7fa4790aca6a7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 17:36:31 -0700 Subject: [PATCH 161/336] Qt: Add option to force a specific version of Qt --- src/platform/qt/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 673170f0f..041ad0830 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -25,7 +25,13 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(QT_LIBRARIES) -set(QT_VERSIONS 6 5) +option(FORCE_QT_VERSION "Force the used Qt version" OFF) + +if(FORCE_QT_VERSION EQUAL 5 OR FORCE_QT_VERSION EQUAL 6) + set(QT_VERSIONS ${FORCE_QT_VERSION}) +else() + set(QT_VERSIONS 6 5) +endif() foreach(V ${QT_VERSIONS}) set(QT Qt${V}) set(QT_V ${V}) From f84208a3e4a14ebd81e1851bca1f90cb955926d3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 22:55:13 -0700 Subject: [PATCH 162/336] GBA Memory: Let raw access read high MMIO addresses --- CHANGES | 1 + src/gba/memory.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 6249e67d8..f06956bfc 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves + - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Updater: Fix updating appimage across filesystems Misc: diff --git a/src/gba/memory.c b/src/gba/memory.c index 455c70bdb..4c72ca80e 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1118,10 +1118,8 @@ uint32_t GBAView32(struct ARMCore* cpu, uint32_t address) { value = GBALoad32(cpu, address, 0); break; case GBA_REGION_IO: - if ((address & OFFSET_MASK) < GBA_REG_MAX) { - value = gba->memory.io[(address & OFFSET_MASK) >> 1]; - value |= gba->memory.io[((address & OFFSET_MASK) >> 1) + 1] << 16; - } + value = GBAView16(cpu, address); + value |= GBAView16(cpu, address + 2) << 16; break; case GBA_REGION_SRAM: value = GBALoad8(cpu, address, 0); @@ -1159,7 +1157,10 @@ uint16_t GBAView16(struct ARMCore* cpu, uint32_t address) { value = GBALoad16(cpu, address, 0); break; case GBA_REGION_IO: - if ((address & OFFSET_MASK) < GBA_REG_MAX) { + if ((address & OFFSET_MASK) < GBA_REG_MAX || (address & OFFSET_MASK) == GBA_REG_POSTFLG) { + value = gba->memory.io[(address & OFFSET_MASK) >> 1]; + } else if ((address & OFFSET_MASK) == GBA_REG_EXWAITCNT_LO || (address & OFFSET_MASK) == GBA_REG_EXWAITCNT_HI) { + address += GBA_REG_INTERNAL_EXWAITCNT_LO - GBA_REG_EXWAITCNT_LO; value = gba->memory.io[(address & OFFSET_MASK) >> 1]; } break; From 2eca3c14779dfb5ad3e82c04e12244b2e4d5f7d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Apr 2024 03:01:33 -0700 Subject: [PATCH 163/336] Vita: Switch to using lw mutexes --- include/mgba-util/platform/psp2/threading.h | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/include/mgba-util/platform/psp2/threading.h b/include/mgba-util/platform/psp2/threading.h index 4c084804c..2edcc4806 100644 --- a/include/mgba-util/platform/psp2/threading.h +++ b/include/mgba-util/platform/psp2/threading.h @@ -9,7 +9,7 @@ #include typedef SceUID Thread; -typedef SceUID Mutex; +typedef SceKernelLwMutexWork Mutex; typedef struct { Mutex mutex; SceUID semaphore; @@ -20,28 +20,23 @@ typedef THREAD_ENTRY (*ThreadEntry)(void*); #define THREAD_EXIT(RES) return RES static inline int MutexInit(Mutex* mutex) { - Mutex id = sceKernelCreateMutex("mutex", 0, 0, 0); - if (id < 0) { - return id; - } - *mutex = id; - return 0; + return sceKernelCreateLwMutex(mutex, "mutex", 0, 0, 0); } static inline int MutexDeinit(Mutex* mutex) { - return sceKernelDeleteMutex(*mutex); + return sceKernelDeleteLwMutex(mutex); } static inline int MutexLock(Mutex* mutex) { - return sceKernelLockMutex(*mutex, 1, 0); + return sceKernelLockLwMutex(mutex, 1, 0); } static inline int MutexTryLock(Mutex* mutex) { - return sceKernelTryLockMutex(*mutex, 1); + return sceKernelTryLockLwMutex(mutex, 1); } static inline int MutexUnlock(Mutex* mutex) { - return sceKernelUnlockMutex(*mutex, 1); + return sceKernelUnlockLwMutex(mutex, 1); } static inline int ConditionInit(Condition* cond) { From afa8a25b5bb032b7a2ce5c41fe39c4101bb00e30 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Apr 2024 16:26:20 -0700 Subject: [PATCH 164/336] Util: Add cosine interpolator --- include/mgba-util/interpolator.h | 10 ++++++++++ src/util/interpolator.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index f01048f34..538115c37 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -28,9 +28,19 @@ struct mInterpolatorSinc { double* windowLut; }; +struct mInterpolatorCosine { + struct mInterpolator d; + + unsigned resolution; + double* lut; +}; + void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width); void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp); +void mInterpolatorCosineInit(struct mInterpolatorCosine* interp, unsigned resolution); +void mInterpolatorCosineDeinit(struct mInterpolatorCosine* interp); + CXX_GUARD_END #endif diff --git a/src/util/interpolator.c b/src/util/interpolator.c index 21dd91d2c..a69d19e81 100644 --- a/src/util/interpolator.c +++ b/src/util/interpolator.c @@ -8,9 +8,12 @@ enum { mSINC_RESOLUTION = 8192, mSINC_WIDTH = 8, + + mCOSINE_RESOLUTION = 8192, }; static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep); +static int16_t mInterpolatorCosineInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep); void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { interp->d.interpolate = mInterpolatorSincInterpolate; @@ -82,3 +85,32 @@ int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, c } return sum / kernelSum; } + +void mInterpolatorCosineInit(struct mInterpolatorCosine* interp, unsigned resolution) { + interp->d.interpolate = mInterpolatorCosineInterpolate; + + if (!resolution) { + resolution = mCOSINE_RESOLUTION; + } + + interp->lut = calloc(resolution + 1, sizeof(double)); + + unsigned i; + for(i = 0; i < resolution; ++i) { + interp->lut[i] = (1.0 - cos(M_PI * i / resolution) * M_PI) * 0.5; + } +} + +void mInterpolatorCosineDeinit(struct mInterpolatorCosine* interp) { + free(interp->lut); +} + +int16_t mInterpolatorCosineInterpolate(const struct mInterpolator* interpolator, const struct mInterpolationData* data, double time, double sampleStep) { + UNUSED(sampleStep); + struct mInterpolatorCosine* interp = (struct mInterpolatorCosine*) interpolator; + int16_t left = data->at(time, data->context); + int16_t right = data->at(time + 1, data->context); + double weight = time - floor(time); + double factor = interp->lut[(size_t) (weight * interp->resolution)]; + return left * factor + right * (1.0 - factor); +} From febedc3a389a88e29ee0237a87b6dee3dfbdec2f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Apr 2024 16:32:45 -0700 Subject: [PATCH 165/336] Util: Allow audio resampler to use different interpolators --- include/mgba-util/audio-resampler.h | 9 +++++++-- include/mgba-util/interpolator.h | 5 +++++ src/util/audio-resampler.c | 29 +++++++++++++++++++++++------ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/mgba-util/audio-resampler.h b/include/mgba-util/audio-resampler.h index 50f298930..e1ec3d84c 100644 --- a/include/mgba-util/audio-resampler.h +++ b/include/mgba-util/audio-resampler.h @@ -21,11 +21,16 @@ struct mAudioResampler { double timestamp; double lowWaterMark; double highWaterMark; - struct mInterpolatorSinc interp; + enum mInterpolatorType interpType; + union { + struct mInterpolator interp; + struct mInterpolatorSinc sinc; + struct mInterpolatorCosine cosine; + }; bool consume; }; -void mAudioResamplerInit(struct mAudioResampler*); +void mAudioResamplerInit(struct mAudioResampler*, enum mInterpolatorType); void mAudioResamplerDeinit(struct mAudioResampler*); void mAudioResamplerSetSource(struct mAudioResampler*, struct mAudioBuffer* source, double rate, bool consume); void mAudioResamplerSetDestination(struct mAudioResampler*, struct mAudioBuffer* destination, double rate); diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index 538115c37..b7a59acd5 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -10,6 +10,11 @@ CXX_GUARD_START +enum mInterpolatorType { + mINTERPOLATOR_SINC, + mINTERPOLATOR_COSINE, +}; + struct mInterpolationData { int16_t (*at)(int index, const void* context); void* context; diff --git a/src/util/audio-resampler.c b/src/util/audio-resampler.c index 0f0147c34..5b7a069e4 100644 --- a/src/util/audio-resampler.c +++ b/src/util/audio-resampler.c @@ -22,15 +22,32 @@ static int16_t _sampleAt(int index, const void* context) { return mAudioBufferPeek(data->resampler->source, data->channel, index); } -void mAudioResamplerInit(struct mAudioResampler* resampler) { +void mAudioResamplerInit(struct mAudioResampler* resampler, enum mInterpolatorType interpType) { memset(resampler, 0, sizeof(*resampler)); - mInterpolatorSincInit(&resampler->interp, 0, 0); - resampler->lowWaterMark = resampler->interp.width; - resampler->highWaterMark = 0; + resampler->interpType = interpType; + switch (interpType) { + case mINTERPOLATOR_SINC: + mInterpolatorSincInit(&resampler->sinc, 0, 0); + resampler->lowWaterMark = resampler->sinc.width; + resampler->highWaterMark = resampler->sinc.width; + break; + case mINTERPOLATOR_COSINE: + mInterpolatorCosineInit(&resampler->cosine, 0); + resampler->lowWaterMark = 0; + resampler->highWaterMark = 1; + break; + } } void mAudioResamplerDeinit(struct mAudioResampler* resampler) { - mInterpolatorSincDeinit(&resampler->interp); + switch (resampler->interpType) { + case mINTERPOLATOR_SINC: + mInterpolatorSincDeinit(&resampler->sinc); + break; + case mINTERPOLATOR_COSINE: + mInterpolatorCosineDeinit(&resampler->cosine); + break; + } resampler->source = NULL; resampler->destination = NULL; } @@ -50,7 +67,7 @@ size_t mAudioResamplerProcess(struct mAudioResampler* resampler) { int16_t sampleBuffer[MAX_CHANNELS] = {0}; double timestep = resampler->sourceRate / resampler->destRate; double timestamp = resampler->timestamp; - struct mInterpolator* interp = &resampler->interp.d; + struct mInterpolator* interp = &resampler->interp; struct mAudioResamplerData context = { .resampler = resampler, }; From 89866aff958499ceb64dd7e2c8824112db448b50 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:29:11 -0700 Subject: [PATCH 166/336] GBA Audio: Remove broken XQ audio pending rewrite Gone but not forgotten. --- CHANGES | 1 + include/mgba/internal/gba/audio.h | 23 -- include/mgba/internal/gba/extra/audio-mixer.h | 19 -- src/gba/CMakeLists.txt | 1 - src/gba/audio.c | 56 +--- src/gba/core.c | 16 - src/gba/extra/audio-mixer.c | 306 ------------------ src/gba/gba.c | 4 - src/platform/qt/SettingsView.cpp | 7 - src/platform/qt/SettingsView.h | 1 - src/platform/qt/SettingsView.ui | 9 +- src/platform/qt/Window.cpp | 9 - 12 files changed, 16 insertions(+), 436 deletions(-) delete mode 100644 include/mgba/internal/gba/extra/audio-mixer.h delete mode 100644 src/gba/extra/audio-mixer.c diff --git a/CHANGES b/CHANGES index f06956bfc..13d7b0f4c 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Misc: - GB: Prevent incompatible BIOSes from being used on differing models - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs + - GBA Audio: Remove broken XQ audio pending rewrite - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index 6702f5ff4..a6eb4824d 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -56,7 +56,6 @@ DECL_BITFIELD(GBARegisterSOUNDBIAS, uint16_t); DECL_BITS(GBARegisterSOUNDBIAS, Bias, 0, 10); DECL_BITS(GBARegisterSOUNDBIAS, Resolution, 14, 2); -struct GBAAudioMixer; struct GBAAudio { struct GBA* p; @@ -82,8 +81,6 @@ struct GBAAudio { size_t samples; GBARegisterSOUNDBIAS soundbias; - struct GBAAudioMixer* mixer; - bool externalMixing; int32_t sampleInterval; int32_t lastSample; @@ -259,26 +256,6 @@ struct GBAMP2kTrack { bool waiting; }; -struct GBAAudioMixer { - struct mCPUComponent d; - struct GBAAudio* p; - - uint32_t contextAddress; - - bool (*engage)(struct GBAAudioMixer* mixer, uint32_t address); - void (*vblank)(struct GBAAudioMixer* mixer); - void (*step)(struct GBAAudioMixer* mixer); - - struct GBAMP2kContext context; - struct GBAMP2kMusicPlayerInfo player; - struct GBAMP2kTrack activeTracks[MP2K_MAX_SOUND_CHANNELS]; - - double tempo; - double frame; - - struct mStereoSample last; -}; - void GBAAudioInit(struct GBAAudio* audio, size_t samples); void GBAAudioReset(struct GBAAudio* audio); void GBAAudioDeinit(struct GBAAudio* audio); diff --git a/include/mgba/internal/gba/extra/audio-mixer.h b/include/mgba/internal/gba/extra/audio-mixer.h deleted file mode 100644 index 369a4aaa3..000000000 --- a/include/mgba/internal/gba/extra/audio-mixer.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (c) 2013-2017 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef GBA_AUDIO_MIXER_H -#define GBA_AUDIO_MIXER_H - -#include - -CXX_GUARD_START - -#include - -void GBAAudioMixerCreate(struct GBAAudioMixer* mixer); - -CXX_GUARD_END - -#endif diff --git a/src/gba/CMakeLists.txt b/src/gba/CMakeLists.txt index 4bf354f3a..933ba3fac 100644 --- a/src/gba/CMakeLists.txt +++ b/src/gba/CMakeLists.txt @@ -40,7 +40,6 @@ set(SIO_FILES sio/lockstep.c) set(EXTRA_FILES - extra/audio-mixer.c extra/battlechip.c extra/proxy.c) diff --git a/src/gba/audio.c b/src/gba/audio.c index b25273f16..56f42b14f 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -50,11 +50,9 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { blip_set_rates(audio->psg.left, GBA_ARM7TDMI_FREQUENCY, 96000); blip_set_rates(audio->psg.right, GBA_ARM7TDMI_FREQUENCY, 96000); - audio->externalMixing = false; audio->forceDisableChA = false; audio->forceDisableChB = false; audio->masterVolume = GBA_AUDIO_VOLUME_MAX; - audio->mixer = NULL; } void GBAAudioReset(struct GBAAudio* audio) { @@ -131,27 +129,6 @@ void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* mLOG(GBA_AUDIO, GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest); return; } - if (audio->mixer) { - uint32_t source = info->source; - uint32_t offsets[] = { 0x350, 0x980 }; - size_t i; - for (i = 0; i < sizeof(offsets) / sizeof(*offsets); ++i) { - if (source < GBA_BASE_EWRAM + offsets[i]) { - continue; - } - if (source >= GBA_BASE_IO + offsets[i]) { - continue; - } - uint32_t value = GBALoad32(audio->p->cpu, source - offsets[i], NULL); - if (value - MP2K_MAGIC <= MP2K_LOCK_MAX) { - audio->mixer->engage(audio->mixer, source - offsets[i]); - break; - } - } - if (i == sizeof(offsets) / sizeof(*offsets)) { - audio->externalMixing = false; - } - } } void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) { @@ -392,28 +369,23 @@ void GBAAudioSample(struct GBAAudio* audio, int32_t timestamp) { sampleLeft >>= psgShift; sampleRight >>= psgShift; - if (audio->mixer) { - audio->mixer->step(audio->mixer); - } - if (!audio->externalMixing) { - if (!audio->forceDisableChA) { - if (audio->chALeft) { - sampleLeft += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; - } - - if (audio->chARight) { - sampleRight += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; - } + if (!audio->forceDisableChA) { + if (audio->chALeft) { + sampleLeft += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; } - if (!audio->forceDisableChB) { - if (audio->chBLeft) { - sampleLeft += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; - } + if (audio->chARight) { + sampleRight += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; + } + } - if (audio->chBRight) { - sampleRight += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; - } + if (!audio->forceDisableChB) { + if (audio->chBLeft) { + sampleLeft += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; + } + + if (audio->chBRight) { + sampleRight += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; } } diff --git a/src/gba/core.c b/src/gba/core.c index 4fb801c4a..fbdd5e85b 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #ifndef DISABLE_THREADING #include @@ -191,7 +190,6 @@ static const struct mCoreRegisterInfo _GBARegisters[] = { struct mVideoLogContext; -#define CPU_COMPONENT_AUDIO_MIXER CPU_COMPONENT_MISC_1 #define LOGO_CRC32 0xD0BEB55E struct GBACore { @@ -216,7 +214,6 @@ struct GBACore { bool hasOverride; struct mDebuggerPlatform* debuggerPlatform; struct mCheatDevice* cheatDevice; - struct GBAAudioMixer* audioMixer; struct mCoreMemoryBlock memoryBlocks[12]; size_t nMemoryBlocks; int memoryBlockType; @@ -269,7 +266,6 @@ static bool _GBACoreInit(struct mCore* core) { #ifndef MINIMAL_CORE gbacore->logContext = NULL; #endif - gbacore->audioMixer = NULL; GBACreate(gba); // TODO: Restore cheats @@ -324,7 +320,6 @@ static void _GBACoreDeinit(struct mCore* core) { if (gbacore->cheatDevice) { mCheatDeviceDestroy(gbacore->cheatDevice); } - free(gbacore->audioMixer); mCoreConfigFreeOpts(&core->opts); free(core); } @@ -387,7 +382,6 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con mCoreConfigCopyValue(&core->config, config, "allowOpposingDirections"); mCoreConfigCopyValue(&core->config, config, "gba.bios"); mCoreConfigCopyValue(&core->config, config, "gba.forceGbp"); - mCoreConfigCopyValue(&core->config, config, "gba.audioHle"); mCoreConfigCopyValue(&core->config, config, "vbaBugCompat"); #ifndef DISABLE_THREADING @@ -734,16 +728,6 @@ static void _GBACoreReset(struct mCore* core) { } } -#ifndef MINIMAL_CORE - int useAudioMixer; - if (!gbacore->audioMixer && mCoreConfigGetIntValue(&core->config, "gba.audioHle", &useAudioMixer) && useAudioMixer) { - gbacore->audioMixer = malloc(sizeof(*gbacore->audioMixer)); - GBAAudioMixerCreate(gbacore->audioMixer); - ((struct ARMCore*) core->cpu)->components[CPU_COMPONENT_AUDIO_MIXER] = &gbacore->audioMixer->d; - ARMHotplugAttach(core->cpu, CPU_COMPONENT_AUDIO_MIXER); - } -#endif - bool forceGbp = false; bool vbaBugCompat = true; mCoreConfigGetBoolValue(&core->config, "gba.forceGbp", &forceGbp); diff --git a/src/gba/extra/audio-mixer.c b/src/gba/extra/audio-mixer.c deleted file mode 100644 index e01b609b4..000000000 --- a/src/gba/extra/audio-mixer.c +++ /dev/null @@ -1,306 +0,0 @@ -/* Copyright (c) 2013-2017 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include - -#include -#include -#include - -#define OVERSAMPLE 2 - -static void _mp2kInit(void* cpu, struct mCPUComponent* component); -static void _mp2kDeinit(struct mCPUComponent* component); - -static bool _mp2kEngage(struct GBAAudioMixer* mixer, uint32_t address); -static void _mp2kVblank(struct GBAAudioMixer* mixer); -static void _mp2kStep(struct GBAAudioMixer* mixer); - -void GBAAudioMixerCreate(struct GBAAudioMixer* mixer) { - mixer->d.init = _mp2kInit; - mixer->d.deinit = _mp2kDeinit; - mixer->engage = _mp2kEngage; - mixer->vblank = _mp2kVblank; - mixer->step = _mp2kStep; -} - -void _mp2kInit(void* cpu, struct mCPUComponent* component) { - struct ARMCore* arm = cpu; - struct GBA* gba = (struct GBA*) arm->master; - struct GBAAudioMixer* mixer = (struct GBAAudioMixer*) component; - gba->audio.mixer = mixer; - mixer->p = &gba->audio; - mixer->contextAddress = 0; - mixer->tempo = 120.0 / 75.0; - mixer->frame = 0; - mixer->last.left = 0; - mixer->last.right = 0; - memset(&mixer->context, 0, sizeof(mixer->context)); - memset(&mixer->activeTracks, 0, sizeof(mixer->activeTracks)); - - size_t i; - for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { - mixer->activeTracks[i].channel = &mixer->context.chans[i]; - mCircleBufferInit(&mixer->activeTracks[i].buffer, 0x10000); - } -} - -void _mp2kDeinit(struct mCPUComponent* component) { - struct GBAAudioMixer* mixer = (struct GBAAudioMixer*) component; - size_t i; - for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { - mCircleBufferDeinit(&mixer->activeTracks[i].buffer); - } -} - -static void _loadInstrument(struct ARMCore* cpu, struct GBAMP2kInstrument* instrument, uint32_t base) { - struct ARMMemory* memory = &cpu->memory; - instrument->type = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, type), 0); - instrument->key = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, key), 0); - instrument->length = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, length), 0); - instrument->ps.pan = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, ps.pan), 0); - if (instrument->type == 0x40 || instrument->type == 0x80) { - instrument->data.subTable = memory->load32(cpu, base + offsetof(struct GBAMP2kInstrument, data.subTable), 0); - instrument->extInfo.map = memory->load32(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.map), 0); - } else { - instrument->data.waveData = memory->load32(cpu, base + offsetof(struct GBAMP2kInstrument, data.waveData), 0); - instrument->extInfo.adsr.attack = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.attack), 0); - instrument->extInfo.adsr.decay = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.decay), 0); - instrument->extInfo.adsr.sustain = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.sustain), 0); - instrument->extInfo.adsr.release = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.release), 0); - } -} - -static void _lookupInstrument(struct ARMCore* cpu, struct GBAMP2kInstrument* instrument, uint8_t key) { - struct ARMMemory* memory = &cpu->memory; - if (instrument->type == 0x40) { - uint32_t subInstrumentBase = instrument->data.subTable; - uint32_t keyTable = instrument->extInfo.map; - uint8_t id = memory->load8(cpu, keyTable + key, 0); - subInstrumentBase += 12 * id; - _loadInstrument(cpu, instrument, subInstrumentBase); - } - if (instrument->type == 0x80) { - uint32_t subInstrumentBase = instrument->data.subTable; - subInstrumentBase += 12 * key; - _loadInstrument(cpu, instrument, subInstrumentBase); - } -} - -static void _stepSample(struct GBAAudioMixer* mixer, struct GBAMP2kTrack* track) { - struct ARMCore* cpu = mixer->p->p->cpu; - struct ARMMemory* memory = &cpu->memory; - uint32_t headerAddress; - struct GBAMP2kInstrument instrument = track->track.instrument; - - uint8_t note = track->track.key; - _lookupInstrument(cpu, &instrument, note); - double freq; - - switch (instrument.type) { - case 0x00: - case 0x08: - case 0x40: - case 0x80: - freq = GBA_ARM7TDMI_FREQUENCY / (double) track->channel->freq; - break; - default: - // We don't care about PSG channels - return; - } - headerAddress = instrument.data.waveData; - if (headerAddress < 0x20) { - mLOG(GBA_AUDIO, ERROR, "Audio track has invalid instrument"); - return; - } - uint32_t loopOffset = memory->load32(cpu, headerAddress + 0x8, 0); - uint32_t endOffset = memory->load32(cpu, headerAddress + 0xC, 0); - uint32_t sampleBase = headerAddress + 0x10; - uint32_t sampleI = track->samplePlaying; - double sampleOffset = track->currentOffset; - double updates = VIDEO_TOTAL_LENGTH / (mixer->tempo * mixer->p->sampleInterval / OVERSAMPLE); - int nSample; - for (nSample = 0; nSample < updates; ++nSample) { - int8_t sample = memory->load8(cpu, sampleBase + sampleI, 0); - - struct mStereoSample stereo = { - (sample * track->channel->leftVolume * track->channel->envelopeV) >> 9, - (sample * track->channel->rightVolume * track->channel->envelopeV) >> 9 - }; - - mCircleBufferWrite16(&track->buffer, stereo.left); - mCircleBufferWrite16(&track->buffer, stereo.right); - - sampleOffset += mixer->p->sampleInterval / OVERSAMPLE; - while (sampleOffset > freq) { - sampleOffset -= freq; - ++sampleI; - if (sampleI >= endOffset) { - sampleI = loopOffset; - } - } - } - - track->samplePlaying = sampleI; - track->currentOffset = sampleOffset; -} - -static void _mp2kReload(struct GBAAudioMixer* mixer) { - struct ARMCore* cpu = mixer->p->p->cpu; - struct ARMMemory* memory = &cpu->memory; - mixer->context.magic = memory->load32(cpu, mixer->contextAddress + offsetof(struct GBAMP2kContext, magic), 0); - int i; - for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { - struct GBAMP2kSoundChannel* ch = &mixer->context.chans[i]; - struct GBAMP2kTrack* track = &mixer->activeTracks[i]; - track->waiting = false; - uint32_t base = mixer->contextAddress + offsetof(struct GBAMP2kContext, chans[i]); - - ch->status = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, status), 0); - ch->type = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, type), 0); - ch->rightVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, rightVolume), 0); - ch->leftVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, leftVolume), 0); - ch->adsr.attack = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.attack), 0); - ch->adsr.decay = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.decay), 0); - ch->adsr.sustain = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.sustain), 0); - ch->adsr.release = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.release), 0); - ch->ky = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, ky), 0); - ch->envelopeV = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, envelopeV), 0); - ch->envelopeRight = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, envelopeRight), 0); - ch->envelopeLeft = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, envelopeLeft), 0); - ch->echoVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, echoVolume), 0); - ch->echoLength = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, echoLength), 0); - ch->d1 = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d1), 0); - ch->d2 = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d2), 0); - ch->gt = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, gt), 0); - ch->midiKey = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, midiKey), 0); - ch->ve = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, ve), 0); - ch->pr = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, pr), 0); - ch->rp = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, rp), 0); - ch->d3[0] = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d3[0]), 0); - ch->d3[1] = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d3[1]), 0); - ch->d3[2] = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d3[2]), 0); - ch->ct = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, ct), 0); - ch->fw = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, fw), 0); - ch->freq = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, freq), 0); - ch->waveData = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, waveData), 0); - ch->cp = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, cp), 0); - ch->track = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, track), 0); - ch->pp = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, pp), 0); - ch->np = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, np), 0); - ch->d4 = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, d4), 0); - ch->xpi = memory->load16(cpu, base + offsetof(struct GBAMP2kSoundChannel, xpi), 0); - ch->xpc = memory->load16(cpu, base + offsetof(struct GBAMP2kSoundChannel, xpc), 0); - - base = ch->track; - if (base) { - track->track.flags = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, flags), 0); - track->track.wait = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, wait), 0); - track->track.patternLevel = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternLevel), 0); - track->track.repN = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, repN), 0); - track->track.gateTime = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, gateTime), 0); - track->track.key = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, key), 0); - track->track.velocity = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, velocity), 0); - track->track.runningStatus = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, runningStatus), 0); - track->track.keyM = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, keyM), 0); - track->track.pitM = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, pitM), 0); - track->track.keyShift = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, keyShift), 0); - track->track.keyShiftX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, keyShiftX), 0); - track->track.tune = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, tune), 0); - track->track.pitX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, pitX), 0); - track->track.bend = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, bend), 0); - track->track.bendRange = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, bendRange), 0); - track->track.volMR = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, volMR), 0); - track->track.volML = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, volML), 0); - track->track.vol = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, vol), 0); - track->track.volX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, volX), 0); - track->track.pan = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, pan), 0); - track->track.panX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, panX), 0); - track->track.modM = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, modM), 0); - track->track.mod = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, mod), 0); - track->track.modT = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, modT), 0); - track->track.lfoSpeed = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoSpeed), 0); - track->track.lfoSpeedC = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoSpeedC), 0); - track->track.lfoDelay = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoDelay), 0); - track->track.lfoDelayC = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoDelayC), 0); - track->track.priority = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, priority), 0); - track->track.echoVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, echoVolume), 0); - track->track.echoLength = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, echoLength), 0); - track->track.chan = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, chan), 0); - _loadInstrument(cpu, &track->track.instrument, base + offsetof(struct GBAMP2kMusicPlayerTrack, instrument)); - track->track.cmdPtr = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, cmdPtr), 0); - track->track.patternStack[0] = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternStack[0]), 0); - track->track.patternStack[1] = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternStack[1]), 0); - track->track.patternStack[2] = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternStack[2]), 0); - } else { - memset(&track->track, 0, sizeof(track->track)); - } - if (track->track.runningStatus == 0xCD) { - // XCMD isn't supported - mixer->p->externalMixing = false; - } - } -} - -bool _mp2kEngage(struct GBAAudioMixer* mixer, uint32_t address) { - if (address != mixer->contextAddress) { - mixer->contextAddress = address; - mixer->p->externalMixing = true; - _mp2kReload(mixer); - } - return true; -} - -void _mp2kStep(struct GBAAudioMixer* mixer) { - mixer->frame += mixer->p->sampleInterval; - - while (mixer->frame >= VIDEO_TOTAL_LENGTH / mixer->tempo) { - int i; - for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { - struct GBAMP2kTrack* track = &mixer->activeTracks[i]; - if (track->channel->status > 0) { - _stepSample(mixer, track); - } else { - track->currentOffset = 0; - track->samplePlaying = 0; - mCircleBufferClear(&track->buffer); - } - } - mixer->frame -= VIDEO_TOTAL_LENGTH / mixer->tempo; - } - - uint32_t interval = mixer->p->sampleInterval / OVERSAMPLE; - int i; - for (i = 0; i < OVERSAMPLE; ++i) { - struct mStereoSample sample = {0}; - size_t track; - for (track = 0; track < MP2K_MAX_SOUND_CHANNELS; ++track) { - if (!mixer->activeTracks[track].channel->status) { - continue; - } - int16_t value; - mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); - sample.left += value; - mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); - sample.right += value; - } - sample.left = (sample.left * mixer->p->masterVolume) >> 8; - sample.right = (sample.right * mixer->p->masterVolume) >> 8; - if (mixer->p->externalMixing) { - blip_add_delta(mixer->p->psg.left, mixer->p->clock + i * interval, sample.left - mixer->last.left); - blip_add_delta(mixer->p->psg.right, mixer->p->clock + i * interval, sample.right - mixer->last.right); - } - mixer->last = sample; - } -} - -void _mp2kVblank(struct GBAAudioMixer* mixer) { - if (!mixer->contextAddress) { - return; - } - mLOG(GBA_AUDIO, DEBUG, "Frame"); - mixer->p->externalMixing = true; - _mp2kReload(mixer); -} diff --git a/src/gba/gba.c b/src/gba/gba.c index 41eee7435..fb0a84ae7 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -928,10 +928,6 @@ void GBABreakpoint(struct ARMCore* cpu, int immediate) { void GBAFrameStarted(struct GBA* gba) { GBATestKeypadIRQ(gba); - if (gba->audio.mixer) { - gba->audio.mixer->vblank(gba->audio.mixer); - } - size_t c; for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) { struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index e95da696c..66c125466 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -607,12 +607,6 @@ void SettingsView::updateConfig() { emit languageChanged(); } - bool oldAudioHle = m_controller->getOption("gba.audioHle", "0") != "0"; - if (oldAudioHle != m_ui.audioHle->isChecked()) { - saveSetting("gba.audioHle", m_ui.audioHle); - emit audioHleChanged(); - } - if (m_ui.multiplayerAudioAll->isChecked()) { m_controller->setQtOption("multiplayerAudio", "all"); } else if (m_ui.multiplayerAudio1->isChecked()) { @@ -740,7 +734,6 @@ void SettingsView::reloadConfig() { loadSetting("logToStdout", m_ui.logToStdout); loadSetting("logFile", m_ui.logFile); loadSetting("useDiscordPresence", m_ui.useDiscordPresence); - loadSetting("gba.audioHle", m_ui.audioHle); loadSetting("dynamicTitle", m_ui.dynamicTitle, true); loadSetting("gba.forceGbp", m_ui.forceGbp); loadSetting("vbaBugCompat", m_ui.vbaBugCompat, true); diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 3543419fc..010b4ef0d 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -63,7 +63,6 @@ signals: void pathsChanged(); void languageChanged(); void libraryCleared(); - void audioHleChanged(); public slots: void selectPage(Page); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 42e4af5a0..8539e6bdb 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -1307,14 +1307,7 @@ - - - - XQ GBA audio (experimental) - - - - + OpenGL enhancements diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index bd52b0862..c75a163ef 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -543,15 +543,6 @@ void Window::openSettingsWindow(SettingsView::Page page) { connect(settingsWindow, &SettingsView::videoRendererChanged, this, &Window::changeRenderer); connect(settingsWindow, &SettingsView::languageChanged, this, &Window::mustRestart); connect(settingsWindow, &SettingsView::pathsChanged, this, &Window::reloadConfig); - connect(settingsWindow, &SettingsView::audioHleChanged, this, [this]() { - if (!m_controller) { - return; - } - if (m_controller->platform() != mPLATFORM_GBA) { - return; - } - mustReset(); - }); #ifdef USE_SQLITE3 connect(settingsWindow, &SettingsView::libraryCleared, m_libraryView, &LibraryController::clear); #endif From f51cb153d109f842fdc5325715be97a71fcacd28 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:42:26 -0700 Subject: [PATCH 167/336] Core: Switch from blip to mAudioResampler --- include/mgba/core/core.h | 3 +- include/mgba/core/interface.h | 4 +- include/mgba/core/sync.h | 5 +- include/mgba/internal/gb/audio.h | 8 +-- include/mgba/internal/gba/audio.h | 4 -- src/core/sync.c | 10 +-- src/core/thread.c | 4 +- src/gb/audio.c | 55 ++++----------- src/gb/core.c | 13 +--- src/gba/audio.c | 51 +++----------- src/gba/core.c | 13 +--- src/platform/3ds/main.c | 22 +++--- src/platform/libretro/libretro.c | 26 +++---- src/platform/psp2/psp2-context.c | 102 +++++++++++++++------------ src/platform/python/_builder.h | 1 - src/platform/python/_builder.py | 1 - src/platform/python/mgba/audio.py | 57 --------------- src/platform/python/mgba/core.py | 8 --- src/platform/qt/AudioDevice.cpp | 67 ++++++++++++++---- src/platform/qt/AudioDevice.h | 13 ++++ src/platform/qt/AudioProcessorQt.cpp | 11 ++- src/platform/qt/AudioProcessorQt.h | 1 + src/platform/sdl/sdl-audio.c | 37 ++++------ src/platform/sdl/sdl-audio.h | 4 ++ src/platform/switch/main.c | 12 +--- src/platform/test/fuzz-main.c | 7 +- src/platform/test/perf-main.c | 1 - src/platform/wii/main.c | 79 ++++++++++----------- 28 files changed, 257 insertions(+), 362 deletions(-) delete mode 100644 src/platform/python/mgba/audio.py diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 7eeb1d8fb..a4bf5826c 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -32,6 +32,7 @@ enum mCoreChecksumType { mCHECKSUM_CRC32, }; +struct mAudioBuffer; struct mCoreConfig; struct mCoreSync; struct mDebuggerSymbols; @@ -79,7 +80,7 @@ struct mCore { void (*putPixels)(struct mCore*, const void* buffer, size_t stride); unsigned (*audioSampleRate)(const struct mCore*); - struct blip_t* (*getAudioChannel)(struct mCore*, int ch); + struct mAudioBuffer* (*getAudioBuffer)(struct mCore*); void (*setAudioBufferSize)(struct mCore*, size_t samples); size_t (*getAudioBufferSize)(struct mCore*); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index f1af5e50d..b07f300f3 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -16,7 +16,7 @@ CXX_GUARD_START struct mCore; struct mStateExtdataItem; -struct blip_t; +struct mAudioBuffer; enum mCoreFeature { mCORE_FEATURE_OPENGL = 1, @@ -41,7 +41,7 @@ struct mAVStream { void (*audioRateChanged)(struct mAVStream*, unsigned rate); void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride); void (*postAudioFrame)(struct mAVStream*, int16_t left, int16_t right); - void (*postAudioBuffer)(struct mAVStream*, struct blip_t* left, struct blip_t* right); + void (*postAudioBuffer)(struct mAVStream*, struct mAudioBuffer*); }; struct mStereoSample { diff --git a/include/mgba/core/sync.h b/include/mgba/core/sync.h index a44994b07..df4e777bb 100644 --- a/include/mgba/core/sync.h +++ b/include/mgba/core/sync.h @@ -22,6 +22,7 @@ struct mCoreSync { bool audioWait; Condition audioRequiredCond; Mutex audioBufferMutex; + size_t audioHighWater; float fpsTarget; }; @@ -32,8 +33,8 @@ bool mCoreSyncWaitFrameStart(struct mCoreSync* sync); void mCoreSyncWaitFrameEnd(struct mCoreSync* sync); void mCoreSyncSetVideoSync(struct mCoreSync* sync, bool wait); -struct blip_t; -bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct blip_t*, size_t samples); +struct mAudioBuffer; +bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct mAudioBuffer*); void mCoreSyncLockAudio(struct mCoreSync* sync); void mCoreSyncUnlockAudio(struct mCoreSync* sync); void mCoreSyncConsumeAudio(struct mCoreSync* sync); diff --git a/include/mgba/internal/gb/audio.h b/include/mgba/internal/gb/audio.h index 5b8993ac5..8b9b775c3 100644 --- a/include/mgba/internal/gb/audio.h +++ b/include/mgba/internal/gb/audio.h @@ -12,6 +12,7 @@ CXX_GUARD_START #include #include +#include #define GB_MAX_SAMPLES 32 @@ -166,14 +167,9 @@ struct GBAudio { struct GBAudioWaveChannel ch3; struct GBAudioNoiseChannel ch4; - struct blip_t* left; - struct blip_t* right; - int16_t lastLeft; - int16_t lastRight; + struct mAudioBuffer buffer; int32_t capLeft; int32_t capRight; - int clock; - int32_t clockRate; uint8_t volumeRight; uint8_t volumeLeft; diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index a6eb4824d..5b5db3a62 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -63,10 +63,6 @@ struct GBAAudio { struct GBAAudioFIFO chA; struct GBAAudioFIFO chB; - int16_t lastLeft; - int16_t lastRight; - int clock; - uint8_t volume; bool volumeChA; bool volumeChB; diff --git a/src/core/sync.c b/src/core/sync.c index b2a65493b..e46e7dcda 100644 --- a/src/core/sync.c +++ b/src/core/sync.c @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include +#include static void _changeVideoSync(struct mCoreSync* sync, bool wait) { // Make sure the video thread can process events while the GBA thread is paused @@ -79,17 +79,17 @@ void mCoreSyncSetVideoSync(struct mCoreSync* sync, bool wait) { _changeVideoSync(sync, wait); } -bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct blip_t* buf, size_t samples) { +bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct mAudioBuffer* buf) { if (!sync) { return true; } - size_t produced = blip_samples_avail(buf); + size_t produced = mAudioBufferAvailable(buf); size_t producedNew = produced; - while (sync->audioWait && producedNew >= samples) { + while (sync->audioWait && sync->audioHighWater && producedNew >= sync->audioHighWater) { ConditionWait(&sync->audioRequiredCond, &sync->audioBufferMutex); produced = producedNew; - producedNew = blip_samples_avail(buf); + producedNew = mAudioBufferAvailable(buf); } MutexUnlock(&sync->audioBufferMutex); return producedNew != produced; diff --git a/src/core/thread.c b/src/core/thread.c index 18c1c20e1..0be5f81e2 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -5,7 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include #include #ifdef ENABLE_SCRIPTING #include @@ -368,7 +367,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { if (impl->sync.audioWait) { MutexUnlock(&impl->stateMutex); mCoreSyncLockAudio(&impl->sync); - mCoreSyncProduceAudio(&impl->sync, core->getAudioChannel(core, 0), core->getAudioBufferSize(core)); + mCoreSyncProduceAudio(&impl->sync, core->getAudioBuffer(core)); MutexLock(&impl->stateMutex); } } @@ -498,6 +497,7 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { threadContext->impl->sync.audioWait = threadContext->core->opts.audioSync; threadContext->impl->sync.videoFrameWait = threadContext->core->opts.videoSync; threadContext->impl->sync.fpsTarget = threadContext->core->opts.fpsTarget; + threadContext->impl->sync.audioHighWater = 512; MutexLock(&threadContext->impl->stateMutex); ThreadCreate(&threadContext->impl->thread, _mCoreThreadRun, threadContext); diff --git a/src/gb/audio.c b/src/gb/audio.c index cf5445e15..4230fb88c 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -5,7 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include #include #include #include @@ -15,15 +14,10 @@ #include #endif -#ifdef __3DS__ -#define blip_add_delta blip_add_delta_fast -#endif - +#define AUDIO_BUFFER_SAMPLES 0x4000 #define FRAME_CYCLES (DMG_SM83_FREQUENCY >> 9) const uint32_t DMG_SM83_FREQUENCY = 0x400000; -static const int CLOCKS_PER_BLIP_FRAME = 0x1000; -static const unsigned BLIP_BUFFER_SIZE = 0x4000; static const int SAMPLE_INTERVAL = 32; static const int FILTER = 65368; const int GB_AUDIO_VOLUME_MAX = 0x100; @@ -57,12 +51,7 @@ static const int _squareChannelDuty[4][8] = { void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAudioStyle style) { audio->samples = samples; - audio->left = blip_new(BLIP_BUFFER_SIZE); - audio->right = blip_new(BLIP_BUFFER_SIZE); - audio->clockRate = DMG_SM83_FREQUENCY; - // Guess too large; we hang producing extra samples if we guess too low - blip_set_rates(audio->left, DMG_SM83_FREQUENCY, 96000); - blip_set_rates(audio->right, DMG_SM83_FREQUENCY, 96000); + mAudioBufferInit(&audio->buffer, AUDIO_BUFFER_SAMPLES, 2); audio->forceDisableCh[0] = false; audio->forceDisableCh[1] = false; audio->forceDisableCh[2] = false; @@ -86,8 +75,7 @@ void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAu } void GBAudioDeinit(struct GBAudio* audio) { - blip_delete(audio->left); - blip_delete(audio->right); + mAudioBufferDeinit(&audio->buffer); } void GBAudioReset(struct GBAudio* audio) { @@ -123,11 +111,9 @@ void GBAudioReset(struct GBAudio* audio) { audio->sampleInterval = SAMPLE_INTERVAL * GB_MAX_SAMPLES; audio->lastSample = 0; audio->sampleIndex = 0; - audio->lastLeft = 0; - audio->lastRight = 0; audio->capLeft = 0; audio->capRight = 0; - audio->clock = 0; + mAudioBufferClear(&audio->buffer); audio->playingCh1 = false; audio->playingCh2 = false; audio->playingCh3 = false; @@ -140,14 +126,8 @@ void GBAudioReset(struct GBAudio* audio) { } void GBAudioResizeBuffer(struct GBAudio* audio, size_t samples) { - if (samples > BLIP_BUFFER_SIZE / 2) { - samples = BLIP_BUFFER_SIZE / 2; - } mCoreSyncLockAudio(audio->p->sync); audio->samples = samples; - blip_clear(audio->left); - blip_clear(audio->right); - audio->clock = 0; mCoreSyncConsumeAudio(audio->p->sync); } @@ -845,34 +825,25 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { unsigned produced; int i; for (i = 0; i < GB_MAX_SAMPLES; ++i) { - int16_t sampleLeft = audio->currentSamples[i].left; - int16_t sampleRight = audio->currentSamples[i].right; - if ((size_t) blip_samples_avail(audio->left) < audio->samples) { - blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft); - blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight); - audio->lastLeft = sampleLeft; - audio->lastRight = sampleRight; - audio->clock += SAMPLE_INTERVAL; - if (audio->clock >= CLOCKS_PER_BLIP_FRAME) { - blip_end_frame(audio->left, CLOCKS_PER_BLIP_FRAME); - blip_end_frame(audio->right, CLOCKS_PER_BLIP_FRAME); - audio->clock -= CLOCKS_PER_BLIP_FRAME; - } - } + int16_t sample[2] = { + audio->currentSamples[i].left, + audio->currentSamples[i].right + }; + mAudioBufferWrite(&audio->buffer, sample, 1); if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight); + audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); } } - produced = blip_samples_avail(audio->left); + produced = mAudioBufferAvailable(&audio->buffer); bool wait = produced >= audio->samples; - if (!mCoreSyncProduceAudio(audio->p->sync, audio->left, audio->samples)) { + if (!mCoreSyncProduceAudio(audio->p->sync, &audio->buffer)) { // Interrupted audio->p->earlyExit = true; } if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, audio->left, audio->right); + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->buffer); } mTimingSchedule(timing, &audio->sampleEvent, audio->sampleInterval * audio->timingFactor - cyclesLate); } diff --git a/src/gb/core.c b/src/gb/core.c index 9ee6d3f84..7023b29f7 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -428,16 +428,9 @@ static void _GBCorePutPixels(struct mCore* core, const void* buffer, size_t stri gbcore->renderer.d.putPixels(&gbcore->renderer.d, stride, buffer); } -static struct blip_t* _GBCoreGetAudioChannel(struct mCore* core, int ch) { +static struct mAudioBuffer* _GBCoreGetAudioBuffer(struct mCore* core) { struct GB* gb = core->board; - switch (ch) { - case 0: - return gb->audio.left; - case 1: - return gb->audio.right; - default: - return NULL; - } + return &gb->audio.buffer; } static void _GBCoreSetAudioBufferSize(struct mCore* core, size_t samples) { @@ -1308,7 +1301,7 @@ struct mCore* GBCoreCreate(void) { core->getPixels = _GBCoreGetPixels; core->putPixels = _GBCorePutPixels; core->audioSampleRate = _GBCoreAudioSampleRate; - core->getAudioChannel = _GBCoreGetAudioChannel; + core->getAudioBuffer = _GBCoreGetAudioBuffer; core->setAudioBufferSize = _GBCoreSetAudioBufferSize; core->getAudioBufferSize = _GBCoreGetAudioBufferSize; core->setAVStream = _GBCoreSetAVStream; diff --git a/src/gba/audio.c b/src/gba/audio.c index 56f42b14f..8ccc7f9d8 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -16,17 +15,12 @@ #define MP2K_LOCK_MAX 8 -#ifdef __3DS__ -#define blip_add_delta blip_add_delta_fast -#endif - mLOG_DEFINE_CATEGORY(GBA_AUDIO, "GBA Audio", "gba.audio"); const unsigned GBA_AUDIO_SAMPLES = 2048; const int GBA_AUDIO_VOLUME_MAX = 0x100; static const int SAMPLE_INTERVAL = GBA_ARM7TDMI_FREQUENCY / 0x4000; -static const int CLOCKS_PER_FRAME = 0x800; static int _applyBias(struct GBAAudio* audio, int sample); static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate); @@ -41,14 +35,10 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { #ifdef __BIG_ENDIAN__ ++nr52; #endif - GBAudioInit(&audio->psg, 0, nr52, GB_AUDIO_GBA); + GBAudioInit(&audio->psg, samples, nr52, GB_AUDIO_GBA); audio->psg.timing = &audio->p->timing; - audio->psg.clockRate = GBA_ARM7TDMI_FREQUENCY; audio->psg.frameEvent.context = audio; audio->samples = samples; - // Guess too large; we hang producing extra samples if we guess too low - blip_set_rates(audio->psg.left, GBA_ARM7TDMI_FREQUENCY, 96000); - blip_set_rates(audio->psg.right, GBA_ARM7TDMI_FREQUENCY, 96000); audio->forceDisableChA = false; audio->forceDisableChB = false; @@ -93,10 +83,6 @@ void GBAAudioReset(struct GBAAudio* audio) { audio->enable = false; audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; audio->psg.sampleInterval = audio->sampleInterval; - - blip_clear(audio->psg.left); - blip_clear(audio->psg.right); - audio->clock = 0; } void GBAAudioDeinit(struct GBAAudio* audio) { @@ -104,14 +90,9 @@ void GBAAudioDeinit(struct GBAAudio* audio) { } void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) { - if (samples > 0x2000) { - samples = 0x2000; - } mCoreSyncLockAudio(audio->p->sync); audio->samples = samples; - blip_clear(audio->psg.left); - blip_clear(audio->psg.right); - audio->clock = 0; + audio->psg.samples = samples; mCoreSyncConsumeAudio(audio->p->sync); } @@ -414,34 +395,24 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { unsigned produced; int i; for (i = 0; i < samples; ++i) { - int16_t sampleLeft = audio->currentSamples[i].left; - int16_t sampleRight = audio->currentSamples[i].right; - if ((size_t) blip_samples_avail(audio->psg.left) < audio->samples) { - blip_add_delta(audio->psg.left, audio->clock, sampleLeft - audio->lastLeft); - blip_add_delta(audio->psg.right, audio->clock, sampleRight - audio->lastRight); - audio->lastLeft = sampleLeft; - audio->lastRight = sampleRight; - audio->clock += audio->sampleInterval; - if (audio->clock >= CLOCKS_PER_FRAME) { - blip_end_frame(audio->psg.left, CLOCKS_PER_FRAME); - blip_end_frame(audio->psg.right, CLOCKS_PER_FRAME); - audio->clock -= CLOCKS_PER_FRAME; - } - } - + int16_t sample[2] = { + audio->currentSamples[i].left, + audio->currentSamples[i].right + }; + mAudioBufferWrite(&audio->psg.buffer, sample, 1); if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight); + audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); } } - produced = blip_samples_avail(audio->psg.left); + produced = mAudioBufferAvailable(&audio->psg.buffer); bool wait = produced >= audio->samples; - if (!mCoreSyncProduceAudio(audio->p->sync, audio->psg.left, audio->samples)) { + if (!mCoreSyncProduceAudio(audio->p->sync, &audio->psg.buffer)) { // Interrupted audio->p->earlyExit = true; } if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, audio->psg.left, audio->psg.right); + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->psg.buffer); } mTimingSchedule(timing, &audio->sampleEvent, SAMPLE_INTERVAL - cyclesLate); diff --git a/src/gba/core.c b/src/gba/core.c index fbdd5e85b..4a437f36d 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -558,16 +558,9 @@ static unsigned _GBACoreAudioSampleRate(const struct mCore* core) { return 65536; } -static struct blip_t* _GBACoreGetAudioChannel(struct mCore* core, int ch) { +static struct mAudioBuffer* _GBACoreGetAudioBuffer(struct mCore* core) { struct GBA* gba = core->board; - switch (ch) { - case 0: - return gba->audio.psg.left; - case 1: - return gba->audio.psg.right; - default: - return NULL; - } + return &gba->audio.psg.buffer; } static void _GBACoreSetAudioBufferSize(struct mCore* core, size_t samples) { @@ -1505,7 +1498,7 @@ struct mCore* GBACoreCreate(void) { core->getPixels = _GBACoreGetPixels; core->putPixels = _GBACorePutPixels; core->audioSampleRate = _GBACoreAudioSampleRate; - core->getAudioChannel = _GBACoreGetAudioChannel; + core->getAudioBuffer = _GBACoreGetAudioBuffer; core->setAudioBufferSize = _GBACoreSetAudioBufferSize; core->getAudioBufferSize = _GBACoreGetAudioBufferSize; core->addCoreCallbacks = _GBACoreAddCoreCallbacks; diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index fb4f63a56..c85103bce 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -4,7 +4,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include #include #include #ifdef M_CORE_GBA @@ -61,7 +60,7 @@ static enum DarkenMode { #define _3DS_INPUT 0x3344534B -#define AUDIO_SAMPLES 384 +#define AUDIO_SAMPLES 1280 #define AUDIO_SAMPLE_BUFFER (AUDIO_SAMPLES * 16) #define DSP_BUFFERS 4 @@ -190,7 +189,7 @@ static void _map3DSKey(struct mInputMap* map, int ctrKey, int key) { mInputBindKey(map, _3DS_INPUT, __builtin_ctz(ctrKey), key); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right); +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer); static void _drawStart(void) { if (frameStarted) { @@ -343,12 +342,13 @@ static void _gameLoaded(struct mGUIRunner* runner) { } osSetSpeedupEnable(true); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 32768); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 32768); if (hasSound != NO_SOUND) { audioPos = 0; } if (hasSound == DSP_SUPPORTED) { + unsigned sampleRate = runner->core->audioSampleRate(runner->core); + double fauxClock = mCoreCalculateFramerateRatio(runner->core, 16756991. / 280095.); + ndspChnSetRate(0, sampleRate * fauxClock); memset(audioLeft, 0, AUDIO_SAMPLE_BUFFER * 2 * sizeof(int16_t)); } unsigned mode; @@ -607,8 +607,7 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_FLIP_VERT(1)); if (hasSound == NO_SOUND) { - blip_clear(runner->core->getAudioChannel(runner->core, 0)); - blip_clear(runner->core->getAudioChannel(runner->core, 1)); + mAudioBufferClear(runner->core->getAudioBuffer(runner->core)); } _drawTex(runner->core, faded, interframeBlending); @@ -775,15 +774,14 @@ static void _requestImage(struct mImageSource* source, const void** buffer, size CAMU_SetReceiving(&imageSource->handles[0], imageSource->buffer, PORT_CAM1, imageSource->bufferSize, imageSource->transferSize); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); if (hasSound == DSP_SUPPORTED) { int startId = bufferId; while (dspBuffer[bufferId].status == NDSP_WBUF_QUEUED || dspBuffer[bufferId].status == NDSP_WBUF_PLAYING) { bufferId = (bufferId + 1) & (DSP_BUFFERS - 1); if (bufferId == startId) { - blip_clear(left); - blip_clear(right); + mAudioBufferClear(buffer); return; } } @@ -791,8 +789,7 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig memset(&dspBuffer[bufferId], 0, sizeof(dspBuffer[bufferId])); dspBuffer[bufferId].data_pcm16 = tmpBuf; dspBuffer[bufferId].nsamples = AUDIO_SAMPLES; - blip_read_samples(left, dspBuffer[bufferId].data_pcm16, AUDIO_SAMPLES, true); - blip_read_samples(right, dspBuffer[bufferId].data_pcm16 + 1, AUDIO_SAMPLES, true); + mAudioBufferRead(buffer, dspBuffer[bufferId].data_pcm16, AUDIO_SAMPLES); DSP_FlushDataCache(dspBuffer[bufferId].data_pcm16, AUDIO_SAMPLES * 2 * sizeof(int16_t)); ndspChnWaveBufAdd(0, &dspBuffer[bufferId]); } @@ -857,7 +854,6 @@ int main(int argc, char* argv[]) { ndspChnReset(0); ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16); ndspChnSetInterp(0, NDSP_INTERP_NONE); - ndspChnSetRate(0, 32822); ndspChnWaveBufClear(0); audioLeft = linearMemAlign(AUDIO_SAMPLES * DSP_BUFFERS * 2 * sizeof(int16_t), 0x80); memset(dspBuffer, 0, sizeof(dspBuffer)); diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 69c547b57..8478eb298 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -7,7 +7,6 @@ #include -#include #include #include #include @@ -30,7 +29,6 @@ #include "libretro_core_options.h" #define GB_SAMPLES 512 -#define SAMPLE_RATE 32768 /* An alpha factor of 1/180 is *somewhat* equivalent * to calculating the average for the last 180 * frames, or 3 seconds of runtime... */ @@ -54,7 +52,7 @@ static retro_set_sensor_state_t sensorStateCallback; static void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args); -static void _postAudioBuffer(struct mAVStream*, blip_t* left, blip_t* right); +static void _postAudioBuffer(struct mAVStream*, struct mAudioBuffer*); static void _setRumble(struct mRumble* rumble, int enable); static uint8_t _readLux(struct GBALuminanceSource* lux); static void _updateLux(struct GBALuminanceSource* lux); @@ -424,7 +422,7 @@ void retro_get_system_av_info(struct retro_system_av_info* info) { info->geometry.aspect_ratio = width / (double) height; info->timing.fps = core->frequency(core) / (float) core->frameCycles(core); - info->timing.sample_rate = SAMPLE_RATE; + info->timing.sample_rate = core->audioSampleRate(core); } void retro_init(void) { @@ -613,9 +611,8 @@ void retro_run(void) { #ifdef M_CORE_GBA if (core->platform(core) == mPLATFORM_GBA) { - blip_t *audioChannelLeft = core->getAudioChannel(core, 0); - blip_t *audioChannelRight = core->getAudioChannel(core, 1); - int samplesAvail = blip_samples_avail(audioChannelLeft); + struct mAudioBuffer *buffer = core->getAudioBuffer(core); + int samplesAvail = mAudioBufferAvailable(buffer); if (samplesAvail > 0) { /* Update 'running average' of number of * samples per frame. @@ -632,8 +629,7 @@ void retro_run(void) { audioSampleBufferSize = (samplesToRead * 2); audioSampleBuffer = realloc(audioSampleBuffer, audioSampleBufferSize * sizeof(int16_t)); } - int produced = blip_read_samples(audioChannelLeft, audioSampleBuffer, samplesToRead, true); - blip_read_samples(audioChannelRight, audioSampleBuffer + 1, samplesToRead, true); + int produced = mAudioBufferRead(buffer, audioSampleBuffer, samplesToRead); if (produced > 0) { if (audioLowPassEnabled) { _audioLowPassFilter(audioSampleBuffer, produced); @@ -884,9 +880,9 @@ bool retro_load_game(const struct retro_game_info* game) { * to nominal number of samples per frame. * Buffer will be resized as required in * retro_run(). */ - size_t audioSamplesPerFrame = (size_t)((float) SAMPLE_RATE * (float) core->frameCycles(core) / + size_t audioSamplesPerFrame = (size_t)((float) core->audioSampleRate(core) * (float) core->frameCycles(core) / (float)core->frequency(core)); - audioSampleBufferSize = audioSamplesPerFrame * 2; + audioSampleBufferSize = ceil(audioSamplesPerFrame) * 2; audioSampleBuffer = malloc(audioSampleBufferSize * sizeof(int16_t)); audioSamplesPerFrameAvg = (float) audioSamplesPerFrame; /* Internal audio buffer size should be @@ -918,9 +914,6 @@ bool retro_load_game(const struct retro_game_info* game) { core->setAudioBufferSize(core, GB_SAMPLES); } - blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), SAMPLE_RATE); - blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), SAMPLE_RATE); - core->setPeripheral(core, mPERIPH_RUMBLE, &rumble); core->setPeripheral(core, mPERIPH_ROTATION, &rotation); @@ -1238,10 +1231,9 @@ void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel level, con } /* Used only for GB/GBC content */ -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); - int produced = blip_read_samples(left, audioSampleBuffer, GB_SAMPLES, true); - blip_read_samples(right, audioSampleBuffer + 1, GB_SAMPLES, true); + int produced = mAudioBufferRead(buffer, audioSampleBuffer, GB_SAMPLES); if (produced > 0) { if (audioLowPassEnabled) { _audioLowPassFilter(audioSampleBuffer, produced); diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 755021f6f..36253aa07 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -5,7 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "psp2-context.h" -#include #include #ifdef M_CORE_GBA @@ -18,9 +17,10 @@ #include "feature/gui/gui-runner.h" #include -#include +#include #include #include +#include #include #include #include @@ -84,14 +84,21 @@ bool frameLimiter = true; extern const uint8_t _binary_backdrop_png_start[]; static vita2d_texture* backdrop = 0; +#define BUFFERS 16 #define PSP2_SAMPLES 512 -#define PSP2_AUDIO_BUFFER_SIZE (PSP2_SAMPLES * 16) +#define PSP2_AUDIO_BUFFER_SIZE (PSP2_SAMPLES * BUFFERS) + +struct mPSP2AudioBuffer { + int16_t samples[PSP2_SAMPLES * 2] __attribute__((__aligned__(64))); + bool full; +}; static struct mPSP2AudioContext { - struct mStereoSample buffer[PSP2_AUDIO_BUFFER_SIZE]; - size_t writeOffset; - size_t readOffset; - size_t samples; + struct mPSP2AudioBuffer outputBuffers[BUFFERS]; + int currentAudioBuffer; + int nextAudioBuffer; + struct mAudioBuffer buffer; + struct mAudioResampler resampler; Mutex mutex; Condition cond; bool running; @@ -103,29 +110,26 @@ void mPSP2MapKey(struct mInputMap* map, int pspKey, int key) { static THREAD_ENTRY _audioThread(void* context) { struct mPSP2AudioContext* audio = (struct mPSP2AudioContext*) context; - uint32_t zeroBuffer[PSP2_SAMPLES] = {0}; - void* buffer = zeroBuffer; + const int16_t zeroBuffer[PSP2_SAMPLES * 2] __attribute__((__aligned__(64))) = {0}; + const void* buffer = zeroBuffer; int audioPort = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, PSP2_SAMPLES, 48000, SCE_AUDIO_OUT_MODE_STEREO); + struct mPSP2AudioBuffer* outputBuffer = NULL; while (audio->running) { MutexLock(&audio->mutex); - if (buffer != zeroBuffer) { + if (outputBuffer) { // Can only happen in successive iterations - audio->samples -= PSP2_SAMPLES; + outputBuffer->full = false; ConditionWake(&audio->cond); } - if (audio->samples >= PSP2_SAMPLES) { - buffer = &audio->buffer[audio->readOffset]; - audio->readOffset += PSP2_SAMPLES; - if (audio->readOffset >= PSP2_AUDIO_BUFFER_SIZE) { - audio->readOffset = 0; - } - // Don't mark samples as read until the next loop iteration to prevent - // writing to the buffer while being read (see above) + outputBuffer = &audio->outputBuffers[audio->currentAudioBuffer]; + if (outputBuffer->full) { + buffer = outputBuffer->samples; + audio->currentAudioBuffer = (audio->currentAudioBuffer + 1) % BUFFERS; } else { buffer = zeroBuffer; + outputBuffer = NULL; } MutexUnlock(&audio->mutex); - sceAudioOutOutput(audioPort, buffer); } sceAudioOutReleasePort(audioPort); @@ -243,25 +247,21 @@ static void _requestImage(struct mImageSource* source, const void** buffer, size sceCameraRead(imageSource->cam - 1, &read); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) { UNUSED(stream); MutexLock(&audioContext.mutex); - while (audioContext.samples + PSP2_SAMPLES >= PSP2_AUDIO_BUFFER_SIZE) { - if (!frameLimiter) { - blip_clear(left); - blip_clear(right); - MutexUnlock(&audioContext.mutex); - return; + mAudioResamplerProcess(&audioContext.resampler); + while (mAudioBufferAvailable(&audioContext.buffer) >= PSP2_SAMPLES) { + struct mPSP2AudioBuffer* buffer = &audioContext.outputBuffers[audioContext.nextAudioBuffer]; + while (buffer->full) { + if (!frameLimiter) { + break; + } + ConditionWait(&audioContext.cond, &audioContext.mutex); } - ConditionWait(&audioContext.cond, &audioContext.mutex); - } - struct mStereoSample* samples = &audioContext.buffer[audioContext.writeOffset]; - blip_read_samples(left, &samples[0].left, PSP2_SAMPLES, true); - blip_read_samples(right, &samples[0].right, PSP2_SAMPLES, true); - audioContext.samples += PSP2_SAMPLES; - audioContext.writeOffset += PSP2_SAMPLES; - if (audioContext.writeOffset >= PSP2_AUDIO_BUFFER_SIZE) { - audioContext.writeOffset = 0; + mAudioBufferRead(&audioContext.buffer, buffer->samples, PSP2_SAMPLES); + buffer->full = true; + audioContext.nextAudioBuffer = (audioContext.nextAudioBuffer + 1) % BUFFERS; } MutexUnlock(&audioContext.mutex); } @@ -294,7 +294,11 @@ void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit) { UNUSED(runner); if (!frameLimiter && limit) { MutexLock(&audioContext.mutex); - while (audioContext.samples) { + while (true) { + struct mPSP2AudioBuffer* buffer = &audioContext.outputBuffers[audioContext.currentAudioBuffer]; + if (!buffer->full) { + break; + } ConditionWait(&audioContext.cond, &audioContext.mutex); } MutexUnlock(&audioContext.mutex); @@ -334,6 +338,9 @@ void mPSP2Setup(struct mGUIRunner* runner) { runner->core->setVideoBuffer(runner->core, vita2d_texture_get_datap(tex[currentTex]), 256); runner->core->setAudioBufferSize(runner->core, PSP2_SAMPLES); + mAudioBufferInit(&audioContext.buffer, PSP2_AUDIO_BUFFER_SIZE, 2); + mAudioResamplerInit(&audioContext.resampler, mINTERPOLATOR_COSINE); + mAudioResamplerSetDestination(&audioContext.resampler, &audioContext.buffer, 48000); rotation.d.sample = _sampleRotation; rotation.d.readTiltX = _readTiltX; @@ -374,12 +381,6 @@ void mPSP2Setup(struct mGUIRunner* runner) { } void mPSP2LoadROM(struct mGUIRunner* runner) { - float rate = 60.0f / 1.001f; - sceDisplayGetRefreshRate(&rate); - double ratio = mCoreCalculateFramerateRatio(runner->core, rate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); - switch (runner->core->platform(runner->core)) { #ifdef M_CORE_GBA case mPLATFORM_GBA: @@ -415,10 +416,17 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { MutexInit(&audioContext.mutex); ConditionInit(&audioContext.cond); - memset(audioContext.buffer, 0, sizeof(audioContext.buffer)); - audioContext.readOffset = 0; - audioContext.writeOffset = 0; + mAudioBufferClear(&audioContext.buffer); + audioContext.nextAudioBuffer = 0; + audioContext.currentAudioBuffer = 0; audioContext.running = true; + + float rate = 60.0f / 1.001f; + sceDisplayGetRefreshRate(&rate); + double ratio = mCoreCalculateFramerateRatio(runner->core, rate); + unsigned sampleRate = runner->core->audioSampleRate(runner->core); + mAudioBufferClear(&audioContext.buffer); + mAudioResamplerSetSource(&audioContext.resampler, runner->core->getAudioBuffer(runner->core), sampleRate / ratio, true); ThreadCreate(&audioThread, _audioThread, &audioContext); } @@ -483,6 +491,8 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { void mPSP2Teardown(struct mGUIRunner* runner) { UNUSED(runner); mCircleBufferDeinit(&rumble.history); + mAudioResamplerDeinit(&audioContext.resampler); + mAudioBufferDeinit(&audioContext.buffer); vita2d_free_texture(tex[0]); vita2d_free_texture(tex[1]); vita2d_free_texture(screenshot); diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index e06e4f5cc..0b51eb19d 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -36,7 +36,6 @@ void free(void*); #include -#include #include #include #include diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index 1e21cc82f..1defca537 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -21,7 +21,6 @@ ffi.set_source("mgba._pylib", """ #define MGBA_EXPORT #include #define OPAQUE_THREADING -#include #include #include #include diff --git a/src/platform/python/mgba/audio.py b/src/platform/python/mgba/audio.py deleted file mode 100644 index a833d0827..000000000 --- a/src/platform/python/mgba/audio.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2013-2018 Jeffrey Pfau -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -from ._pylib import ffi, lib # pylint: disable=no-name-in-module - - -class Buffer(object): - def __init__(self, native, internal_rate): - self._native = native - self._internal_rate = internal_rate - - @property - def available(self): - return lib.blip_samples_avail(self._native) - - def set_rate(self, rate): - lib.blip_set_rates(self._native, self._internal_rate, rate) - - def read(self, samples): - buffer = ffi.new("short[%i]" % samples) - count = self.read_into(buffer, samples, 1, 0) - return buffer[:count] - - def read_into(self, buffer, samples, channels=1, interleave=0): - return lib.blip_read_samples(self._native, ffi.addressof(buffer, interleave), samples, channels == 2) - - def clear(self): - lib.blip_clear(self._native) - - -class StereoBuffer(object): - def __init__(self, left, right): - self._left = left - self._right = right - - @property - def available(self): - return min(self._left.available, self._right.available) - - def set_rate(self, rate): - self._left.set_rate(rate) - self._right.set_rate(rate) - - def read(self, samples): - buffer = ffi.new("short[%i]" % (2 * samples)) - count = self.read_into(buffer, samples) - return buffer[0:2 * count] - - def read_into(self, buffer, samples): - samples = self._left.read_into(buffer, samples, 2, 0) - return self._right.read_into(buffer, samples, 2, 1) - - def clear(self): - self._left.clear() - self._right.clear() diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 51f543d3a..75fd1a1cc 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -250,14 +250,6 @@ class Core(object): def audio_buffer_size(self): return self._core.getAudioBufferSize(self._core) - @protected - def get_audio_channels(self): - return audio.StereoBuffer(self.get_audio_channel(0), self.get_audio_channel(1)); - - @protected - def get_audio_channel(self, channel): - return audio.Buffer(self._core.getAudioChannel(self._core, channel), self.frequency) - @protected def reset(self): self._core.reset(self._core) diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index ec6dd3133..bf027cd43 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -7,11 +7,12 @@ #include "LogController.h" -#include #include #include #include +#include + using namespace QGBA; AudioDevice::AudioDevice(QObject* parent) @@ -19,6 +20,13 @@ AudioDevice::AudioDevice(QObject* parent) , m_context(nullptr) { setOpenMode(ReadOnly); + mAudioBufferInit(&m_buffer, 0x4000, 2); + mAudioResamplerInit(&m_resampler, mINTERPOLATOR_SINC); +} + +AudioDevice::~AudioDevice() { + mAudioResamplerDeinit(&m_resampler); + mAudioBufferDeinit(&m_buffer); } void AudioDevice::setFormat(const QAudioFormat& format) { @@ -26,15 +34,18 @@ void AudioDevice::setFormat(const QAudioFormat& format) { LOG(QT, INFO) << tr("Can't set format of context-less audio device"); return; } - double fauxClock = mCoreCalculateFramerateRatio(m_context->core, m_context->impl->sync.fpsTarget); mCoreSyncLockAudio(&m_context->impl->sync); - blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), - m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); - blip_set_rates(m_context->core->getAudioChannel(m_context->core, 1), - m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); + mCore* core = m_context->core; + mAudioResamplerSetSource(&m_resampler, core->getAudioBuffer(core), core->audioSampleRate(core), true); + m_format = format; + adjustResampler(); mCoreSyncUnlockAudio(&m_context->impl->sync); } +void AudioDevice::setBufferSamples(int samples) { + m_samples = samples; +} + void AudioDevice::setInput(mCoreThread* input) { m_context = input; } @@ -45,15 +56,25 @@ qint64 AudioDevice::readData(char* data, qint64 maxSize) { return 0; } - maxSize /= sizeof(mStereoSample); + if (!maxSize) { + return 0; + } + mCoreSyncLockAudio(&m_context->impl->sync); - int available = std::min({ - blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)), - maxSize, + mAudioResamplerProcess(&m_resampler); + if (mAudioBufferAvailable(&m_buffer) < 128) { + mCoreSyncConsumeAudio(&m_context->impl->sync); + // Audio is running slow...let's wait a tiny bit for more to come in + QThread::usleep(100); + mCoreSyncLockAudio(&m_context->impl->sync); + mAudioResamplerProcess(&m_resampler); + } + quint64 available = std::min({ + mAudioBufferAvailable(&m_buffer), + static_cast(maxSize / sizeof(mStereoSample)), std::numeric_limits::max() }); - blip_read_samples(m_context->core->getAudioChannel(m_context->core, 0), &reinterpret_cast(data)->left, available, true); - blip_read_samples(m_context->core->getAudioChannel(m_context->core, 1), &reinterpret_cast(data)->right, available, true); + mAudioBufferRead(&m_buffer, reinterpret_cast(data), available); mCoreSyncConsumeAudio(&m_context->impl->sync); return available * sizeof(mStereoSample); } @@ -64,15 +85,33 @@ qint64 AudioDevice::writeData(const char*, qint64) { } bool AudioDevice::atEnd() const { - return !bytesAvailable(); + return false; } qint64 AudioDevice::bytesAvailable() const { + if (!m_context->core) { + return true; + } + int available = mAudioBufferAvailable(&m_buffer); + return available * sizeof(mStereoSample); +} + +qint64 AudioDevice::bytesAvailable() { if (!m_context->core) { return true; } mCoreSyncLockAudio(&m_context->impl->sync); - int available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)); + adjustResampler(); + mAudioResamplerProcess(&m_resampler); + int available = mAudioBufferAvailable(&m_buffer); mCoreSyncUnlockAudio(&m_context->impl->sync); return available * sizeof(mStereoSample); } + +void AudioDevice::adjustResampler() { + mCore* core = m_context->core; + double fauxClock = mCoreCalculateFramerateRatio(m_context->core, m_context->impl->sync.fpsTarget); + mAudioResamplerSetDestination(&m_resampler, &m_buffer, m_format.sampleRate() * fauxClock); + m_context->impl->sync.audioHighWater = m_samples + m_resampler.highWaterMark + m_resampler.lowWaterMark; + m_context->impl->sync.audioHighWater *= core->audioSampleRate(core) / (m_format.sampleRate() * fauxClock); +} diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index e4386bda2..04247cf98 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -8,6 +8,9 @@ #include #include +#include +#include + struct mCoreThread; namespace QGBA { @@ -17,18 +20,28 @@ Q_OBJECT public: AudioDevice(QObject* parent = nullptr); + virtual ~AudioDevice(); void setInput(mCoreThread* input); void setFormat(const QAudioFormat& format); + void setBufferSamples(int samples); bool atEnd() const override; qint64 bytesAvailable() const override; + qint64 bytesAvailable(); + bool isSequential() const override { return true; } protected: virtual qint64 readData(char* data, qint64 maxSize) override; virtual qint64 writeData(const char* data, qint64 maxSize) override; private: + size_t m_samples = 512; + QAudioFormat m_format; mCoreThread* m_context; + mAudioBuffer m_buffer; + mAudioResampler m_resampler; + + void adjustResampler(); }; } diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index 3e4c5474e..87ad5b5ac 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -83,6 +83,7 @@ bool AudioProcessorQt::start() { if (state != QAudio::IdleState) { return; } + recheckUnderflow(); m_recheckTimer.start(); }); #endif @@ -91,6 +92,7 @@ bool AudioProcessorQt::start() { if (m_audioOutput->state() == QAudio::SuspendedState) { m_audioOutput->resume(); } else { + m_device->setBufferSamples(m_samples); m_device->setInput(input()); m_device->setFormat(m_audioOutput->format()); m_audioOutput->start(m_device.get()); @@ -107,12 +109,17 @@ void AudioProcessorQt::pause() { } } -void AudioProcessorQt::setBufferSamples(int) { +void AudioProcessorQt::setBufferSamples(int samples) { + m_samples = samples; + if (m_device) { + m_device->setBufferSamples(samples); + } } void AudioProcessorQt::inputParametersChanged() { if (m_device) { m_device->setFormat(m_audioOutput->format()); + m_device->setBufferSamples(m_samples); } } @@ -138,7 +145,7 @@ void AudioProcessorQt::recheckUnderflow() { m_recheckTimer.stop(); return; } - if (!m_device->atEnd()) { + if (m_device->bytesAvailable()) { start(); m_recheckTimer.stop(); } diff --git a/src/platform/qt/AudioProcessorQt.h b/src/platform/qt/AudioProcessorQt.h index bdfa17a77..bc01a8c07 100644 --- a/src/platform/qt/AudioProcessorQt.h +++ b/src/platform/qt/AudioProcessorQt.h @@ -51,6 +51,7 @@ private: std::unique_ptr m_audioOutput; #endif std::unique_ptr m_device; + size_t m_samples = 1024; unsigned m_sampleRate = 44100; }; diff --git a/src/platform/sdl/sdl-audio.c b/src/platform/sdl/sdl-audio.c index ff7ddd2da..d90ad95d3 100644 --- a/src/platform/sdl/sdl-audio.c +++ b/src/platform/sdl/sdl-audio.c @@ -7,12 +7,6 @@ #include #include -#include -#include - -#include - -#define BUFFER_SIZE (GBA_AUDIO_SAMPLES >> 2) mLOG_DEFINE_CATEGORY(SDL_AUDIO, "SDL Audio", "platform.sdl.audio"); @@ -47,6 +41,10 @@ bool mSDLInitAudio(struct mSDLAudio* context, struct mCoreThread* threadContext) } context->core = 0; + mAudioBufferInit(&context->buffer, context->samples, context->obtainedSpec.channels); + mAudioResamplerInit(&context->resampler, mINTERPOLATOR_SINC); + mAudioResamplerSetDestination(&context->resampler, &context->buffer, context->obtainedSpec.freq); + if (threadContext) { context->core = threadContext->core; context->sync = &threadContext->impl->sync; @@ -70,6 +68,8 @@ void mSDLDeinitAudio(struct mSDLAudio* context) { SDL_PauseAudio(1); SDL_CloseAudio(); #endif + mAudioBufferDeinit(&context->buffer); + mAudioResamplerDeinit(&context->resampler); SDL_QuitSubSystem(SDL_INIT_AUDIO); } @@ -97,13 +97,11 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { memset(data, 0, len); return; } - blip_t* left = NULL; - blip_t* right = NULL; - int32_t clockRate = 1; + struct mAudioBuffer* buffer = NULL; + unsigned sampleRate = 32768; if (audioContext->core) { - clockRate = audioContext->core->frequency(audioContext->core); - left = audioContext->core->getAudioChannel(audioContext->core, 0); - right = audioContext->core->getAudioChannel(audioContext->core, 1); + buffer = audioContext->core->getAudioBuffer(audioContext->core); + sampleRate = audioContext->core->audioSampleRate(audioContext->core); } double fauxClock = 1; if (audioContext->sync) { @@ -111,18 +109,13 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { fauxClock = mCoreCalculateFramerateRatio(audioContext->core, audioContext->sync->fpsTarget); } mCoreSyncLockAudio(audioContext->sync); + audioContext->sync->audioHighWater = audioContext->samples + audioContext->resampler.highWaterMark + audioContext->resampler.lowWaterMark; + audioContext->sync->audioHighWater *= sampleRate / (fauxClock * audioContext->obtainedSpec.freq); } - blip_set_rates(left, clockRate, audioContext->obtainedSpec.freq * fauxClock); - blip_set_rates(right, clockRate, audioContext->obtainedSpec.freq * fauxClock); + mAudioResamplerSetSource(&audioContext->resampler, buffer, sampleRate / fauxClock, true); + mAudioResamplerProcess(&audioContext->resampler); len /= 2 * audioContext->obtainedSpec.channels; - int available = blip_samples_avail(left); - if (available > len) { - available = len; - } - blip_read_samples(left, (short*) data, available, audioContext->obtainedSpec.channels == 2); - if (audioContext->obtainedSpec.channels == 2) { - blip_read_samples(right, ((short*) data) + 1, available, 1); - } + int available = mAudioBufferRead(&audioContext->buffer, (int16_t*) data, len); if (audioContext->sync) { mCoreSyncConsumeAudio(audioContext->sync); diff --git a/src/platform/sdl/sdl-audio.h b/src/platform/sdl/sdl-audio.h index 2ae920af4..b8fa00c85 100644 --- a/src/platform/sdl/sdl-audio.h +++ b/src/platform/sdl/sdl-audio.h @@ -11,6 +11,8 @@ CXX_GUARD_START #include +#include +#include #include // Altivec sometimes defines this @@ -30,6 +32,8 @@ struct mSDLAudio { unsigned sampleRate; // State + struct mAudioBuffer buffer; + struct mAudioResampler resampler; SDL_AudioSpec desiredSpec; SDL_AudioSpec obtainedSpec; #if SDL_VERSION_ATLEAST(2, 0, 0) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 0dc866dfd..8307f9811 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -4,7 +4,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "feature/gui/gui-runner.h" -#include #include #include #include @@ -305,9 +304,6 @@ static void _setup(struct mGUIRunner* runner) { u32 samplerate = runner->core->audioSampleRate(runner->core); double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate); - audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / ratio); audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); @@ -576,7 +572,7 @@ static bool _running(struct mGUIRunner* runner) { return appletMainLoop(); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); int i; while (true) { @@ -590,15 +586,13 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig break; } if (!frameLimiter) { - blip_clear(left); - blip_clear(right); + mAudioBufferClear(buffer); return; } audrenWaitFrame(); } struct mStereoSample* samples = audioBuffer[i]; - blip_read_samples(left, &samples[0].left, SAMPLES, true); - blip_read_samples(right, &samples[0].right, SAMPLES, true); + mAudioBufferRead(buffer, (int16_t*) samples, SAMPLES); armDCacheFlush(samples, SAMPLES * sizeof(struct mStereoSample)); audrvVoiceAddWaveBuf(&audrenDriver, 0, &audrvBuffer[i]); diff --git a/src/platform/test/fuzz-main.c b/src/platform/test/fuzz-main.c index eb42b449b..af3bcf083 100644 --- a/src/platform/test/fuzz-main.c +++ b/src/platform/test/fuzz-main.c @@ -3,7 +3,6 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include #include #include #include @@ -153,9 +152,6 @@ int main(int argc, char** argv) { savestate = 0; } - blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 0x8000); - blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 0x8000); - _fuzzRunloop(core, fuzzOpts.frames); if (hasDebugger) { @@ -188,8 +184,7 @@ static void _fuzzRunloop(struct mCore* core, int frames) { do { core->runFrame(core); --frames; - blip_clear(core->getAudioChannel(core, 0)); - blip_clear(core->getAudioChannel(core, 1)); + mAudioBufferClear(core->getAudioBuffer(core)); } while (frames > 0 && !_dispatchExiting); } diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index 668205296..38d50b30c 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -3,7 +3,6 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include #include #include #include diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 4e955a0ad..f21c7e19b 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -14,13 +14,13 @@ #include -#include #include #include "feature/gui/gui-runner.h" #include #include #include #include +#include #include #include #include @@ -76,7 +76,7 @@ static enum VideoMode { static void _retraceCallback(u32 count); -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right); +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer*); static void _audioDMA(void); static void _setRumble(struct mRumble* rumble, int enable); static void _sampleRotation(struct mRotationSource* source); @@ -141,12 +141,14 @@ static void* framebuffer[2] = { 0, 0 }; static int whichFb = 0; static struct AudioBuffer { - struct mStereoSample samples[SAMPLES] __attribute__((__aligned__(32))); - volatile size_t size; -} audioBuffer[BUFFERS] = {0}; + int16_t samples[SAMPLES * 2] __attribute__((__aligned__(32))); + volatile bool full; +} audioBuffers[BUFFERS] = {0}; +static struct mAudioBuffer audioBuffer; static volatile int currentAudioBuffer = 0; static volatile int nextAudioBuffer = 0; static double audioSampleRate = 60.0 / 1.001; +static struct mAudioResampler resampler; static struct GUIFont* font; @@ -246,11 +248,6 @@ static void reconfigureScreen(struct mGUIRunner* runner) { if (runner) { runner->params.width = vmode->fbWidth * guiScale * wAdjust; runner->params.height = vmode->efbHeight * guiScale * hAdjust; - if (runner->core) { - double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); - } } } @@ -269,7 +266,10 @@ int main(int argc, char* argv[]) { AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); AUDIO_RegisterDMACallback(_audioDMA); - memset(audioBuffer, 0, sizeof(audioBuffer)); + memset(audioBuffers, 0, sizeof(audioBuffers)); + mAudioBufferInit(&audioBuffer, SAMPLES * BUFFERS, 2); + mAudioResamplerInit(&resampler, mINTERPOLATOR_COSINE); + mAudioResamplerSetDestination(&resampler, &audioBuffer, 48000); #ifdef FIXED_ROM_BUFFER romBufferSize = GBA_SIZE_ROM0; romBuffer = SYS_GetArena2Lo(); @@ -663,6 +663,9 @@ int main(int argc, char* argv[]) { VIDEO_WaitVSync(); mGUIDeinit(&runner); + mAudioResamplerDeinit(&resampler); + mAudioBufferDeinit(&audioBuffer); + free(fifo); free(texmem); free(rescaleTexmem); @@ -678,41 +681,38 @@ int main(int argc, char* argv[]) { } static void _audioDMA(void) { - struct AudioBuffer* buffer = &audioBuffer[currentAudioBuffer]; - if (buffer->size != SAMPLES) { + struct AudioBuffer* buffer = &audioBuffers[currentAudioBuffer]; + if (!buffer->full) { + printf("Recv %i %i%s", currentAudioBuffer, buffer->full, buffer->full ? "" : "!"); return; } DCFlushRange(buffer->samples, SAMPLES * sizeof(struct mStereoSample)); AUDIO_InitDMA((u32) buffer->samples, SAMPLES * sizeof(struct mStereoSample)); - buffer->size = 0; + buffer->full = false; currentAudioBuffer = (currentAudioBuffer + 1) % BUFFERS; } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) { UNUSED(stream); - + UNUSED(buf); + mAudioResamplerProcess(&resampler); u32 level = 0; + bool gotAudio = false; _CPU_ISR_Disable(level); - struct AudioBuffer* buffer = &audioBuffer[nextAudioBuffer]; - int available = blip_samples_avail(left); - if (available + buffer->size > SAMPLES) { - available = SAMPLES - buffer->size; - } - if (available > 0) { - // These appear to be reversed for AUDIO_InitDMA - blip_read_samples(left, &buffer->samples[buffer->size].right, available, true); - blip_read_samples(right, &buffer->samples[buffer->size].left, available, true); - buffer->size += available; - } - if (buffer->size == SAMPLES) { - int next = (nextAudioBuffer + 1) % BUFFERS; - if ((currentAudioBuffer + BUFFERS - next) % BUFFERS != 1) { - nextAudioBuffer = next; - } - if (!AUDIO_GetDMAEnableFlag()) { - _audioDMA(); - AUDIO_StartDMA(); + while (mAudioBufferAvailable(&audioBuffer) >= SAMPLES) { + struct AudioBuffer* buffer = &audioBuffers[nextAudioBuffer]; + if (buffer->full) { + printf("Send %i %i%s", nextAudioBuffer, buffer->full, buffer->full ? "!!" : ""); + break; } + mAudioBufferRead(&audioBuffer, buffer->samples, SAMPLES); + buffer->full = true; + nextAudioBuffer = (nextAudioBuffer + 1) % BUFFERS; + gotAudio = true; + } + if (gotAudio && !AUDIO_GetDMAEnableFlag()) { + _audioDMA(); + AUDIO_StartDMA(); } _CPU_ISR_Restore(level); } @@ -1416,15 +1416,11 @@ void _setup(struct mGUIRunner* runner) { nextAudioBuffer = 0; currentAudioBuffer = 0; - int i; - for (i = 0; i < BUFFERS; ++i) { - audioBuffer[i].size = 0; - } + memset(audioBuffers, 0, sizeof(audioBuffers)); runner->core->setAudioBufferSize(runner->core, SAMPLES); double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); + mAudioResamplerSetSource(&resampler, runner->core->getAudioBuffer(runner->core), runner->core->audioSampleRate(runner->core) / ratio, true); frameLimiter = true; } @@ -1433,6 +1429,7 @@ void _gameUnloaded(struct mGUIRunner* runner) { UNUSED(runner); AUDIO_StopDMA(); frameLimiter = true; + mAudioBufferClear(&audioBuffer); VIDEO_SetBlack(true); VIDEO_Flush(); VIDEO_WaitVSync(); From fa2fe8eed4fdf47766e8107b3a75ec5af762be9d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:49:34 -0700 Subject: [PATCH 168/336] Third-Party: Remove blip_buf --- CMakeLists.txt | 4 +- README.md | 1 - README_DE.md | 1 - README_ES.md | 1 - README_ZH_CN.md | 1 - include/mgba/core/blip_buf.h | 72 ---- res/licenses/blip_buf.txt | 504 --------------------------- src/third-party/blip_buf/blip_buf.c | 344 ------------------ src/third-party/blip_buf/license.txt | 504 --------------------------- 9 files changed, 1 insertion(+), 1431 deletions(-) delete mode 100644 include/mgba/core/blip_buf.h delete mode 100644 res/licenses/blip_buf.txt delete mode 100644 src/third-party/blip_buf/blip_buf.c delete mode 100644 src/third-party/blip_buf/license.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 24caaaf9f..d573b0c6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -586,8 +586,6 @@ if(USE_FFMPEG) endif() endif() -list(APPEND THIRD_PARTY_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/blip_buf/blip_buf.c") - if(WANT_ZLIB AND NOT USE_ZLIB) set(SKIP_INSTALL_ALL ON) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib zlib EXCLUDE_FROM_ALL) @@ -1085,7 +1083,7 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba-util DESTINATION ${CM install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mgba COMPONENT ${BINARY_NAME}-dev) # Packaging -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/blip_buf.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) +install(FILES DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/inih.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) if(USE_DISCORD_RPC) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/discord-rpc.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) diff --git a/README.md b/README.md index 78b69f255..d937fa0c9 100644 --- a/README.md +++ b/README.md @@ -260,7 +260,6 @@ mGBA is Copyright © 2013 – 2023 Jeffrey Pfau. It is distributed under the [Mo mGBA contains the following third-party libraries: - [inih](https://github.com/benhoyt/inih), which is copyright © 2009 – 2020 Ben Hoyt and used under a BSD 3-clause license. -- [blip-buf](https://code.google.com/archive/p/blip-buf), which is copyright © 2003 – 2009 Shay Green and used under a Lesser GNU Public License. - [LZMA SDK](http://www.7-zip.org/sdk.html), which is public domain. - [MurmurHash3](https://github.com/aappleby/smhasher) implementation by Austin Appleby, which is public domain. - [getopt for MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/), which is public domain. diff --git a/README_DE.md b/README_DE.md index 9b653c5d2..9a4066a0f 100644 --- a/README_DE.md +++ b/README_DE.md @@ -247,7 +247,6 @@ Copyright für mGBA © 2013 – 2021 Jeffrey Pfau. mGBA wird unter der [Mozilla mGBA beinhaltet die folgenden Bibliotheken von Drittanbietern: - [inih](https://github.com/benhoyt/inih), Copyright © 2009 - 2020 Ben Hoyt, verwendet unter einer BSD 3-clause-Lizenz. -- [blip-buf](https://code.google.com/archive/b/blip-buf), Copyright © 2003 - 2009 Shay Green, verwendet unter einer Lesser GNU Public License. - [LZMA SDK](http://www.7-zip.org/sdk.html), Public Domain. - [MurmurHash3](https://github.com/aappleby/smhasher), Implementierung von Austin Appleby, Public Domain. - [getopt fot MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/), Public Domain. diff --git a/README_ES.md b/README_ES.md index f174e114c..1a6d0b797 100644 --- a/README_ES.md +++ b/README_ES.md @@ -247,7 +247,6 @@ mGBA es Copyright © 2013 – 2021 Jeffrey Pfau. Es distribuído bajo la [licenc mGBA contiene las siguientes bibliotecas de terceros: - [inih](https://github.com/benhoyt/inih), que es copyright © 2009 - 2020 Ben Hoyt y se utiliza bajo licencia de la cláusula 3 de BSD. -- [blip-buf](https://code.google.com/archive/p/blip-buf), que es copyright © 2003 - 2009 Shay Green y se usa bajo LGPL. - [LZMA SDK](http://www.7-zip.org/sdk.html), la cual está en el dominio público. - [MurmurHash3](https://github.com/aappleby/smhasher), implementación por Austin Appleby, la cual está en el dominio público. - [getopt for MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/), la cual está en el dominio público. diff --git a/README_ZH_CN.md b/README_ZH_CN.md index 757f1d0c6..ab725694c 100644 --- a/README_ZH_CN.md +++ b/README_ZH_CN.md @@ -245,7 +245,6 @@ mGBA ç‰ˆæƒ Â© 2013 – 2020 Jeffrey Pfau。基于 [Mozilla 公共许å¯è¯ç‰ˆ mGBA 包å«ä»¥ä¸‹ç¬¬ä¸‰æ–¹åº“: - [inih](https://github.com/benhoyt/inih)ï¼šç‰ˆæƒ Â© 2009 – 2020 Ben Hoyt,基于 BSD 3-clause 许å¯è¯ä½¿ç”¨ã€‚ -- [blip-buf](https://code.google.com/archive/p/blip-buf)ï¼šç‰ˆæƒ Â© 2003 – 2009 Shay Green,基于 Lesser GNU 公共许å¯è¯ä½¿ç”¨ã€‚ - [LZMA SDK](http://www.7-zip.org/sdk.html):属公有领域使用。 - [MurmurHash3](https://github.com/aappleby/smhasher):由 Austin Appleby 实施,属公有领域使用。 - [getopt for MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/):属公有领域使用。 diff --git a/include/mgba/core/blip_buf.h b/include/mgba/core/blip_buf.h deleted file mode 100644 index 22b0a3ec8..000000000 --- a/include/mgba/core/blip_buf.h +++ /dev/null @@ -1,72 +0,0 @@ -/** \file -Sample buffer that resamples from input clock rate to output sample rate */ - -/* blip_buf 1.1.0 */ -#ifndef BLIP_BUF_H -#define BLIP_BUF_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** First parameter of most functions is blip_t*, or const blip_t* if nothing -is changed. */ -typedef struct blip_t blip_t; - -/** Creates new buffer that can hold at most sample_count samples. Sets rates -so that there are blip_max_ratio clocks per sample. Returns pointer to new -buffer, or NULL if insufficient memory. */ -blip_t* blip_new( int sample_count ); - -/** Sets approximate input clock rate and output sample rate. For every -clock_rate input clocks, approximately sample_rate samples are generated. */ -void blip_set_rates( blip_t*, double clock_rate, double sample_rate ); - -enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate, -clock_rate must not be greater than sample_rate*blip_max_ratio. */ -blip_max_ratio = 0x100000 }; - -/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */ -void blip_clear( blip_t* ); - -/** Adds positive/negative delta into buffer at specified clock time. */ -void blip_add_delta( blip_t*, unsigned int clock_time, int delta ); - -/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */ -void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta ); - -/** Length of time frame, in clocks, needed to make sample_count additional -samples available. */ -int blip_clocks_needed( const blip_t*, int sample_count ); - -enum { /** Maximum number of samples that can be generated from one time frame. */ -blip_max_frame = 4000 }; - -/** Makes input clocks before clock_duration available for reading as output -samples. Also begins new time frame at clock_duration, so that clock time 0 in -the new time frame specifies the same clock as clock_duration in the old time -frame specified. Deltas can have been added slightly past clock_duration (up to -however many clocks there are in two output samples). */ -void blip_end_frame( blip_t*, unsigned int clock_duration ); - -/** Number of buffered samples available for reading. */ -int blip_samples_avail( const blip_t* ); - -/** Reads and removes at most 'count' samples and writes them to 'out'. If -'stereo' is true, writes output to every other element of 'out', allowing easy -interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed -samples. Returns number of samples actually read. */ -int blip_read_samples( blip_t*, short out [], int count, int stereo ); - -/** Frees buffer. No effect if NULL is passed. */ -void blip_delete( blip_t* ); - - -/* Deprecated */ -typedef blip_t blip_buffer_t; - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/res/licenses/blip_buf.txt b/res/licenses/blip_buf.txt deleted file mode 100644 index 5faba9d48..000000000 --- a/res/licenses/blip_buf.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/src/third-party/blip_buf/blip_buf.c b/src/third-party/blip_buf/blip_buf.c deleted file mode 100644 index 6bc7da8bd..000000000 --- a/src/third-party/blip_buf/blip_buf.c +++ /dev/null @@ -1,344 +0,0 @@ -/* blip_buf 1.1.0. http://www.slack.net/~ant/ */ - -#include - -#include -#include -#include -#include - -/* Library Copyright (C) 2003-2009 Shay Green. This library is free software; -you can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -library is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#if defined (BLARGG_TEST) && BLARGG_TEST - #include "blargg_test.h" -#endif - -/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000. -Avoids constants that don't fit in 32 bits. */ -#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF - typedef unsigned long fixed_t; - enum { pre_shift = 32 }; - -#elif defined(ULLONG_MAX) - typedef unsigned long long fixed_t; - enum { pre_shift = 32 }; - -#else - typedef unsigned fixed_t; - enum { pre_shift = 0 }; - -#endif - -enum { time_bits = pre_shift + 20 }; - -static fixed_t const time_unit = (fixed_t) 1 << time_bits; - -enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */ -enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */ - -enum { half_width = 8 }; -enum { buf_extra = half_width*2 + end_frame_extra }; -enum { phase_bits = 5 }; -enum { phase_count = 1 << phase_bits }; -enum { delta_bits = 15 }; -enum { delta_unit = 1 << delta_bits }; -enum { frac_bits = time_bits - pre_shift }; - -/* We could eliminate avail and encode whole samples in offset, but that would -limit the total buffered samples to blip_max_frame. That could only be -increased by decreasing time_bits, which would reduce resample ratio accuracy. -*/ - -/** Sample buffer that resamples to output rate and accumulates samples -until they're read out */ -struct blip_t -{ - fixed_t factor; - fixed_t offset; - int avail; - int size; - int integrator; -}; - -typedef int buf_t; - -/* probably not totally portable */ -#define SAMPLES( buf ) ((buf_t*) ((buf) + 1)) - -/* Arithmetic (sign-preserving) right shift */ -#define ARITH_SHIFT( n, shift ) \ - ((n) >> (shift)) - -enum { max_sample = +32767 }; -enum { min_sample = -32768 }; - -#define CLAMP( n ) \ - {\ - if ( (short) n != n )\ - n = ARITH_SHIFT( n, 16 ) ^ max_sample;\ - } - -static void check_assumptions( void ) -{ - int n; - - #if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF - #error "int must be at least 32 bits" - #endif - - assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */ - - n = max_sample * 2; - CLAMP( n ); - assert( n == max_sample ); - - n = min_sample * 2; - CLAMP( n ); - assert( n == min_sample ); - - assert( blip_max_ratio <= time_unit ); - assert( blip_max_frame <= (fixed_t) -1 >> time_bits ); -} - -blip_t* blip_new( int size ) -{ - blip_t* m; - assert( size >= 0 ); - - m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) ); - if ( m ) - { - m->factor = time_unit / blip_max_ratio; - m->size = size; - blip_clear( m ); - check_assumptions(); - } - return m; -} - -void blip_delete( blip_t* m ) -{ - if ( m != NULL ) - { - /* Clear fields in case user tries to use after freeing */ - memset( m, 0, sizeof *m ); - free( m ); - } -} - -void blip_set_rates( blip_t* m, double clock_rate, double sample_rate ) -{ - double factor = time_unit * sample_rate / clock_rate; - m->factor = (fixed_t) factor; - - /* Fails if clock_rate exceeds maximum, relative to sample_rate */ - assert( 0 <= factor - m->factor && factor - m->factor < 1 ); - - /* Avoid requiring math.h. Equivalent to - m->factor = (int) ceil( factor ) */ - if ( m->factor < factor ) - m->factor++; - - /* At this point, factor is most likely rounded up, but could still - have been rounded down in the floating-point calculation. */ -} - -void blip_clear( blip_t* m ) -{ - /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if - factor is rounded up. factor-1 is suitable if factor is rounded down. - Since we don't know rounding direction, factor/2 accommodates either, - with the slight loss of showing an error in half the time. Since for - a 64-bit factor this is years, the halving isn't a problem. */ - - m->offset = m->factor / 2; - m->avail = 0; - m->integrator = 0; - memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) ); -} - -int blip_clocks_needed( const blip_t* m, int samples ) -{ - fixed_t needed; - - /* Fails if buffer can't hold that many more samples */ - assert( samples >= 0 && m->avail + samples <= m->size ); - - needed = (fixed_t) samples * time_unit; - if ( needed < m->offset ) - return 0; - - return (needed - m->offset + m->factor - 1) / m->factor; -} - -void blip_end_frame( blip_t* m, unsigned t ) -{ - fixed_t off = t * m->factor + m->offset; - m->avail += off >> time_bits; - m->offset = off & (time_unit - 1); - - /* Fails if buffer size was exceeded */ - assert( m->avail <= m->size ); -} - -int blip_samples_avail( const blip_t* m ) -{ - return m->avail; -} - -static void remove_samples( blip_t* m, int count ) -{ - buf_t* buf = SAMPLES( m ); - int remain = m->avail + buf_extra - count; - m->avail -= count; - - memmove( &buf [0], &buf [count], remain * sizeof buf [0] ); - memset( &buf [remain], 0, count * sizeof buf [0] ); -} - -int blip_read_samples( blip_t* m, short out [], int count, int stereo ) -{ - assert( count >= 0 ); - - if ( count > m->avail ) - count = m->avail; - - if ( count ) - { - int const step = stereo ? 2 : 1; - buf_t const* in = SAMPLES( m ); - buf_t const* end = in + count; - int sum = m->integrator; - do - { - /* Eliminate fraction */ - int s = ARITH_SHIFT( sum, delta_bits ); - - sum += *in++; - - CLAMP( s ); - - *out = s; - out += step; - - /* High-pass filter */ - sum -= s << (delta_bits - bass_shift); - } - while ( in != end ); - m->integrator = sum; - - remove_samples( m, count ); - } - - return count; -} - -/* Things that didn't help performance on x86: - __attribute__((aligned(128))) - #define short int - restrict -*/ - -/* Sinc_Generator( 0.9, 0.55, 4.5 ) */ -static short const bl_step [phase_count + 1] [half_width] = -{ -{ 43, -115, 350, -488, 1136, -914, 5861,21022}, -{ 44, -118, 348, -473, 1076, -799, 5274,21001}, -{ 45, -121, 344, -454, 1011, -677, 4706,20936}, -{ 46, -122, 336, -431, 942, -549, 4156,20829}, -{ 47, -123, 327, -404, 868, -418, 3629,20679}, -{ 47, -122, 316, -375, 792, -285, 3124,20488}, -{ 47, -120, 303, -344, 714, -151, 2644,20256}, -{ 46, -117, 289, -310, 634, -17, 2188,19985}, -{ 46, -114, 273, -275, 553, 117, 1758,19675}, -{ 44, -108, 255, -237, 471, 247, 1356,19327}, -{ 43, -103, 237, -199, 390, 373, 981,18944}, -{ 42, -98, 218, -160, 310, 495, 633,18527}, -{ 40, -91, 198, -121, 231, 611, 314,18078}, -{ 38, -84, 178, -81, 153, 722, 22,17599}, -{ 36, -76, 157, -43, 80, 824, -241,17092}, -{ 34, -68, 135, -3, 8, 919, -476,16558}, -{ 32, -61, 115, 34, -60, 1006, -683,16001}, -{ 29, -52, 94, 70, -123, 1083, -862,15422}, -{ 27, -44, 73, 106, -184, 1152,-1015,14824}, -{ 25, -36, 53, 139, -239, 1211,-1142,14210}, -{ 22, -27, 34, 170, -290, 1261,-1244,13582}, -{ 20, -20, 16, 199, -335, 1301,-1322,12942}, -{ 18, -12, -3, 226, -375, 1331,-1376,12293}, -{ 15, -4, -19, 250, -410, 1351,-1408,11638}, -{ 13, 3, -35, 272, -439, 1361,-1419,10979}, -{ 11, 9, -49, 292, -464, 1362,-1410,10319}, -{ 9, 16, -63, 309, -483, 1354,-1383, 9660}, -{ 7, 22, -75, 322, -496, 1337,-1339, 9005}, -{ 6, 26, -85, 333, -504, 1312,-1280, 8355}, -{ 4, 31, -94, 341, -507, 1278,-1205, 7713}, -{ 3, 35, -102, 347, -506, 1238,-1119, 7082}, -{ 1, 40, -110, 350, -499, 1190,-1021, 6464}, -{ 0, 43, -115, 350, -488, 1136, -914, 5861} -}; - -/* Shifting by pre_shift allows calculation using unsigned int rather than -possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient. -And by having pre_shift 32, a 32-bit platform can easily do the shift by -simply ignoring the low half. */ - -void blip_add_delta( blip_t* m, unsigned time, int delta ) -{ - unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); - buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); - - int const phase_shift = frac_bits - phase_bits; - int phase = fixed >> phase_shift & (phase_count - 1); - short const* in = bl_step [phase]; - short const* rev = bl_step [phase_count - phase]; - - int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); - int delta2 = (delta * interp) >> delta_bits; - delta -= delta2; - - /* Fails if buffer size was exceeded */ - assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); - - out [0] += in[0]*delta + in[half_width+0]*delta2; - out [1] += in[1]*delta + in[half_width+1]*delta2; - out [2] += in[2]*delta + in[half_width+2]*delta2; - out [3] += in[3]*delta + in[half_width+3]*delta2; - out [4] += in[4]*delta + in[half_width+4]*delta2; - out [5] += in[5]*delta + in[half_width+5]*delta2; - out [6] += in[6]*delta + in[half_width+6]*delta2; - out [7] += in[7]*delta + in[half_width+7]*delta2; - - in = rev; - out [ 8] += in[7]*delta + in[7-half_width]*delta2; - out [ 9] += in[6]*delta + in[6-half_width]*delta2; - out [10] += in[5]*delta + in[5-half_width]*delta2; - out [11] += in[4]*delta + in[4-half_width]*delta2; - out [12] += in[3]*delta + in[3-half_width]*delta2; - out [13] += in[2]*delta + in[2-half_width]*delta2; - out [14] += in[1]*delta + in[1-half_width]*delta2; - out [15] += in[0]*delta + in[0-half_width]*delta2; -} - -void blip_add_delta_fast( blip_t* m, unsigned time, int delta ) -{ - unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); - buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); - - int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1); - int delta2 = delta * interp; - - /* Fails if buffer size was exceeded */ - assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); - - out [7] += delta * delta_unit - delta2; - out [8] += delta2; -} diff --git a/src/third-party/blip_buf/license.txt b/src/third-party/blip_buf/license.txt deleted file mode 100644 index 5faba9d48..000000000 --- a/src/third-party/blip_buf/license.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - From d422cbe65d8074365d85e1fd52ebf8d2e721bdfd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:52:26 -0700 Subject: [PATCH 169/336] OpenEmu: Remove upstream core This is maintained downstream and not synchronized back upstream --- CMakeLists.txt | 29 +- src/platform/openemu/Info.plist.in | 52 --- .../openemu/OEGBASystemResponderClient.h | 51 --- src/platform/openemu/mGBAGameCore.h | 6 - src/platform/openemu/mGBAGameCore.m | 298 ------------------ 5 files changed, 1 insertion(+), 435 deletions(-) delete mode 100644 src/platform/openemu/Info.plist.in delete mode 100644 src/platform/openemu/OEGBASystemResponderClient.h delete mode 100644 src/platform/openemu/mGBAGameCore.h delete mode 100644 src/platform/openemu/mGBAGameCore.m diff --git a/CMakeLists.txt b/CMakeLists.txt index d573b0c6c..2d69b000b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,9 +68,6 @@ if(NOT LIBMGBA_ONLY) set(BUILD_QT ON CACHE BOOL "Build Qt frontend") set(BUILD_SDL ON CACHE BOOL "Build SDL frontend") set(BUILD_LIBRETRO OFF CACHE BOOL "Build libretro core") - if(APPLE) - set(BUILD_OPENEMU OFF CACHE BOOL "Build OpenEmu core") - endif() set(BUILD_PERF OFF CACHE BOOL "Build performance profiling tool") set(BUILD_TEST OFF CACHE BOOL "Build testing harness") set(BUILD_SUITE OFF CACHE BOOL "Build test suite") @@ -80,7 +77,7 @@ if(NOT LIBMGBA_ONLY) set(BUILD_PYTHON OFF CACHE BOOL "Build Python bindings") set(BUILD_STATIC OFF CACHE BOOL "Build a static library") set(BUILD_SHARED ON CACHE BOOL "Build a shared library") - set(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro or OpenEmu cores)") + set(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro core)") set(BUILD_GL ON CACHE BOOL "Build with OpenGL") set(BUILD_GLES2 ON CACHE BOOL "Build with OpenGL|ES 2") set(BUILD_GLES3 ON CACHE BOOL "Build with OpenGL|ES 3") @@ -144,11 +141,6 @@ if (BUILD_LIBRETRO) mark_as_advanced(LIBRETRO_LIBDIR) endif() -if (BUILD_OPENEMU) - set(OE_LIBDIR "${LIBDIR}" CACHE PATH "Installed library directory (OpenEmu)") - mark_as_advanced(OE_LIBDIR) -endif() - if (DISTBUILD) set(EXTRA_LICENSES "" CACHE FILEPATH "Extra licenses to include in distribution packaages") mark_as_advanced(EXTRA_LICENSES) @@ -1001,22 +993,6 @@ if(BUILD_LIBRETRO) endif() endif() -if(BUILD_OPENEMU) - find_library(FOUNDATION Foundation) - find_library(OPENEMUBASE OpenEmuBase) - file(GLOB OE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/openemu/*.m) - add_library(${BINARY_NAME}-openemu MODULE ${CORE_SRC} ${OS_SRC}) - set_target_properties(${BINARY_NAME}-openemu PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/openemu/Info.plist.in - BUNDLE TRUE - BUNDLE_EXTENSION oecoreplugin - OUTPUT_NAME ${PROJECT_NAME} - COMPILE_OPTIONS "-fobjc-arc" - COMPILE_DEFINITIONS "DISABLE_THREADING;MGBA_STANDALONE;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=1") - target_link_libraries(${BINARY_NAME}-openemu ${OS_LIB} ${FOUNDATION} ${OPENEMUBASE}) - install(TARGETS ${BINARY_NAME}-openemu LIBRARY DESTINATION ${OE_LIBDIR} COMPONENT ${BINARY_NAME}.oecoreplugin NAMELINK_SKIP) -endif() - if(BUILD_QT AND (WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux")) set(BUILD_UPDATER ON) endif() @@ -1345,9 +1321,6 @@ if(NOT QUIET AND NOT LIBMGBA_ONLY) message(STATUS " ROM tester: ${BUILD_ROM_TEST}") message(STATUS "Cores:") message(STATUS " Libretro core: ${BUILD_LIBRETRO}") - if(APPLE) - message(STATUS " OpenEmu core: ${BUILD_OPENEMU}") - endif() message(STATUS "Libraries:") message(STATUS " Static: ${BUILD_STATIC}") message(STATUS " Shared: ${BUILD_SHARED}") diff --git a/src/platform/openemu/Info.plist.in b/src/platform/openemu/Info.plist.in deleted file mode 100644 index b4ecfa95e..000000000 --- a/src/platform/openemu/Info.plist.in +++ /dev/null @@ -1,52 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${PROJECT_NAME} - CFBundleIconFile - mGBA - CFBundleIdentifier - com.endrift.mgba - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - ${VERSION_STRING} - NSPrincipalClass - OEGameCoreController - OEGameCoreClass - mGBAGameCore - OEGameCoreOptions - - openemu.system.gba - - OEGameCoreRewindBufferSeconds - 60 - OEGameCoreRewindInterval - 0 - OEGameCoreSupportsRewinding - - OEGameCoreSupportsCheatCode - - - - OEGameCorePlayerCount - 1 - OEProjectURL - https://mgba.io/ - OESystemIdentifiers - - openemu.system.gba - - SUEnableAutomaticChecks - 1 - SUFeedURL - https://raw.github.com/OpenEmu/OpenEmu-Update/master/mgba_appcast.xml - - diff --git a/src/platform/openemu/OEGBASystemResponderClient.h b/src/platform/openemu/OEGBASystemResponderClient.h deleted file mode 100644 index 4fc0179d1..000000000 --- a/src/platform/openemu/OEGBASystemResponderClient.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (c) 2011, OpenEmu Team - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the OpenEmu Team nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import - -@protocol OESystemResponderClient; - -typedef enum _OEGBAButton -{ - OEGBAButtonUp, - OEGBAButtonDown, - OEGBAButtonLeft, - OEGBAButtonRight, - OEGBAButtonA, - OEGBAButtonB, - OEGBAButtonL, - OEGBAButtonR, - OEGBAButtonStart, - OEGBAButtonSelect, - OEGBAButtonCount -} OEGBAButton; - -@protocol OEGBASystemResponderClient - -- (oneway void)didPushGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player; -- (oneway void)didReleaseGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player; - -@end diff --git a/src/platform/openemu/mGBAGameCore.h b/src/platform/openemu/mGBAGameCore.h deleted file mode 100644 index 744fdecfe..000000000 --- a/src/platform/openemu/mGBAGameCore.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -OE_EXPORTED_CLASS -@interface mGBAGameCore : OEGameCore -@end diff --git a/src/platform/openemu/mGBAGameCore.m b/src/platform/openemu/mGBAGameCore.m deleted file mode 100644 index 7656a8945..000000000 --- a/src/platform/openemu/mGBAGameCore.m +++ /dev/null @@ -1,298 +0,0 @@ -/* - Copyright (c) 2016, Jeffrey Pfau - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - */ - -#import "mGBAGameCore.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#import -#import "OEGBASystemResponderClient.h" -#import - -#define SAMPLES 1024 - -@interface mGBAGameCore () -{ - struct mCore* core; - void* outputBuffer; - NSMutableDictionary *cheatSets; -} -@end - -@implementation mGBAGameCore - -- (id)init -{ - if ((self = [super init])) - { - core = GBACoreCreate(); - mCoreInitConfig(core, nil); - - struct mCoreOptions opts = { - .useBios = true, - }; - mCoreConfigLoadDefaults(&core->config, &opts); - core->init(core); - outputBuffer = nil; - - unsigned width, height; - core->baseVideoSize(core, &width, &height); - outputBuffer = malloc(width * height * BYTES_PER_PIXEL); - core->setVideoBuffer(core, outputBuffer, width); - core->setAudioBufferSize(core, SAMPLES); - cheatSets = [[NSMutableDictionary alloc] init]; - } - - return self; -} - -- (void)dealloc -{ - mCoreConfigDeinit(&core->config); - core->deinit(core); - free(outputBuffer); -} - -#pragma mark - Execution - -- (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error -{ - NSString *batterySavesDirectory = [self batterySavesDirectoryPath]; - [[NSFileManager defaultManager] createDirectoryAtURL:[NSURL fileURLWithPath:batterySavesDirectory] - withIntermediateDirectories:YES - attributes:nil - error:nil]; - if (core->dirs.save) { - core->dirs.save->close(core->dirs.save); - } - core->dirs.save = VDirOpen([batterySavesDirectory fileSystemRepresentation]); - - if (!mCoreLoadFile(core, [path fileSystemRepresentation])) { - *error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:nil]; - return NO; - } - mCoreAutoloadSave(core); - - core->reset(core); - - return YES; -} - -- (void)executeFrame -{ - core->runFrame(core); - - int16_t samples[SAMPLES * 2]; - size_t available = 0; - available = blip_samples_avail(core->getAudioChannel(core, 0)); - blip_read_samples(core->getAudioChannel(core, 0), samples, available, true); - blip_read_samples(core->getAudioChannel(core, 1), samples + 1, available, true); - [[self ringBufferAtIndex:0] write:samples maxLength:available * 4]; -} - -- (void)resetEmulation -{ - core->reset(core); -} - -- (void)setupEmulation -{ - blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768); - blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768); -} - -#pragma mark - Video - -- (OEIntSize)aspectSize -{ - return OEIntSizeMake(3, 2); -} - -- (OEIntRect)screenRect -{ - unsigned width, height; - core->currentVideoSize(core, &width, &height); - return OEIntRectMake(0, 0, width, height); -} - -- (OEIntSize)bufferSize -{ - unsigned width, height; - core->baseVideoSize(core, &width, &height); - return OEIntSizeMake(width, height); -} - -- (const void *)getVideoBufferWithHint:(void *)hint -{ - OEIntSize bufferSize = [self bufferSize]; - - if (!hint) { - hint = outputBuffer; - } - - outputBuffer = hint; - core->setVideoBuffer(core, hint, bufferSize.width); - - return hint; -} - -- (GLenum)pixelFormat -{ - return GL_RGBA; -} - -- (GLenum)pixelType -{ - return GL_UNSIGNED_INT_8_8_8_8_REV; -} - -- (NSTimeInterval)frameInterval -{ - return core->frequency(core) / (double) core->frameCycles(core); -} - -#pragma mark - Audio - -- (NSUInteger)channelCount -{ - return 2; -} - -- (double)audioSampleRate -{ - return 32768; -} - -#pragma mark - Save State - -- (NSData *)serializeStateWithError:(NSError **)outError -{ - struct VFile* vf = VFileMemChunk(nil, 0); - if (!mCoreSaveStateNamed(core, vf, SAVESTATE_SAVEDATA)) { - *outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil]; - vf->close(vf); - return nil; - } - size_t size = vf->size(vf); - void* data = vf->map(vf, size, MAP_READ); - NSData *nsdata = [NSData dataWithBytes:data length:size]; - vf->unmap(vf, data, size); - vf->close(vf); - return nsdata; -} - -- (BOOL)deserializeState:(NSData *)state withError:(NSError **)outError -{ - struct VFile* vf = VFileFromConstMemory(state.bytes, state.length); - if (!mCoreLoadStateNamed(core, vf, SAVESTATE_SAVEDATA)) { - *outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil]; - vf->close(vf); - return NO; - } - vf->close(vf); - return YES; -} - -- (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block -{ - struct VFile* vf = VFileOpen([fileName fileSystemRepresentation], O_CREAT | O_TRUNC | O_RDWR); - block(mCoreSaveStateNamed(core, vf, 0), nil); - vf->close(vf); -} - -- (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block -{ - struct VFile* vf = VFileOpen([fileName fileSystemRepresentation], O_RDONLY); - block(mCoreLoadStateNamed(core, vf, 0), nil); - vf->close(vf); -} - -#pragma mark - Input - -const int GBAMap[] = { - GBA_KEY_UP, - GBA_KEY_DOWN, - GBA_KEY_LEFT, - GBA_KEY_RIGHT, - GBA_KEY_A, - GBA_KEY_B, - GBA_KEY_L, - GBA_KEY_R, - GBA_KEY_START, - GBA_KEY_SELECT -}; - -- (oneway void)didPushGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player -{ - UNUSED(player); - core->addKeys(core, 1 << GBAMap[button]); -} - -- (oneway void)didReleaseGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player -{ - UNUSED(player); - core->clearKeys(core, 1 << GBAMap[button]); -} - -#pragma mark - Cheats - -- (void)setCheat:(NSString *)code setType:(NSString *)type setEnabled:(BOOL)enabled -{ - code = [code stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - code = [code stringByReplacingOccurrencesOfString:@" " withString:@""]; - - NSString *codeId = [code stringByAppendingFormat:@"/%@", type]; - struct mCheatSet* cheatSet = [[cheatSets objectForKey:codeId] pointerValue]; - if (cheatSet) { - cheatSet->enabled = enabled; - return; - } - struct mCheatDevice* cheats = core->cheatDevice(core); - cheatSet = cheats->createSet(cheats, [codeId UTF8String]); - size_t size = mCheatSetsSize(&cheats->cheats); - if (size) { - cheatSet->copyProperties(cheatSet, *mCheatSetsGetPointer(&cheats->cheats, size - 1)); - } - int codeType = GBA_CHEAT_AUTODETECT; - NSArray *codeSet = [code componentsSeparatedByString:@"+"]; - for (id c in codeSet) { - mCheatAddLine(cheatSet, [c UTF8String], codeType); - } - cheatSet->enabled = enabled; - [cheatSets setObject:[NSValue valueWithPointer:cheatSet] forKey:codeId]; - mCheatAddSet(cheats, cheatSet); -} -@end - From 2cbbaea48359c3bbd3367c99298c0ad9a3e5eb88 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:04:34 -0700 Subject: [PATCH 170/336] Python: Attempt to fix build --- src/platform/python/mgba/core.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 75fd1a1cc..22965b3f9 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -4,7 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. from ._pylib import ffi, lib # pylint: disable=no-name-in-module -from . import tile, audio +from . import tile from cached_property import cached_property from functools import wraps @@ -242,14 +242,6 @@ class Core(object): def set_video_buffer(self, image): self._core.setVideoBuffer(self._core, image.buffer, image.stride) - @protected - def set_audio_buffer_size(self, size): - self._core.setAudioBufferSize(self._core, size) - - @property - def audio_buffer_size(self): - return self._core.getAudioBufferSize(self._core) - @protected def reset(self): self._core.reset(self._core) From 21d4f0f5fc52ede32c71c1bf2a2b4fd90b7ec098 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:07:54 -0700 Subject: [PATCH 171/336] All: Split ENABLE_VFS out from MINIMAL_CORE=2 --- CMakeLists.txt | 21 +++++++++++++---- include/mgba-util/configuration.h | 4 +++- include/mgba-util/image.h | 4 ++++ include/mgba-util/vfs.h | 9 ++++--- include/mgba/core/cheats.h | 2 +- include/mgba/core/config.h | 2 +- include/mgba/core/core.h | 6 ++--- include/mgba/core/directories.h | 2 +- include/mgba/core/library.h | 4 ++++ include/mgba/core/scripting.h | 2 ++ include/mgba/gba/interface.h | 4 +++- include/mgba/script/context.h | 2 ++ src/core/CMakeLists.txt | 6 ++++- src/core/cheats.c | 2 +- src/core/config.c | 2 +- src/core/core.c | 12 ++++++---- src/core/directories.c | 2 +- src/core/flags.h.in | 4 ++++ src/core/log.c | 5 ++-- src/core/scripting.c | 38 ++++++++++++++++++++---------- src/core/test/core.c | 4 ++-- src/debugger/cli-debugger.c | 24 ++++++++++++------- src/debugger/cli-el-backend.c | 4 ++++ src/feature/CMakeLists.txt | 6 ++++- src/feature/commandline.c | 5 ++++ src/gb/core.c | 8 +++---- src/gb/debugger/cli.c | 6 ++--- src/gba/cart/ereader.c | 4 +++- src/gba/core.c | 8 +++---- src/gba/debugger/cli.c | 6 ++--- src/platform/3ds/CMakeLists.txt | 4 ++-- src/platform/opengl/gles2.c | 2 ++ src/platform/opengl/gles2.h | 2 ++ src/platform/psp2/CMakeLists.txt | 4 ++-- src/platform/switch/CMakeLists.txt | 4 ++-- src/platform/wii/CMakeLists.txt | 4 ++-- src/script/CMakeLists.txt | 2 +- src/script/context.c | 2 ++ src/script/image.c | 24 ++++++++++++++----- src/util/configuration.c | 26 ++++++++++---------- src/util/image.c | 4 ++++ src/util/test/vfs.c | 4 ++-- src/util/vfs.c | 4 ++++ 43 files changed, 199 insertions(+), 95 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d69b000b..ae561189e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,7 +220,7 @@ if(WIN32) endif() endif() list(APPEND OS_LIB ws2_32 shlwapi) - list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/vfs-w32.c) + list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/vfs-w32.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/*.c) source_group("Windows-specific code" FILES ${OS_SRC}) elseif(UNIX) @@ -230,7 +230,7 @@ elseif(UNIX) add_definitions(-D_GNU_SOURCE) endif() - list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) + list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/posix/*.c) source_group("POSIX-specific code" FILES ${OS_SRC}) endif() @@ -349,6 +349,9 @@ elseif(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") endif() check_include_files("xlocale.h" HAVE_XLOCALE) + +set(ENABLE_VFS ON) + if(CMAKE_SYSTEM_NAME STREQUAL "Generic") if(NOT IS_EMBEDDED) set(DISABLE_DEPS ON CACHE BOOL "This platform cannot build with dependencies" FORCE) @@ -852,6 +855,10 @@ if(ENABLE_SCRIPTING) list(APPEND TEST_SRC ${SCRIPT_TEST_SRC}) endif() +if(ENABLE_VFS) + list(APPEND ENABLES VFS) +endif() + foreach(FEATURE IN LISTS FEATURES) list(APPEND FEATURE_DEFINES "USE_${FEATURE}") endforeach() @@ -890,7 +897,11 @@ list(APPEND CORE_SRC ${THIRD_PARTY_SRC}) list(APPEND TEST_SRC ${UTIL_TEST_SRC}) -set(SRC ${CORE_SRC} ${VFS_SRC}) +set(SRC ${CORE_SRC}) +if(ENABLE_VFS) + list(APPEND SRC ${VFS_SRC}) +endif() + if(NOT MINIMAL_CORE) set(ENABLE_EXTRA ON) if(M_CORE_GBA) @@ -922,7 +933,7 @@ if(NOT SKIP_LIBRARY) endif() if(BUILD_SHARED) - add_library(${BINARY_NAME} SHARED ${SRC} ${VFS_SRC}) + add_library(${BINARY_NAME} SHARED ${SRC}) set(EXPORT_DEFINES MGBA_DLL) if(BUILD_STATIC) add_library(${BINARY_NAME}-static STATIC ${SRC}) @@ -993,7 +1004,7 @@ if(BUILD_LIBRETRO) endif() endif() -if(BUILD_QT AND (WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux")) +if(BUILD_QT AND (WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux") AND ENABLE_VFS) set(BUILD_UPDATER ON) endif() diff --git a/include/mgba-util/configuration.h b/include/mgba-util/configuration.h index e19ad13ef..f4c206d6a 100644 --- a/include/mgba-util/configuration.h +++ b/include/mgba-util/configuration.h @@ -34,10 +34,12 @@ const char* ConfigurationGetValue(const struct Configuration*, const char* secti void ConfigurationClearValue(struct Configuration*, const char* section, const char* key); +#ifdef ENABLE_VFS bool ConfigurationRead(struct Configuration*, const char* path); -bool ConfigurationReadVFile(struct Configuration*, struct VFile* vf); bool ConfigurationWrite(const struct Configuration*, const char* path); bool ConfigurationWriteSection(const struct Configuration*, const char* path, const char* section); +#endif +bool ConfigurationReadVFile(struct Configuration*, struct VFile* vf); bool ConfigurationWriteVFile(const struct Configuration*, struct VFile* vf); void ConfigurationEnumerateSections(const struct Configuration* configuration, void (*handler)(const char* sectionName, void* user), void* user); diff --git a/include/mgba-util/image.h b/include/mgba-util/image.h index b86b2135a..681e0a3a6 100644 --- a/include/mgba-util/image.h +++ b/include/mgba-util/image.h @@ -114,12 +114,16 @@ struct VFile; struct mImage* mImageCreate(unsigned width, unsigned height, enum mColorFormat format); struct mImage* mImageCreateWithStride(unsigned width, unsigned height, unsigned stride, enum mColorFormat format); struct mImage* mImageCreateFromConstBuffer(unsigned width, unsigned height, unsigned stride, enum mColorFormat format, const void* pixels); +#ifdef ENABLE_VFS struct mImage* mImageLoad(const char* path); +#endif struct mImage* mImageLoadVF(struct VFile* vf); struct mImage* mImageConvertToFormat(const struct mImage*, enum mColorFormat format); void mImageDestroy(struct mImage*); +#ifdef ENABLE_VFS bool mImageSave(const struct mImage*, const char* path, const char* format); +#endif bool mImageSaveVF(const struct mImage*, struct VFile* vf, const char* format); uint32_t mImageGetPixel(const struct mImage* image, unsigned x, unsigned y); diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index b9c4ca6b2..0ff100143 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -50,6 +50,7 @@ struct VFile { bool (*sync)(struct VFile* vf, void* buffer, size_t size); }; +#ifdef ENABLE_VFS struct VDirEntry { const char* (*name)(struct VDirEntry* vde); enum VFSType (*type)(struct VDirEntry* vde); @@ -68,6 +69,7 @@ struct VFile* VFileOpen(const char* path, int flags); struct VFile* VFileOpenFD(const char* path, int flags); struct VFile* VFileFromFD(int fd); +#endif struct VFile* VFileFromMemory(void* mem, size_t size); struct VFile* VFileFromConstMemory(const void* mem, size_t size); @@ -76,6 +78,7 @@ struct VFile* VFileMemChunk(const void* mem, size_t size); struct mCircleBuffer; struct VFile* VFileFIFO(struct mCircleBuffer* backing); +#ifdef ENABLE_VFS struct VDir* VDirOpen(const char* path); struct VDir* VDirOpenArchive(const char* path); @@ -92,20 +95,20 @@ struct VDir* VDeviceList(void); #endif bool VDirCreate(const char* path); +struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); +struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); #ifdef USE_VFS_FILE struct VFile* VFileFOpen(const char* path, const char* mode); struct VFile* VFileFromFILE(FILE* file); #endif +#endif void separatePath(const char* path, char* dirname, char* basename, char* extension); bool isAbsolute(const char* path); void makeAbsolute(const char* path, const char* base, char* out); -struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); -struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); - ssize_t VFileReadline(struct VFile* vf, char* buffer, size_t size); ssize_t VFileWrite32LE(struct VFile* vf, int32_t word); diff --git a/include/mgba/core/cheats.h b/include/mgba/core/cheats.h index 1da1aa859..a1c6c555c 100644 --- a/include/mgba/core/cheats.h +++ b/include/mgba/core/cheats.h @@ -118,7 +118,7 @@ bool mCheatSaveFile(struct mCheatDevice*, struct VFile*); bool mCheatParseLibretroFile(struct mCheatDevice*, struct VFile*); bool mCheatParseEZFChtFile(struct mCheatDevice*, struct VFile*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS void mCheatAutosave(struct mCheatDevice*); #endif diff --git a/include/mgba/core/config.h b/include/mgba/core/config.h index 2082c11db..4a68b49ee 100644 --- a/include/mgba/core/config.h +++ b/include/mgba/core/config.h @@ -64,7 +64,7 @@ struct mCoreOptions { void mCoreConfigInit(struct mCoreConfig*, const char* port); void mCoreConfigDeinit(struct mCoreConfig*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS bool mCoreConfigLoad(struct mCoreConfig*); bool mCoreConfigSave(const struct mCoreConfig*); bool mCoreConfigLoadPath(struct mCoreConfig*, const char* path); diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index a4bf5826c..97f256c82 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -11,7 +11,7 @@ CXX_GUARD_START #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS #include #endif #ifndef MINIMAL_CORE @@ -46,7 +46,7 @@ struct mCore { struct mDebuggerSymbols* symbolTable; struct mVideoLogger* videoLogger; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS struct mDirectorySet dirs; #endif #ifndef MINIMAL_CORE @@ -176,7 +176,7 @@ struct mCore { #endif }; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS struct mCore* mCoreFind(const char* path); bool mCoreLoadFile(struct mCore* core, const char* path); diff --git a/include/mgba/core/directories.h b/include/mgba/core/directories.h index d421e7f51..f9f59cb8d 100644 --- a/include/mgba/core/directories.h +++ b/include/mgba/core/directories.h @@ -10,7 +10,7 @@ CXX_GUARD_START -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS struct VDir; struct mDirectorySet { diff --git a/include/mgba/core/library.h b/include/mgba/core/library.h index d12aa0411..ededd5463 100644 --- a/include/mgba/core/library.h +++ b/include/mgba/core/library.h @@ -10,6 +10,8 @@ CXX_GUARD_START +#ifdef ENABLE_VFS + #include #include @@ -48,6 +50,8 @@ void mLibraryAttachGameDB(struct mLibrary* library, const struct NoIntroDB* db); #endif +#endif + CXX_GUARD_END #endif diff --git a/include/mgba/core/scripting.h b/include/mgba/core/scripting.h index a8fdbc425..c0fdcb413 100644 --- a/include/mgba/core/scripting.h +++ b/include/mgba/core/scripting.h @@ -70,7 +70,9 @@ void mScriptBridgeDebuggerEntered(struct mScriptBridge*, enum mDebuggerEntryReas #endif void mScriptBridgeRun(struct mScriptBridge*); +#ifdef ENABLE_VFS bool mScriptBridgeLoadScript(struct mScriptBridge*, const char* name); +#endif bool mScriptBridgeLookupSymbol(struct mScriptBridge*, const char* name, int32_t* out); diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index c64d00391..a04685e49 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -139,7 +139,7 @@ struct GBA; void GBACartEReaderQueueCard(struct GBA* gba, const void* data, size_t size); struct EReaderScan; -#ifdef USE_PNG +#if defined(USE_PNG) && defined(ENABLE_VFS) MGBA_EXPORT struct EReaderScan* EReaderScanLoadImagePNG(const char* filename); #endif MGBA_EXPORT struct EReaderScan* EReaderScanLoadImage(const void* pixels, unsigned width, unsigned height, unsigned stride); @@ -149,7 +149,9 @@ MGBA_EXPORT void EReaderScanDestroy(struct EReaderScan*); MGBA_EXPORT bool EReaderScanCard(struct EReaderScan*); MGBA_EXPORT void EReaderScanOutputBitmap(const struct EReaderScan*, void* output, size_t stride); +#ifdef ENABLE_VFS MGBA_EXPORT bool EReaderScanSaveRaw(const struct EReaderScan*, const char* filename, bool strict); +#endif CXX_GUARD_END diff --git a/include/mgba/script/context.h b/include/mgba/script/context.h index 25628d785..ef740fb45 100644 --- a/include/mgba/script/context.h +++ b/include/mgba/script/context.h @@ -109,7 +109,9 @@ const char* mScriptEngineGetDocstring(struct mScriptEngineContext*, const char* struct VFile; bool mScriptContextLoadVF(struct mScriptContext*, const char* name, struct VFile* vf); +#ifdef ENABLE_VFS bool mScriptContextLoadFile(struct mScriptContext*, const char* path); +#endif struct mScriptContext* mScriptActiveContext(void); bool mScriptContextActivate(struct mScriptContext*); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 184445023..e86e4fe55 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -8,7 +8,6 @@ set(SOURCE_FILES directories.c input.c interface.c - library.c lockstep.c log.c map-cache.c @@ -23,6 +22,11 @@ set(SOURCE_FILES set(TEST_FILES test/core.c) +if(ENABLE_VFS) + list(APPEND SOURCE_FILES + library.c) +endif() + if(ENABLE_SCRIPTING) set(SCRIPTING_FILES scripting.c) diff --git a/src/core/cheats.c b/src/core/cheats.c index 60f73abcc..85a06b80d 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -622,7 +622,7 @@ bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { return true; } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS void mCheatAutosave(struct mCheatDevice* device) { if (!device->autosave) { return; diff --git a/src/core/config.c b/src/core/config.c index 4d4733cd9..4fa27ba55 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -167,7 +167,7 @@ void mCoreConfigDeinit(struct mCoreConfig* config) { free(config->port); } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS bool mCoreConfigLoad(struct mCoreConfig* config) { char path[PATH_MAX + 1]; mCoreConfigDirectory(path, PATH_MAX); diff --git a/src/core/core.c b/src/core/core.c index bcc72115a..20f9fdefc 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -15,6 +15,10 @@ #include #endif +#ifdef USE_PNG +#include +#endif + #ifdef M_CORE_GB #include #include @@ -86,9 +90,7 @@ struct mCore* mCoreCreate(enum mPlatform platform) { return NULL; } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 -#include - +#ifdef ENABLE_VFS #ifdef PSP2 #include #endif @@ -381,7 +383,7 @@ void mCoreInitConfig(struct mCore* core, const char* port) { } void mCoreLoadConfig(struct mCore* core) { -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mCoreConfigLoad(&core->config); #endif mCoreLoadForeignConfig(core, &core->config); @@ -389,7 +391,7 @@ void mCoreLoadConfig(struct mCore* core) { void mCoreLoadForeignConfig(struct mCore* core, const struct mCoreConfig* config) { mCoreConfigMap(config, &core->opts); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetMapOptions(&core->dirs, &core->opts); #endif if (core->opts.audioBuffers) { diff --git a/src/core/directories.c b/src/core/directories.c index c35773f1e..c4551b6c7 100644 --- a/src/core/directories.c +++ b/src/core/directories.c @@ -8,7 +8,7 @@ #include #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS void mDirectorySetInit(struct mDirectorySet* dirs) { dirs->base = NULL; dirs->archive = NULL; diff --git a/src/core/flags.h.in b/src/core/flags.h.in index ebfd67ed9..b91e1907a 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -61,6 +61,10 @@ #cmakedefine ENABLE_SCRIPTING #endif +#ifndef ENABLE_VFS +#cmakedefine ENABLE_VFS +#endif + // USE flags #ifndef USE_DISCORD_RPC diff --git a/src/core/log.c b/src/core/log.c index b897fedb4..39d6db88c 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -278,15 +278,16 @@ void mStandardLoggerDeinit(struct mStandardLogger* logger) { } void mStandardLoggerConfig(struct mStandardLogger* logger, struct mCoreConfig* config) { +#ifdef ENABLE_VFS bool logToFile = false; const char* logFile = mCoreConfigGetValue(config, "logFile"); - mCoreConfigGetBoolValue(config, "logToStdout", &logger->logToStdout); mCoreConfigGetBoolValue(config, "logToFile", &logToFile); if (logToFile && logFile) { logger->logFile = VFileOpen(logFile, O_WRONLY | O_CREAT | O_APPEND); } - +#endif + mCoreConfigGetBoolValue(config, "logToStdout", &logger->logToStdout); mLogFilterLoad(logger->d.filter, config); } diff --git a/src/core/scripting.c b/src/core/scripting.c index acf324e1f..57d0eed2b 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -129,6 +129,7 @@ void mScriptBridgeRun(struct mScriptBridge* sb) { HashTableEnumerate(&sb->engines, _seRun, NULL); } +#ifdef ENABLE_VFS bool mScriptBridgeLoadScript(struct mScriptBridge* sb, const char* name) { struct VFile* vf = VFileOpen(name, O_RDONLY); if (!vf) { @@ -143,6 +144,7 @@ bool mScriptBridgeLoadScript(struct mScriptBridge* sb, const char* name) { vf->close(vf); return info.success; } +#endif bool mScriptBridgeLookupSymbol(struct mScriptBridge* sb, const char* name, int32_t* out) { struct mScriptSymbol info = { @@ -417,6 +419,7 @@ static struct mScriptValue* _mScriptCoreSaveState(struct mCore* core, int32_t fl return value; } +#ifdef ENABLE_VFS static int _mScriptCoreSaveStateFile(struct mCore* core, const char* path, int flags) { struct VFile* vf = VFileOpen(path, O_WRONLY | O_TRUNC | O_CREAT); if (!vf) { @@ -427,13 +430,6 @@ static int _mScriptCoreSaveStateFile(struct mCore* core, const char* path, int f return ok; } -static int32_t _mScriptCoreLoadState(struct mCore* core, struct mScriptString* buffer, int32_t flags) { - struct VFile* vf = VFileFromConstMemory(buffer->buffer, buffer->size); - int ret = mCoreLoadStateNamed(core, vf, flags); - vf->close(vf); - return ret; -} - static int _mScriptCoreLoadStateFile(struct mCore* core, const char* path, int flags) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -456,6 +452,14 @@ static void _mScriptCoreTakeScreenshot(struct mCore* core, const char* filename) mCoreTakeScreenshot(core); } } +#endif + +static int32_t _mScriptCoreLoadState(struct mCore* core, struct mScriptString* buffer, int32_t flags) { + struct VFile* vf = VFileFromConstMemory(buffer->buffer, buffer->size); + int ret = mCoreLoadStateNamed(core, vf, flags); + vf->close(vf); + return ret; +} static struct mScriptValue* _mScriptCoreTakeScreenshotToImage(struct mCore* core) { size_t stride; @@ -480,10 +484,12 @@ static struct mScriptValue* _mScriptCoreTakeScreenshotToImage(struct mCore* core return result; } +#ifdef ENABLE_VFS // Loading functions mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, loadFile, mCoreLoadFile, 1, CHARP, path); mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, autoloadSave, mCoreAutoloadSave, 0); mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, loadSaveFile, mCoreLoadSaveFile, 2, CHARP, path, BOOL, temporary); +#endif // Info functions mSCRIPT_DECLARE_STRUCT_CD_METHOD(mCore, S32, platform, 0); @@ -523,27 +529,31 @@ mSCRIPT_DECLARE_STRUCT_METHOD(mCore, WSTR, readRegister, _mScriptCoreReadRegiste mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mCore, writeRegister, _mScriptCoreWriteRegister, 2, CHARP, regName, S32, value); // Savestate functions -mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateSlot, mCoreSaveState, 2, S32, slot, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, WSTR, saveStateBuffer, _mScriptCoreSaveState, 1, S32, flags); +mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateBuffer, _mScriptCoreLoadState, 2, STR, buffer, S32, flags); +#ifdef ENABLE_VFS +mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateSlot, mCoreSaveState, 2, S32, slot, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateFile, _mScriptCoreSaveStateFile, 2, CHARP, path, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateSlot, mCoreLoadState, 2, S32, slot, S32, flags); -mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateBuffer, _mScriptCoreLoadState, 2, STR, buffer, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateFile, _mScriptCoreLoadStateFile, 2, CHARP, path, S32, flags); // Miscellaneous functions mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(mCore, screenshot, _mScriptCoreTakeScreenshot, 1, CHARP, filename); +#endif mSCRIPT_DECLARE_STRUCT_METHOD(mCore, W(mImage), screenshotToImage, _mScriptCoreTakeScreenshotToImage, 0); mSCRIPT_DEFINE_STRUCT(mCore) mSCRIPT_DEFINE_CLASS_DOCSTRING( "An instance of an emulator core." ) +#ifdef ENABLE_VFS mSCRIPT_DEFINE_DOCSTRING("Load a ROM file into the current state of this core") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadFile) mSCRIPT_DEFINE_DOCSTRING("Load the save data associated with the currently loaded ROM file") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, autoloadSave) mSCRIPT_DEFINE_DOCSTRING("Load save data from the given path. If the `temporary` flag is set, the given save data will not be written back to disk") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadSaveFile) +#endif mSCRIPT_DEFINE_DOCSTRING("Get which platform is being emulated. See C.PLATFORM for possible values") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, platform) @@ -605,21 +615,23 @@ mSCRIPT_DEFINE_STRUCT(mCore) mSCRIPT_DEFINE_DOCSTRING("Write the value of the register with the given name") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, writeRegister) - mSCRIPT_DEFINE_DOCSTRING("Save state to the slot number. See C.SAVESTATE for possible values for `flags`") - mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateSlot) mSCRIPT_DEFINE_DOCSTRING("Save state and return as a buffer. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateBuffer) + mSCRIPT_DEFINE_DOCSTRING("Load state from a buffer. See C.SAVESTATE for possible values for `flags`") + mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateBuffer) +#ifdef ENABLE_VFS + mSCRIPT_DEFINE_DOCSTRING("Save state to the slot number. See C.SAVESTATE for possible values for `flags`") + mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateSlot) mSCRIPT_DEFINE_DOCSTRING("Save state to the given path. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateFile) mSCRIPT_DEFINE_DOCSTRING("Load state from the slot number. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateSlot) - mSCRIPT_DEFINE_DOCSTRING("Load state from a buffer. See C.SAVESTATE for possible values for `flags`") - mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateBuffer) mSCRIPT_DEFINE_DOCSTRING("Load state from the given path. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateFile) mSCRIPT_DEFINE_DOCSTRING("Save a screenshot to a file") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, screenshot) +#endif mSCRIPT_DEFINE_DOCSTRING("Get a screenshot in an struct::mImage") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, screenshotToImage) mSCRIPT_DEFINE_END; diff --git a/src/core/test/core.c b/src/core/test/core.c index 10c566b2c..645a45486 100644 --- a/src/core/test/core.c +++ b/src/core/test/core.c @@ -8,7 +8,7 @@ #include #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS M_TEST_DEFINE(findNullPath) { struct mCore* core = mCoreFind(NULL); assert_null(core); @@ -29,7 +29,7 @@ M_TEST_DEFINE(findEmpty) { } M_TEST_SUITE_DEFINE(mCore, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS cmocka_unit_test(findNullPath), #endif cmocka_unit_test(findNullVF), diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 95b2037dc..b5a6595d3 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -75,13 +75,15 @@ static void _dumpByte(struct CLIDebugger*, struct CLIDebugVector*); static void _dumpHalfword(struct CLIDebugger*, struct CLIDebugVector*); static void _dumpWord(struct CLIDebugger*, struct CLIDebugVector*); static void _events(struct CLIDebugger*, struct CLIDebugVector*); -#ifdef ENABLE_SCRIPTING -static void _source(struct CLIDebugger*, struct CLIDebugVector*); -#endif static void _backtrace(struct CLIDebugger*, struct CLIDebugVector*); static void _finish(struct CLIDebugger*, struct CLIDebugVector*); static void _setStackTraceMode(struct CLIDebugger*, struct CLIDebugVector*); +#ifdef ENABLE_VFS static void _loadSymbols(struct CLIDebugger*, struct CLIDebugVector*); +#ifdef ENABLE_SCRIPTING +static void _source(struct CLIDebugger*, struct CLIDebugVector*); +#endif +#endif static void _setSymbol(struct CLIDebugger*, struct CLIDebugVector*); static void _findSymbol(struct CLIDebugger*, struct CLIDebugVector*); @@ -96,6 +98,9 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "help", _printHelp, "S", "Print help" }, { "listb", _listBreakpoints, "", "List breakpoints" }, { "listw", _listWatchpoints, "", "List watchpoints" }, +#ifdef ENABLE_VFS + { "load-symbols", _loadSymbols, "S", "Load symbols from an external file" }, +#endif { "next", _next, "", "Execute next instruction" }, { "print", _print, "S+", "Print a value" }, { "print/t", _printBin, "S+", "Print a value as binary" }, @@ -106,10 +111,12 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "r/2", _readHalfword, "I", "Read a halfword from a specified offset" }, { "r/4", _readWord, "I", "Read a word from a specified offset" }, { "set", _setSymbol, "SI", "Assign a symbol to an address" }, +#if defined(ENABLE_SCRIPTING) && defined(ENABLE_VFS) + { "source", _source, "S", "Load a script" }, +#endif { "stack", _setStackTraceMode, "S", "Change the stack tracing mode" }, { "status", _printStatus, "", "Print the current status" }, { "symbol", _findSymbol, "I", "Find the symbol name for an address" }, - { "load-symbols", _loadSymbols, "S", "Load symbols from an external file" }, { "trace", _trace, "Is", "Trace a number of instructions" }, { "w/1", _writeByte, "II", "Write a byte at a specified offset" }, { "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" }, @@ -126,9 +133,6 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "x/1", _dumpByte, "Ii", "Examine bytes at a specified offset" }, { "x/2", _dumpHalfword, "Ii", "Examine halfwords at a specified offset" }, { "x/4", _dumpWord, "Ii", "Examine words at a specified offset" }, -#ifdef ENABLE_SCRIPTING - { "source", _source, "S", "Load a script" }, -#endif #if !defined(NDEBUG) && !defined(_WIN32) { "!", _breakInto, "", "Break into attached debugger (for developers)" }, #endif @@ -586,7 +590,7 @@ static void _dumpWord(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { } } -#ifdef ENABLE_SCRIPTING +#if defined(ENABLE_SCRIPTING) && defined(ENABLE_VFS) static void _source(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { if (!dv) { debugger->backend->printf(debugger->backend, "Needs a filename\n"); @@ -829,9 +833,11 @@ static void _trace(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { if (debugger->traceRemaining == 0) { return; } +#ifdef ENABLE_VFS if (dv->next && dv->next->charValue) { debugger->traceVf = VFileOpen(dv->next->charValue, O_CREAT | O_WRONLY | O_APPEND); } +#endif if (_doTrace(debugger)) { debugger->d.isPaused = false; mDebuggerUpdatePaused(debugger->d.p); @@ -1398,6 +1404,7 @@ static void _setStackTraceMode(struct CLIDebugger* debugger, struct CLIDebugVect } } +#ifdef ENABLE_VFS static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct mDebuggerSymbols* symbolTable = debugger->d.p->core->symbolTable; if (!symbolTable) { @@ -1431,6 +1438,7 @@ static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv } vf->close(vf); } +#endif static void _setSymbol(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct mDebuggerSymbols* symbolTable = debugger->d.p->core->symbolTable; diff --git a/src/debugger/cli-el-backend.c b/src/debugger/cli-el-backend.c index 382a05c14..b32afb159 100644 --- a/src/debugger/cli-el-backend.c +++ b/src/debugger/cli-el-backend.c @@ -85,6 +85,7 @@ static void CLIDebuggerEditLineInit(struct CLIDebuggerBackend* be) { history(elbe->histate, &ev, H_SETSIZE, 200); el_set(elbe->elstate, EL_HIST, history, elbe->histate); +#ifdef ENABLE_VFS char path[PATH_MAX + 1]; mCoreConfigDirectory(path, PATH_MAX); if (path[0]) { @@ -99,6 +100,7 @@ static void CLIDebuggerEditLineInit(struct CLIDebuggerBackend* be) { vf->close(vf); } } +#endif MutexInit(&elbe->promptMutex); ConditionInit(&elbe->promptRead); @@ -120,6 +122,7 @@ static void CLIDebuggerEditLineDeinit(struct CLIDebuggerBackend* be) { MutexUnlock(&elbe->promptMutex); ThreadJoin(&elbe->promptThread); +#ifdef ENABLE_VFS char path[PATH_MAX + 1]; mCoreConfigDirectory(path, PATH_MAX); if (path[0]) { @@ -139,6 +142,7 @@ static void CLIDebuggerEditLineDeinit(struct CLIDebuggerBackend* be) { vf->close(vf); } } +#endif history_end(elbe->histate); el_end(elbe->elstate); free(elbe); diff --git a/src/feature/CMakeLists.txt b/src/feature/CMakeLists.txt index b692338f4..966c25520 100644 --- a/src/feature/CMakeLists.txt +++ b/src/feature/CMakeLists.txt @@ -3,10 +3,14 @@ set(SOURCE_FILES commandline.c proxy-backend.c thread-proxy.c - updater.c video-backend.c video-logger.c) +if(ENABLE_VFS) + list(APPEND SOURCE_FILES + updater.c) +endif() + set(GUI_FILES gui/cheats.c gui/gui-config.c diff --git a/src/feature/commandline.c b/src/feature/commandline.c index cdf788b19..59735e69b 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -245,6 +245,7 @@ bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, } void mArgumentsApplyFileLoads(const struct mArguments* args, struct mCore* core) { +#ifdef ENABLE_VFS if (args->patch) { struct VFile* patch = VFileOpen(args->patch, O_RDONLY); if (patch) { @@ -266,6 +267,10 @@ void mArgumentsApplyFileLoads(const struct mArguments* args, struct mCore* core) } else { mCoreAutoloadCheats(core); } +#else + UNUSED(args); + UNUSED(core); +#endif } void mArgumentsDeinit(struct mArguments* args) { diff --git a/src/gb/core.c b/src/gb/core.c index 7023b29f7..9dbf36bc1 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -149,7 +149,7 @@ static bool _GBCoreInit(struct mCore* core) { gbcore->keys = 0; gb->keySource = &gbcore->keys; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetInit(&core->dirs); #endif @@ -161,7 +161,7 @@ static void _GBCoreDeinit(struct mCore* core) { GBDestroy(core->board); mappedMemoryFree(core->cpu, sizeof(struct SM83Core)); mappedMemoryFree(core->board, sizeof(struct GB)); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetDeinit(&core->dirs); #endif #ifdef ENABLE_DEBUGGERS @@ -597,7 +597,7 @@ static void _GBCoreReset(struct mCore* core) { } } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS if (!gb->biosVf && core->opts.useBios) { struct VFile* bios = NULL; bool found = false; @@ -1108,7 +1108,7 @@ static void _GBCoreDetachDebugger(struct mCore* core) { static void _GBCoreLoadSymbols(struct mCore* core, struct VFile* vf) { core->symbolTable = mDebuggerSymbolTableCreate(); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS if (!vf && core->dirs.base) { vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); } diff --git a/src/gb/debugger/cli.c b/src/gb/debugger/cli.c index f32f299a3..0b3ec6678 100644 --- a/src/gb/debugger/cli.c +++ b/src/gb/debugger/cli.c @@ -16,14 +16,14 @@ static void _GBCLIDebuggerInit(struct CLIDebuggerSystem*); static bool _GBCLIDebuggerCustom(struct CLIDebuggerSystem*); static void _frame(struct CLIDebugger*, struct CLIDebugVector*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger*, struct CLIDebugVector*); static void _save(struct CLIDebugger*, struct CLIDebugVector*); #endif struct CLIDebuggerCommandSummary _GBCLIDebuggerCommands[] = { { "frame", _frame, "", "Frame advance" }, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS { "load", _load, "*", "Load a savestate" }, { "save", _save, "*", "Save a savestate" }, #endif @@ -78,7 +78,7 @@ static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { gbDebugger->inVblank = GBRegisterSTATGetMode(((struct GB*) gbDebugger->core->board)->memory.io[GB_REG_STAT]) == 1; } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { diff --git a/src/gba/cart/ereader.c b/src/gba/cart/ereader.c index 6a3ce58b0..fc4d4c11d 100644 --- a/src/gba/cart/ereader.c +++ b/src/gba/cart/ereader.c @@ -875,7 +875,7 @@ void EReaderScanDestroy(struct EReaderScan* scan) { free(scan); } -#ifdef USE_PNG +#if defined(USE_PNG) && defined(ENABLE_VFS) struct EReaderScan* EReaderScanLoadImagePNG(const char* filename) { struct VFile* vf = VFileOpen(filename, O_RDONLY); if (!vf) { @@ -1564,6 +1564,7 @@ void EReaderScanOutputBitmap(const struct EReaderScan* scan, void* output, size_ } } +#ifdef ENABLE_VFS bool EReaderScanSaveRaw(const struct EReaderScan* scan, const char* filename, bool strict) { size_t blocks = EReaderBlockListSize(&scan->blocks); if (!blocks) { @@ -1633,5 +1634,6 @@ bool EReaderScanSaveRaw(const struct EReaderScan* scan, const char* filename, bo free(data); return true; } +#endif #endif diff --git a/src/gba/core.c b/src/gba/core.c index 4a437f36d..47da3a0e0 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -294,7 +294,7 @@ static bool _GBACoreInit(struct mCore* core) { gbacore->proxyRenderer.logger = NULL; #endif -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetInit(&core->dirs); #endif @@ -306,7 +306,7 @@ static void _GBACoreDeinit(struct mCore* core) { GBADestroy(core->board); mappedMemoryFree(core->cpu, sizeof(struct ARMCore)); mappedMemoryFree(core->board, sizeof(struct GBA)); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetDeinit(&core->dirs); #endif #ifdef ENABLE_DEBUGGERS @@ -741,7 +741,7 @@ static void _GBACoreReset(struct mCore* core) { } gbacore->memoryBlockType = -2; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS if (!gba->biosVf && core->opts.useBios) { struct VFile* bios = NULL; bool found = false; @@ -1244,7 +1244,7 @@ static void _GBACoreDetachDebugger(struct mCore* core) { static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { bool closeAfter = false; core->symbolTable = mDebuggerSymbolTableCreate(); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS #ifdef USE_ELF if (!vf && core->dirs.base) { closeAfter = true; diff --git a/src/gba/debugger/cli.c b/src/gba/debugger/cli.c index 8538f4515..8cb6c6043 100644 --- a/src/gba/debugger/cli.c +++ b/src/gba/debugger/cli.c @@ -16,14 +16,14 @@ static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*); static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem*); static void _frame(struct CLIDebugger*, struct CLIDebugVector*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger*, struct CLIDebugVector*); static void _save(struct CLIDebugger*, struct CLIDebugVector*); #endif struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = { { "frame", _frame, "", "Frame advance" }, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS { "load", _load, "*", "Load a savestate" }, { "save", _save, "*", "Save a savestate" }, #endif @@ -77,7 +77,7 @@ static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[GBA_REG(DISPSTAT)]); } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index ef70eed51..7469fe6d4 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -31,9 +31,9 @@ source_group("3DS-specific code" FILES ${OS_SRC}) if(USE_VFS_3DS) list(APPEND OS_DEFINES USE_VFS_3DS) else() - list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) + list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) endif() -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) list(APPEND GUI_SRC diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 6350bd287..fa6716be9 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -1081,6 +1081,7 @@ static bool _loadUniform(struct Configuration* description, size_t pass, struct return true; } +#ifdef ENABLE_VFS bool mGLES2ShaderLoad(struct VideoShader* shader, struct VDir* dir) { struct VFile* manifest = dir->openFile(dir, "manifest.ini", O_RDONLY); if (!manifest) { @@ -1204,6 +1205,7 @@ bool mGLES2ShaderLoad(struct VideoShader* shader, struct VDir* dir) { ConfigurationDeinit(&description); return success; } +#endif void mGLES2ShaderFree(struct VideoShader* shader) { free((void*) shader->name); diff --git a/src/platform/opengl/gles2.h b/src/platform/opengl/gles2.h index e53a1bab5..e3f46a9c0 100644 --- a/src/platform/opengl/gles2.h +++ b/src/platform/opengl/gles2.h @@ -106,8 +106,10 @@ void mGLES2ShaderDeinit(struct mGLES2Shader*); void mGLES2ShaderAttach(struct mGLES2Context*, struct mGLES2Shader*, size_t nShaders); void mGLES2ShaderDetach(struct mGLES2Context*); +#ifdef ENABLE_VFS struct VDir; bool mGLES2ShaderLoad(struct VideoShader*, struct VDir*); +#endif void mGLES2ShaderFree(struct VideoShader*); CXX_GUARD_END diff --git a/src/platform/psp2/CMakeLists.txt b/src/platform/psp2/CMakeLists.txt index c42f5355b..9653205fb 100644 --- a/src/platform/psp2/CMakeLists.txt +++ b/src/platform/psp2/CMakeLists.txt @@ -10,8 +10,8 @@ file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/psp2-*.c) set(OS_SRC ${OS_SRC} PARENT_SCOPE) source_group("PS Vita-specific code" FILES ${OS_SRC}) -list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sce-vfs.c) -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sce-vfs.c) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_LIB -lvita2d -l${M_LIBRARY} -lSceAppMgr_stub diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 716b33449..55db05d12 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -5,7 +5,7 @@ find_library(GLAPI_LIBRARY glapi REQUIRED) find_library(EGL_LIBRARY EGL REQUIRED) set(OS_DEFINES _GNU_SOURCE IOAPI_NO_64) -list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) +list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) include_directories(AFTER ${OPENGLES3_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIR}) @@ -17,7 +17,7 @@ else() find_library(NOUVEAU_LIBRARY drm_nouveau REQUIRED) list(APPEND OS_LIB nx) endif() -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) set(OS_LIB ${OS_LIB} PARENT_SCOPE) diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index 569408523..f8e6984f4 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -9,14 +9,14 @@ if(WIIDRC_LIBRARY) endif() set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64 FIXED_ROM_BUFFER) -list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) +list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) include_directories(${CMAKE_CURRENT_BINARY_DIR}) list(APPEND OS_LIB wiiuse bte fat ogc) set(OS_LIB ${OS_LIB} PARENT_SCOPE) source_group("Wii-specific code" FILES ${OS_SRC}) -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) list(APPEND GUI_SRC ${CMAKE_CURRENT_BINARY_DIR}/font.c ${CMAKE_CURRENT_BINARY_DIR}/icons.c ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt index 0f64514c0..a72f48d22 100644 --- a/src/script/CMakeLists.txt +++ b/src/script/CMakeLists.txt @@ -12,7 +12,7 @@ set(TEST_FILES test/classes.c test/types.c) -if(USE_JSON_C) +if(USE_JSON_C AND ENABLE_VFS) list(APPEND SOURCE_FILES storage.c) endif() diff --git a/src/script/context.c b/src/script/context.c index 47a4460f6..ab0937500 100644 --- a/src/script/context.c +++ b/src/script/context.c @@ -424,6 +424,7 @@ bool mScriptContextLoadVF(struct mScriptContext* context, const char* name, stru return info.context->load(info.context, name, vf); } +#ifdef ENABLE_VFS bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -433,6 +434,7 @@ bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) { vf->close(vf); return ret; } +#endif struct mScriptContext* mScriptActiveContext(void) { return ThreadLocalGetValue(_threadContext); diff --git a/src/script/image.c b/src/script/image.c index 2bd5a8736..533af131f 100644 --- a/src/script/image.c +++ b/src/script/image.c @@ -29,6 +29,7 @@ static struct mScriptValue* _mImageNew(unsigned width, unsigned height) { return result; } +#ifdef ENABLE_VFS static struct mScriptValue* _mImageLoad(const char* path) { struct mImage* image = mImageLoad(path); if (!image) { @@ -39,6 +40,7 @@ static struct mScriptValue* _mImageLoad(const char* path) { result->flags = mSCRIPT_VALUE_FLAG_DEINIT; return result; } +#endif static struct mScriptValue* _mImageNewPainter(struct mScriptValue* image) { mScriptValueRef(image); @@ -54,16 +56,10 @@ static struct mScriptValue* _mImageNewPainter(struct mScriptValue* image) { mSCRIPT_DECLARE_STRUCT_C_METHOD(mImage, U32, getPixel, mImageGetPixel, 2, U32, x, U32, y); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, setPixel, mImageSetPixel, 3, U32, x, U32, y, U32, color); -mSCRIPT_DECLARE_STRUCT_C_METHOD_WITH_DEFAULTS(mImage, BOOL, save, mImageSave, 2, CHARP, path, CHARP, format); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, _deinit, mImageDestroy, 0); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, drawImageOpaque, mImageBlit, 3, CS(mImage), image, U32, x, U32, y); mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(mImage, drawImage, mImageCompositeWithAlpha, 4, CS(mImage), image, U32, x, U32, y, F32, alpha); -mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, save) - mSCRIPT_NO_DEFAULT, - mSCRIPT_CHARP("PNG") -mSCRIPT_DEFINE_DEFAULTS_END; - mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, drawImage) mSCRIPT_NO_DEFAULT, mSCRIPT_NO_DEFAULT, @@ -71,13 +67,23 @@ mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, drawImage) mSCRIPT_F32(1.0f) mSCRIPT_DEFINE_DEFAULTS_END; +#ifdef ENABLE_VFS +mSCRIPT_DECLARE_STRUCT_C_METHOD_WITH_DEFAULTS(mImage, BOOL, save, mImageSave, 2, CHARP, path, CHARP, format); +mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, save) + mSCRIPT_NO_DEFAULT, + mSCRIPT_CHARP("PNG") +mSCRIPT_DEFINE_DEFAULTS_END; +#endif + mSCRIPT_DEFINE_STRUCT(mImage) mSCRIPT_DEFINE_CLASS_DOCSTRING( "A single, static image." ) mSCRIPT_DEFINE_STRUCT_DEINIT(mImage) +#ifdef ENABLE_VFS mSCRIPT_DEFINE_DOCSTRING("Save the image to a file. Currently, only `PNG` format is supported") mSCRIPT_DEFINE_STRUCT_METHOD(mImage, save) +#endif mSCRIPT_DEFINE_DOCSTRING("Get the ARGB value of the pixel at a given coordinate") mSCRIPT_DEFINE_STRUCT_METHOD(mImage, getPixel) mSCRIPT_DEFINE_DOCSTRING("Set the ARGB value of the pixel at a given coordinate") @@ -93,7 +99,9 @@ mSCRIPT_DEFINE_STRUCT(mImage) mSCRIPT_DEFINE_END; mSCRIPT_BIND_FUNCTION(mImageNew_Binding, W(mImage), _mImageNew, 2, U32, width, U32, height); +#ifdef ENABLE_VFS mSCRIPT_BIND_FUNCTION(mImageLoad_Binding, W(mImage), _mImageLoad, 1, CHARP, path); +#endif mSCRIPT_BIND_FUNCTION(mImageNewPainter_Binding, W(mScriptPainter), _mImageNewPainter, 1, W(mImage), image); void _mPainterSetBlend(struct mPainter* painter, bool enable) { @@ -186,12 +194,16 @@ mSCRIPT_DEFINE_END; void mScriptContextAttachImage(struct mScriptContext* context) { mScriptContextExportNamespace(context, "image", (struct mScriptKVPair[]) { mSCRIPT_KV_PAIR(new, &mImageNew_Binding), +#ifdef ENABLE_VFS mSCRIPT_KV_PAIR(load, &mImageLoad_Binding), +#endif mSCRIPT_KV_PAIR(newPainter, &mImageNewPainter_Binding), mSCRIPT_KV_SENTINEL }); mScriptContextSetDocstring(context, "image", "Methods for creating struct::mImage and struct::mPainter instances"); mScriptContextSetDocstring(context, "image.new", "Create a new image with the given dimensions"); +#ifdef ENABLE_VFS mScriptContextSetDocstring(context, "image.load", "Load an image from a path. Currently, only `PNG` format is supported"); +#endif mScriptContextSetDocstring(context, "image.newPainter", "Create a new painter from an existing image"); } diff --git a/src/util/configuration.c b/src/util/configuration.c index dbcefef8f..8b7320b5c 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c @@ -160,6 +160,7 @@ static char* _vfgets(char* stream, int size, void* user) { return 0; } +#ifdef ENABLE_VFS bool ConfigurationRead(struct Configuration* configuration, const char* path) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -170,12 +171,6 @@ bool ConfigurationRead(struct Configuration* configuration, const char* path) { return res; } -bool ConfigurationReadVFile(struct Configuration* configuration, struct VFile* vf) { - HashTableClear(&configuration->root); - HashTableClear(&configuration->sections); - return ini_parse_stream(_vfgets, vf, _iniRead, configuration) == 0; -} - bool ConfigurationWrite(const struct Configuration* configuration, const char* path) { struct VFile* vf = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { @@ -186,12 +181,6 @@ bool ConfigurationWrite(const struct Configuration* configuration, const char* p return res; } -bool ConfigurationWriteVFile(const struct Configuration* configuration, struct VFile* vf) { - HashTableEnumerate(&configuration->root, _keyHandler, vf); - HashTableEnumerate(&configuration->sections, _sectionHandler, vf); - return true; -} - bool ConfigurationWriteSection(const struct Configuration* configuration, const char* path, const char* section) { const struct Table* currentSection = &configuration->root; struct VFile* vf = VFileOpen(path, O_WRONLY | O_CREAT | O_APPEND); @@ -213,6 +202,19 @@ bool ConfigurationWriteSection(const struct Configuration* configuration, const vf->close(vf); return true; } +#endif + +bool ConfigurationReadVFile(struct Configuration* configuration, struct VFile* vf) { + HashTableClear(&configuration->root); + HashTableClear(&configuration->sections); + return ini_parse_stream(_vfgets, vf, _iniRead, configuration) == 0; +} + +bool ConfigurationWriteVFile(const struct Configuration* configuration, struct VFile* vf) { + HashTableEnumerate(&configuration->root, _keyHandler, vf); + HashTableEnumerate(&configuration->sections, _sectionHandler, vf); + return true; +} void ConfigurationEnumerateSections(const struct Configuration* configuration, void (*handler)(const char* sectionName, void* user), void* user) { struct ConfigurationSectionHandlerData handlerData = { handler, user }; diff --git a/src/util/image.c b/src/util/image.c index f1f1a0fef..64e8aeec6 100644 --- a/src/util/image.c +++ b/src/util/image.c @@ -132,6 +132,7 @@ struct mImage* mImageCreateFromConstBuffer(unsigned width, unsigned height, unsi return image; } +#ifdef ENABLE_VFS struct mImage* mImageLoad(const char* path) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -141,6 +142,7 @@ struct mImage* mImageLoad(const char* path) { vf->close(vf); return image; } +#endif #ifdef USE_PNG static struct mImage* mImageLoadPNG(struct VFile* vf) { @@ -299,6 +301,7 @@ void mImageDestroy(struct mImage* image) { free(image); } +#ifdef ENABLE_VFS bool mImageSave(const struct mImage* image, const char* path, const char* format) { struct VFile* vf = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { @@ -314,6 +317,7 @@ bool mImageSave(const struct mImage* image, const char* path, const char* format vf->close(vf); return success; } +#endif #ifdef USE_PNG bool mImageSavePNG(const struct mImage* image, struct VFile* vf) { diff --git a/src/util/test/vfs.c b/src/util/test/vfs.c index 4fd995275..2d1cfd56a 100644 --- a/src/util/test/vfs.c +++ b/src/util/test/vfs.c @@ -7,7 +7,7 @@ #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS M_TEST_DEFINE(openNullPathR) { struct VFile* vf = VFileOpen(NULL, O_RDONLY); assert_null(vf); @@ -146,7 +146,7 @@ M_TEST_DEFINE(mapMemChunk) { } M_TEST_SUITE_DEFINE(VFS, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS cmocka_unit_test(openNullPathR), cmocka_unit_test(openNullPathW), cmocka_unit_test(openNullPathCreate), diff --git a/src/util/vfs.c b/src/util/vfs.c index d99f5020f..09ae81047 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -18,6 +18,7 @@ #include #endif +#ifdef ENABLE_VFS struct VFile* VFileOpen(const char* path, int flags) { #ifdef USE_VFS_FILE const char* chflags; @@ -115,6 +116,7 @@ struct VDir* VDirOpenArchive(const char* path) { #endif return dir; } +#endif ssize_t VFileReadline(struct VFile* vf, char* buffer, size_t size) { size_t bytesRead = 0; @@ -246,6 +248,7 @@ void makeAbsolute(const char* path, const char* base, char* out) { strncpy(out, buf, PATH_MAX); } +#ifdef ENABLE_VFS struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)) { dir->rewind(dir); struct VDirEntry* dirent = dir->listNext(dir); @@ -310,3 +313,4 @@ struct VFile* VDirFindNextAvailable(struct VDir* dir, const char* basename, cons path[PATH_MAX - 1] = '\0'; return dir->openFile(dir, path, mode); } +#endif From 267167a236f1451da59cf17105e07f2836bd0c3a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:24:22 -0700 Subject: [PATCH 172/336] Libretro: Fix non-ENABLE_VFS build --- CMakeLists.txt | 2 +- src/platform/libretro/libretro.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae561189e..7fc7e05fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -995,7 +995,7 @@ if(BUILD_LIBRETRO) file(GLOB RETRO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/libretro/*.c) add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC}) add_dependencies(${BINARY_NAME}_libretro ${BINARY_NAME}-version-info) - set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "__LIBRETRO__;COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;MGBA_STANDALONE;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=2") + set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "__LIBRETRO__;COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;MGBA_STANDALONE;${OS_DEFINES};${FUNCTION_DEFINES};ENABLE_VFS;MINIMAL_CORE=2") target_link_libraries(${BINARY_NAME}_libretro ${OS_LIB}) if(MSVC) install(TARGETS ${BINARY_NAME}_libretro RUNTIME DESTINATION ${LIBRETRO_LIBDIR} COMPONENT ${BINARY_NAME}_libretro) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 8478eb298..86a692837 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -848,9 +848,11 @@ bool retro_load_game(const struct retro_game_info* game) { dataSize = game->size; memcpy(data, game->data, game->size); rom = VFileFromMemory(data, game->size); +#ifdef ENABLE_VFS } else { - data = 0; + data = NULL; rom = VFileOpen(game->path, O_RDONLY); +#endif } if (!rom) { return false; @@ -973,6 +975,7 @@ bool retro_load_game(const struct retro_game_info* game) { } #endif +#ifdef ENABLE_VFS if (core->opts.useBios && sysDir && biosName) { snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, biosName); struct VFile* bios = VFileOpen(biosPath, O_RDONLY); @@ -980,6 +983,7 @@ bool retro_load_game(const struct retro_game_info* game) { core->loadBIOS(core, bios, 0); } } +#endif core->reset(core); _setupMaps(core); From d5e49a5981da1d7e08c6174c8a8f0718a27eab00 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:34:55 -0700 Subject: [PATCH 173/336] All: Remove unmaintained RasPi and Pandora code --- CMakeLists.txt | 14 ---- src/platform/sdl/CMakeLists.txt | 40 +++------- src/platform/sdl/gles2-sdl.c | 15 +--- src/platform/sdl/main.c | 4 - src/platform/sdl/main.h | 24 ------ src/platform/sdl/pandora-sdl.c | 129 -------------------------------- src/platform/sdl/rpi-common.c | 84 --------------------- src/platform/sdl/rpi-common.h | 20 ----- src/platform/sdl/sdl-events.c | 18 ----- 9 files changed, 12 insertions(+), 336 deletions(-) delete mode 100644 src/platform/sdl/pandora-sdl.c delete mode 100644 src/platform/sdl/rpi-common.c delete mode 100644 src/platform/sdl/rpi-common.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fc7e05fb..3767bae8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,20 +269,6 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf") endif() -if(BUILD_BBB OR BUILD_RASPI OR BUILD_PANDORA) - if(NOT BUILD_EGL) - add_definitions(-DCOLOR_16_BIT -DCOLOR_5_6_5) - endif() -endif() - -if(BUILD_RASPI) - set(BUILD_GL OFF CACHE BOOL "OpenGL not supported" FORCE) -endif() - -if(BUILD_PANDORA) - add_definitions(-DBUILD_PANDORA) -endif() - if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*") enable_language(ASM) endif() diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index ca1919da9..38e328d73 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -80,37 +80,19 @@ set(SDLMAIN_LIBRARY "${SDLMAIN_LIBRARY}" PARENT_SCOPE) set(MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -if(BUILD_RASPI) - add_definitions(-DBUILD_RASPI) - list(APPEND PLATFORM_SRC ${PROJECT_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c ${CMAKE_CURRENT_SOURCE_DIR}/rpi-common.c) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) - set(OPENGLES2_LIBRARY "-lEGL -lGLESv2 -lbcm_host") - set(BUILD_GLES2 ON CACHE BOOL "Using OpenGL|ES 2" FORCE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fgnu89-inline") - add_executable(${BINARY_NAME}-rpi ${PLATFORM_SRC} ${MAIN_SRC}) - set_target_properties(${BINARY_NAME}-rpi PROPERTIES COMPILE_DEFINITIONS "${FEATURE_DEFINES};${FUNCTION_DEFINES}") - target_link_libraries(${BINARY_NAME}-rpi ${BINARY_NAME} ${PLATFORM_LIBRARY} ${OPENGLES2_LIBRARY}) - install(TARGETS ${BINARY_NAME}-rpi DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-rpi) - unset(OPENGLES2_INCLUDE_DIR CACHE) # Clear NOTFOUND +if(BUILD_GL) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) endif() - -if(BUILD_PANDORA) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pandora-sdl.c) +if(BUILD_GLES2) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) + include_directories(${OPENGLES2_INCLUDE_DIR}) +endif() +if(SDL_VERSION EQUAL "2") + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl2.c) else() - if(BUILD_GL) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) - endif() - if(BUILD_GLES2) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) - include_directories(${OPENGLES2_INCLUDE_DIR}) - endif() - if(SDL_VERSION EQUAL "2") - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl2.c) - else() - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl1.c) - endif() + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl1.c) endif() if(ENABLE_SCRIPTING) diff --git a/src/platform/sdl/gles2-sdl.c b/src/platform/sdl/gles2-sdl.c index 9bae33b95..a4aa386df 100644 --- a/src/platform/sdl/gles2-sdl.c +++ b/src/platform/sdl/gles2-sdl.c @@ -6,9 +6,6 @@ #include "main.h" #include "gl-common.h" -#ifdef BUILD_RASPI -#include "rpi-common.h" -#endif #include @@ -43,11 +40,7 @@ bool mSDLGLES2Init(struct mSDLRenderer* renderer) { renderer->gl2.d.lockAspectRatio = renderer->lockAspectRatio; renderer->gl2.d.lockIntegerScaling = renderer->lockIntegerScaling; renderer->gl2.d.filter = renderer->filter; -#ifdef BUILD_RASPI - renderer->gl2.d.swap = mRPIGLCommonSwap; -#else renderer->gl2.d.swap = mSDLGLCommonSwap; -#endif renderer->gl2.d.init(&renderer->gl2.d, 0); struct mRectangle dims = { @@ -66,13 +59,7 @@ void mSDLGLES2Deinit(struct mSDLRenderer* renderer) { if (renderer->gl2.d.deinit) { renderer->gl2.d.deinit(&renderer->gl2.d); } -#ifdef BUILD_RASPI - eglMakeCurrent(renderer->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroySurface(renderer->eglDisplay, renderer->eglSurface); - eglDestroyContext(renderer->eglDisplay, renderer->eglContext); - eglTerminate(renderer->eglDisplay); - bcm_host_deinit(); -#elif SDL_VERSION_ATLEAST(2, 0, 0) +#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_DeleteContext(renderer->glCtx); #endif free(renderer->outputBuffer); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 1a1d3f6fc..b1b850e21 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -133,11 +133,7 @@ int main(int argc, char** argv) { mSDLGLCreate(&renderer); } else #elif defined(BUILD_GLES2) || defined(USE_EPOXY) -#ifdef BUILD_RASPI - mRPIGLCommonInit(&renderer); -#else if (mSDLGLCommonInit(&renderer)) -#endif { mSDLGLES2Create(&renderer); } else diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index 10135da2f..43701b3c2 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -18,17 +18,6 @@ CXX_GUARD_START #include "platform/opengl/gl.h" #endif -#ifdef BUILD_RASPI -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#include -#include - -#include -#pragma GCC diagnostic pop -#endif - #if defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) #include "gl-common.h" #include "platform/opengl/gles2.h" @@ -82,19 +71,6 @@ struct mSDLRenderer { pixman_image_t* pix; pixman_image_t* screenpix; #endif - -#ifdef BUILD_RASPI - EGLDisplay eglDisplay; - EGLSurface eglSurface; - EGLContext eglContext; - EGL_DISPMANX_WINDOW_T eglWindow; -#endif - -#ifdef BUILD_PANDORA - int fb; - int odd; - void* base[2]; -#endif }; void mSDLSWCreate(struct mSDLRenderer* renderer); diff --git a/src/platform/sdl/pandora-sdl.c b/src/platform/sdl/pandora-sdl.c deleted file mode 100644 index 673d419b6..000000000 --- a/src/platform/sdl/pandora-sdl.c +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "main.h" - -#include "gba/supervisor/thread.h" - -#include -#include -#include -#include - -#ifndef FBIO_WAITFORVSYNC -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -#endif - -static bool mSDLInit(struct SDLSoftwareRenderer* renderer); -static void mSDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer); -static void mSDLDeinit(struct SDLSoftwareRenderer* renderer); - -void mSDLGLCreate(struct SDLSoftwareRenderer* renderer) { - renderer->init = mSDLInit; - renderer->deinit = mSDLDeinit; - renderer->runloop = mSDLRunloop; -} - -void mSDLSWCreate(struct SDLSoftwareRenderer* renderer) { - renderer->init = mSDLInit; - renderer->deinit = mSDLDeinit; - renderer->runloop = mSDLRunloop; -} - -bool mSDLInit(struct SDLSoftwareRenderer* renderer) { - SDL_SetVideoMode(800, 480, 16, SDL_FULLSCREEN); - - renderer->odd = 0; - renderer->fb = open("/dev/fb1", O_RDWR); - if (renderer->fb < 0) { - return false; - } - - struct omapfb_plane_info plane; - struct omapfb_mem_info mem; - if (ioctl(renderer->fb, OMAPFB_QUERY_PLANE, &plane) < 0) { - return false; - } - if (ioctl(renderer->fb, OMAPFB_QUERY_MEM, &mem) < 0) { - return false; - } - - if (plane.enabled) { - plane.enabled = 0; - ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); - } - - mem.size = GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4; - ioctl(renderer->fb, OMAPFB_SETUP_MEM, &mem); - - plane.enabled = 1; - plane.pos_x = 40; - plane.pos_y = 0; - plane.out_width = 720; - plane.out_height = 480; - ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); - - struct fb_var_screeninfo info; - ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); - info.xres = GBA_VIDEO_HORIZONTAL_PIXELS; - info.yres = GBA_VIDEO_VERTICAL_PIXELS; - info.xres_virtual = GBA_VIDEO_HORIZONTAL_PIXELS; - info.yres_virtual = GBA_VIDEO_VERTICAL_PIXELS * 2; - info.bits_per_pixel = 16; - ioctl(renderer->fb, FBIOPUT_VSCREENINFO, &info); - - renderer->odd = 0; - renderer->base[0] = mmap(0, GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4, PROT_READ | PROT_WRITE, MAP_SHARED, renderer->fb, 0); - renderer->base[1] = (uint16_t*) renderer->base[0] + GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS; - - renderer->d.outputBuffer = renderer->base[0]; - renderer->d.outputBufferStride = GBA_VIDEO_HORIZONTAL_PIXELS; - return true; -} - -void mSDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) { - SDL_Event event; - - while (context->state < THREAD_EXITING) { - while (SDL_PollEvent(&event)) { - mSDLHandleEventGBA(context, &renderer->player, &event); - } - - if (mCoreSyncWaitFrameStart(&context->sync)) { - struct fb_var_screeninfo info; - ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); - info.yoffset = GBA_VIDEO_VERTICAL_PIXELS * renderer->odd; - ioctl(renderer->fb, FBIOPAN_DISPLAY, &info); - - int arg = 0; - ioctl(renderer->fb, FBIO_WAITFORVSYNC, &arg); - - renderer->odd = !renderer->odd; - renderer->d.outputBuffer = renderer->base[renderer->odd]; - } - mCoreSyncWaitFrameEnd(&context->sync); - } -} - -void mSDLDeinit(struct SDLSoftwareRenderer* renderer) { - munmap(renderer->base[0], GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4); - - struct omapfb_plane_info plane; - struct omapfb_mem_info mem; - ioctl(renderer->fb, OMAPFB_QUERY_PLANE, &plane); - ioctl(renderer->fb, OMAPFB_QUERY_MEM, &mem); - - mem.size = 0; - ioctl(renderer->fb, OMAPFB_SETUP_MEM, &mem); - - plane.enabled = 0; - plane.pos_x = 0; - plane.pos_y = 0; - plane.out_width = 0; - plane.out_height = 0; - ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); - - close(renderer->fb); -} diff --git a/src/platform/sdl/rpi-common.c b/src/platform/sdl/rpi-common.c deleted file mode 100644 index be141718e..000000000 --- a/src/platform/sdl/rpi-common.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "main.h" - -#include - -void mRPIGLCommonSwap(struct VideoBackend* context) { - struct mSDLRenderer* renderer = (struct mSDLRenderer*) context->user; - eglSwapBuffers(renderer->eglDisplay, renderer->eglSurface); -} - -void mRPIGLCommonInit(struct mSDLRenderer* renderer) { - bcm_host_init(); - renderer->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - int major, minor; - if (EGL_FALSE == eglInitialize(renderer->eglDisplay, &major, &minor)) { - printf("Failed to initialize EGL"); - return false; - } - - if (EGL_FALSE == eglBindAPI(EGL_OPENGL_ES_API)) { - printf("Failed to get GLES API"); - return false; - } - - const EGLint requestConfig[] = { - EGL_RED_SIZE, 5, - EGL_GREEN_SIZE, 5, - EGL_BLUE_SIZE, 5, - EGL_ALPHA_SIZE, 1, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_NONE - }; - - EGLConfig config; - EGLint numConfigs; - - if (EGL_FALSE == eglChooseConfig(renderer->eglDisplay, requestConfig, &config, 1, &numConfigs)) { - printf("Failed to choose EGL config\n"); - return false; - } - - const EGLint contextAttributes[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - int dispWidth = 240, dispHeight = 160, adjWidth; - renderer->eglContext = eglCreateContext(renderer->eglDisplay, config, EGL_NO_CONTEXT, contextAttributes); - graphics_get_display_size(0, &dispWidth, &dispHeight); - adjWidth = dispHeight / 2 * 3; - - DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0); - DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); - - VC_RECT_T destRect = { - .x = (dispWidth - adjWidth) / 2, - .y = 0, - .width = adjWidth, - .height = dispHeight - }; - - VC_RECT_T srcRect = { - .x = 0, - .y = 0, - .width = 240 << 16, - .height = 160 << 16 - }; - - DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(update, display, 0, &destRect, 0, &srcRect, DISPMANX_PROTECTION_NONE, 0, 0, 0); - vc_dispmanx_update_submit_sync(update); - - renderer->eglWindow.element = element; - renderer->eglWindow.width = dispWidth; - renderer->eglWindow.height = dispHeight; - - renderer->eglSurface = eglCreateWindowSurface(renderer->eglDisplay, config, &renderer->eglWindow, 0); - if (EGL_FALSE == eglMakeCurrent(renderer->eglDisplay, renderer->eglSurface, renderer->eglSurface, renderer->eglContext)) { - return false; - } -} diff --git a/src/platform/sdl/rpi-common.h b/src/platform/sdl/rpi-common.h deleted file mode 100644 index b58532de5..000000000 --- a/src/platform/sdl/rpi-common.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef SDL_RPI_COMMON_H -#define SDL_RPI_COMMON_H - -#include - -CXX_GUARD_START - -#include "main.h" - -void mRPIGLCommonSwap(struct VideoBackend* context); -void mRPIGLCommonInit(struct mSDLRenderer* renderer); - -CXX_GUARD_END - -#endif diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 950bb94f3..afeedba68 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -143,18 +143,6 @@ void mSDLEventsLoadConfig(struct mSDLEvents* context, const struct Configuration } void mSDLInitBindingsGBA(struct mInputMap* inputMap) { -#ifdef BUILD_PANDORA - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_PAGEDOWN, GBA_KEY_A); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_END, GBA_KEY_B); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RSHIFT, GBA_KEY_L); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RCTRL, GBA_KEY_R); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LALT, GBA_KEY_START); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LCTRL, GBA_KEY_SELECT); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT); -#else mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_x, GBA_KEY_A); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_z, GBA_KEY_B); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_a, GBA_KEY_L); @@ -165,7 +153,6 @@ void mSDLInitBindingsGBA(struct mInputMap* inputMap) { mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT); -#endif #if SDL_VERSION_ATLEAST(2, 0, 0) mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_A, GBA_KEY_A); @@ -522,11 +509,6 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer* context->frameCallback = _pauseAfterFrame; mCoreThreadUnpause(context); return; -#ifdef BUILD_PANDORA - case SDLK_ESCAPE: - mCoreThreadEnd(context); - return; -#endif default: if ((event->keysym.mod & GUI_MOD) && (event->keysym.mod & GUI_MOD) == event->keysym.mod) { switch (event->keysym.sym) { From 3f54bcbc878b8cc27211adf729d6231474e53976 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 04:19:50 -0700 Subject: [PATCH 174/336] GB, GBA Audio: More efficient sample writing --- src/gb/audio.c | 14 +++++--------- src/gba/audio.c | 14 +++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/gb/audio.c b/src/gb/audio.c index 4230fb88c..9603175a8 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -823,15 +823,11 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { mCoreSyncLockAudio(audio->p->sync); unsigned produced; - int i; - for (i = 0; i < GB_MAX_SAMPLES; ++i) { - int16_t sample[2] = { - audio->currentSamples[i].left, - audio->currentSamples[i].right - }; - mAudioBufferWrite(&audio->buffer, sample, 1); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); + mAudioBufferWrite(&audio->buffer, (int16_t*) audio->currentSamples, GB_MAX_SAMPLES); + if (audio->p->stream && audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < GB_MAX_SAMPLES; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); } } diff --git a/src/gba/audio.c b/src/gba/audio.c index 8ccc7f9d8..8c07bcb51 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -393,15 +393,11 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { mCoreSyncLockAudio(audio->p->sync); unsigned produced; - int i; - for (i = 0; i < samples; ++i) { - int16_t sample[2] = { - audio->currentSamples[i].left, - audio->currentSamples[i].right - }; - mAudioBufferWrite(&audio->psg.buffer, sample, 1); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); + mAudioBufferWrite(&audio->psg.buffer, (int16_t*) audio->currentSamples, samples); + if (audio->p->stream && audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < samples; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); } } produced = mAudioBufferAvailable(&audio->psg.buffer); From 2bce03023bb051aeb22e16a2b3a7160713c672b7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 21:38:54 -0700 Subject: [PATCH 175/336] GB, GBA Audio: Refactor stream code to do less when no stream is present --- src/gb/audio.c | 25 +++++++++++++------------ src/gba/audio.c | 24 +++++++++++++----------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/gb/audio.c b/src/gb/audio.c index 9603175a8..b090018f6 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -822,25 +822,26 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { GBAudioSample(audio, mTimingCurrentTime(audio->timing)); mCoreSyncLockAudio(audio->p->sync); - unsigned produced; mAudioBufferWrite(&audio->buffer, (int16_t*) audio->currentSamples, GB_MAX_SAMPLES); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - int i; - for (i = 0; i < GB_MAX_SAMPLES; ++i) { - audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + if (audio->p->stream) { + if (audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < GB_MAX_SAMPLES; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + } + } + if (audio->p->stream->postAudioBuffer) { + unsigned produced = mAudioBufferAvailable(&audio->buffer); + bool wait = produced >= audio->samples; + if (wait) { + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->buffer); + } } } - - produced = mAudioBufferAvailable(&audio->buffer); - bool wait = produced >= audio->samples; if (!mCoreSyncProduceAudio(audio->p->sync, &audio->buffer)) { // Interrupted audio->p->earlyExit = true; } - - if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, &audio->buffer); - } mTimingSchedule(timing, &audio->sampleEvent, audio->sampleInterval * audio->timingFactor - cyclesLate); } diff --git a/src/gba/audio.c b/src/gba/audio.c index 8c07bcb51..c84d6ce27 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -392,25 +392,27 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { memset(audio->chB.samples, audio->chB.samples[samples - 1], sizeof(audio->chB.samples)); mCoreSyncLockAudio(audio->p->sync); - unsigned produced; mAudioBufferWrite(&audio->psg.buffer, (int16_t*) audio->currentSamples, samples); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - int i; - for (i = 0; i < samples; ++i) { - audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + if (audio->p->stream) { + if (audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < samples; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + } + } + if (audio->p->stream->postAudioBuffer) { + unsigned produced = mAudioBufferAvailable(&audio->psg.buffer); + bool wait = produced >= audio->samples; + if (wait) { + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->psg.buffer); + } } } - produced = mAudioBufferAvailable(&audio->psg.buffer); - bool wait = produced >= audio->samples; if (!mCoreSyncProduceAudio(audio->p->sync, &audio->psg.buffer)) { // Interrupted audio->p->earlyExit = true; } - if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, &audio->psg.buffer); - } - mTimingSchedule(timing, &audio->sampleEvent, SAMPLE_INTERVAL - cyclesLate); } From 55add8a2c6b69faa97a08682cb62d59572aef16d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 21:42:34 -0700 Subject: [PATCH 176/336] Util: Early exist mAudioBufferRead if the buffer is full --- src/util/audio-buffer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/audio-buffer.c b/src/util/audio-buffer.c index 5d67827fb..028946b48 100644 --- a/src/util/audio-buffer.c +++ b/src/util/audio-buffer.c @@ -52,6 +52,9 @@ size_t mAudioBufferRead(struct mAudioBuffer* buffer, int16_t* samples, size_t co size_t mAudioBufferWrite(struct mAudioBuffer* buffer, const int16_t* samples, size_t count) { size_t free = mCircleBufferCapacity(&buffer->data) - mCircleBufferSize(&buffer->data); if (count * buffer->channels * sizeof(int16_t) > free) { + if (!free) { + return 0; + } count = free / (buffer->channels * sizeof(int16_t)); } return mCircleBufferWrite(&buffer->data, samples, count * buffer->channels * sizeof(int16_t)) / From 96702f7db19e62388a23ab64a495e49a7c3f2184 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 23 Apr 2024 22:33:57 -0700 Subject: [PATCH 177/336] Util: Use HAS_IPV6 more where appropriate --- include/mgba-util/socket.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mgba-util/socket.h b/include/mgba-util/socket.h index ff9d89626..4b109eaea 100644 --- a/include/mgba-util/socket.h +++ b/include/mgba-util/socket.h @@ -234,7 +234,7 @@ static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) #else err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); #endif -#if !defined(__3DS__) && !defined(GEKKO) +#ifdef HAS_IPV6 } else { struct sockaddr_in6 bindInfo; memset(&bindInfo, 0, sizeof(bindInfo)); @@ -333,7 +333,7 @@ static inline Socket SocketAccept(Socket socket, struct Address* address) { #else return accept(socket, (struct sockaddr*) &addrInfo, &len); #endif -#if !defined(__3DS__) && !defined(GEKKO) +#ifdef HAS_IPV6 } else { struct sockaddr_in6 addrInfo; memset(&addrInfo, 0, sizeof(addrInfo)); From 88a8f80ebdea737885ee885600d1b2288e8bde9c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 24 Apr 2024 22:54:43 -0700 Subject: [PATCH 178/336] VFS: Rename USE_VFS_* to ENABLE_VFS_* --- include/mgba-util/vfs.h | 2 +- src/platform/3ds/3ds-vfs.c | 2 +- src/platform/3ds/CMakeLists.txt | 8 ++++---- src/util/vfs.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index 0ff100143..004dbd685 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -98,7 +98,7 @@ bool VDirCreate(const char* path); struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); -#ifdef USE_VFS_FILE +#ifdef ENABLE_VFS_FILE struct VFile* VFileFOpen(const char* path, const char* mode); struct VFile* VFileFromFILE(FILE* file); #endif diff --git a/src/platform/3ds/3ds-vfs.c b/src/platform/3ds/3ds-vfs.c index f2aaeb84a..88297e9cd 100644 --- a/src/platform/3ds/3ds-vfs.c +++ b/src/platform/3ds/3ds-vfs.c @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#ifdef USE_VFS_3DS +#ifdef ENABLE_VFS_3DS #include #include diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index 7469fe6d4..2073e13fe 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -1,5 +1,5 @@ -set(USE_VFS_3DS OFF CACHE BOOL "Use 3DS-specific file support") -mark_as_advanced(USE_VFS_3DS) +set(ENABLE_VFS_3DS OFF CACHE BOOL "Use 3DS-specific file support") +mark_as_advanced(ENABLE_VFS_3DS) find_program(3DSLINK 3dslink) find_program(3DSXTOOL 3dsxtool) @@ -28,8 +28,8 @@ set(OS_SRC set(OS_LIB ${OS_LIB} PARENT_SCOPE) source_group("3DS-specific code" FILES ${OS_SRC}) -if(USE_VFS_3DS) - list(APPEND OS_DEFINES USE_VFS_3DS) +if(ENABLE_VFS_3DS) + list(APPEND OS_DEFINES ENABLE_VFS_3DS) else() list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) endif() diff --git a/src/util/vfs.c b/src/util/vfs.c index 09ae81047..74a96b369 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -20,7 +20,7 @@ #ifdef ENABLE_VFS struct VFile* VFileOpen(const char* path, int flags) { -#ifdef USE_VFS_FILE +#ifdef ENABLE_VFS_FILE const char* chflags; switch (flags & O_ACCMODE) { case O_WRONLY: @@ -68,7 +68,7 @@ struct VFile* VFileOpen(const char* path, int flags) { sceFlags |= SCE_O_CREAT; } return VFileOpenSce(path, sceFlags, 0666); -#elif defined(USE_VFS_3DS) +#elif defined(ENABLE_VFS_3DS) int ctrFlags = FS_OPEN_READ; switch (flags & O_ACCMODE) { case O_WRONLY: From 87653b7b197d0bd2a217dd6b61421d1518bc9191 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 24 Apr 2024 23:19:31 -0700 Subject: [PATCH 179/336] Qt: Fix potential crash when configuring shortcuts --- CHANGES | 1 + src/platform/qt/ShortcutModel.cpp | 48 +++++++++++++++++-------------- src/platform/qt/ShortcutModel.h | 4 +-- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index 13d7b0f4c..328de47b8 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Other fixes: - GB: Fix uninitialized save data when loading undersized temporary saves - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) + - Qt: Fix potential crash when configuring shortcuts - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/ShortcutModel.cpp b/src/platform/qt/ShortcutModel.cpp index b73982cad..f90667935 100644 --- a/src/platform/qt/ShortcutModel.cpp +++ b/src/platform/qt/ShortcutModel.cpp @@ -28,11 +28,11 @@ QVariant ShortcutModel::data(const QModelIndex& index, int role) const { if (role != Qt::DisplayRole || !index.isValid()) { return QVariant(); } - const Item* item = static_cast(index.internalPointer()); - const Shortcut* shortcut = item->shortcut; + const Item& item = m_cache[index.internalId()]; + const Shortcut* shortcut = item.shortcut; switch (index.column()) { case 0: - return m_controller->visibleName(item->name); + return m_controller->visibleName(item.name); case 1: return shortcut ? keyName(shortcut->shortcut()) : QVariant(); case 2: @@ -77,28 +77,31 @@ QVariant ShortcutModel::headerData(int section, Qt::Orientation orientation, int QModelIndex ShortcutModel::index(int row, int column, const QModelIndex& parent) const { QString pmenu; if (parent.isValid()) { - pmenu = static_cast(parent.internalPointer())->name; + const Item& item = m_cache[parent.internalId()]; + pmenu = item.name; } QString name = m_controller->name(row, pmenu); - Item* item = &m_cache[name]; - item->name = name; - item->shortcut = m_controller->shortcut(name); - return createIndex(row, column, item); + size_t hash = qHash(name); + Item& item = m_cache[hash]; + item.name = name; + item.shortcut = m_controller->shortcut(name); + return createIndex(row, column, hash); } QModelIndex ShortcutModel::parent(const QModelIndex& index) const { if (!index.isValid() || !index.internalPointer()) { return QModelIndex(); } - Item* item = static_cast(index.internalPointer()); - QString parent = m_controller->parent(item->name); + const Item& item = m_cache[index.internalId()]; + QString parent = m_controller->parent(item.name); if (parent.isNull()) { return QModelIndex(); } - Item* pitem = &m_cache[parent]; - pitem->name = parent; - pitem->shortcut = m_controller->shortcut(parent); - return createIndex(m_controller->indexIn(parent), 0, pitem); + size_t hash = qHash(parent); + Item& pitem = m_cache[hash]; + pitem.name = parent; + pitem.shortcut = m_controller->shortcut(parent); + return createIndex(m_controller->indexIn(parent), 0, hash); } int ShortcutModel::columnCount(const QModelIndex&) const { @@ -109,25 +112,26 @@ int ShortcutModel::rowCount(const QModelIndex& index) const { if (!index.isValid()) { return m_controller->count(); } - Item* item = static_cast(index.internalPointer()); - return m_controller->count(item->name); + const Item& item = m_cache[index.internalId()]; + return m_controller->count(item.name); } QString ShortcutModel::name(const QModelIndex& index) const { if (!index.isValid()) { return {}; } - Item* item = static_cast(index.internalPointer()); - return item->name; + const Item& item = m_cache[index.internalId()]; + return item.name; } void ShortcutModel::addRowNamed(const QString& name) { QString parent = m_controller->parent(name); - Item* item = &m_cache[parent]; - item->name = parent; - item->shortcut = m_controller->shortcut(parent); + size_t hash = qHash(name); + Item& item = m_cache[hash]; + item.name = parent; + item.shortcut = m_controller->shortcut(parent); int index = m_controller->indexIn(name); - beginInsertRows(createIndex(m_controller->indexIn(parent), 0, item), index, index + 1); + beginInsertRows(createIndex(m_controller->indexIn(parent), 0, hash), index, index + 1); endInsertRows(); } diff --git a/src/platform/qt/ShortcutModel.h b/src/platform/qt/ShortcutModel.h index 3eb3b1178..64a1d3301 100644 --- a/src/platform/qt/ShortcutModel.h +++ b/src/platform/qt/ShortcutModel.h @@ -44,7 +44,7 @@ private: const Shortcut* shortcut = nullptr; }; - mutable QHash m_cache; + mutable QHash m_cache; }; -} \ No newline at end of file +} From aae9c502f02e097e8154fbe23e85b0a676288652 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 25 Apr 2024 01:03:08 -0700 Subject: [PATCH 180/336] Misc: Fix a slew of less-than-important warnings --- src/core/cheats.c | 12 ++++++------ src/feature/commandline.c | 5 ++++- src/gb/audio.c | 2 +- src/gba/cart/ereader.c | 2 +- src/gba/sharkport.c | 4 ++-- src/util/image.c | 6 +++--- src/util/image/png-io.c | 7 +++++-- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/core/cheats.c b/src/core/cheats.c index 85a06b80d..53f71e907 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -282,14 +282,14 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { StringListDeinit(&directives); return false; } - while (isspace((int) cheat[i])) { + while (isspace((unsigned) cheat[i])) { ++i; } switch (cheat[i]) { case '#': do { ++i; - } while (isspace((int) cheat[i])); + } while (isspace((unsigned) cheat[i])); newSet = device->createSet(device, &cheat[i]); newSet->enabled = !nextDisabled; nextDisabled = false; @@ -305,7 +305,7 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { case '!': do { ++i; - } while (isspace((int) cheat[i])); + } while (isspace((unsigned) cheat[i])); if (strcasecmp(&cheat[i], "disabled") == 0) { nextDisabled = true; break; @@ -384,7 +384,7 @@ bool mCheatParseLibretroFile(struct mCheatDevice* device, struct VFile* vf) { return false; } ++eq; - while (isspace((int) eq[0])) { + while (isspace((unsigned) eq[0])) { if (eq[0] == '\0') { return false; } @@ -393,7 +393,7 @@ bool mCheatParseLibretroFile(struct mCheatDevice* device, struct VFile* vf) { char* end; unsigned long nCheats = strtoul(eq, &end, 10); - if (end[0] != '\0' && !isspace(end[0])) { + if (end[0] != '\0' && !isspace((unsigned) end[0])) { return false; } @@ -423,7 +423,7 @@ bool mCheatParseLibretroFile(struct mCheatDevice* device, struct VFile* vf) { return false; } ++eq; - while (isspace((int) eq[0])) { + while (isspace((unsigned) eq[0])) { if (eq[0] == '\0') { return false; } diff --git a/src/feature/commandline.c b/src/feature/commandline.c index 59735e69b..fca5c7747 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -217,9 +217,12 @@ void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparser } bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, struct mDebugger* debugger) { + UNUSED(args); + UNUSED(core); + UNUSED(debugger); bool hasDebugger = false; - #ifdef USE_EDITLINE +#ifdef USE_EDITLINE if (args->debugCli) { struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_CLI, core); if (module) { diff --git a/src/gb/audio.c b/src/gb/audio.c index b090018f6..783b1fcb9 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -602,7 +602,7 @@ void GBAudioRun(struct GBAudio* audio, int32_t timestamp, int channels) { int32_t last = 0; int samples = 0; int positiveSamples = 0; - int lsb; + int lsb = 0; int coeff; if (audio->ch4.power) { // TODO: Can this be batched too? diff --git a/src/gba/cart/ereader.c b/src/gba/cart/ereader.c index fc4d4c11d..1712f2833 100644 --- a/src/gba/cart/ereader.c +++ b/src/gba/cart/ereader.c @@ -371,7 +371,7 @@ void GBACartEReaderScan(struct GBACartEReader* ereader, const void* data, size_t memset(ereader->dots, 0, EREADER_DOTCODE_SIZE); uint8_t blockRS[44][0x10]; - uint8_t block0[0x30]; + uint8_t block0[0x30] = {0}; bool parsed = false; bool bitmap = false; bool reducedHeader = false; diff --git a/src/gba/sharkport.c b/src/gba/sharkport.c index 2f33e3d41..f6b908f3a 100644 --- a/src/gba/sharkport.c +++ b/src/gba/sharkport.c @@ -202,7 +202,7 @@ bool GBASavedataExportSharkPort(const struct GBA* gba, struct VFile* vf) { char c[0x1C]; int32_t i; } buffer; - uint32_t size = strlen(SHARKPORT_HEADER); + int32_t size = strlen(SHARKPORT_HEADER); STORE_32(size, 0, &buffer.i); if (vf->write(vf, &buffer.i, 4) < 4) { return false; @@ -271,7 +271,7 @@ bool GBASavedataExportSharkPort(const struct GBA* gba, struct VFile* vf) { } uint32_t checksum = 0; - size_t i; + ssize_t i; for (i = 0; i < 0x1C; ++i) { checksum += buffer.c[i] << (checksum % 24); } diff --git a/src/util/image.c b/src/util/image.c index 64e8aeec6..e5ee9f9e2 100644 --- a/src/util/image.c +++ b/src/util/image.c @@ -904,9 +904,9 @@ uint32_t mColorConvert(uint32_t color, enum mColorFormat from, enum mColorFormat return color; } - int r; - int g; - int b; + int r = 0; + int g = 0; + int b = 0; int a = 0xFF; switch (from) { diff --git a/src/util/image/png-io.c b/src/util/image/png-io.c index e7df1d64f..0207e03a8 100644 --- a/src/util/image/png-io.c +++ b/src/util/image/png-io.c @@ -62,7 +62,7 @@ static png_infop _pngWriteHeader(png_structp png, unsigned width, unsigned heigh } png_infop PNGWriteHeader(png_structp png, unsigned width, unsigned height, enum mColorFormat fmt) { - int type; + int type = -1; switch (fmt) { case mCOLOR_XBGR8: case mCOLOR_XRGB8: @@ -94,6 +94,9 @@ png_infop PNGWriteHeader(png_structp png, unsigned width, unsigned height, enum type = PNG_COLOR_TYPE_PALETTE; break; } + if (type < 0) { + return NULL; + } return _pngWriteHeader(png, width, height, NULL, 0, type); } @@ -373,6 +376,7 @@ bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned s } else { depth = 3; } + stride *= mColorFormatBytes(fmt); png_bytep row = malloc(sizeof(png_byte) * width * depth); if (!row) { return false; @@ -383,7 +387,6 @@ bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned s return false; } const png_byte* pixelRow = pixelData; - stride *= mColorFormatBytes(fmt); unsigned i; for (i = 0; i < height; ++i, pixelRow += stride) { switch (fmt) { From db1e02521e5835059117c35abefe971f0861e7c5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 26 Apr 2024 19:05:38 -0700 Subject: [PATCH 181/336] GBA Core: Fix audio sample rate dynamically changing (fixes #3194) --- src/gba/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 47da3a0e0..3d874dfe3 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -554,8 +554,8 @@ static void _GBACorePutPixels(struct mCore* core, const void* buffer, size_t str } static unsigned _GBACoreAudioSampleRate(const struct mCore* core) { - UNUSED(core); - return 65536; + struct GBA* gba = core->board; + return GBA_ARM7TDMI_FREQUENCY / gba->audio.sampleInterval; } static struct mAudioBuffer* _GBACoreGetAudioBuffer(struct mCore* core) { From 5a28564b125bf135b55686fe6d94a659a3d11f99 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 18:17:50 -0700 Subject: [PATCH 182/336] Switch: Fix audio resampling after GBA fix --- src/platform/switch/main.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 8307f9811..9a3441b9b 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -20,7 +20,7 @@ #include #define AUTO_INPUT 0x4E585031 -#define SAMPLES 0x200 +#define SAMPLES 0x400 #define N_BUFFERS 6 #define ANALOG_DEADZONE 0x4000 @@ -91,6 +91,7 @@ static struct mRotationSource rotation = {0}; static AudioDriver audrenDriver; static AudioDriverWaveBuf audrvBuffer[N_BUFFERS]; static struct mStereoSample* audioBuffer[N_BUFFERS]; +static double fpsRatio = 1; static bool frameLimiter = true; static unsigned framecount = 0; static unsigned framecap = 10; @@ -266,6 +267,19 @@ static void _updateRenderer(struct mGUIRunner* runner, bool gl) { } } +static void _resetSampleRate(u32 samplerate) { + if (!samplerate) { + samplerate = 32768; + } + audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / fpsRatio); + audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 0, 1); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 1, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 1, 1); + audrvUpdate(&audrenDriver); +} + static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_A, GBA_KEY_A); _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_B, GBA_KEY_B); @@ -303,14 +317,8 @@ static void _setup(struct mGUIRunner* runner) { runner->core->setAudioBufferSize(runner->core, SAMPLES); u32 samplerate = runner->core->audioSampleRate(runner->core); - double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); - audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / ratio); - audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); - audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); - audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 0, 1); - audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 1, 0); - audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 1, 1); - audrvUpdate(&audrenDriver); + fpsRatio = mCoreCalculateFramerateRatio(runner->core, 60.0); + _resetSampleRate(samplerate); } static void _gameLoaded(struct mGUIRunner* runner) { @@ -572,6 +580,11 @@ static bool _running(struct mGUIRunner* runner) { return appletMainLoop(); } +static void _audioRateChanged(struct mAVStream* stream, uint32_t samplerate) { + UNUSED(stream); + _resetSampleRate(samplerate); +} + static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); int i; @@ -891,6 +904,7 @@ int main(int argc, char* argv[]) { stream.postVideoFrame = NULL; stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; + stream.audioRateChanged = _audioRateChanged; size_t i; for (i = 0; i < N_BUFFERS; ++i) { From 5e581b0ade6b78e744dddd647fa6175f921ba65e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 18:29:29 -0700 Subject: [PATCH 183/336] 3DS: Fix audio resampling after GBA fix --- src/platform/3ds/main.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index c85103bce..de6575eff 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -90,6 +90,7 @@ static color_t* screenshotBuffer = NULL; static struct mAVStream stream; static int16_t* audioLeft = 0; static size_t audioPos = 0; +static double fpsRatio; static C3D_Tex outputTexture[2]; static int activeOutputTexture = 0; static ndspWaveBuf dspBuffer[DSP_BUFFERS]; @@ -189,8 +190,6 @@ static void _map3DSKey(struct mInputMap* map, int ctrKey, int key) { mInputBindKey(map, _3DS_INPUT, __builtin_ctz(ctrKey), key); } -static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer); - static void _drawStart(void) { if (frameStarted) { return; @@ -347,8 +346,11 @@ static void _gameLoaded(struct mGUIRunner* runner) { } if (hasSound == DSP_SUPPORTED) { unsigned sampleRate = runner->core->audioSampleRate(runner->core); - double fauxClock = mCoreCalculateFramerateRatio(runner->core, 16756991. / 280095.); - ndspChnSetRate(0, sampleRate * fauxClock); + if (!sampleRate) { + sampleRate = 32768; + } + fpsRatio = mCoreCalculateFramerateRatio(runner->core, 16756991. / 280095.); + ndspChnSetRate(0, sampleRate * fpsRatio); memset(audioLeft, 0, AUDIO_SAMPLE_BUFFER * 2 * sizeof(int16_t)); } unsigned mode; @@ -795,6 +797,14 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buff } } +static void _audioRateChanged(struct mAVStream* stream, unsigned sampleRate) { + UNUSED(stream); + if (!sampleRate) { + sampleRate = 32768; + } + ndspChnSetRate(0, sampleRate * fpsRatio); +} + static enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) { SwkbdState swkbd; swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 2, keyboard->maxLen); @@ -830,10 +840,11 @@ int main(int argc, char* argv[]) { rotation.d.readTiltY = _readTiltY; rotation.d.readGyroZ = _readGyroZ; - stream.videoDimensionsChanged = 0; - stream.postVideoFrame = 0; - stream.postAudioFrame = 0; + stream.videoDimensionsChanged = NULL; + stream.postVideoFrame = NULL; + stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; + stream.audioRateChanged = _audioRateChanged; camera.d.startRequestImage = _startRequestImage; camera.d.stopRequestImage = _stopRequestImage; From 4aba51e9553343b64b56fafee48bcd609c402f16 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 18:55:18 -0700 Subject: [PATCH 184/336] Vita: Fix audio resampling after GBA fix --- src/platform/psp2/psp2-context.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 36253aa07..0f456fa7e 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -54,6 +54,7 @@ static int currentTex; static vita2d_texture* tex[2]; static vita2d_texture* screenshot; static Thread audioThread; +static double fpsRatio = 1; static bool interframeBlending = false; static bool sgbCrop = false; static bool blurry = false; @@ -266,6 +267,20 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) MutexUnlock(&audioContext.mutex); } +static void _audioRateChanged(struct mAVStream* stream, unsigned sampleRate) { + UNUSED(stream); + if (!sampleRate) { + return; + } + if (!audioContext.resampler.source || !audioContext.resampler.destination) { + return; + } + MutexLock(&audioContext.mutex); + mAudioResamplerProcess(&audioContext.resampler); + mAudioResamplerSetSource(&audioContext.resampler, audioContext.resampler.source, sampleRate / fpsRatio, true); + MutexUnlock(&audioContext.mutex); +} + uint16_t mPSP2PollInput(struct mGUIRunner* runner) { SceCtrlData pad; sceCtrlPeekBufferPositiveExt2(0, &pad, 1); @@ -364,6 +379,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; stream.postVideoFrame = NULL; + stream.audioRateChanged = _audioRateChanged; runner->core->setAVStream(runner->core, &stream); frameLimiter = true; @@ -423,10 +439,13 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { float rate = 60.0f / 1.001f; sceDisplayGetRefreshRate(&rate); - double ratio = mCoreCalculateFramerateRatio(runner->core, rate); + fpsRatio = mCoreCalculateFramerateRatio(runner->core, rate); unsigned sampleRate = runner->core->audioSampleRate(runner->core); + if (!sampleRate) { + sampleRate = 32768; + } mAudioBufferClear(&audioContext.buffer); - mAudioResamplerSetSource(&audioContext.resampler, runner->core->getAudioBuffer(runner->core), sampleRate / ratio, true); + mAudioResamplerSetSource(&audioContext.resampler, runner->core->getAudioBuffer(runner->core), sampleRate / fpsRatio, true); ThreadCreate(&audioThread, _audioThread, &audioContext); } From df75204a0bfe0453540ad92c6d30abb9d83a5388 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 19:15:04 -0700 Subject: [PATCH 185/336] Wii: Fix audio resampling after GBA fix --- src/platform/wii/main.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index f21c7e19b..55bae9738 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -77,6 +77,7 @@ static enum VideoMode { static void _retraceCallback(u32 count); static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer*); +static void _audioRateChanged(struct mAVStream* stream, unsigned); static void _audioDMA(void); static void _setRumble(struct mRumble* rumble, int enable); static void _sampleRotation(struct mRotationSource* source); @@ -147,7 +148,8 @@ static struct AudioBuffer { static struct mAudioBuffer audioBuffer; static volatile int currentAudioBuffer = 0; static volatile int nextAudioBuffer = 0; -static double audioSampleRate = 60.0 / 1.001; +static double fps = 60.0 / 1.001; +static double fpsRatio = 1; static struct mAudioResampler resampler; static struct GUIFont* font; @@ -162,7 +164,7 @@ static void reconfigureScreen(struct mGUIRunner* runner) { wAdjust = 1.f; hAdjust = 1.f; guiScale = GUI_SCALE; - audioSampleRate = 60.0 / 1.001; + fps = 60.0 / 1.001; s32 signalMode = CONF_GetVideo(); @@ -210,7 +212,7 @@ static void reconfigureScreen(struct mGUIRunner* runner) { break; } wAdjust = 0.5f; - audioSampleRate = 90.0 / 1.50436; + fps = 90.0 / 1.50436; guiScale = GUI_SCALE_240p; break; } @@ -348,6 +350,7 @@ int main(int argc, char* argv[]) { stream.postVideoFrame = NULL; stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; + stream.audioRateChanged = _audioRateChanged; struct mGUIRunner runner = { .params = { @@ -717,6 +720,18 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) _CPU_ISR_Restore(level); } +static void _audioRateChanged(struct mAVStream* stream, unsigned sampleRate) { + UNUSED(stream); + if (!sampleRate) { + return; + } + if (!resampler.source || !resampler.destination) { + return; + } + mAudioResamplerProcess(&resampler); + mAudioResamplerSetSource(&resampler, resampler.source, sampleRate / fpsRatio, true); +} + static void _drawStart(void) { VIDEO_SetBlack(false); @@ -1419,8 +1434,12 @@ void _setup(struct mGUIRunner* runner) { memset(audioBuffers, 0, sizeof(audioBuffers)); runner->core->setAudioBufferSize(runner->core, SAMPLES); - double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); - mAudioResamplerSetSource(&resampler, runner->core->getAudioBuffer(runner->core), runner->core->audioSampleRate(runner->core) / ratio, true); + fpsRatio = mCoreCalculateFramerateRatio(runner->core, fps); + unsigned sampleRate = runner->core->audioSampleRate(runner->core); + if (!sampleRate) { + sampleRate = 32768; + } + mAudioResamplerSetSource(&resampler, runner->core->getAudioBuffer(runner->core), sampleRate / fpsRatio, true); frameLimiter = true; } From 1d2b8bf918890e4e71957a1677a7bee72c796c08 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Apr 2024 02:57:41 -0700 Subject: [PATCH 186/336] Libretro: Add Super Game Boy Color support (closes #3188) --- CHANGES | 1 + src/platform/libretro/libretro.c | 4 ++++ src/platform/libretro/libretro_core_options.h | 11 ++++++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 328de47b8..15f85e7f0 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - GBA Audio: Remove broken XQ audio pending rewrite + - Libretro: Add Super Game Boy Color support (closes mgba.io/i/3188) - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 86a692837..d2565a42b 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -268,6 +268,8 @@ static void _reloadSettings(void) { model = GB_MODEL_SGB; } else if (strcmp(var.value, "Game Boy Color") == 0) { model = GB_MODEL_CGB; + } else if (strcmp(var.value, "Super Game Boy Color") == 0) { + model = GB_MODEL_SCGB; } else if (strcmp(var.value, "Game Boy Advance") == 0) { model = GB_MODEL_AGB; } else { @@ -278,6 +280,8 @@ static void _reloadSettings(void) { mCoreConfigSetDefaultValue(&core->config, "gb.model", modelName); mCoreConfigSetDefaultValue(&core->config, "sgb.model", modelName); mCoreConfigSetDefaultValue(&core->config, "cgb.model", modelName); + mCoreConfigSetDefaultValue(&core->config, "cgb.hybridModel", modelName); + mCoreConfigSetDefaultValue(&core->config, "cgb.sgbModel", modelName); } var.key = "mgba_sgb_borders"; diff --git a/src/platform/libretro/libretro_core_options.h b/src/platform/libretro/libretro_core_options.h index 76ca634f9..f0a4b3f04 100644 --- a/src/platform/libretro/libretro_core_options.h +++ b/src/platform/libretro/libretro_core_options.h @@ -87,11 +87,12 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "system", { - { "Autodetect", NULL }, - { "Game Boy", NULL }, - { "Super Game Boy", NULL }, - { "Game Boy Color", NULL }, - { "Game Boy Advance", NULL }, + { "Autodetect", NULL }, + { "Game Boy", NULL }, + { "Super Game Boy", NULL }, + { "Game Boy Color", NULL }, + { "Super Game Boy Color", NULL }, + { "Game Boy Advance", NULL }, { NULL, NULL }, }, "Autodetect" From d9e080b9a9f2b9fec8631988474bcf18b52d249a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 6 May 2024 15:35:23 -0700 Subject: [PATCH 187/336] GBA: Prefix SIO constants with GBA_ --- include/mgba/gba/interface.h | 12 +++---- src/gba/cart/gpio.c | 2 +- src/gba/core.c | 4 +-- src/gba/extra/battlechip.c | 4 +-- src/gba/gba.c | 2 +- src/gba/sio.c | 40 ++++++++++----------- src/gba/sio/gbp.c | 4 +-- src/gba/sio/lockstep.c | 42 +++++++++++------------ src/platform/python/mgba/gba.py | 14 ++++---- src/platform/qt/CoreController.cpp | 4 +-- src/platform/qt/MultiplayerController.cpp | 10 +++--- 11 files changed, 69 insertions(+), 69 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index a04685e49..97e0a5b9c 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -21,12 +21,12 @@ enum { }; enum GBASIOMode { - SIO_NORMAL_8 = 0, - SIO_NORMAL_32 = 1, - SIO_MULTI = 2, - SIO_UART = 3, - SIO_GPIO = 8, - SIO_JOYBUS = 12 + GBA_SIO_NORMAL_8 = 0, + GBA_SIO_NORMAL_32 = 1, + GBA_SIO_MULTI = 2, + GBA_SIO_UART = 3, + GBA_SIO_GPIO = 8, + GBA_SIO_JOYBUS = 12 }; enum GBASIOJOYCommand { diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index 811dc1e8a..0a396f746 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -525,7 +525,7 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer uint32_t when; LOAD_32(when, 0, &state->hw.gbpNextEvent); if (hw->devices & HW_GB_PLAYER) { - GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, SIO_NORMAL_32); + GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, GBA_SIO_NORMAL_32); if (hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) { mTimingSchedule(&hw->p->timing, &hw->p->sio.gbp.event, when); } diff --git a/src/gba/core.c b/src/gba/core.c index 3d874dfe3..256aebdab 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -891,8 +891,8 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { gba->luminanceSource = periph; break; case mPERIPH_GBA_BATTLECHIP_GATE: - GBASIOSetDriver(&gba->sio, periph, SIO_MULTI); - GBASIOSetDriver(&gba->sio, periph, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, periph, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, periph, GBA_SIO_NORMAL_32); break; default: return; diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index fa6be9796..3ab9f1403 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -84,7 +84,7 @@ uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { int32_t cycles; - if (gate->d.p->mode == SIO_NORMAL_32) { + if (gate->d.p->mode == GBA_SIO_NORMAL_32) { cycles = GBA_ARM7TDMI_FREQUENCY / 0x40000; } else { cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(gate->d.p->siocnt)][1]; @@ -97,7 +97,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle UNUSED(timing); struct GBASIOBattlechipGate* gate = user; - if (gate->d.p->mode == SIO_NORMAL_32) { + if (gate->d.p->mode == GBA_SIO_NORMAL_32) { gate->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0; gate->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0; gate->d.p->siocnt = GBASIONormalClearStart(gate->d.p->siocnt); diff --git a/src/gba/gba.c b/src/gba/gba.c index fb0a84ae7..94ed7562a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -232,7 +232,7 @@ void GBAReset(struct ARMCore* cpu) { // GB Player SIO control should not be engaged before detection, even if we already know it's GBP gba->memory.hw.devices &= ~HW_GB_PLAYER; if (gba->sio.drivers.normal == &gba->sio.gbp.d) { - GBASIOSetDriver(&gba->sio, NULL, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, NULL, GBA_SIO_NORMAL_32); } bool isELF = false; diff --git a/src/gba/sio.c b/src/gba/sio.c index 1082d0062..beb8efdfe 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -20,12 +20,12 @@ const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) { switch (mode) { - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: return sio->drivers.normal; - case SIO_MULTI: + case GBA_SIO_MULTI: return sio->drivers.multiplayer; - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: return sio->drivers.joybus; default: return 0; @@ -34,15 +34,15 @@ static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mo static const char* _modeName(enum GBASIOMode mode) { switch (mode) { - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: return "NORMAL8"; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: return "NORMAL32"; - case SIO_MULTI: + case GBA_SIO_MULTI: return "MULTI"; - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: return "JOYBUS"; - case SIO_GPIO: + case GBA_SIO_GPIO: return "GPIO"; default: return "(unknown)"; @@ -113,22 +113,22 @@ void GBASIOReset(struct GBASIO* sio) { } void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers) { - GBASIOSetDriver(sio, drivers->normal, SIO_NORMAL_8); - GBASIOSetDriver(sio, drivers->multiplayer, SIO_MULTI); - GBASIOSetDriver(sio, drivers->joybus, SIO_JOYBUS); + GBASIOSetDriver(sio, drivers->normal, GBA_SIO_NORMAL_8); + GBASIOSetDriver(sio, drivers->multiplayer, GBA_SIO_MULTI); + GBASIOSetDriver(sio, drivers->joybus, GBA_SIO_JOYBUS); } void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode) { struct GBASIODriver** driverLoc; switch (mode) { - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: driverLoc = &sio->drivers.normal; break; - case SIO_MULTI: + case GBA_SIO_MULTI: driverLoc = &sio->drivers.multiplayer; break; - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: driverLoc = &sio->drivers.joybus; break; default: @@ -182,8 +182,8 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { } else { // Dummy drivers switch (sio->mode) { - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: value = GBASIONormalFillSi(value); if ((value & 0x0081) == 0x0081) { if (GBASIONormalIsIrq(value)) { @@ -193,7 +193,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { value = GBASIONormalClearStart(value); } break; - case SIO_MULTI: + case GBA_SIO_MULTI: value &= 0xFF83; value |= 0xC; break; @@ -211,7 +211,7 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu } // Dummy drivers switch (sio->mode) { - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: switch (address) { case GBA_REG_JOYCNT: return (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index 8400cc8b1..b5f987352 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -56,7 +56,7 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { void GBASIOPlayerReset(struct GBASIOPlayer* gbp) { if (gbp->p->sio.drivers.normal == &gbp->d) { - GBASIOSetDriver(&gbp->p->sio, NULL, SIO_NORMAL_32); + GBASIOSetDriver(&gbp->p->sio, NULL, GBA_SIO_NORMAL_32); } } @@ -88,7 +88,7 @@ void GBASIOPlayerUpdate(struct GBA* gba) { gba->sio.gbp.oldCallback = gba->keyCallback; gba->keyCallback = &gba->sio.gbp.callback.d; // TODO: Check if the SIO driver is actually used first - GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, GBA_SIO_NORMAL_32); } } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 71373a237..4f12610f1 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -103,7 +103,7 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->mode = driver->p->mode; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; node->d.p->rcnt |= 3; ATOMIC_ADD(node->p->attachedMulti, 1); @@ -125,8 +125,8 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->d.p->siocnt = GBASIOMultiplayerClearSlave(node->d.p->siocnt); } break; - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: if (ATOMIC_ADD(node->p->attachedNormal, 1) > node->id + 1 && node->id > 0) { node->d.p->siocnt = GBASIONormalSetSi(node->d.p->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); } else { @@ -154,11 +154,11 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { node->mode = driver->p->mode; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: ATOMIC_SUB(node->p->attachedMulti, 1); break; - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: ATOMIC_SUB(node->p->attachedNormal, 1); break; default: @@ -180,7 +180,7 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { } // Invalidate SIO mode - node->mode = SIO_GPIO; + node->mode = GBA_SIO_GPIO; mLockstepUnlock(&node->p->d); @@ -235,7 +235,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { struct GBASIO* sio = node->d.p; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: sio->p->memory.io[GBA_REG(SIOMULTI0)] = node->p->multiRecv[0]; sio->p->memory.io[GBA_REG(SIOMULTI1)] = node->p->multiRecv[1]; sio->p->memory.io[GBA_REG(SIOMULTI2)] = node->p->multiRecv[2]; @@ -247,7 +247,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); } break; - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: // TODO sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { @@ -260,7 +260,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); } break; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: // TODO sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { @@ -299,7 +299,7 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { case TRANSFER_IDLE: // If the master hasn't initiated a transfer, it can keep going. node->nextEvent += LOCKSTEP_INCREMENT; - if (node->mode == SIO_MULTI) { + if (node->mode == GBA_SIO_MULTI) { node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached); } break; @@ -307,7 +307,7 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { // Start the transfer, but wait for the other GBAs to catch up node->transferFinished = false; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: node->p->multiRecv[0] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF; node->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF; @@ -317,11 +317,11 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { node->p->multiRecv[2] = 0xFFFF; node->p->multiRecv[3] = 0xFFFF; break; - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: node->p->multiRecv[0] = 0xFFFF; node->p->normalRecv[0] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF; break; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: node->p->multiRecv[0] = 0xFFFF; mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]); mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)]); @@ -393,7 +393,7 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { ATOMIC_LOAD(transferActive, node->p->d.transferActive); ATOMIC_LOAD(attached, node->p->d.attached); - if (node->mode == SIO_MULTI) { + if (node->mode == GBA_SIO_MULTI) { ATOMIC_LOAD(attachedMode, node->p->attachedMulti); node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMode == attached); } else { @@ -415,7 +415,7 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { } node->transferFinished = false; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: node->d.p->rcnt &= ~1; node->p->multiRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF; @@ -424,11 +424,11 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { node->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF; node->d.p->siocnt = GBASIOMultiplayerFillBusy(node->d.p->siocnt); break; - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: node->p->multiRecv[node->id] = 0xFFFF; node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF; break; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: node->p->multiRecv[node->id] = 0xFFFF; node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]; node->p->normalRecv[node->id] |= node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] << 16; @@ -466,11 +466,11 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, node->eventDiff += cyclesLate; if (node->p->d.attached < 2) { switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][0]; break; - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: if (node->nextEvent <= 0) { cycles = _masterUpdate(node); node->eventDiff = 0; diff --git a/src/platform/python/mgba/gba.py b/src/platform/python/mgba/gba.py index a0c86ac84..109de4d50 100644 --- a/src/platform/python/mgba/gba.py +++ b/src/platform/python/mgba/gba.py @@ -23,12 +23,12 @@ class GBA(Core): KEY_L = lib.GBA_KEY_L KEY_R = lib.GBA_KEY_R - SIO_NORMAL_8 = lib.SIO_NORMAL_8 - SIO_NORMAL_32 = lib.SIO_NORMAL_32 - SIO_MULTI = lib.SIO_MULTI - SIO_UART = lib.SIO_UART - SIO_JOYBUS = lib.SIO_JOYBUS - SIO_GPIO = lib.SIO_GPIO + SIO_NORMAL_8 = lib.GBA_SIO_NORMAL_8 + SIO_NORMAL_32 = lib.GBA_SIO_NORMAL_32 + SIO_MULTI = lib.GBA_SIO_MULTI + SIO_UART = lib.GBA_SIO_UART + SIO_JOYBUS = lib.GBA_SIO_JOYBUS + SIO_GPIO = lib.GBA_SIO_GPIO def __init__(self, native): super(GBA, self).__init__(native) @@ -52,7 +52,7 @@ class GBA(Core): super(GBA, self)._load() self.memory = GBAMemory(self._core, self._native.memory.romSize) - def attach_sio(self, link, mode=lib.SIO_MULTI): + def attach_sio(self, link, mode=lib.GBA_SIO_MULTI): self._sio.add(mode) lib.GBASIOSetDriver(ffi.addressof(self._native.sio), link._native, mode) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 660de1f57..02cd4db4c 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -424,7 +424,7 @@ bool CoreController::attachDolphin(const Address& address) { } if (GBASIODolphinConnect(&m_dolphin, &address, 0, 0)) { GBA* gba = static_cast(m_threadContext.core->board); - GBASIOSetDriver(&gba->sio, &m_dolphin.d, SIO_JOYBUS); + GBASIOSetDriver(&gba->sio, &m_dolphin.d, GBA_SIO_JOYBUS); return true; } return false; @@ -433,7 +433,7 @@ bool CoreController::attachDolphin(const Address& address) { void CoreController::detachDolphin() { if (platform() == mPLATFORM_GBA) { GBA* gba = static_cast(m_threadContext.core->board); - GBASIOSetDriver(&gba->sio, nullptr, SIO_JOYBUS); + GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_JOYBUS); } GBASIODolphinDestroy(&m_dolphin); } diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index 7ded956a4..149df2386 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -92,7 +92,7 @@ MultiplayerController::MultiplayerController() { if (!id) { for (int i = 1; i < controller->m_players.count(); ++i) { player = controller->player(i); - if (player->node.gba->d.p->mode > SIO_MULTI) { + if (player->node.gba->d.p->mode > GBA_SIO_MULTI) { player->controller->setSync(true); continue; } @@ -254,8 +254,8 @@ bool MultiplayerController::attachGame(CoreController* controller) { GBASIOLockstepAttachNode(&m_gbaLockstep, node); player.node.gba = node; - GBASIOSetDriver(&gba->sio, &node->d, SIO_MULTI); - GBASIOSetDriver(&gba->sio, &node->d, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_32); break; } #endif @@ -342,8 +342,8 @@ void MultiplayerController::detachGame(CoreController* controller) { case mPLATFORM_GBA: { GBA* gba = static_cast(thread->core->board); GBASIOLockstepNode* node = reinterpret_cast(gba->sio.drivers.multiplayer); - GBASIOSetDriver(&gba->sio, nullptr, SIO_MULTI); - GBASIOSetDriver(&gba->sio, nullptr, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_32); if (node) { GBASIOLockstepDetachNode(&m_gbaLockstep, node); delete node; From ff2dfeb5164a3bd93a6fd517e00ad0d35dcfa32a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:02:49 -0700 Subject: [PATCH 188/336] Util: Clean up VFileOpen backing a bit more --- CMakeLists.txt | 4 +++- include/mgba-util/vfs.h | 12 +++++++----- src/core/flags.h.in | 8 ++++++++ src/platform/3ds/CMakeLists.txt | 1 + src/platform/switch/CMakeLists.txt | 2 +- src/platform/wii/CMakeLists.txt | 2 +- src/util/vfs.c | 4 +++- 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3767bae8b..8b8262b8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,6 +207,7 @@ elseif(BUILD_PGO AND PGO_STAGE_2) endif() # Platform support +set(OS_DEFINES) if(WIN32) set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}") set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) @@ -220,6 +221,7 @@ if(WIN32) endif() endif() list(APPEND OS_LIB ws2_32 shlwapi) + list(APPEND OS_DEFINES ENABLE_VFS_FD) list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/vfs-w32.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/*.c) source_group("Windows-specific code" FILES ${OS_SRC}) @@ -230,6 +232,7 @@ elseif(UNIX) add_definitions(-D_GNU_SOURCE) endif() + list(APPEND OS_DEFINES ENABLE_VFS_FD) list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/posix/*.c) source_group("POSIX-specific code" FILES ${OS_SRC}) @@ -858,7 +861,6 @@ source_group("Extra features" FILES ${FEATURE_SRC}) source_group("Third-party code" FILES ${THIRD_PARTY_SRC}) # Platform binaries -set(OS_DEFINES) if(DEFINED 3DS) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/3ds ${CMAKE_CURRENT_BINARY_DIR}/3ds) endif() diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index 004dbd685..0279fb755 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -66,11 +66,18 @@ struct VDir { }; struct VFile* VFileOpen(const char* path, int flags); +#endif +#ifdef ENABLE_VFS_FD struct VFile* VFileOpenFD(const char* path, int flags); struct VFile* VFileFromFD(int fd); #endif +#ifdef ENABLE_VFS_FILE +struct VFile* VFileFOpen(const char* path, const char* mode); +struct VFile* VFileFromFILE(FILE* file); +#endif + struct VFile* VFileFromMemory(void* mem, size_t size); struct VFile* VFileFromConstMemory(const void* mem, size_t size); struct VFile* VFileMemChunk(const void* mem, size_t size); @@ -97,11 +104,6 @@ struct VDir* VDeviceList(void); bool VDirCreate(const char* path); struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); - -#ifdef ENABLE_VFS_FILE -struct VFile* VFileFOpen(const char* path, const char* mode); -struct VFile* VFileFromFILE(FILE* file); -#endif #endif void separatePath(const char* path, char* dirname, char* basename, char* extension); diff --git a/src/core/flags.h.in b/src/core/flags.h.in index b91e1907a..3507df032 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -65,6 +65,14 @@ #cmakedefine ENABLE_VFS #endif +#ifndef ENABLE_VFS_FD +#cmakedefine ENABLE_VFS_FD +#endif + +#ifndef ENABLE_VFS_FILE +#cmakedefine ENABLE_VFS_FILE +#endif + // USE flags #ifndef USE_DISCORD_RPC diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index 2073e13fe..a52c5e81e 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -31,6 +31,7 @@ source_group("3DS-specific code" FILES ${OS_SRC}) if(ENABLE_VFS_3DS) list(APPEND OS_DEFINES ENABLE_VFS_3DS) else() + list(APPEND OS_DEFINES ENABLE_VFS_FD) list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) endif() set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 55db05d12..66e5b6f4a 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -4,7 +4,7 @@ find_program(BUILD_ROMFS build_romfs) find_library(GLAPI_LIBRARY glapi REQUIRED) find_library(EGL_LIBRARY EGL REQUIRED) -set(OS_DEFINES _GNU_SOURCE IOAPI_NO_64) +set(OS_DEFINES _GNU_SOURCE IOAPI_NO_64 ENABLE_VFS_FD) list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index f8e6984f4..a5f77e84d 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -8,7 +8,7 @@ if(WIIDRC_LIBRARY) add_definitions(-DWIIDRC) endif() -set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64 FIXED_ROM_BUFFER) +set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64 FIXED_ROM_BUFFER ENABLE_VFS_FD) list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/util/vfs.c b/src/util/vfs.c index 74a96b369..a14100bbf 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -96,8 +96,10 @@ struct VFile* VFileOpen(const char* path, int flags) { vf->seek(vf, vf->size(vf), SEEK_SET); } return vf; -#else +#elif defined(ENABLE_VFS_FD) return VFileOpenFD(path, flags); +#else +#error "Can't build VFS subsystem without a VFile backend" #endif } From 8106fbf51c05878050747842722b6f544edb45d6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:05:27 -0700 Subject: [PATCH 189/336] Libretro: Fix build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b8262b8b..1742cb805 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -981,7 +981,7 @@ endif() if(BUILD_LIBRETRO) file(GLOB RETRO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/libretro/*.c) - add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC}) + add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC} ${VFS_SRC}) add_dependencies(${BINARY_NAME}_libretro ${BINARY_NAME}-version-info) set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "__LIBRETRO__;COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;MGBA_STANDALONE;${OS_DEFINES};${FUNCTION_DEFINES};ENABLE_VFS;MINIMAL_CORE=2") target_link_libraries(${BINARY_NAME}_libretro ${OS_LIB}) From e5333f4e7c92d9a12c853cbcbedaa3f190342579 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:32:33 -0700 Subject: [PATCH 190/336] GBA Audio: Call audioRateChanged on reset if applicable --- src/gba/audio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gba/audio.c b/src/gba/audio.c index c84d6ce27..e6b495382 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -43,6 +43,7 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { audio->forceDisableChA = false; audio->forceDisableChB = false; audio->masterVolume = GBA_AUDIO_VOLUME_MAX; + audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; } void GBAAudioReset(struct GBAAudio* audio) { @@ -81,7 +82,12 @@ void GBAAudioReset(struct GBAAudio* audio) { audio->chBLeft = false; audio->chBTimer = false; audio->enable = false; - audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; + if (audio->sampleInterval != GBA_ARM7TDMI_FREQUENCY / 0x8000) { + audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; + if (audio->p->stream && audio->p->stream->audioRateChanged) { + audio->p->stream->audioRateChanged(audio->p->stream, GBA_ARM7TDMI_FREQUENCY / audio->sampleInterval); + } + } audio->psg.sampleInterval = audio->sampleInterval; } From 1ca75446c6f4f3c26c4593c03ff4a8f26330fa42 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:32:58 -0700 Subject: [PATCH 191/336] Libretro: Fix audio resampling after GBA fix --- src/platform/libretro/libretro.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index d2565a42b..8191d4868 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -53,6 +53,7 @@ static retro_set_sensor_state_t sensorStateCallback; static void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args); static void _postAudioBuffer(struct mAVStream*, struct mAudioBuffer*); +static void _audioRateChanged(struct mAVStream*, unsigned rate); static void _setRumble(struct mRumble* rumble, int enable); static uint8_t _readLux(struct GBALuminanceSource* lux); static void _updateLux(struct GBALuminanceSource* lux); @@ -498,10 +499,11 @@ void retro_init(void) { logger.log = GBARetroLog; mLogSetDefaultLogger(&logger); - stream.videoDimensionsChanged = 0; - stream.postAudioFrame = 0; - stream.postAudioBuffer = _postAudioBuffer; - stream.postVideoFrame = 0; + stream.videoDimensionsChanged = NULL; + stream.postAudioFrame = NULL; + stream.postAudioBuffer = NULL; + stream.postVideoFrame = NULL; + stream.audioRateChanged = _audioRateChanged; imageSource.startRequestImage = _startImage; imageSource.stopRequestImage = _stopImage; @@ -913,13 +915,14 @@ bool retro_load_game(const struct retro_game_info* game) { * using the regular stream-set _postAudioBuffer() * callback with a fixed buffer size, which seems * (historically) to produce adequate results */ - core->setAVStream(core, &stream); + stream.postAudioBuffer = _postAudioBuffer; audioSampleBufferSize = GB_SAMPLES * 2; audioSampleBuffer = malloc(audioSampleBufferSize * sizeof(int16_t)); audioSamplesPerFrameAvg = GB_SAMPLES; core->setAudioBufferSize(core, GB_SAMPLES); } + core->setAVStream(core, &stream); core->setPeripheral(core, mPERIPH_RUMBLE, &rumble); core->setPeripheral(core, mPERIPH_ROTATION, &rotation); @@ -1250,6 +1253,13 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buff } } +static void _audioRateChanged(struct mAVStream* stream, unsigned rate) { + UNUSED(stream); + struct retro_system_av_info info; + retro_get_system_av_info(&info); + environCallback(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info); +} + static void _setRumble(struct mRumble* rumble, int enable) { UNUSED(rumble); if (!rumbleInitDone) { From e73f302aee38323ee77a5242c84ae2f87298daf0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2024 17:06:53 -0700 Subject: [PATCH 192/336] Libretro: Attempt to fix #3202 --- src/platform/libretro/libretro.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 8191d4868..38fbcdbb9 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -744,7 +744,7 @@ static void _setupMaps(struct mCore* core) { #ifdef M_CORE_GB if (core->platform(core) == mPLATFORM_GB) { struct GB* gb = core->board; - struct retro_memory_descriptor descs[11]; + struct retro_memory_descriptor descs[12]; struct retro_memory_map mmaps; memset(descs, 0, sizeof(descs)); @@ -814,8 +814,16 @@ static void _setupMaps(struct mCore* core) { if (savedataSize) { descs[i].ptr = savedata; descs[i].start = GB_BASE_EXTERNAL_RAM; - descs[i].len = savedataSize; + descs[i].len = savedataSize < GB_SIZE_EXTERNAL_RAM ? savedataSize : GB_SIZE_EXTERNAL_RAM; i++; + + if ((savedataSize & ~0xFF) > GB_SIZE_EXTERNAL_RAM) { + descs[i].ptr = savedata; + descs[i].offset = GB_SIZE_EXTERNAL_RAM; + descs[i].start = GB_BASE_EXTERNAL_RAM; + descs[i].len = savedataSize - GB_SIZE_EXTERNAL_RAM; + i++; + } } if (gb->model >= GB_MODEL_CGB) { @@ -825,7 +833,6 @@ static void _setupMaps(struct mCore* core) { descs[i].ptr = gb->memory.wram + 0x2000; descs[i].start = 0x10000; descs[i].len = GB_SIZE_WORKING_RAM - 0x2000; - descs[i].select = 0xFFFFA000; i++; } From f6851eba95a94d7018f4744ae11ce63011a27e2b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2024 17:26:54 -0700 Subject: [PATCH 193/336] Libretro: Fix mapped high SRAM start address --- src/platform/libretro/libretro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 38fbcdbb9..b7d7d8243 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -820,7 +820,7 @@ static void _setupMaps(struct mCore* core) { if ((savedataSize & ~0xFF) > GB_SIZE_EXTERNAL_RAM) { descs[i].ptr = savedata; descs[i].offset = GB_SIZE_EXTERNAL_RAM; - descs[i].start = GB_BASE_EXTERNAL_RAM; + descs[i].start = 0x16000; descs[i].len = savedataSize - GB_SIZE_EXTERNAL_RAM; i++; } From 92b67f960c447296f8693e7e0485156e91a48b77 Mon Sep 17 00:00:00 2001 From: Evrins Hu Date: Sat, 11 May 2024 10:46:28 +0800 Subject: [PATCH 194/336] doc: update readme in zh_cn --- README_ZH_CN.md | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/README_ZH_CN.md b/README_ZH_CN.md index ab725694c..1991e2d1d 100644 --- a/README_ZH_CN.md +++ b/README_ZH_CN.md @@ -5,7 +5,9 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 å¯åœ¨ä»¥ä¸‹ç½‘å€æ‰¾åˆ°æœ€æ–°æ–°é—»å’Œä¸‹è½½ï¼š[mgba.io](https://mgba.io/)。 -[![Build status](https://travis-ci.org/mgba-emu/mgba.svg?branch=master)](https://travis-ci.org/mgba-emu/mgba) +[![Build status](https://buildbot.mgba.io/badges/build-win32.svg)](https://buildbot.mgba.io) +[![Translation status](https://hosted.weblate.org/widgets/mgba/-/svg-badge.svg)](https://hosted.weblate.org/engage/mgba) + 功能 -------- @@ -13,7 +15,7 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 - 支æŒé«˜ç²¾ç¡®çš„ Game Boy Advance 硬件[[1]](#missing)。 - æ”¯æŒ Game Boy/Game Boy Color 硬件。 - 快速模拟:已知å³ä½¿åœ¨ä½Žç«¯ç¡¬ä»¶ï¼ˆä¾‹å¦‚上网本)上也能够全速è¿è¡Œã€‚ -- 用于é‡åž‹å’Œè½»åž‹å‰ç«¯çš„ Qt å’Œ SDL 端å£ã€‚ +- å¯ç”¨äºŽé‡åž‹å’Œè½»åž‹å‰ç«¯çš„ Qt å’Œ SDL 移æ¤ã€‚ - 支æŒæœ¬åœ°ï¼ˆåŒä¸€å°è®¡ç®—机)链接电缆。 - 存档类型检测,å³ä½¿æ˜¯é—ªå­˜å¤§å°ä¹Ÿå¯æ£€æµ‹[[2]](#flashdetect)。 - 支æŒé™„带有è¿åŠ¨ä¼ æ„Ÿå™¨å’ŒæŒ¯åŠ¨æœºåˆ¶çš„å¡å¸¦ï¼ˆä»…适用于游æˆæŽ§åˆ¶å™¨ï¼‰ã€‚ @@ -21,6 +23,7 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 - 支æŒã€Šæˆ‘们的太阳》系列游æˆçš„太阳能传感器。 - æ”¯æŒ Game Boy 相机和 Game Boy 打å°æœºã€‚ - 内置 BIOS 执行,并具有加载外部 BIOS 文件的功能。 +- 支æŒä½¿ç”¨ Lua 编写脚本 - æ”¯æŒ Turbo/å¿«è¿›åŠŸèƒ½ï¼ˆæŒ‰ä½ Tab 键)。 - 支æŒå€’带(按ä½å引å·é”®ï¼‰ã€‚ - 支æŒè·³å¸§ï¼Œæœ€å¤šå¯é…ç½® 10 级。 @@ -32,10 +35,11 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 - å¯é‡æ–°æ˜ å°„键盘和游æˆæ‰‹æŸ„的控制键。 - 支æŒä»Ž ZIP å’Œ 7z 文件中加载。 - æ”¯æŒ IPSã€UPS å’Œ BPS è¡¥ä¸ã€‚ -- 支æŒé€šè¿‡å‘½ä»¤è¡Œç•Œé¢å’Œ GDB 远程支æŒè¿›è¡Œæ¸¸æˆè°ƒè¯•ï¼Œå…¼å®¹ IDA Pro。 +- 支æŒé€šè¿‡å‘½ä»¤è¡Œç•Œé¢å’Œ GDB 远程支æŒè¿›è¡Œæ¸¸æˆè°ƒè¯•ï¼Œå…¼å®¹ Ghidra å’Œ IDA Pro。 - 支æŒå¯é…置的模拟倒带。 - 支æŒè½½å…¥å’Œå¯¼å‡º GameShark å’Œ Action Replay 快照。 - 适用于 RetroArch/Libretro å’Œ OpenEmu 的内核。 +- 社区支æŒçš„多ç§è¯­è¨€ç¿»è¯‘ [Weblate](https://hosted.weblate.org/engage/mgba). - 许许多多的å°çŽ©æ„。 #### Game Boy 映射器(mapper) @@ -51,9 +55,10 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 - MBC5+振动 - MBC7 - Wisdom Tree(未授æƒï¼‰ +- NT "old type" 1 and 2 (未授æƒå¤šåˆä¸€å¡å¸¦) +- NT "new type" (æœªæŽˆæƒ MBC5-like) - Pokémon Jade/Diamond(未授æƒï¼‰ -- BBD(未授æƒã€ç±» MBC5) -- Hitek(未授æƒã€ç±» MBC5) +- Sachen MMC1 (未授æƒ) 部分支æŒä»¥ä¸‹ mapper: @@ -63,6 +68,11 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 - TAMA5(缺少 RTC 支æŒï¼‰ - HuC-1(缺少 IR 支æŒï¼‰ - HuC-3(缺少 IR å’Œ RTC 支æŒï¼‰ +- Sachen MMC2 (缺少备用接线支æŒ) +- BBD (缺少图标切æ¢) +- Hitek (缺少图标切æ¢) +- GGB-81 (缺少图标切æ¢) +- Li Cheng (缺少图标切æ¢) ### 计划加入的功能 @@ -70,7 +80,6 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 - æ”¯æŒ Dolphin/JOY 总线链接电缆。 - MP2k 音频混åˆï¼ŒèŽ·å¾—比硬件更高质é‡çš„声音。 - 支æŒé’ˆå¯¹å·¥å…·è¾…助竞速(Tool-Assisted Speedrun)的é‡å½•åŠŸèƒ½ã€‚ -- æ”¯æŒ Lua 脚本。 - 全方ä½çš„调试套件。 - 支æŒæ— çº¿é€‚é…器。 @@ -112,17 +121,19 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 编译 --------- -编译需è¦ä½¿ç”¨ CMake 3.1 或更新版本。已知 GCC å’Œ Clang 都å¯ä»¥ç¼–译 mGBA,而 Visual Studio 2013 和更旧的版本则无法编译。我们å³å°†å®žçŽ°å¯¹ Visual Studio 2015 或更新版本的支æŒã€‚ +编译需è¦ä½¿ç”¨ CMake 3.1 或更新版本。已知 GCC , Clang å’Œ Visual Studio 2013 都å¯ä»¥ç¼–译 mGBA。 #### Docker 构建 对于大多数平å°æ¥è¯´ï¼Œå»ºè®®ä½¿ç”¨ Docker 进行构建。我们æ供了多个 Docker 映åƒï¼Œå…¶ä¸­åŒ…å«åœ¨å¤šä¸ªå¹³å°ä¸Šæž„建 mGBA 所需的工具链和ä¾èµ–项。 +注æ„: 如果你是用的是 Widnows 10 之å‰çš„旧版本 Windows 系统, ä½ å¯èƒ½éœ€è¦é…置你的 Docker 使用 VirtualBox å…±äº«æ–‡ä»¶å¤¹ä»¥æ­£ç¡®æ˜ å°„ä½ å½“å‰ mGBA 检出目录到 Docker é•œåƒä¸­çš„工作目录. 详细细节å‚è§ issue [#1985](https://mgba.io/i/1985) + è¦ä½¿ç”¨ Docker 映åƒæž„建 mGBA,åªéœ€åœ¨ mGBA 的签出(checkout)根目录中è¿è¡Œä»¥ä¸‹å‘½ä»¤ï¼š docker run --rm -t -v $PWD:/home/mgba/src mgba/windows:w32 -æ­¤å‘½ä»¤å°†ç”Ÿæˆ `build-win32` 目录。将 `mgba/windows:w32` 替æ¢ä¸ºå…¶ä»–å¹³å°ä¸Šçš„ Docker 映åƒï¼Œä¼šç”Ÿæˆç›¸åº”的其他目录。Docker Hub 上æ供了以下 Docker 映åƒï¼š +å¯åŠ¨ Docker 容器之åŽ, æ­¤å‘½ä»¤å°†ç”Ÿæˆ `build-win32` 目录, 此目录中包å«ç¼–译产物。将 `mgba/windows:w32` 替æ¢ä¸ºå…¶ä»–å¹³å°ä¸Šçš„ Docker 映åƒï¼Œä¼šç”Ÿæˆç›¸åº”的其他目录。Docker Hub 上æ供了以下 Docker 映åƒï¼š - mgba/3ds - mgba/switch @@ -135,6 +146,8 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 - mgba/windows:w32 - mgba/windows:w64 +如果你希望加速编译过程, å¯ä»¥è€ƒè™‘添加编译选项 `-e MAKEFLAGS=-jN`, 使用 `N` 个 CPU 核心æ¥å¹¶è¡Œæž„建 mGBA + #### *nix 构建 è¦åœ¨åŸºäºŽ Unix 的系统上使用 CMake 进行构建,推è执行以下命令: @@ -147,7 +160,7 @@ mGBA 是一个è¿è¡Œ Game Boy Advance 游æˆçš„模拟器。mGBA 的目标是比 这些命令将构建 mGBA 并将其安装到 `/usr/bin` å’Œ `/usr/lib` 中。系统会自动检测已安装的ä¾èµ–项,如果未找到ä¾èµ–项,则会在æ示找ä¸åˆ°ä¾èµ–项的情况下è¿è¡Œ `cmake` 命令,并显示已被ç¦ç”¨çš„功能。 -如果您使用的是 MacOS,则步骤略有ä¸åŒã€‚å‡è®¾æ‚¨ä½¿ç”¨çš„是自制软件包管ç†å™¨ï¼Œå»ºè®®ä½¿ç”¨ä»¥ä¸‹å‘½ä»¤æ¥èŽ·å–ä¾èµ–项并进行构建: +如果您使用的是 MacOS,则步骤略有ä¸åŒã€‚å‡è®¾æ‚¨ä½¿ç”¨çš„ homebrew 软件包管ç†å™¨ï¼Œå»ºè®®ä½¿ç”¨ä»¥ä¸‹å‘½ä»¤æ¥èŽ·å–ä¾èµ–项并进行构建: brew install cmake ffmpeg libzip qt5 sdl2 libedit pkg-config mkdir build @@ -220,10 +233,12 @@ mGBA 没有硬性的ä¾èµ–项,但是特定功能需è¦ä»¥ä¸‹å¯é€‰çš„ä¾èµ–项 - libzip 或 zlib:载入储存在 ZIP 文件中的 ROM 的所需ä¾èµ–项。 - SQLite3:游æˆæ•°æ®åº“的所需ä¾èµ–项 - libelf:ELF 载入的所需ä¾èµ–项 +- Lua: è„šæœ¬æ”¯æŒ +- json-c: 脚本 `storage` API æ”¯æŒ SQLite3ã€libpng ä»¥åŠ zlib 已包å«åœ¨æ¨¡æ‹Ÿå™¨ä¸­ï¼Œå› æ­¤ä¸éœ€è¦å…ˆå¯¹è¿™äº›ä¾èµ–项进行外部编译。 -Footnotes +脚注 --------- [1] ç›®å‰ç¼ºå¤±çš„功能有 @@ -232,7 +247,7 @@ Footnotes [2] 闪存大å°æ£€æµ‹åœ¨æŸäº›æƒ…况下ä¸èµ·ä½œç”¨ã€‚ 这些å¯ä»¥åœ¨è¿è¡Œæ—¶ä¸­è¿›è¡Œé…置,但如果é‡åˆ°æ­¤ç±»æƒ…况,建议æ交错误。 -[3] ä»… Qt 端å£éœ€è¦ 10.9。应该å¯ä»¥åœ¨ 10.7 或更早版本上构建或è¿è¡Œ Qt 端å£ï¼Œä½†è¿™ç±»æ“作ä¸å—官方支æŒã€‚已知 SDL 端å£å¯ä»¥åœ¨ 10.5 上è¿è¡Œï¼Œå¹¶ä¸”å¯èƒ½èƒ½å¤Ÿåœ¨æ—§ç‰ˆæœ¬ä¸Šè¿è¡Œã€‚ +[3] ä»… Qt 移æ¤éœ€è¦ 10.9。应该å¯ä»¥åœ¨ 10.7 或更早版本上构建或è¿è¡Œ Qt 移æ¤ï¼Œä½†è¿™ç±»æ“作ä¸å—官方支æŒã€‚已知 SDL 移æ¤å¯ä»¥åœ¨ 10.5 上è¿è¡Œï¼Œå¹¶ä¸”å¯èƒ½èƒ½å¤Ÿåœ¨æ—§ç‰ˆæœ¬ä¸Šè¿è¡Œã€‚ [downloads]: http://mgba.io/downloads.html [source]: https://github.com/mgba-emu/mgba/ @@ -240,7 +255,7 @@ Footnotes ç‰ˆæƒ --------- -mGBA ç‰ˆæƒ Â© 2013 – 2020 Jeffrey Pfau。基于 [Mozilla 公共许å¯è¯ç‰ˆæœ¬ 2.0](https://www.mozilla.org/MPL/2.0/) 许å¯è¯åˆ†å‘。分å‘çš„ LICENSE 文件中æ供了许å¯è¯çš„副本。 +mGBA ç‰ˆæƒ Â© 2013 – 2023 Jeffrey Pfau。基于 [Mozilla 公共许å¯è¯ç‰ˆæœ¬ 2.0](https://www.mozilla.org/MPL/2.0/) 许å¯è¯åˆ†å‘。分å‘çš„ LICENSE 文件中æ供了许å¯è¯çš„副本。 mGBA 包å«ä»¥ä¸‹ç¬¬ä¸‰æ–¹åº“: From 6e3a00e0814d4f3a6af080bfdbb9c0d073f95da9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 11 May 2024 21:40:56 -0700 Subject: [PATCH 195/336] Qt: Fix crash when applying changes to GB I/O registers in I/O view --- CHANGES | 1 + src/platform/qt/IOViewer.cpp | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 15f85e7f0..899b3391a 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Other fixes: - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts + - Qt: Fix crash when applying changes to GB I/O registers in I/O view - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index 531ba6955..ef995921c 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -1687,7 +1687,20 @@ void IOViewer::bitFlipped() { void IOViewer::writeback() { { CoreController::Interrupter interrupter(m_controller); - GBAIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + switch (m_controller->platform()) { +#ifdef M_CORE_GB + case mPLATFORM_GB: + GBIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + break; +#endif +#ifdef M_CORE_GBA + case mPLATFORM_GBA: + GBAIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + break; +#endif + case mPLATFORM_NONE: + return; + } } updateRegister(); } From b723ed47645c0d87c3a95197de12bd17648570a5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2024 02:48:05 -0700 Subject: [PATCH 196/336] Qt: Better fix for I/O viewer --- src/platform/qt/IOViewer.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index ef995921c..90a97fdbb 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -1687,19 +1687,14 @@ void IOViewer::bitFlipped() { void IOViewer::writeback() { { CoreController::Interrupter interrupter(m_controller); - switch (m_controller->platform()) { -#ifdef M_CORE_GB - case mPLATFORM_GB: - GBIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + mCore* core = m_controller->thread()->core; + switch (m_width) { + case 0: + core->busWrite8(core, m_base + m_register, m_value); break; -#endif -#ifdef M_CORE_GBA - case mPLATFORM_GBA: - GBAIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + case 1: + core->busWrite16(core, m_base + m_register, m_value); break; -#endif - case mPLATFORM_NONE: - return; } } updateRegister(); From 8b1efec1161411c57d9643f4d437fd9bbdc4a5fb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2024 02:51:07 -0700 Subject: [PATCH 197/336] Qt: Fix LCDC background priority/enable bit being mis-mapped in I/O view --- CHANGES | 1 + src/platform/qt/IOViewer.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 899b3391a..60c1a61fb 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Other fixes: - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts - Qt: Fix crash when applying changes to GB I/O registers in I/O view + - Qt: Fix LCDC background priority/enable bit being mis-mapped in I/O view - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index 90a97fdbb..9b44af04f 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -1323,7 +1323,7 @@ const QList& IOViewer::registerDescriptions(mPlat }); // 0xFF40: LCDC regGB.append({ - { tr("Background enable/priority"), 1 }, + { tr("Background enable/priority"), 0 }, { tr("Enable sprites"), 1 }, { tr("Double-height sprites"), 2 }, { tr("Background tile map"), 3, 1, { From 649be1b5056ad8c99e00c7d8d308cfc9fe8bcd5c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2024 23:02:35 -0700 Subject: [PATCH 198/336] SDL: Properly disable SDL build if libsdl isn't found (fixes #3213) --- src/platform/sdl/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 38e328d73..d62c74694 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -40,6 +40,7 @@ endif() if (NOT SDL2_FOUND AND NOT SDL_FOUND) set(SDL_FOUND OFF PARENT_SCOPE) + set(BUILD_SDL OFF PARENT_SCOPE) return() endif() From 8c0a28477b23db01c0ce8ec916542097c1aa05f5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2024 01:31:25 -0700 Subject: [PATCH 199/336] GBA SIO: Improve MULTI timing --- src/gba/sio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gba/sio.c b/src/gba/sio.c index beb8efdfe..4ffeb6388 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -12,10 +12,10 @@ mLOG_DEFINE_CATEGORY(GBA_SIO, "GBA Serial I/O", "gba.sio"); const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { - { 38326, 73003, 107680, 142356 }, - { 9582, 18251, 26920, 35589 }, - { 6388, 12167, 17947, 23726 }, - { 3194, 6075, 8973, 11863 } + { 31976, 63427, 94884, 125829 }, + { 8378, 16241, 24104, 31457 }, + { 5750, 10998, 16241, 20972 }, + { 3140, 5755, 8376, 10486 } }; static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) { From 2b394e1e26a38359c731a6db507fea6559723cce Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2024 21:17:10 -0700 Subject: [PATCH 200/336] GBA SIO: Remove erroneous RCNT setting --- src/gba/sio/lockstep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 4f12610f1..ba620911e 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -105,7 +105,6 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { switch (node->mode) { case GBA_SIO_MULTI: node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; - node->d.p->rcnt |= 3; ATOMIC_ADD(node->p->attachedMulti, 1); node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, node->p->attachedMulti == node->p->d.attached); if (node->id) { From 3a3ebb5dc7a1dc6f8f893093d213a637acfc4024 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 25 May 2024 01:33:26 -0700 Subject: [PATCH 201/336] Third-Party: Cherry-pick rapidjson buildfix --- src/third-party/discord-rpc/include/rapidjson/document.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/third-party/discord-rpc/include/rapidjson/document.h b/src/third-party/discord-rpc/include/rapidjson/document.h index e3e20dfbd..b0f1f70be 100644 --- a/src/third-party/discord-rpc/include/rapidjson/document.h +++ b/src/third-party/discord-rpc/include/rapidjson/document.h @@ -316,8 +316,6 @@ struct GenericStringRef { GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} - GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; } - //! implicit conversion to plain CharType pointer operator const Ch *() const { return s; } From c7b5d1054644b31d3fcd7b60d471948eb33648ed Mon Sep 17 00:00:00 2001 From: oltolm Date: Sat, 25 May 2024 14:11:53 +0200 Subject: [PATCH 202/336] fix Qt deprecation warnings --- src/platform/qt/ConfigController.cpp | 4 ++++ src/platform/qt/FrameView.cpp | 8 ++++++++ src/platform/qt/MapView.cpp | 5 +++++ src/platform/qt/MemoryModel.cpp | 10 ++++++++++ src/platform/qt/SaveConverter.cpp | 2 +- src/platform/qt/Swatch.cpp | 5 +++++ src/platform/qt/TilePainter.cpp | 5 +++++ src/platform/qt/Window.cpp | 8 ++++++++ src/platform/qt/main.cpp | 6 ++++++ 9 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 91ecf8e7a..ccec60432 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -318,7 +318,11 @@ void ConfigController::setOption(const char* key, const char* value) { } void ConfigController::setOption(const char* key, const QVariant& value) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (value.type() == QVariant::Bool) { +#else + if (value.typeId() == QMetaType::Type::Bool) { +#endif setOption(key, value.toBool()); return; } diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 2fe37e64c..ada077d74 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -505,12 +505,20 @@ bool FrameView::eventFilter(QObject*, QEvent* event) { QPointF pos; switch (event->type()) { case QEvent::MouseButtonPress: +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) pos = static_cast(event)->localPos(); +#else + pos = static_cast(event)->position(); +#endif pos /= m_ui.magnification->value(); selectLayer(pos); return true; case QEvent::MouseButtonDblClick: +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) pos = static_cast(event)->localPos(); +#else + pos = static_cast(event)->position(); +#endif pos /= m_ui.magnification->value(); disableLayer(pos); return true; diff --git a/src/platform/qt/MapView.cpp b/src/platform/qt/MapView.cpp index a00c63c0e..aef8c58b7 100644 --- a/src/platform/qt/MapView.cpp +++ b/src/platform/qt/MapView.cpp @@ -161,8 +161,13 @@ bool MapView::eventFilter(QObject*, QEvent* event) { if (event->type() != QEvent::MouseButtonPress) { return false; } +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) int x = static_cast(event)->x(); int y = static_cast(event)->y(); +#else + int x = static_cast(event)->position().x(); + int y = static_cast(event)->position().y(); +#endif x /= 8 * m_ui.magnification->value(); y /= 8 * m_ui.magnification->value(); selectTile(x, y); diff --git a/src/platform/qt/MemoryModel.cpp b/src/platform/qt/MemoryModel.cpp index 538ce2c51..9bcf54223 100644 --- a/src/platform/qt/MemoryModel.cpp +++ b/src/platform/qt/MemoryModel.cpp @@ -511,8 +511,13 @@ void MemoryModel::wheelEvent(QWheelEvent* event) { } void MemoryModel::mousePressEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (event->x() < m_margins.left() || event->y() < m_margins.top() || event->x() > size().width() - m_margins.right()) { +#else + if (event->position().x() < m_margins.left() || event->position().y() < m_margins.top() || + event->position().x() > size().width() - m_margins.right()) { +#endif m_selection = qMakePair(0, 0); return; } @@ -540,8 +545,13 @@ void MemoryModel::mousePressEvent(QMouseEvent* event) { } void MemoryModel::mouseMoveEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (event->x() < m_margins.left() || event->y() < m_margins.top() || event->x() > size().width() - m_margins.right()) { +#else + if (event->position().x() < m_margins.left() || event->position().y() < m_margins.top() || + event->position().x() > size().width() - m_margins.right()) { +#endif return; } diff --git a/src/platform/qt/SaveConverter.cpp b/src/platform/qt/SaveConverter.cpp index d16eeeea4..974f31af0 100644 --- a/src/platform/qt/SaveConverter.cpp +++ b/src/platform/qt/SaveConverter.cpp @@ -281,7 +281,7 @@ void SaveConverter::detectFromHeaders(std::shared_ptr vf) { } free(data); } - } else if (buffer.left(gsv.count()) == gsv) { + } else if (buffer.left(gsv.size()) == gsv) { size_t size; void* data = GBASavedataGSVGetPayload(*vf, &size, nullptr, false); if (data) { diff --git a/src/platform/qt/Swatch.cpp b/src/platform/qt/Swatch.cpp index 3eb85d780..f4a9ad7c3 100644 --- a/src/platform/qt/Swatch.cpp +++ b/src/platform/qt/Swatch.cpp @@ -56,8 +56,13 @@ void Swatch::paintEvent(QPaintEvent*) { } void Swatch::mousePressEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) int x = event->x() / (m_size + 1); int y = event->y() / (m_size + 1); +#else + int x = event->position().x() / (m_size + 1); + int y = event->position().y() / (m_size + 1); +#endif emit indexPressed(y * m_dims.width() + x); } diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp index c27ade72e..fcb62d420 100644 --- a/src/platform/qt/TilePainter.cpp +++ b/src/platform/qt/TilePainter.cpp @@ -39,8 +39,13 @@ void TilePainter::resizeEvent(QResizeEvent*) { } void TilePainter::mousePressEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) int x = event->x() / m_size; int y = event->y() / m_size; +#else + int x = event->position().x() / m_size; + int y = event->position().y() / m_size; +#endif int index = y * (width() / m_size) + x; if (index < m_tileCount) { emit indexPressed(index); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index c75a163ef..a5576c1c9 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -918,7 +918,11 @@ void Window::gameStarted() { #ifdef M_CORE_GBA if (m_controller->platform() == mPLATFORM_GBA) { QVariant eCardList = m_config->takeArgvOption(QString("ecard")); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (eCardList.canConvert(QMetaType::QStringList)) { +#else + if (QMetaType::canConvert(eCardList.metaType(), QMetaType(QMetaType::QStringList))) { +#endif m_controller->scanCards(eCardList.toStringList()); } } @@ -2149,7 +2153,11 @@ void Window::setController(CoreController* controller, const QString& fname) { #ifdef M_CORE_GBA if (m_controller->platform() == mPLATFORM_GBA) { QVariant mb = m_config->takeArgvOption(QString("mb")); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (mb.canConvert(QMetaType::QString)) { +#else + if (QMetaType::canConvert(mb.metaType(), QMetaType(QMetaType::QString))) { +#endif m_controller->replaceGame(mb.toString()); } } diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index 62967bf1a..f98d2cd88 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -90,7 +90,9 @@ int main(int argc, char* argv[]) { QApplication::setApplicationName(projectName); QApplication::setApplicationVersion(projectVersion); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); +#endif #ifdef BUILD_GLES2 QSurfaceFormat format; @@ -109,7 +111,11 @@ int main(int argc, char* argv[]) { #endif QTranslator qtTranslator; +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { +#else + if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { +#endif application.installTranslator(&qtTranslator); } From b7729c9e80736e34a46ff9f38fcaf0d1ed97a7b2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2024 02:57:11 -0700 Subject: [PATCH 203/336] GBA Video: Add special circlular window handling in OpenGL renderer --- CHANGES | 1 + include/mgba/internal/gba/renderers/gl.h | 2 + src/gba/renderers/gl.c | 138 ++++++++++++++++++++++- 3 files changed, 139 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 60c1a61fb..3d477b022 100644 --- a/CHANGES +++ b/CHANGES @@ -32,6 +32,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - GBA Audio: Remove broken XQ audio pending rewrite + - GBA Video: Add special circlular window handling in OpenGL renderer - Libretro: Add Super Game Boy Color support (closes mgba.io/i/3188) - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 14cf11678..74baec41e 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -118,6 +118,8 @@ enum { GBA_GL_WIN_FLAGS, GBA_GL_WIN_WIN0, GBA_GL_WIN_WIN1, + GBA_GL_WIN_CIRCLE0, + GBA_GL_WIN_CIRCLE1, GBA_GL_FINALIZE_SCALE = 2, GBA_GL_FINALIZE_LAYERS, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index c80da2bcb..afc9c54ac 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -486,6 +486,8 @@ static const struct GBAVideoGLUniform _uniformsWindow[] = { { "flags", GBA_GL_WIN_FLAGS, }, { "win0", GBA_GL_WIN_WIN0, }, { "win1", GBA_GL_WIN_WIN1, }, + { "circle0", GBA_GL_WIN_CIRCLE0, }, + { "circle1", GBA_GL_WIN_CIRCLE1, }, { 0 } }; @@ -496,6 +498,8 @@ static const char* const _renderWindow = "uniform ivec3 flags;\n" "uniform ivec4 win0[160];\n" "uniform ivec4 win1[160];\n" + "uniform vec3 circle0;\n" + "uniform vec3 circle1;\n" "OUT(0) out ivec4 window;\n" "bool crop(vec4 windowParams) {\n" @@ -529,13 +533,20 @@ static const char* const _renderWindow = " return vec4(mix(bottom.xy, top.xy, fract(texCoord.y)), top.zw);\n" "}\n" + "bool test(vec3 circle, vec4 top, vec4 bottom) {\n" + " if (circle.z > 0) {\n" + " return distance(circle.xy, texCoord.xy) <= circle.z;\n" + " }\n" + " return crop(interpolate(top, bottom));\n" + "}\n" + "void main() {\n" " ivec4 windowFlags = ivec4(flags.z, blend, 0);\n" " int top = int(texCoord.y);\n" " int bottom = max(top - 1, 0);\n" - " if ((dispcnt & 0x20) != 0 && crop(interpolate(vec4(win0[top]), vec4(win0[bottom])))) { \n" + " if ((dispcnt & 0x20) != 0 && test(circle0, vec4(win0[top]), vec4(win0[bottom]))) {\n" " windowFlags.x = flags.x;\n" - " } else if ((dispcnt & 0x40) != 0 && crop(interpolate(vec4(win1[top]), vec4(win1[bottom])))) {\n" + " } else if ((dispcnt & 0x40) != 0 && test(circle1, vec4(win1[top]), vec4(win1[bottom]))) {\n" " windowFlags.x = flags.y;\n" " }\n" " window = windowFlags;\n" @@ -1924,6 +1935,127 @@ void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } +static void _detectCircle(struct GBAVideoGLRenderer* renderer, int y, int window) { + int lastStart = 0; + int lastEnd = 0; + + int startX = 0; + int endX = 0; + + int firstY = -1; + float centerX; + float centerY = -1; + float radius = 0; + bool invalid = false; + + int i; + for (i = renderer->firstY; i <= y; ++i) { + lastStart = startX; + lastEnd = endX; + startX = renderer->winNHistory[window][i * 4]; + endX = renderer->winNHistory[window][i * 4 + 1]; + int startY = renderer->winNHistory[window][i * 4 + 2]; + int endY = renderer->winNHistory[window][i * 4 + 3]; + + if (startX == endX || i < startY || i >= endY) { + if (firstY >= 0) { + // The bottom edge of the circle + centerY = (firstY + i) / 2.f; + firstY = -1; + } + continue; + } + if (lastEnd - lastStart <= 0) { + continue; + } + + // The previous segment was non-zero + if (startX >= GBA_VIDEO_HORIZONTAL_PIXELS) { + invalid = true; + break; + } + + int startDiff = lastStart - startX; + int endDiff = endX - lastEnd; + // Make sure the slopes match, otherwise this isn't a circle + if (startDiff - endDiff < -1 || startDiff - endDiff > 1) { + invalid = true; + break; + } + + if (startX < lastStart) { + centerX = (startX + endX) / 2.f; + if (radius > 0) { + // We found two separate shapes, which the interpolation can't handle + invalid = true; + break; + } + } else if (startX > lastStart && radius <= 0) { + radius = (lastEnd - lastStart) / 2.f; + } + + if (firstY < 0 && i - 1 >= startY && i - 1 < endY) { + firstY = i - 1; + } + } + + if (radius <= 0) { + invalid = true; + } + if (centerY < 0) { + invalid = true; + } + + // Check validity + for (i = renderer->firstY; i <= y && !invalid; ++i) { + int startX = renderer->winNHistory[window][i * 4]; + int endX = renderer->winNHistory[window][i * 4 + 1]; + int startY = renderer->winNHistory[window][i * 4 + 2]; + int endY = renderer->winNHistory[window][i * 4 + 3]; + + bool xActive = startX < endX; + bool yActive = i >= startY && i < endY; + + if (xActive && yActive) { + // Real window would be active, make sure simulated window would too + if (centerY - i > radius) { + // y is above the radius + invalid = true; + break; + } + if (i - centerY > radius) { + // y is below the radius + invalid = true; + break; + } + + float cosine = fabsf(i - centerY); + float sine = sqrtf(radius * radius - cosine * cosine); + if (fabsf(centerX - sine - startX) <= 1 && fabsf(centerX + sine - endX) <= 1) { + continue; + } + + if (radius >= cosine + 1) { + sine = sqrtf(radius * radius - (cosine + 1) * (cosine + 1)); + if (fabsf(centerX - sine - startX) <= 1 && fabsf(centerX + sine - endX) <= 1) { + continue; + } + } + // y is active on the wrong parts of the scanline + invalid = true; + } else if (centerY - i < radius && i - centerY < radius) { + // Real window would be inactive, make sure simulated window would too + invalid = true; + } + } + + if (invalid) { + glUniform3f(renderer->windowShader.uniforms[GBA_GL_WIN_CIRCLE0 + window], 0, 0, 0); + } else { + glUniform3f(renderer->windowShader.uniforms[GBA_GL_WIN_CIRCLE0 + window], centerX, centerY, radius - 0.499); + } +} + void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { const struct GBAVideoGLShader* shader = &renderer->windowShader; const GLuint* uniforms = shader->uniforms; @@ -1950,6 +2082,8 @@ void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { glUniform3i(uniforms[GBA_GL_WIN_FLAGS], renderer->winN[0].control, renderer->winN[1].control, renderer->winout); glUniform4iv(uniforms[GBA_GL_WIN_WIN0], GBA_VIDEO_VERTICAL_PIXELS, renderer->winNHistory[0]); glUniform4iv(uniforms[GBA_GL_WIN_WIN1], GBA_VIDEO_VERTICAL_PIXELS, renderer->winNHistory[1]); + _detectCircle(renderer, y, 0); + _detectCircle(renderer, y, 1); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); break; } From 56023cfd02a1a95c3c9f15b4463ff0c6479550c9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2024 00:07:19 -0700 Subject: [PATCH 204/336] Core: Fix warnings --- src/core/thread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/thread.c b/src/core/thread.c index 0be5f81e2..2462407cc 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -459,11 +459,11 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { } logger->filter = NULL; - return 0; + THREAD_EXIT(0); } bool mCoreThreadStart(struct mCoreThread* threadContext) { - threadContext->impl = calloc(sizeof(*threadContext->impl), 1); + threadContext->impl = calloc(1, sizeof(*threadContext->impl)); threadContext->impl->state = mTHREAD_INITIALIZED; threadContext->impl->requested = 0; threadContext->logger.p = threadContext; From 942167acdf44a3d99494179a63dfd942ecf725d5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:17:24 -0700 Subject: [PATCH 205/336] ARM: Backport some CPU table improvements from medusa --- include/mgba/internal/arm/emitter-arm.h | 521 ++++++++++++------------ 1 file changed, 261 insertions(+), 260 deletions(-) diff --git a/include/mgba/internal/arm/emitter-arm.h b/include/mgba/internal/arm/emitter-arm.h index e99a1b7ee..bdea1db8a 100644 --- a/include/mgba/internal/arm/emitter-arm.h +++ b/include/mgba/internal/arm/emitter-arm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014 Jeffrey Pfau +/* Copyright (c) 2013-2024 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -67,269 +67,270 @@ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)), \ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)) -#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2) \ - DO_8(DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2)))) +#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2, NAME3) \ + DO_8(DO_INTERLACE( \ + DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2))), \ + DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME3))))) #define DECLARE_ARM_SWI_BLOCK(EMITTER) \ DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI)) #define DECLARE_ARM_EMITTER_BLOCK(EMITTER) \ - DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, SWP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \ - DECLARE_INSTRUCTION_ARM(EMITTER, BX), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, SWPB), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, SMLALS, LDRHPU, LDRSBPU, LDRSHPU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, SMLAL, STRHPUW, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, SMLALS, LDRHPUW, LDRSBPUW, LDRSHPUW), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, SMLAL, STRHIPU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, SMLALS, LDRHIPU, LDRSBIPU, LDRSHIPU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, SMLAL, STRHIPUW, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, SMLALS, LDRHIPUW, LDRSBIPUW, LDRSHIPUW), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W), \ - DECLARE_ARM_BRANCH_BLOCK(EMITTER, B), \ - DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ - DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \ - DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MRC), \ - DECLARE_ARM_SWI_BLOCK(EMITTER) + /* -00---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \ + /* -01---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \ + /* -02---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL), \ + /* -03---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH), \ + /* -04---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL), \ + /* -05---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI), \ + /* -06---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL), \ + /* -07---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI), \ + /* -08---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL), \ + /* -09---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU), \ + /* -0A---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL), \ + /* -0B---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU), \ + /* -0C---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL), \ + /* -0D---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU), \ + /* -0E---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL), \ + /* -0F---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU), \ + /* -10---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \ + /* -10---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, SWP), \ + /* -10---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHP), \ + /* -10---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -11---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP), \ + /* -12---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \ + /* -12---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, BX), \ + /* -12---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \ + /* -12---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \ + /* -12---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -13---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \ + /* -14---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \ + /* -14---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, SWPB), \ + /* -14---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP), \ + /* -14---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -15---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \ + /* -16---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \ + /* -16---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \ + /* -16---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -17---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \ + /* -18---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \ + /* -19---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, SMLALS, LDRHPU, LDRSBPU, LDRSHPU), \ + /* -1A---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, SMLAL, STRHPUW, ILL, ILL), \ + /* -1B---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, SMLALS, LDRHPUW, LDRSBPUW, LDRSHPUW), \ + /* -1C---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, SMLAL, STRHIPU, ILL, ILL), \ + /* -1D---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, SMLALS, LDRHIPU, LDRSBIPU, LDRSHIPU), \ + /* -1E---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, SMLAL, STRHIPUW, ILL, ILL), \ + /* -1F---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, SMLALS, LDRHIPUW, LDRSBIPUW, LDRSHIPUW), \ + /* -20---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND), \ + /* -21---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS), \ + /* -22---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR), \ + /* -23---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS), \ + /* -24---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB), \ + /* -25---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS), \ + /* -26---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB), \ + /* -27---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS), \ + /* -28---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD), \ + /* -29---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS), \ + /* -2A---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC), \ + /* -2B---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS), \ + /* -2C---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \ + /* -2D---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \ + /* -2E---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \ + /* -2F---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \ + /* -30---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ + /* -31---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ + /* -32---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ + /* -33---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \ + /* -34---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ + /* -35---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ + /* -36---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR), \ + /* -37---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \ + /* -38---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR), \ + /* -39---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS), \ + /* -3A---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV), \ + /* -3B---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS), \ + /* -3C---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC), \ + /* -3D---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \ + /* -3E---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \ + /* -3F---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \ + /* -40---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \ + /* -41---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \ + /* -42---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \ + /* -43---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \ + /* -44---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \ + /* -45---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \ + /* -46---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \ + /* -47---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \ + /* -48---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \ + /* -49---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \ + /* -4A---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \ + /* -4B---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \ + /* -4C---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \ + /* -4D---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \ + /* -4E---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \ + /* -4F---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \ + /* -50---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \ + /* -51---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \ + /* -52---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \ + /* -53---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \ + /* -54---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \ + /* -55---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \ + /* -56---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \ + /* -57---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \ + /* -58---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \ + /* -59---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \ + /* -5A---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \ + /* -5B---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \ + /* -5C---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \ + /* -5D---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \ + /* -5E---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \ + /* -5F---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \ + /* -60---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \ + /* -61---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \ + /* -62---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \ + /* -63---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \ + /* -64---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \ + /* -65---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \ + /* -66---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \ + /* -67---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \ + /* -68---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \ + /* -69---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \ + /* -6A---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \ + /* -6B---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \ + /* -6C---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \ + /* -6D---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \ + /* -6E---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \ + /* -6F---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \ + /* -70---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \ + /* -71---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \ + /* -72---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \ + /* -73---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \ + /* -74---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \ + /* -75---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \ + /* -76---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \ + /* -77---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \ + /* -78---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \ + /* -79---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \ + /* -7A---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \ + /* -7B---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \ + /* -7C---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \ + /* -7D---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \ + /* -7E---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \ + /* -7F---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \ + /* -80---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \ + /* -81---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \ + /* -82---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \ + /* -83---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \ + /* -84---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \ + /* -85---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \ + /* -86---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \ + /* -87---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \ + /* -88---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \ + /* -89---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \ + /* -8A---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \ + /* -8B---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \ + /* -8C---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \ + /* -8D---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \ + /* -8E---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \ + /* -8F---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \ + /* -90---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \ + /* -91---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \ + /* -92---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \ + /* -93---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \ + /* -94---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \ + /* -95---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \ + /* -96---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \ + /* -97---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \ + /* -98---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \ + /* -99---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \ + /* -9A---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \ + /* -9B---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \ + /* -9C---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \ + /* -9D---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \ + /* -9E---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \ + /* -9F---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W), \ + /* -AX---X- */ DECLARE_ARM_BRANCH_BLOCK(EMITTER, B), \ + /* -BX---X- */ DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL), \ + /* -C0---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ), \ + /* -C1---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ), \ + /* -C2---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W), \ + /* -C3---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W), \ + /* -C4---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ), \ + /* -C5---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ), \ + /* -C6---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W), \ + /* -C7---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W), \ + /* -C8---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ), \ + /* -C9---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ), \ + /* -CA---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W), \ + /* -CB---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W), \ + /* -CC---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ), \ + /* -CD---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ), \ + /* -CE---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W), \ + /* -CF---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W), \ + /* -D0---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ), \ + /* -D1---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ), \ + /* -D2---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W), \ + /* -D3---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W), \ + /* -D4---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ + /* -D5---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ + /* -D6---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ + /* -D7---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ + /* -D8---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ), \ + /* -D9---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ), \ + /* -DA---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W), \ + /* -DB---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W), \ + /* -DC---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ + /* -DD---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ + /* -DE---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ + /* -DF---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ + /* -EX---X- */ DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR, MRC), \ + /* -FX---X- */ DECLARE_ARM_SWI_BLOCK(EMITTER) #endif From e4e455dd5ed09ac38d65d099aba2d2e0e082fad8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:30:17 -0700 Subject: [PATCH 206/336] ARM: Add framework for coprocessor support --- CHANGES | 1 + include/mgba/internal/arm/arm.h | 7 ++++++ src/arm/arm.c | 1 + src/arm/isa-arm.c | 39 ++++++++++++++++++++++++++++++--- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 3d477b022..7c48e3ab1 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Features: - New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81 - Debugger: Add range watchpoints Emulation fixes: + - ARM: Add framework for coprocessor support - GB Audio: Fix audio envelope timing resetting too often (fixes mgba.io/i/3164) - GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501) - GB Serialize: Add missing Pocket Cam state to savestates diff --git a/include/mgba/internal/arm/arm.h b/include/mgba/internal/arm/arm.h index f9eeafdb6..5f25acf90 100644 --- a/include/mgba/internal/arm/arm.h +++ b/include/mgba/internal/arm/arm.h @@ -134,6 +134,12 @@ struct ARMMemory { void (*setActiveRegion)(struct ARMCore*, uint32_t address); }; +struct ARMCoprocessor { + int32_t (*mrc)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2); + void (*mcr)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2, int32_t value); + void (*cdp)(struct ARMCore*, int crn, int crm, int crd, int opcode1, int opcode2); +}; + struct ARMInterruptHandler { void (*reset)(struct ARMCore* cpu); void (*processEvents)(struct ARMCore* cpu); @@ -179,6 +185,7 @@ struct ARMCore { struct ARMMemory memory; struct ARMInterruptHandler irqh; + struct ARMCoprocessor cp[16]; struct mCPUComponent* master; diff --git a/src/arm/arm.c b/src/arm/arm.c index cb93136aa..0b92d7f55 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -45,6 +45,7 @@ void ARMSetPrivilegeMode(struct ARMCore* cpu, enum PrivilegeMode mode) { } void ARMInit(struct ARMCore* cpu) { + memset(cpu->cp, 0, sizeof(cpu->cp)); cpu->master->init(cpu, cpu->master); size_t i; for (i = 0; i < cpu->numComponents; ++i) { diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index 7f158dc6e..aaecf2517 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -655,11 +655,44 @@ DEFINE_INSTRUCTION_ARM(BX, // Begin coprocessor definitions -DEFINE_INSTRUCTION_ARM(CDP, ARM_STUB) +#define DEFINE_COPROCESSOR_INSTRUCTION(NAME, BODY) \ + DEFINE_INSTRUCTION_ARM(NAME, \ + int op1 = (opcode >> 21) & 7; \ + int op2 = (opcode >> 5) & 7; \ + int rd = (opcode >> 12) & 0xF; \ + int cp = (opcode >> 8) & 0xF; \ + int crn = (opcode >> 16) & 0xF; \ + int crm = opcode & 0xF; \ + UNUSED(op1); \ + UNUSED(op2); \ + UNUSED(rd); \ + UNUSED(crn); \ + UNUSED(crm); \ + BODY;) + +DEFINE_COPROCESSOR_INSTRUCTION(MRC, + if (cpu->cp[cp].mrc) { + cpu->gprs[rd] = cpu->cp[cp].mrc(cpu, crn, crm, op1, op2); + } else { + ARM_ILL; + }) + +DEFINE_COPROCESSOR_INSTRUCTION(MCR, + if (cpu->cp[cp].mcr) { + cpu->cp[cp].mcr(cpu, crn, crm, op1, op2, cpu->gprs[rd]); + } else { + ARM_ILL; + }) + +DEFINE_COPROCESSOR_INSTRUCTION(CDP, + if (cpu->cp[cp].cdp) { + cpu->cp[cp].cdp(cpu, crn, crm, rd, op1, op2); + } else { + ARM_ILL; + }) + DEFINE_INSTRUCTION_ARM(LDC, ARM_STUB) DEFINE_INSTRUCTION_ARM(STC, ARM_STUB) -DEFINE_INSTRUCTION_ARM(MCR, ARM_STUB) -DEFINE_INSTRUCTION_ARM(MRC, ARM_STUB) // Begin miscellaneous definitions From 455060ec08548905a16428a0aeebb34a3e1faafd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:33:25 -0700 Subject: [PATCH 207/336] GBA: Add baseline CP0 (Wii U VC) and CP1 (DCC) implementations --- CHANGES | 1 + src/gba/gba.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/CHANGES b/CHANGES index 7c48e3ab1..2ff272fb6 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ Emulation fixes: - GB Serialize: Add missing Pocket Cam state to savestates - GB Video: Implement DMG-style sprite ordering - GBA: Unhandled bkpt should be treated as an undefined exception + - GBA: Add baseline CP0 (Wii U VC) and CP1 (DCC) implementations - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) diff --git a/src/gba/gba.c b/src/gba/gba.c index 94ed7562a..3783a0c44 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -40,6 +40,8 @@ static const uint8_t GBA_ROM_MAGIC2[] = { 0x96 }; static const size_t GBA_MB_MAGIC_OFFSET = 0xC0; static void GBAInit(void* cpu, struct mCPUComponent* component); +static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int opcode1, int opcode2); +static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2); static void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh); static void GBAProcessEvents(struct ARMCore* cpu); static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode); @@ -72,6 +74,8 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) { gba->sync = 0; GBAInterruptHandlerInit(&gba->cpu->irqh); + gba->cpu->cp[0].cdp = GBACP0Process; + gba->cpu->cp[14].mrc = GBACP14Read; GBAMemoryInit(gba); gba->memory.savedata.timing = &gba->timing; @@ -186,6 +190,20 @@ void GBADestroy(struct GBA* gba) { mCoreCallbacksListDeinit(&gba->coreCallbacks); } +static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int opcode1, int opcode2) { + UNUSED(cpu); + mLOG(GBA, INFO, "Hit Wii U VC opcode: cdp p0, %i, c%i, c%i, c%i, %i", opcode1, crd, crn, crm, opcode2); +} + +static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2) { + UNUSED(cpu); + UNUSED(crn); + UNUSED(crm); + UNUSED(opcode1); + UNUSED(opcode2); + return 0xF000B570; +} + void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { irqh->reset = GBAReset; irqh->processEvents = GBAProcessEvents; From cf959fe20e13744690c5830a3fd9a81f182317d6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:37:18 -0700 Subject: [PATCH 208/336] GBA: Actually it reads open bus --- src/gba/gba.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gba/gba.c b/src/gba/gba.c index 3783a0c44..2f0ae76d6 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -196,12 +196,12 @@ static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int op } static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2) { - UNUSED(cpu); UNUSED(crn); UNUSED(crm); UNUSED(opcode1); UNUSED(opcode2); - return 0xF000B570; + mLOG(GBA, GAME_ERROR, "Read from missing CP14"); + return GBALoadBad(cpu); } void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { From 8b041e9a2315ebed008d92bbf7b2aa3fce19a582 Mon Sep 17 00:00:00 2001 From: yeah-its-gloria <32610623+yeah-its-gloria@users.noreply.github.com> Date: Mon, 3 Jun 2024 19:49:23 -0400 Subject: [PATCH 209/336] Qt: Ignore rewind while loading/saving states --- src/platform/qt/Window.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index a5576c1c9..010dde782 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1464,6 +1464,11 @@ void Window::setupMenu(QMenuBar* menubar) { }, "emu"); auto rewindHeld = m_actions.addHeldAction(tr("Rewind (held)"), "holdRewind", [this](bool held) { + // Prevent rewinding while the load/save state window is active + if (held && this->m_stateWindow != nullptr) { + return; + } + if (m_controller) { m_controller->setRewinding(held); } From 7451decdacc7f0abcdac36ad9f6951e8ae7090b3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 3 Jun 2024 18:44:01 -0700 Subject: [PATCH 210/336] Windows: Inno Setup fixes Update minimum Windows version to 7, add DisableDirPage=no --- src/platform/windows/setup/setup.iss.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platform/windows/setup/setup.iss.in b/src/platform/windows/setup/setup.iss.in index 3aad9ef1b..7fdda053e 100644 --- a/src/platform/windows/setup/setup.iss.in +++ b/src/platform/windows/setup/setup.iss.in @@ -32,10 +32,11 @@ DefaultDirName={pf}\{#AppName} DefaultGroupName={#AppName} AllowNoIcons=yes DirExistsWarning=no +DisableDirPage=no ChangesAssociations=True AppendDefaultDirName=False UninstallDisplayIcon={app}\{#AppName}.exe -MinVersion=0,6.0 +MinVersion=6.1 AlwaysShowDirOnReadyPage=True UsePreviousSetupType=True UsePreviousTasks=True @@ -52,7 +53,7 @@ OutputBaseFilename={#AppName}-setup-{#CleanVersionString}-win{#WinBits} UsePreviousLanguage=False DisableWelcomePage=False VersionInfoDescription={#AppName} is an open-source Game Boy Advance emulator -VersionInfoCopyright=© 2013–2022 Jeffrey Pfau +VersionInfoCopyright=© 2013–2024 Jeffrey Pfau VersionInfoProductName={#AppName} VersionInfoVersion={#AppVer} Compression=lzma2/ultra From 59f4fb71326205d890b75ade9e523fe7b59d2b2f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 00:55:07 -0700 Subject: [PATCH 211/336] Test: Read config file in rom-test --- src/platform/test/rom-test-main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/test/rom-test-main.c b/src/platform/test/rom-test-main.c index 8524a852f..be9f36e8e 100644 --- a/src/platform/test/rom-test-main.c +++ b/src/platform/test/rom-test-main.c @@ -93,6 +93,7 @@ int main(int argc, char * argv[]) { mCoreConfigSetDefaultValue(&core->config, "idleOptimization", "remove"); mCoreConfigSetDefaultIntValue(&core->config, "logToStdout", true); + mCoreLoadConfig(core); mStandardLoggerInit(&_logger); mStandardLoggerConfig(&_logger, &core->config); From 6f261f6f1b164451f903a541949577d70ac56f45 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 01:12:14 -0700 Subject: [PATCH 212/336] Scripting: Split console implementation out from Core scripting --- include/mgba/core/scripting.h | 27 ---- include/mgba/script.h | 1 + src/core/scripting.c | 133 ----------------- .../qt/scripting/ScriptingTextBuffer.h | 1 + src/script/CMakeLists.txt | 1 + src/script/console.c | 141 ++++++++++++++++++ 6 files changed, 144 insertions(+), 160 deletions(-) create mode 100644 src/script/console.c diff --git a/include/mgba/core/scripting.h b/include/mgba/core/scripting.h index c0fdcb413..bab2009cf 100644 --- a/include/mgba/core/scripting.h +++ b/include/mgba/core/scripting.h @@ -20,8 +20,6 @@ struct mCore; struct mScriptTextBuffer; mSCRIPT_DECLARE_STRUCT(mCore); mSCRIPT_DECLARE_STRUCT(mLogger); -mSCRIPT_DECLARE_STRUCT(mScriptConsole); -mSCRIPT_DECLARE_STRUCT(mScriptTextBuffer); struct mScriptBridge; struct VFile; @@ -40,24 +38,6 @@ struct mScriptEngine { #endif }; -struct mScriptTextBuffer { - void (*init)(struct mScriptTextBuffer*, const char* name); - void (*deinit)(struct mScriptTextBuffer*); - - void (*setName)(struct mScriptTextBuffer*, const char* text); - - uint32_t (*getX)(const struct mScriptTextBuffer*); - uint32_t (*getY)(const struct mScriptTextBuffer*); - uint32_t (*cols)(const struct mScriptTextBuffer*); - uint32_t (*rows)(const struct mScriptTextBuffer*); - - void (*print)(struct mScriptTextBuffer*, const char* text); - void (*clear)(struct mScriptTextBuffer*); - void (*setSize)(struct mScriptTextBuffer*, uint32_t cols, uint32_t rows); - void (*moveCursor)(struct mScriptTextBuffer*, uint32_t x, uint32_t y); - void (*advance)(struct mScriptTextBuffer*, int32_t); -}; - struct mScriptBridge* mScriptBridgeCreate(void); void mScriptBridgeDestroy(struct mScriptBridge*); @@ -80,13 +60,6 @@ struct mScriptContext; void mScriptContextAttachCore(struct mScriptContext*, struct mCore*); void mScriptContextDetachCore(struct mScriptContext*); -struct mLogger; -void mScriptContextAttachLogger(struct mScriptContext*, struct mLogger*); -void mScriptContextDetachLogger(struct mScriptContext*); - -typedef struct mScriptTextBuffer* (*mScriptContextBufferFactory)(void*); -void mScriptContextSetTextBufferFactory(struct mScriptContext*, mScriptContextBufferFactory factory, void* cbContext); - CXX_GUARD_END #endif diff --git a/include/mgba/script.h b/include/mgba/script.h index 747dfedc1..44ec86b3c 100644 --- a/include/mgba/script.h +++ b/include/mgba/script.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/src/core/scripting.c b/src/core/scripting.c index 57d0eed2b..13cc403c8 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -207,12 +207,6 @@ struct mScriptCoreAdapter { #endif }; -struct mScriptConsole { - struct mLogger* logger; - mScriptContextBufferFactory textBufferFactory; - void* textBufferContext; -}; - #define CALCULATE_SEGMENT_INFO \ uint32_t segmentSize = adapter->block.end - adapter->block.start; \ uint32_t segmentStart = adapter->block.segmentStart - adapter->block.start; \ @@ -1354,130 +1348,3 @@ void mScriptContextDetachCore(struct mScriptContext* context) { mScriptContextRemoveGlobal(context, "emu"); } - -static struct mScriptTextBuffer* _mScriptConsoleCreateBuffer(struct mScriptConsole* lib, const char* name) { - struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext); - buffer->init(buffer, name); - return buffer; -} - -static void mScriptConsoleLog(struct mScriptConsole* console, const char* msg) { - if (console->logger) { - mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); - } else { - mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); - } -} - -static void mScriptConsoleWarn(struct mScriptConsole* console, const char* msg) { - if (console->logger) { - mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); - } else { - mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); - } -} - -static void mScriptConsoleError(struct mScriptConsole* console, const char* msg) { - if (console->logger) { - mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); - } else { - mLog(_mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); - } -} - -mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, log, mScriptConsoleLog, 1, CHARP, msg); -mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, warn, mScriptConsoleWarn, 1, CHARP, msg); -mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, error, mScriptConsoleError, 1, CHARP, msg); -mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptConsole, S(mScriptTextBuffer), createBuffer, _mScriptConsoleCreateBuffer, 1, CHARP, name); - -mSCRIPT_DEFINE_STRUCT(mScriptConsole) - mSCRIPT_DEFINE_CLASS_DOCSTRING( - "A global singleton object `console` that can be used for presenting textual information to the user via a console." - ) - mSCRIPT_DEFINE_DOCSTRING("Print a log to the console") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, log) - mSCRIPT_DEFINE_DOCSTRING("Print a warning to the console") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, warn) - mSCRIPT_DEFINE_DOCSTRING("Print an error to the console") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, error) - mSCRIPT_DEFINE_DOCSTRING("Create a text buffer that can be used to display custom information") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, createBuffer) -mSCRIPT_DEFINE_END; - -mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptConsole, createBuffer) - mSCRIPT_CHARP(NULL) -mSCRIPT_DEFINE_DEFAULTS_END; - -static struct mScriptConsole* _ensureConsole(struct mScriptContext* context) { - struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); - if (value) { - return value->value.opaque; - } - struct mScriptConsole* console = calloc(1, sizeof(*console)); - value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptConsole)); - value->value.opaque = console; - value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER; - mScriptContextSetGlobal(context, "console", value); - mScriptContextSetDocstring(context, "console", "Singleton instance of struct::mScriptConsole"); - return console; -} - -void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) { - struct mScriptConsole* console = _ensureConsole(context); - console->logger = logger; -} - -void mScriptContextDetachLogger(struct mScriptContext* context) { - struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); - if (!value) { - return; - } - struct mScriptConsole* console = value->value.opaque; - console->logger = mLogGetContext(); -} - -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getX, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getY, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, cols, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, rows, 0); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, print, 1, CHARP, text); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, clear, 0); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setSize, 2, U32, cols, U32, rows); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, moveCursor, 2, U32, x, U32, y); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, advance, 1, S32, adv); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setName, 1, CHARP, name); - -mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer) - mSCRIPT_DEFINE_CLASS_DOCSTRING( - "An object that can be used to present texual data to the user. It is displayed monospaced, " - "and text can be edited after sending by moving the cursor or clearing the buffer." - ) - mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(mScriptTextBuffer, deinit) - mSCRIPT_DEFINE_DOCSTRING("Get the current x position of the cursor") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getX) - mSCRIPT_DEFINE_DOCSTRING("Get the current y position of the cursor") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getY) - mSCRIPT_DEFINE_DOCSTRING("Get number of columns in the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, cols) - mSCRIPT_DEFINE_DOCSTRING("Get number of rows in the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, rows) - mSCRIPT_DEFINE_DOCSTRING("Print a string to the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, print) - mSCRIPT_DEFINE_DOCSTRING("Clear the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear) - mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize) - mSCRIPT_DEFINE_DOCSTRING("Set the position of the cursor") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor) - mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance) - mSCRIPT_DEFINE_DOCSTRING("Set the user-visible name of this buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName) -mSCRIPT_DEFINE_END; - -void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) { - struct mScriptConsole* console = _ensureConsole(context); - console->textBufferFactory = factory; - console->textBufferContext = cbContext; -} diff --git a/src/platform/qt/scripting/ScriptingTextBuffer.h b/src/platform/qt/scripting/ScriptingTextBuffer.h index b70e9f82a..b4a9c5b83 100644 --- a/src/platform/qt/scripting/ScriptingTextBuffer.h +++ b/src/platform/qt/scripting/ScriptingTextBuffer.h @@ -10,6 +10,7 @@ #include #include +#include #include namespace QGBA { diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt index a72f48d22..19802c278 100644 --- a/src/script/CMakeLists.txt +++ b/src/script/CMakeLists.txt @@ -1,6 +1,7 @@ include(ExportDirectory) set(SOURCE_FILES canvas.c + console.c context.c input.c image.c diff --git a/src/script/console.c b/src/script/console.c new file mode 100644 index 000000000..d908534f6 --- /dev/null +++ b/src/script/console.c @@ -0,0 +1,141 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +#include + +struct mScriptConsole { + struct mLogger* logger; + mScriptContextBufferFactory textBufferFactory; + void* textBufferContext; +}; + +static struct mScriptTextBuffer* _mScriptConsoleCreateBuffer(struct mScriptConsole* lib, const char* name) { + struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext); + buffer->init(buffer, name); + return buffer; +} + +static void mScriptConsoleLog(struct mScriptConsole* console, const char* msg) { + if (console->logger) { + mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); + } else { + mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); + } +} + +static void mScriptConsoleWarn(struct mScriptConsole* console, const char* msg) { + if (console->logger) { + mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); + } else { + mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); + } +} + +static void mScriptConsoleError(struct mScriptConsole* console, const char* msg) { + if (console->logger) { + mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); + } else { + mLog(_mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); + } +} + +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, log, mScriptConsoleLog, 1, CHARP, msg); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, warn, mScriptConsoleWarn, 1, CHARP, msg); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, error, mScriptConsoleError, 1, CHARP, msg); +mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptConsole, S(mScriptTextBuffer), createBuffer, _mScriptConsoleCreateBuffer, 1, CHARP, name); + +mSCRIPT_DEFINE_STRUCT(mScriptConsole) + mSCRIPT_DEFINE_CLASS_DOCSTRING( + "A global singleton object `console` that can be used for presenting textual information to the user via a console." + ) + mSCRIPT_DEFINE_DOCSTRING("Print a log to the console") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, log) + mSCRIPT_DEFINE_DOCSTRING("Print a warning to the console") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, warn) + mSCRIPT_DEFINE_DOCSTRING("Print an error to the console") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, error) + mSCRIPT_DEFINE_DOCSTRING("Create a text buffer that can be used to display custom information") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, createBuffer) +mSCRIPT_DEFINE_END; + +mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptConsole, createBuffer) + mSCRIPT_CHARP(NULL) +mSCRIPT_DEFINE_DEFAULTS_END; + +static struct mScriptConsole* _ensureConsole(struct mScriptContext* context) { + struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); + if (value) { + return value->value.opaque; + } + struct mScriptConsole* console = calloc(1, sizeof(*console)); + value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptConsole)); + value->value.opaque = console; + value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER; + mScriptContextSetGlobal(context, "console", value); + mScriptContextSetDocstring(context, "console", "Singleton instance of struct::mScriptConsole"); + return console; +} + +void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) { + struct mScriptConsole* console = _ensureConsole(context); + console->logger = logger; +} + +void mScriptContextDetachLogger(struct mScriptContext* context) { + struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); + if (!value) { + return; + } + struct mScriptConsole* console = value->value.opaque; + console->logger = mLogGetContext(); +} + +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getX, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getY, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, cols, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, rows, 0); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, print, 1, CHARP, text); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, clear, 0); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setSize, 2, U32, cols, U32, rows); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, moveCursor, 2, U32, x, U32, y); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, advance, 1, S32, adv); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setName, 1, CHARP, name); + +mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer) + mSCRIPT_DEFINE_CLASS_DOCSTRING( + "An object that can be used to present texual data to the user. It is displayed monospaced, " + "and text can be edited after sending by moving the cursor or clearing the buffer." + ) + mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(mScriptTextBuffer, deinit) + mSCRIPT_DEFINE_DOCSTRING("Get the current x position of the cursor") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getX) + mSCRIPT_DEFINE_DOCSTRING("Get the current y position of the cursor") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getY) + mSCRIPT_DEFINE_DOCSTRING("Get number of columns in the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, cols) + mSCRIPT_DEFINE_DOCSTRING("Get number of rows in the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, rows) + mSCRIPT_DEFINE_DOCSTRING("Print a string to the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, print) + mSCRIPT_DEFINE_DOCSTRING("Clear the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear) + mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize) + mSCRIPT_DEFINE_DOCSTRING("Set the position of the cursor") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor) + mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance) + mSCRIPT_DEFINE_DOCSTRING("Set the user-visible name of this buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName) +mSCRIPT_DEFINE_END; + +void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) { + struct mScriptConsole* console = _ensureConsole(context); + console->textBufferFactory = factory; + console->textBufferContext = cbContext; +} From 2c975157427090c93dfda6cf296b6a216a64f5d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 01:15:25 -0700 Subject: [PATCH 213/336] Script: Add missing include --- include/mgba/script/console.h | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 include/mgba/script/console.h diff --git a/include/mgba/script/console.h b/include/mgba/script/console.h new file mode 100644 index 000000000..8e7a64345 --- /dev/null +++ b/include/mgba/script/console.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2013-2024 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef M_SCRIPT_CONSOLE_H +#define M_SCRIPT_CONSOLE_H + +#include + +CXX_GUARD_START + +#include +#include +#include + +struct mCore; +struct mScriptTextBuffer; +mSCRIPT_DECLARE_STRUCT(mCore); +mSCRIPT_DECLARE_STRUCT(mLogger); +mSCRIPT_DECLARE_STRUCT(mScriptConsole); +mSCRIPT_DECLARE_STRUCT(mScriptTextBuffer); + +struct mScriptTextBuffer { + void (*init)(struct mScriptTextBuffer*, const char* name); + void (*deinit)(struct mScriptTextBuffer*); + + void (*setName)(struct mScriptTextBuffer*, const char* text); + + uint32_t (*getX)(const struct mScriptTextBuffer*); + uint32_t (*getY)(const struct mScriptTextBuffer*); + uint32_t (*cols)(const struct mScriptTextBuffer*); + uint32_t (*rows)(const struct mScriptTextBuffer*); + + void (*print)(struct mScriptTextBuffer*, const char* text); + void (*clear)(struct mScriptTextBuffer*); + void (*setSize)(struct mScriptTextBuffer*, uint32_t cols, uint32_t rows); + void (*moveCursor)(struct mScriptTextBuffer*, uint32_t x, uint32_t y); + void (*advance)(struct mScriptTextBuffer*, int32_t); +}; + +struct mLogger; +void mScriptContextAttachLogger(struct mScriptContext*, struct mLogger*); +void mScriptContextDetachLogger(struct mScriptContext*); + +typedef struct mScriptTextBuffer* (*mScriptContextBufferFactory)(void*); +void mScriptContextSetTextBufferFactory(struct mScriptContext*, mScriptContextBufferFactory factory, void* cbContext); + +CXX_GUARD_END + +#endif From e16dfc264a7b0949cbfad2ce347adc1686849206 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 02:20:27 -0700 Subject: [PATCH 214/336] GBA: CP14 mcr also is a no-op --- src/gba/gba.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/gba/gba.c b/src/gba/gba.c index 2f0ae76d6..6e1fb8923 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -42,6 +42,7 @@ static const size_t GBA_MB_MAGIC_OFFSET = 0xC0; static void GBAInit(void* cpu, struct mCPUComponent* component); static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int opcode1, int opcode2); static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2); +static void GBACP14Write(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2, int32_t value); static void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh); static void GBAProcessEvents(struct ARMCore* cpu); static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode); @@ -76,6 +77,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) { GBAInterruptHandlerInit(&gba->cpu->irqh); gba->cpu->cp[0].cdp = GBACP0Process; gba->cpu->cp[14].mrc = GBACP14Read; + gba->cpu->cp[14].mcr = GBACP14Write; GBAMemoryInit(gba); gba->memory.savedata.timing = &gba->timing; @@ -204,6 +206,16 @@ static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, i return GBALoadBad(cpu); } +static void GBACP14Write(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2, int32_t value) { + UNUSED(cpu); + UNUSED(crn); + UNUSED(crm); + UNUSED(opcode1); + UNUSED(opcode2); + UNUSED(value); + mLOG(GBA, GAME_ERROR, "Write to missing CP14"); +} + void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { irqh->reset = GBAReset; irqh->processEvents = GBAProcessEvents; From 20fc7b6ef30cc9a51499b374762f46e54704b1af Mon Sep 17 00:00:00 2001 From: Rib <1957489+RibShark@users.noreply.github.com> Date: Sun, 9 Jun 2024 22:28:51 +0100 Subject: [PATCH 215/336] GBA Memory: Support the Chinese version of Digimon Sapphire by Vast Fame --- include/mgba/internal/gba/cart/vfame.h | 3 ++- src/gba/cart/vfame.c | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/mgba/internal/gba/cart/vfame.h b/include/mgba/internal/gba/cart/vfame.h index eff24a039..cda1d145c 100644 --- a/include/mgba/internal/gba/cart/vfame.h +++ b/include/mgba/internal/gba/cart/vfame.h @@ -16,7 +16,8 @@ CXX_GUARD_START enum GBAVFameCartType { VFAME_NO = 0, VFAME_STANDARD = 1, - VFAME_GEORGE = 2 + VFAME_ALTERNATE = 2, + VFAME_GEORGE = 3 }; struct GBAVFameCart { diff --git a/src/gba/cart/vfame.c b/src/gba/cart/vfame.c index aedcf5d3e..0daabcc8c 100644 --- a/src/gba/cart/vfame.c +++ b/src/gba/cart/vfame.c @@ -7,12 +7,18 @@ #include #include +#include static const uint8_t ADDRESS_REORDERING[4][16] = { { 15, 14, 9, 1, 8, 10, 7, 3, 5, 11, 4, 0, 13, 12, 2, 6 }, { 15, 7, 13, 5, 11, 6, 0, 9, 12, 2, 10, 14, 3, 1, 8, 4 }, { 15, 0, 3, 12, 2, 4, 14, 13, 1, 8, 6, 7, 9, 5, 11, 10 } }; +static const uint8_t ADDRESS_REORDERING_ALTERNATE[4][16] = { + { 15, 0, 13, 5, 8, 4, 7, 3, 1, 2, 10, 14, 9, 12, 11, 6 }, + { 15, 7, 9, 1, 2, 6, 14, 13, 12, 11, 4, 0, 3, 5, 8, 10 }, + { 15, 14, 3, 12, 11, 10, 0, 9, 5, 8, 6, 7, 13, 1, 2, 4 } +}; static const uint8_t ADDRESS_REORDERING_GEORGE[4][16] = { { 15, 7, 13, 1, 11, 10, 14, 9, 12, 2, 4, 0, 3, 5, 8, 6 }, { 15, 14, 3, 12, 8, 4, 0, 13, 5, 11, 6, 7, 9, 1, 2, 10 }, @@ -23,6 +29,11 @@ static const uint8_t VALUE_REORDERING[4][16] = { { 3, 2, 1, 0, 7, 6, 5, 4 }, { 1, 0, 7, 6, 5, 4, 3, 2 } }; +static const uint8_t VALUE_REORDERING_ALTERNATE[4][16] = { + { 5, 4, 7, 2, 1, 0, 3, 6 }, + { 1, 2, 3, 0, 5, 6, 7, 4 }, + { 3, 0, 1, 6, 7, 4, 5, 2 } +}; static const uint8_t VALUE_REORDERING_GEORGE[4][16] = { { 3, 0, 7, 2, 1, 4, 5, 6 }, { 1, 4, 3, 0, 5, 6, 7, 2 }, @@ -65,13 +76,18 @@ void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize) { mLOG(GBA_MEM, INFO, "Vast Fame game detected"); } - // This game additionally operates with a different set of SRAM modes - // Its initialisation seems to be identical so the difference must be in the cart HW itself + // These games additionally operates with a different set of SRAM modes + // Their initialisation seems to be identical so the difference must be in the cart HW itself // Other undumped games may have similar differences if (memcmp("George Sango", &((struct GBACartridge*) rom)->title, 12) == 0) { cart->cartType = VFAME_GEORGE; mLOG(GBA_MEM, INFO, "George mode"); } + // Chinese version of Digimon Sapphire; header is identical to the English version which uses the normal reordering + // so we have to use some other way to detect it + else if (doCrc32(rom, romSize) == 0x793A328F) { + cart->cartType = VFAME_STANDARD; + } } // This is not currently being used but would be called on ROM reads @@ -256,6 +272,8 @@ static uint32_t _modifySramAddress(enum GBAVFameCartType type, uint32_t address, return address; } else if (type == VFAME_GEORGE) { return _reorderBits(address, ADDRESS_REORDERING_GEORGE[mode - 1], 16); + } else if (type == VFAME_ALTERNATE) { + return _reorderBits(address, ADDRESS_REORDERING_ALTERNATE[mode - 1], 16); } else { return _reorderBits(address, ADDRESS_REORDERING[mode - 1], 16); } @@ -266,6 +284,8 @@ static int8_t _modifySramValue(enum GBAVFameCartType type, uint8_t value, int mo if (reorderType != 0) { if (type == VFAME_GEORGE) { value = _reorderBits(value, VALUE_REORDERING_GEORGE[reorderType - 1], 8); + } else if (type == VFAME_ALTERNATE) { + value = _reorderBits(value, VALUE_REORDERING_ALTERNATE[reorderType - 1], 8); } else { value = _reorderBits(value, VALUE_REORDERING[reorderType - 1], 8); } From 58651f205451054d4869238031b3bf56bd3e5133 Mon Sep 17 00:00:00 2001 From: Rib <1957489+RibShark@users.noreply.github.com> Date: Sun, 9 Jun 2024 22:28:51 +0100 Subject: [PATCH 216/336] GBA Memory: Clean up Vast Fame code somewhat --- include/mgba/internal/gba/cart/vfame.h | 8 ++++--- src/gba/cart/vfame.c | 32 ++++++++++++-------------- src/gba/gba.c | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/mgba/internal/gba/cart/vfame.h b/include/mgba/internal/gba/cart/vfame.h index cda1d145c..5bee28848 100644 --- a/include/mgba/internal/gba/cart/vfame.h +++ b/include/mgba/internal/gba/cart/vfame.h @@ -13,11 +13,13 @@ CXX_GUARD_START +#define DIGIMON_SAPPHIRE_CHINESE_CRC32 0x793A328F + enum GBAVFameCartType { VFAME_NO = 0, VFAME_STANDARD = 1, - VFAME_ALTERNATE = 2, - VFAME_GEORGE = 3 + VFAME_GEORGE = 2, + VFAME_ALTERNATE = 3, }; struct GBAVFameCart { @@ -29,7 +31,7 @@ struct GBAVFameCart { }; void GBAVFameInit(struct GBAVFameCart* cart); -void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize); +void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize, uint32_t crc32); void GBAVFameSramWrite(struct GBAVFameCart* cart, uint32_t address, uint8_t value, uint8_t* sramData); uint32_t GBAVFameModifyRomAddress(struct GBAVFameCart* cart, uint32_t address, size_t romSize); uint32_t GBAVFameGetPatternValue(uint32_t address, int bits); diff --git a/src/gba/cart/vfame.c b/src/gba/cart/vfame.c index 0daabcc8c..260db35b8 100644 --- a/src/gba/cart/vfame.c +++ b/src/gba/cart/vfame.c @@ -7,38 +7,37 @@ #include #include -#include static const uint8_t ADDRESS_REORDERING[4][16] = { { 15, 14, 9, 1, 8, 10, 7, 3, 5, 11, 4, 0, 13, 12, 2, 6 }, { 15, 7, 13, 5, 11, 6, 0, 9, 12, 2, 10, 14, 3, 1, 8, 4 }, { 15, 0, 3, 12, 2, 4, 14, 13, 1, 8, 6, 7, 9, 5, 11, 10 } }; -static const uint8_t ADDRESS_REORDERING_ALTERNATE[4][16] = { - { 15, 0, 13, 5, 8, 4, 7, 3, 1, 2, 10, 14, 9, 12, 11, 6 }, - { 15, 7, 9, 1, 2, 6, 14, 13, 12, 11, 4, 0, 3, 5, 8, 10 }, - { 15, 14, 3, 12, 11, 10, 0, 9, 5, 8, 6, 7, 13, 1, 2, 4 } -}; static const uint8_t ADDRESS_REORDERING_GEORGE[4][16] = { { 15, 7, 13, 1, 11, 10, 14, 9, 12, 2, 4, 0, 3, 5, 8, 6 }, { 15, 14, 3, 12, 8, 4, 0, 13, 5, 11, 6, 7, 9, 1, 2, 10 }, { 15, 0, 9, 5, 2, 6, 7, 3, 1, 8, 10, 14, 13, 12, 11, 4 } }; +static const uint8_t ADDRESS_REORDERING_ALTERNATE[4][16] = { + { 15, 0, 13, 5, 8, 4, 7, 3, 1, 2, 10, 14, 9, 12, 11, 6 }, + { 15, 7, 9, 1, 2, 6, 14, 13, 12, 11, 4, 0, 3, 5, 8, 10 }, + { 15, 14, 3, 12, 11, 10, 0, 9, 5, 8, 6, 7, 13, 1, 2, 4 } +}; static const uint8_t VALUE_REORDERING[4][16] = { { 5, 4, 3, 2, 1, 0, 7, 6 }, { 3, 2, 1, 0, 7, 6, 5, 4 }, { 1, 0, 7, 6, 5, 4, 3, 2 } }; -static const uint8_t VALUE_REORDERING_ALTERNATE[4][16] = { - { 5, 4, 7, 2, 1, 0, 3, 6 }, - { 1, 2, 3, 0, 5, 6, 7, 4 }, - { 3, 0, 1, 6, 7, 4, 5, 2 } -}; static const uint8_t VALUE_REORDERING_GEORGE[4][16] = { { 3, 0, 7, 2, 1, 4, 5, 6 }, { 1, 4, 3, 0, 5, 6, 7, 2 }, { 5, 2, 1, 6, 7, 0, 3, 4 } }; +static const uint8_t VALUE_REORDERING_ALTERNATE[4][16] = { + { 5, 4, 7, 2, 1, 0, 3, 6 }, + { 1, 2, 3, 0, 5, 6, 7, 4 }, + { 3, 0, 1, 6, 7, 4, 5, 2 } +}; static const int8_t MODE_CHANGE_START_SEQUENCE[5] = { 0x99, 0x02, 0x05, 0x02, 0x03 }; static const int8_t MODE_CHANGE_END_SEQUENCE[5] = { 0x99, 0x03, 0x62, 0x02, 0x56 }; @@ -60,7 +59,7 @@ void GBAVFameInit(struct GBAVFameCart* cart) { cart->acceptingModeChange = false; } -void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize) { +void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize, uint32_t crc32) { cart->cartType = VFAME_NO; // The initialisation code is also present & run in the dumps of Digimon Ruby & Sapphire from hacked/deprotected reprint carts, @@ -82,11 +81,10 @@ void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize) { if (memcmp("George Sango", &((struct GBACartridge*) rom)->title, 12) == 0) { cart->cartType = VFAME_GEORGE; mLOG(GBA_MEM, INFO, "George mode"); - } - // Chinese version of Digimon Sapphire; header is identical to the English version which uses the normal reordering - // so we have to use some other way to detect it - else if (doCrc32(rom, romSize) == 0x793A328F) { - cart->cartType = VFAME_STANDARD; + } else if (crc32 == DIGIMON_SAPPHIRE_CHINESE_CRC32) { + // Chinese version of Digimon Sapphire; header is identical to the English version which uses the normal reordering + // so we have to use some other way to detect it + cart->cartType = VFAME_ALTERNATE; } } diff --git a/src/gba/gba.c b/src/gba/gba.c index 6e1fb8923..0ceb8209a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -493,7 +493,7 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) { gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); } GBAHardwareInit(&gba->memory.hw, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); - GBAVFameDetect(&gba->memory.vfame, gba->memory.rom, gba->memory.romSize); + GBAVFameDetect(&gba->memory.vfame, gba->memory.rom, gba->memory.romSize, gba->romCrc32); // TODO: error check return true; } From ab0194fb49b24a45181acbc7c538a3499d0e17ab Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2024 03:08:21 -0700 Subject: [PATCH 217/336] GB MBC: Switch Pocket Cam to using standard color conversion methods --- src/gb/mbc/pocket-cam.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/gb/mbc/pocket-cam.c b/src/gb/mbc/pocket-cam.c index c587dfa6a..0eab34aba 100644 --- a/src/gb/mbc/pocket-cam.c +++ b/src/gb/mbc/pocket-cam.c @@ -95,39 +95,32 @@ void _GBPocketCamCapture(struct GBMemory* memory) { case mCOLOR_XRGB8: case mCOLOR_ARGB8: case mCOLOR_ABGR8: - color = ((const uint32_t*) image)[y * stride + x]; - gray = (color & 0xFF) + ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF); - break; case mCOLOR_BGRX8: case mCOLOR_RGBX8: case mCOLOR_RGBA8: case mCOLOR_BGRA8: color = ((const uint32_t*) image)[y * stride + x]; - gray = ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF) + ((color >> 24) & 0xFF); break; case mCOLOR_BGR5: case mCOLOR_RGB5: case mCOLOR_ARGB5: case mCOLOR_ABGR5: - color = ((const uint16_t*) image)[y * stride + x]; - gray = ((color << 3) & 0xF8) + ((color >> 2) & 0xF8) + ((color >> 7) & 0xF8); - break; case mCOLOR_BGR565: case mCOLOR_RGB565: - color = ((const uint16_t*) image)[y * stride + x]; - gray = ((color << 3) & 0xF8) + ((color >> 3) & 0xFC) + ((color >> 8) & 0xF8); - break; case mCOLOR_BGRA5: case mCOLOR_RGBA5: color = ((const uint16_t*) image)[y * stride + x]; - gray = ((color << 2) & 0xF8) + ((color >> 3) & 0xF8) + ((color >> 8) & 0xF8); + break; + case mCOLOR_L8: + color = ((const uint8_t*) image)[y * stride + x]; break; default: mLOG(GB_MBC, WARN, "Unsupported pixel format: %X", format); return; } uint16_t exposure = (pocketCam->registers[2] << 8) | (pocketCam->registers[3]); - gray = (gray + 1) * exposure / 0x300; + gray = mColorConvert(color, format, mCOLOR_L8); + gray = (gray + 1) * exposure / 0x100; // TODO: Additional processing int matrixEntry = 3 * ((x & 3) + 4 * (y & 3)); if (gray < pocketCam->registers[matrixEntry + 6]) { From 3837ea8444d84a90720a54eb81e9484dfb4c10c1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2024 23:20:52 -0700 Subject: [PATCH 218/336] GB Debugger: Fix file formatting --- src/gb/debugger/debugger.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gb/debugger/debugger.c b/src/gb/debugger/debugger.c index cc05bb7a5..1a3743e42 100644 --- a/src/gb/debugger/debugger.c +++ b/src/gb/debugger/debugger.c @@ -3,14 +3,14 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - #include +#include - #include - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include +#include static const struct SM83Segment _GBSegments[] = { { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, From 745e36e6bcc6b0c2758193fe18f2b9a70a38573f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2024 23:23:13 -0700 Subject: [PATCH 219/336] GB Video: Remove leftover #include --- src/gb/video.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gb/video.c b/src/gb/video.c index 37c1e3650..38be72a5a 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include From 458300b02ec9934948d7c1e9255bde1e0c987456 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 16 Jun 2024 23:28:04 -0700 Subject: [PATCH 220/336] Core: Improve rumble emulation by averaging state over entire frame (fixes #3232) --- CHANGES | 1 + include/mgba/core/interface.h | 15 +++++++- include/mgba/internal/gb/memory.h | 1 + include/mgba/internal/gba/gba.h | 1 + src/core/interface.c | 41 ++++++++++++++++++++++ src/core/scripting.c | 15 ++++++-- src/gb/gb.c | 6 ++++ src/gb/mbc.c | 1 + src/gb/mbc/mbc.c | 4 ++- src/gb/mbc/unlicensed.c | 4 ++- src/gba/cart/gpio.c | 4 ++- src/gba/gba.c | 7 ++++ src/gba/sio/gbp.c | 5 +-- src/platform/libretro/libretro.c | 34 +++++------------- src/platform/psp2/psp2-context.c | 27 ++++----------- src/platform/qt/input/SDLInputDriver.cpp | 2 +- src/platform/sdl/main.c | 2 +- src/platform/sdl/sdl-events.c | 44 +++++++----------------- src/platform/sdl/sdl-events.h | 5 +-- src/platform/switch/main.c | 40 +++++++-------------- src/platform/wii/main.c | 5 +-- 21 files changed, 142 insertions(+), 122 deletions(-) diff --git a/CHANGES b/CHANGES index 2ff272fb6..626e9aa41 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ Other fixes: - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) + - Core: Improve rumble emulation by averaging state over entire frame (fixes mgba.io/i/3232) - GB: Prevent incompatible BIOSes from being used on differing models - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index b07f300f3..3e6261e9c 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -110,9 +110,22 @@ struct mRTCGenericState { void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core); struct mRumble { - void (*setRumble)(struct mRumble*, int enable); + void (*reset)(struct mRumble*, bool enable); + void (*setRumble)(struct mRumble*, bool enable, uint32_t sinceLast); + void (*integrate)(struct mRumble*, uint32_t period); }; +struct mRumbleIntegrator { + struct mRumble d; + bool state; + uint32_t timeOn; + uint32_t totalTime; + + void (*setRumble)(struct mRumbleIntegrator*, float value); +}; + +void mRumbleIntegratorInit(struct mRumbleIntegrator*); + struct mCoreChannelInfo { size_t id; const char* internalName; diff --git a/include/mgba/internal/gb/memory.h b/include/mgba/internal/gb/memory.h index 052a9f77e..e4b34088b 100644 --- a/include/mgba/internal/gb/memory.h +++ b/include/mgba/internal/gb/memory.h @@ -339,6 +339,7 @@ struct GBMemory { struct mRTCSource* rtc; struct mRotationSource* rotation; struct mRumble* rumble; + int32_t lastRumble; struct mImageSource* cam; }; diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index e66ac47f3..83246ff98 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -91,6 +91,7 @@ struct GBA { struct GBALuminanceSource* luminanceSource; struct mRTCSource* rtcSource; struct mRumble* rumble; + int32_t lastRumble; bool isPristine; size_t pristineRomSize; diff --git a/src/core/interface.c b/src/core/interface.c index d63754895..e5b7f8378 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -109,3 +109,44 @@ void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core) { rtc->d.serialize = _rtcGenericSerialize; rtc->d.deserialize = _rtcGenericDeserialize; } + +static void mRumbleIntegratorReset(struct mRumble* rumble, bool enable) { + struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; + integrator->state = enable; + integrator->timeOn = 0; + integrator->totalTime = 0; +} + +static void mRumbleIntegratorSetRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast) { + struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; + + if (integrator->state) { + integrator->timeOn += sinceLast; + } + integrator->totalTime += sinceLast; + integrator->state = enable; +} + +static void mRumbleIntegratorIntegrate(struct mRumble* rumble, uint32_t period) { + if (!period) { + return; + } + + struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; + if (integrator->state) { + integrator->timeOn += period - integrator->totalTime; + } + integrator->setRumble(integrator, fminf(integrator->timeOn / (float) period, 1.0f)); + + integrator->totalTime = 0; + integrator->timeOn = 0; +} + +void mRumbleIntegratorInit(struct mRumbleIntegrator* integrator) { + integrator->d.reset = mRumbleIntegratorReset; + integrator->d.setRumble = mRumbleIntegratorSetRumble; + integrator->d.integrate = mRumbleIntegratorIntegrate; + + integrator->state = false; + integrator->timeOn = 0; +} diff --git a/src/core/scripting.c b/src/core/scripting.c index 13cc403c8..ea0af459d 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -196,6 +196,7 @@ struct mScriptCoreAdapter { struct mScriptDebugger debugger; #endif struct mRumble rumble; + struct mRumbleIntegrator rumbleIntegrator; struct mRumble* oldRumble; struct mRotationSource rotation; struct mScriptValue* rotationCbTable; @@ -1165,16 +1166,22 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) mSCRIPT_DEFINE_STRUCT_CAST_TO_MEMBER(mScriptCoreAdapter, CS(mCore), _core) mSCRIPT_DEFINE_END; -static void _setRumble(struct mRumble* rumble, int enable) { +static void _setRumble(struct mRumble* rumble, bool enable, uint32_t timeSince) { struct mScriptCoreAdapter* adapter = containerof(rumble, struct mScriptCoreAdapter, rumble); if (adapter->oldRumble) { - adapter->oldRumble->setRumble(adapter->oldRumble, enable); + adapter->oldRumble->setRumble(adapter->oldRumble, enable, timeSince); } + adapter->rumbleIntegrator.d.setRumble(&adapter->rumbleIntegrator.d, enable, timeSince); +} + +static void _setRumbleFloat(struct mRumbleIntegrator* integrator, float level) { + struct mScriptCoreAdapter* adapter = containerof(integrator, struct mScriptCoreAdapter, rumbleIntegrator); + struct mScriptList args; mScriptListInit(&args, 1); - *mScriptListAppend(&args) = mSCRIPT_MAKE_BOOL(!!enable); + *mScriptListAppend(&args) = mSCRIPT_MAKE_F32(level); mScriptContextTriggerCallback(adapter->context, "rumble", &args); mScriptListDeinit(&args); } @@ -1293,6 +1300,8 @@ void mScriptContextAttachCore(struct mScriptContext* context, struct mCore* core adapter->memory.type = mSCRIPT_TYPE_MS_TABLE; adapter->memory.type->alloc(&adapter->memory); + mRumbleIntegratorInit(&adapter->rumbleIntegrator); + adapter->rumbleIntegrator.setRumble = _setRumbleFloat; adapter->rumble.setRumble = _setRumble; adapter->rotation.sample = _rotationSample; adapter->rotation.readTiltX = _rotationReadTiltX; diff --git a/src/gb/gb.c b/src/gb/gb.c index c0e966c27..c6198ed58 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -1174,6 +1174,12 @@ void GBFrameEnded(struct GB* gb) { } } + struct mRumble* rumble = gb->memory.rumble; + if (rumble && rumble->integrate) { + gb->memory.lastRumble = mTimingCurrentTime(&gb->timing); + rumble->integrate(rumble, GB_VIDEO_TOTAL_LENGTH); + } + // TODO: Move to common code if (gb->stream && gb->stream->postVideoFrame) { const color_t* pixels; diff --git a/src/gb/mbc.c b/src/gb/mbc.c index 76c005f96..c9ebed546 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -540,6 +540,7 @@ void GBMBCReset(struct GB* gb) { gb->memory.cartBus = 0xFF; gb->memory.cartBusPc = 0; gb->memory.cartBusDecay = 1; + gb->memory.lastRumble = 0; memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); GBMBCInit(gb); diff --git a/src/gb/mbc/mbc.c b/src/gb/mbc/mbc.c index 864b6e9f8..699bdb209 100644 --- a/src/gb/mbc/mbc.c +++ b/src/gb/mbc/mbc.c @@ -253,7 +253,9 @@ void _GBMBC5(struct GB* gb, uint16_t address, uint8_t value) { case 0x4: case 0x5: if (memory->mbcType == GB_MBC5_RUMBLE && memory->rumble) { - memory->rumble->setRumble(memory->rumble, (value >> 3) & 1); + int32_t currentTime = mTimingCurrentTime(&gb->timing); + memory->rumble->setRumble(memory->rumble, (value >> 3) & 1, currentTime - memory->lastRumble); + memory->lastRumble = currentTime; value &= ~8; } GBMBCSwitchSramBank(gb, value & 0xF); diff --git a/src/gb/mbc/unlicensed.c b/src/gb/mbc/unlicensed.c index 1577a15fa..950ddf074 100644 --- a/src/gb/mbc/unlicensed.c +++ b/src/gb/mbc/unlicensed.c @@ -228,7 +228,9 @@ void _GBNTOld2(struct GB* gb, uint16_t address, uint8_t value) { } if (mbcState->rumble && memory->rumble) { - memory->rumble->setRumble(memory->rumble, !!(mbcState->swapped ? value & 0x08 : value & 0x02)); + int32_t currentTime = mTimingCurrentTime(&gb->timing); + memory->rumble->setRumble(memory->rumble, !!(mbcState->swapped ? value & 0x08 : value & 0x02), currentTime - memory->lastRumble); + memory->lastRumble = currentTime; } break; } diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index 0a396f746..fde4e3714 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -354,7 +354,9 @@ void _rumbleReadPins(struct GBACartridgeHardware* hw) { return; } - rumble->setRumble(rumble, !!(hw->pinState & 8)); + int32_t currentTime = mTimingCurrentTime(&hw->p->timing); + rumble->setRumble(rumble, !!(hw->pinState & 8), currentTime - hw->p->lastRumble); + hw->p->lastRumble = currentTime; } // == Light sensor diff --git a/src/gba/gba.c b/src/gba/gba.c index 0ceb8209a..013dcad4e 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -250,6 +250,7 @@ void GBAReset(struct ARMCore* cpu) { gba->memory.romMask = toPow2(gba->memory.romSize) - 1; gba->yankedRomSize = 0; } + gba->lastRumble = 0; mTimingClear(&gba->timing); GBAMemoryReset(gba); GBAVideoReset(&gba->video); @@ -993,6 +994,12 @@ void GBAFrameEnded(struct GBA* gba) { GBASIOPlayerUpdate(gba); } + struct mRumble* rumble = gba->rumble; + if (rumble && rumble->integrate) { + gba->lastRumble = mTimingCurrentTime(&gba->timing); + rumble->integrate(rumble, VIDEO_TOTAL_LENGTH); + } + size_t c; for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) { struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c); diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index b5f987352..d992ebe2e 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -108,12 +108,13 @@ uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uin if (gbp->txPosition < 12 && gbp->txPosition > 0) { // TODO: Check expected } else if (gbp->txPosition >= 12) { - uint32_t mask = 0x33; // 0x00 = Stop // 0x11 = Hard Stop // 0x22 = Start if (gbp->p->rumble) { - gbp->p->rumble->setRumble(gbp->p->rumble, (rx & mask) == 0x22); + int32_t currentTime = mTimingCurrentTime(&gbp->p->timing); + gbp->p->rumble->setRumble(gbp->p->rumble, (rx & 0x33) == 0x22, currentTime - gbp->p->lastRumble); + gbp->p->lastRumble = currentTime; } } mTimingDeschedule(&gbp->p->timing, &gbp->event); diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index b7d7d8243..88743b63e 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -33,7 +33,6 @@ * to calculating the average for the last 180 * frames, or 3 seconds of runtime... */ #define SAMPLES_PER_FRAME_MOVING_AVG_ALPHA (1.0f / 180.0f) -#define RUMBLE_PWM 35 #define EVENT_RATE 60 #define VIDEO_WIDTH_MAX 256 @@ -54,7 +53,7 @@ static void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel lev static void _postAudioBuffer(struct mAVStream*, struct mAudioBuffer*); static void _audioRateChanged(struct mAVStream*, unsigned rate); -static void _setRumble(struct mRumble* rumble, int enable); +static void _setRumble(struct mRumbleIntegrator*, float level); static uint8_t _readLux(struct GBALuminanceSource* lux); static void _updateLux(struct GBALuminanceSource* lux); static void _updateCamera(const uint32_t* buffer, unsigned width, unsigned height, size_t pitch); @@ -77,9 +76,7 @@ static void* savedata; static struct mAVStream stream; static bool sensorsInitDone; static bool rumbleInitDone; -static int rumbleUp; -static int rumbleDown; -static struct mRumble rumble; +static struct mRumbleIntegrator rumble; static struct GBALuminanceSource lux; static struct mRotationSource rotation; static bool tiltEnabled; @@ -467,6 +464,7 @@ void retro_init(void) { // TODO: RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME when BIOS booting is supported rumbleInitDone = false; + mRumbleIntegratorInit(&rumble); rumble.setRumble = _setRumble; rumbleCallback = 0; @@ -645,18 +643,6 @@ void retro_run(void) { } } #endif - - if (rumbleCallback) { - if (rumbleUp) { - rumbleCallback(0, RETRO_RUMBLE_STRONG, rumbleUp * 0xFFFF / (rumbleUp + rumbleDown)); - rumbleCallback(0, RETRO_RUMBLE_WEAK, rumbleUp * 0xFFFF / (rumbleUp + rumbleDown)); - } else { - rumbleCallback(0, RETRO_RUMBLE_STRONG, 0); - rumbleCallback(0, RETRO_RUMBLE_WEAK, 0); - } - rumbleUp = 0; - rumbleDown = 0; - } } static void _setupMaps(struct mCore* core) { @@ -848,10 +834,8 @@ static void _setupMaps(struct mCore* core) { void retro_reset(void) { core->reset(core); + mRumbleIntegratorInit(&rumble); _setupMaps(core); - - rumbleUp = 0; - rumbleDown = 0; } bool retro_load_game(const struct retro_game_info* game) { @@ -1267,7 +1251,7 @@ static void _audioRateChanged(struct mAVStream* stream, unsigned rate) { environCallback(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info); } -static void _setRumble(struct mRumble* rumble, int enable) { +static void _setRumble(struct mRumbleIntegrator* rumble, float level) { UNUSED(rumble); if (!rumbleInitDone) { _initRumble(); @@ -1275,11 +1259,9 @@ static void _setRumble(struct mRumble* rumble, int enable) { if (!rumbleCallback) { return; } - if (enable) { - ++rumbleUp; - } else { - ++rumbleDown; - } + + rumbleCallback(0, RETRO_RUMBLE_STRONG, level * 0xFFFF); + rumbleCallback(0, RETRO_RUMBLE_WEAK, level * 0xFFFF); } static void _updateLux(struct GBALuminanceSource* lux) { diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 0f456fa7e..be9ff4495 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -36,7 +36,6 @@ #include -#define RUMBLE_PWM 8 #define CDRAM_ALIGN 0x40000 mLOG_DECLARE_CATEGORY(GUI_PSP2); @@ -64,11 +63,7 @@ static struct mSceRotationSource { struct SceMotionSensorState state; } rotation; -static struct mSceRumble { - struct mRumble d; - struct mCircleBuffer history; - int current; -} rumble; +static struct mRumbleIntegrator rumble; static struct mSceImageSource { struct mImageSource d; @@ -157,17 +152,10 @@ static int32_t _readGyroZ(struct mRotationSource* source) { return rotation->state.gyro.z * -0x8000000; } -static void _setRumble(struct mRumble* source, int enable) { - struct mSceRumble* rumble = (struct mSceRumble*) source; - rumble->current += enable; - if (mCircleBufferSize(&rumble->history) == RUMBLE_PWM) { - int8_t oldLevel; - mCircleBufferRead8(&rumble->history, &oldLevel); - rumble->current -= oldLevel; - } - mCircleBufferWrite8(&rumble->history, enable); - int small = (rumble->current << 21) / 65793; - int big = ((rumble->current * rumble->current) << 18) / 65793; +static void _setRumble(struct mRumbleIntegrator* source, float level) { + UNUSED(source); + int small = level * 255; + int big = (level * level) * 255; struct SceCtrlActuator state = { small, big @@ -363,8 +351,8 @@ void mPSP2Setup(struct mGUIRunner* runner) { rotation.d.readGyroZ = _readGyroZ; runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation.d); - rumble.d.setRumble = _setRumble; - mCircleBufferInit(&rumble.history, RUMBLE_PWM); + mRumbleIntegratorInit(&rumble); + rumble.setRumble = _setRumble; runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); camera.d.startRequestImage = _startRequestImage; @@ -509,7 +497,6 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { void mPSP2Teardown(struct mGUIRunner* runner) { UNUSED(runner); - mCircleBufferDeinit(&rumble.history); mAudioResamplerDeinit(&audioContext.resampler); mAudioBufferDeinit(&audioContext.buffer); vita2d_free_texture(tex[0]); diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index 72d148057..402b92a12 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -112,7 +112,7 @@ void SDLInputDriver::bindDefaults(InputController* controller) { mRumble* SDLInputDriver::rumble() { #if SDL_VERSION_ATLEAST(2, 0, 0) if (m_playerAttached) { - return &m_sdlPlayer.rumble.d; + return &m_sdlPlayer.rumble.d.d; } #endif return nullptr; diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index b1b850e21..4debea3ee 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -157,7 +157,7 @@ int main(int argc, char** argv) { mSDLPlayerLoadConfig(&renderer.player, mCoreConfigGetInput(&renderer.core->config)); #if SDL_VERSION_ATLEAST(2, 0, 0) - renderer.core->setPeripheral(renderer.core, mPERIPH_RUMBLE, &renderer.player.rumble.d); + renderer.core->setPeripheral(renderer.core, mPERIPH_RUMBLE, &renderer.player.rumble.d.d); #endif int ret; diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index afeedba68..ca8345d22 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -22,15 +22,14 @@ #endif #define GYRO_STEPS 100 -#define RUMBLE_PWM 16 -#define RUMBLE_STEPS 2 +#define RUMBLE_THRESHOLD 1.f / 128.f mLOG_DEFINE_CATEGORY(SDL_EVENTS, "SDL Events", "platform.sdl.events"); DEFINE_VECTOR(SDL_JoystickList, struct SDL_JoystickCombo); #if SDL_VERSION_ATLEAST(2, 0, 0) -static void _mSDLSetRumble(struct mRumble* rumble, int enable); +static void _mSDLSetRumble(struct mRumbleIntegrator* rumble, float level); #endif static int32_t _mSDLReadTiltX(struct mRotationSource* rumble); static int32_t _mSDLReadTiltY(struct mRotationSource* rumble); @@ -188,9 +187,8 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { } #if SDL_VERSION_ATLEAST(2, 0, 0) + mRumbleIntegratorInit(&player->rumble.d); player->rumble.d.setRumble = _mSDLSetRumble; - mCircleBufferInit(&player->rumble.history, RUMBLE_PWM); - player->rumble.level = 0; player->rumble.activeLevel = 0; player->rumble.p = player; #endif @@ -281,9 +279,6 @@ void mSDLDetachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { } --events->playersAttached; mCircleBufferDeinit(&player->rotation.zHistory); -#if SDL_VERSION_ATLEAST(2, 0, 0) - mCircleBufferDeinit(&player->rumble.history); -#endif } void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration* config) { @@ -701,7 +696,7 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, } #if SDL_VERSION_ATLEAST(2, 0, 0) -static void _mSDLSetRumble(struct mRumble* rumble, int enable) { +static void _mSDLSetRumble(struct mRumbleIntegrator* rumble, float level) { struct mSDLRumble* sdlRumble = (struct mSDLRumble*) rumble; if (!sdlRumble->p->joystick) { return; @@ -719,36 +714,23 @@ static void _mSDLSetRumble(struct mRumble* rumble, int enable) { } #endif - int8_t originalLevel = sdlRumble->level; - sdlRumble->level += enable; - if (mCircleBufferSize(&sdlRumble->history) == RUMBLE_PWM) { - int8_t oldLevel; - mCircleBufferRead8(&sdlRumble->history, &oldLevel); - sdlRumble->level -= oldLevel; - } - mCircleBufferWrite8(&sdlRumble->history, enable); - if (sdlRumble->level == originalLevel) { - return; - } - float activeLevel = ceil(RUMBLE_STEPS * sdlRumble->level / (float) RUMBLE_PWM) / RUMBLE_STEPS; - if (fabsf(sdlRumble->activeLevel - activeLevel) < 0.75 / RUMBLE_STEPS) { - return; - } - sdlRumble->activeLevel = activeLevel; #if SDL_VERSION_ATLEAST(2, 0, 9) - if (sdlRumble->p->joystick->controller) { - SDL_GameControllerRumble(sdlRumble->p->joystick->controller, activeLevel * 0xFFFF, activeLevel * 0xFFFF, 500); - } else { - SDL_JoystickRumble(sdlRumble->p->joystick->joystick, activeLevel * 0xFFFF, activeLevel * 0xFFFF, 500); + if (sdlRumble->activeLevel > RUMBLE_THRESHOLD || level > RUMBLE_THRESHOLD) { + if (sdlRumble->p->joystick->controller) { + SDL_GameControllerRumble(sdlRumble->p->joystick->controller, level * 0xFFFF, level * 0xFFFF, 67); + } else { + SDL_JoystickRumble(sdlRumble->p->joystick->joystick, level * 0xFFFF, level * 0xFFFF, 67); + } } #else - if (sdlRumble->activeLevel > 0.5 / RUMBLE_STEPS) { + if (sdlRumble->activeLevel > RUMBLE_THRESHOLD || level > RUMBLE_THRESHOLD) { SDL_HapticRumbleStop(sdlRumble->p->joystick->haptic); - SDL_HapticRumblePlay(sdlRumble->p->joystick->haptic, activeLevel, 500); + SDL_HapticRumblePlay(sdlRumble->p->joystick->haptic, level, 500); } else { SDL_HapticRumbleStop(sdlRumble->p->joystick->haptic); } #endif + sdlRumble->activeLevel = level; } #endif diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index 877818a01..59b7c7e92 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -71,12 +71,9 @@ struct mSDLPlayer { SDL_Window* window; struct mSDLRumble { - struct mRumble d; + struct mRumbleIntegrator d; struct mSDLPlayer* p; - - int level; float activeLevel; - struct mCircleBuffer history; } rumble; #else int newWidth; diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 9a3441b9b..c829ab9b0 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -82,9 +82,7 @@ static struct GUIFont* font; static color_t* frameBuffer; static struct mAVStream stream; static struct mSwitchRumble { - struct mRumble d; - int up; - int down; + struct mRumbleIntegrator d; HidVibrationValue value; } rumble; static struct mRotationSource rotation = {0}; @@ -298,7 +296,8 @@ static void _setup(struct mGUIRunner* runner) { } _updateRenderer(runner, fakeBool); - runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); + mRumbleIntegratorInit(&rumble.d); + runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d.d); runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation); runner->core->setAVStream(runner->core, &stream); @@ -365,12 +364,12 @@ static void _gameLoaded(struct mGUIRunner* runner) { } } - rumble.up = 0; - rumble.down = 0; + mRumbleIntegratorInit(&rumble.d); } static void _gameUnloaded(struct mGUIRunner* runner) { UNUSED(runner); + mRumbleIntegratorInit(&rumble.d); HidVibrationValue values[4]; memcpy(&values[0], &vibrationStop, sizeof(rumble.value)); memcpy(&values[1], &vibrationStop, sizeof(rumble.value)); @@ -510,24 +509,12 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { _drawTex(runner, width, height, faded, false); } - HidVibrationValue values[4]; - if (rumble.up) { - rumble.value.amp_low = rumble.up / (float) (rumble.up + rumble.down); - rumble.value.amp_high = rumble.up / (float) (rumble.up + rumble.down); - memcpy(&values[0], &rumble.value, sizeof(rumble.value)); - memcpy(&values[1], &rumble.value, sizeof(rumble.value)); - memcpy(&values[2], &rumble.value, sizeof(rumble.value)); - memcpy(&values[3], &rumble.value, sizeof(rumble.value)); - } else { - memcpy(&values[0], &vibrationStop, sizeof(rumble.value)); - memcpy(&values[1], &vibrationStop, sizeof(rumble.value)); - memcpy(&values[2], &vibrationStop, sizeof(rumble.value)); - memcpy(&values[3], &vibrationStop, sizeof(rumble.value)); - } + memcpy(&values[0], &rumble.value, sizeof(rumble.value)); + memcpy(&values[1], &rumble.value, sizeof(rumble.value)); + memcpy(&values[2], &rumble.value, sizeof(rumble.value)); + memcpy(&values[3], &rumble.value, sizeof(rumble.value)); hidSendVibrationValues(vibrationDeviceHandles, values, 4); - rumble.up = 0; - rumble.down = 0; } static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { @@ -615,13 +602,10 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buff audrvUpdate(&audrenDriver); } -void _setRumble(struct mRumble* rumble, int enable) { +void _setRumble(struct mRumbleIntegrator* rumble, float level) { struct mSwitchRumble* sr = (struct mSwitchRumble*) rumble; - if (enable) { - ++sr->up; - } else { - ++sr->down; - } + sr->value.amp_low = level; + sr->value.amp_high = level; } void _sampleRotation(struct mRotationSource* source) { diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 55bae9738..f05e00897 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -79,7 +79,7 @@ static void _retraceCallback(u32 count); static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer*); static void _audioRateChanged(struct mAVStream* stream, unsigned); static void _audioDMA(void); -static void _setRumble(struct mRumble* rumble, int enable); +static void _setRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast); static void _sampleRotation(struct mRotationSource* source); static int32_t _readTiltX(struct mRotationSource* source); static int32_t _readTiltY(struct mRotationSource* source); @@ -1722,8 +1722,9 @@ void _incrementScreenMode(struct mGUIRunner* runner) { } } -void _setRumble(struct mRumble* rumble, int enable) { +void _setRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast) { UNUSED(rumble); + UNUSED(sinceLast); WPAD_Rumble(0, enable); if (enable) { PAD_ControlMotor(0, PAD_MOTOR_RUMBLE); From 2ea11feda65c7b632c78a8f0ecca565aaf4ad9ac Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 17 Jun 2024 02:27:31 -0700 Subject: [PATCH 221/336] GBA Memory: Improve VRAM access stall cycle estimation --- CHANGES | 1 + include/mgba/internal/gba/video.h | 8 ++- src/gba/memory.c | 80 +++++++++++++++++++++------- src/gba/video.c | 86 +++++++++++++++++++++++++++++-- 4 files changed, 151 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index 626e9aa41..6119069f3 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - GBA Audio: Remove broken XQ audio pending rewrite + - GBA Memory: Improve VRAM access stall cycle estimation - GBA Video: Add special circlular window handling in OpenGL renderer - Libretro: Add Super Game Boy Color support (closes mgba.io/i/3188) - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 5b12d1541..b29b3d607 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -16,6 +16,12 @@ CXX_GUARD_START mLOG_DECLARE_CATEGORY(GBA_VIDEO); +#define GBA_VSTALL_T4(X) (0x011 << (X)) +#define GBA_VSTALL_T8(X) (0x010 << (X)) +#define GBA_VSTALL_A2 0x100 +#define GBA_VSTALL_A3 0x200 +#define GBA_VSTALL_B 0x400 + enum { VIDEO_HBLANK_PIXELS = 68, VIDEO_HDRAW_LENGTH = 1008, @@ -208,7 +214,7 @@ struct GBAVideo { struct mTimingEvent event; int vcount; - int shouldStall; + unsigned stallMask; uint16_t palette[512]; uint16_t* vram; diff --git a/src/gba/memory.c b/src/gba/memory.c index 4c72ca80e..62b26b1e3 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -401,7 +401,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) { LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \ } \ ++wait; \ - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ wait += GBAMemoryStallVRAM(gba, wait, 1); \ } @@ -561,7 +561,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { } else { LOAD_16(value, address & 0x0001FFFE, gba->video.vram); } - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -676,7 +676,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { } else { value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF]; } - if (gba->video.shouldStall) { + if (gba->video.stallMask) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -781,7 +781,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { } \ } \ ++wait; \ - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ wait += GBAMemoryStallVRAM(gba, wait, 1); \ } @@ -908,7 +908,7 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); } } - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -1038,7 +1038,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo gba->video.renderer->vram[(address & 0x1FFFE) >> 1] = ((uint8_t) value) | (value << 8); gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); } - if (gba->video.shouldStall) { + if (gba->video.stallMask) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -1778,20 +1778,64 @@ int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait) { } int32_t GBAMemoryStallVRAM(struct GBA* gba, int32_t wait, int extra) { - UNUSED(extra); - // TODO - uint16_t dispcnt = gba->memory.io[GBA_REG(DISPCNT)]; - int32_t stall = 0; - switch (GBARegisterDISPCNTGetMode(dispcnt)) { - case 2: - if (GBARegisterDISPCNTIsBg2Enable(dispcnt) && GBARegisterDISPCNTIsBg3Enable(dispcnt)) { - // If both backgrounds are enabled, VRAM access is entirely blocked during hdraw - stall = mTimingUntil(&gba->timing, &gba->video.event); + static const uint16_t stallLUT[32] = { + GBA_VSTALL_T4(0) | GBA_VSTALL_A3, + GBA_VSTALL_T4(1) | GBA_VSTALL_A3, + GBA_VSTALL_T4(2) | GBA_VSTALL_A2, + GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T4(0) | GBA_VSTALL_A3, + GBA_VSTALL_T4(1) | GBA_VSTALL_A3, + GBA_VSTALL_T4(2) | GBA_VSTALL_A2, + GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_A3, + GBA_VSTALL_A3, + GBA_VSTALL_A2, + GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T8(0) | GBA_VSTALL_A3, + GBA_VSTALL_T8(1) | GBA_VSTALL_A3, + GBA_VSTALL_T8(2) | GBA_VSTALL_A2, + GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_A3, + GBA_VSTALL_A3, + GBA_VSTALL_A2, + GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T4(0) | GBA_VSTALL_A3, + GBA_VSTALL_T4(1) | GBA_VSTALL_A3, + GBA_VSTALL_T4(2) | GBA_VSTALL_A2, + GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_A3, + GBA_VSTALL_A3, + GBA_VSTALL_A2, + GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T8(0) | GBA_VSTALL_A3, + GBA_VSTALL_T8(1) | GBA_VSTALL_A3, + GBA_VSTALL_T8(2) | GBA_VSTALL_A2, + GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + }; + + int32_t until = mTimingUntil(&gba->timing, &gba->video.event); + int period = -until & 0x1F; + + int32_t stall = until; + + int i; + for (i = 0; i < 16; ++i) { + if (!(stallLUT[(period + i) & 0x1F] & gba->video.stallMask)) { + if (!extra) { + stall = i; + break; + } + --extra; } - break; - default: - return 0; } + stall -= wait; if (stall < 0) { return 0; diff --git a/src/gba/video.c b/src/gba/video.c index bfe556943..5a4d2c8c0 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -32,6 +32,7 @@ static void GBAVideoDummyRendererPutPixels(struct GBAVideoRenderer* renderer, si static void _startHblank(struct mTiming*, void* context, uint32_t cyclesLate); static void _startHdraw(struct mTiming*, void* context, uint32_t cyclesLate); +static unsigned _calculateStallMask(struct GBA* gba); MGBA_EXPORT const int GBAVideoObjSizes[16][2] = { { 8, 8 }, @@ -78,7 +79,7 @@ void GBAVideoReset(struct GBAVideo* video) { video->frameCounter = 0; video->frameskipCounter = 0; - video->shouldStall = 0; + video->stallMask = 0; memset(video->palette, 0, sizeof(video->palette)); memset(video->oam.raw, 0, sizeof(video->oam.raw)); @@ -149,7 +150,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) { video->p->memory.io[GBA_REG(VCOUNT)] = video->vcount; if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS) { - video->shouldStall = 1; + video->stallMask = _calculateStallMask(video->p); } GBARegisterDISPSTAT dispstat = video->p->memory.io[GBA_REG(DISPSTAT)]; @@ -214,7 +215,7 @@ void _startHblank(struct mTiming* timing, void* context, uint32_t cyclesLate) { if (GBARegisterDISPSTATIsHblankIRQ(dispstat)) { GBARaiseIRQ(video->p, GBA_IRQ_HBLANK, cyclesLate - 6); // TODO: Where does this fudge factor come from? } - video->shouldStall = 0; + video->stallMask = 0; video->p->memory.io[GBA_REG(DISPSTAT)] = dispstat; } @@ -224,6 +225,81 @@ void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value) { // TODO: Does a VCounter IRQ trigger on write? } +static unsigned _calculateStallMask(struct GBA* gba) { + unsigned mask = 0; + + unsigned dispcnt = gba->memory.io[GBA_REG(DISPCNT)]; + switch (GBARegisterDISPCNTGetMode(dispcnt)) { + case 0: + if (GBARegisterDISPCNTIsBg0Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG0CNT)])) { + mask |= GBA_VSTALL_T8(0); + } else { + mask |= GBA_VSTALL_T4(0); + } + } + if (GBARegisterDISPCNTIsBg1Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG1CNT)])) { + mask |= GBA_VSTALL_T8(1); + } else { + mask |= GBA_VSTALL_T4(1); + } + } + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG2CNT)])) { + mask |= GBA_VSTALL_T8(2); + } else { + mask |= GBA_VSTALL_T4(2); + } + } + if (GBARegisterDISPCNTIsBg3Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG3CNT)])) { + mask |= GBA_VSTALL_T8(3); + } else { + mask |= GBA_VSTALL_T4(3); + } + } + break; + case 1: + if (GBARegisterDISPCNTIsBg0Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG0CNT)])) { + mask |= GBA_VSTALL_T8(0); + } else { + mask |= GBA_VSTALL_T4(0); + } + } + if (GBARegisterDISPCNTIsBg1Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG1CNT)])) { + mask |= GBA_VSTALL_T8(1); + } else { + mask |= GBA_VSTALL_T4(1); + } + } + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + mask |= GBA_VSTALL_A2; + } + break; + case 2: + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + mask |= GBA_VSTALL_A2; + } + if (GBARegisterDISPCNTIsBg3Enable(dispcnt)) { + mask |= GBA_VSTALL_A3; + } + break; + case 3: + case 4: + case 5: + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + mask |= GBA_VSTALL_B; + } + break; + default: + break; + } + return mask; +} + static void GBAVideoDummyRendererInit(struct GBAVideoRenderer* renderer) { UNUSED(renderer); // Nothing to do @@ -353,7 +429,7 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState } LOAD_32(video->frameCounter, 0, &state->video.frameCounter); - video->shouldStall = 0; + video->stallMask = 0; int32_t flags; LOAD_32(flags, 0, &state->video.flags); GBARegisterDISPSTAT dispstat = state->io[GBA_REG(DISPSTAT)]; @@ -370,7 +446,7 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState break; case 2: video->event.callback = _startHblank; - video->shouldStall = 1; + video->stallMask = _calculateStallMask(video->p); break; case 3: video->event.callback = _startHdraw; From 9318e9b2cb1c019e8862755c0aad5675405648de Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2024 02:20:36 -0700 Subject: [PATCH 222/336] All: Clean up how assertions are done --- include/mgba-util/common.h | 20 ++++++++++++++++ src/core/tile-cache.c | 10 ++------ src/gba/gba.c | 13 +++-------- src/script/canvas.c | 6 ++--- src/script/context.c | 4 +--- src/script/types.c | 13 ++++------- src/util/audio-resampler.c | 4 +--- src/util/circle-buffer.c | 48 +++++++------------------------------- src/util/sfo.c | 4 +--- src/util/vfs/vfs-zip.c | 4 +--- 10 files changed, 43 insertions(+), 83 deletions(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index d91a6557c..c5008e01f 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -314,6 +314,26 @@ typedef intptr_t ssize_t; #define ROR(I, ROTATE) ((((uint32_t) (I)) >> ROTATE) | ((uint32_t) (I) << ((-ROTATE) & 31))) +#define mASSERT(COND) \ + if (!(COND)) { \ + abort(); \ + } +#define mASSERT_DEBUG(COND) assert((COND)) + +#define mASSERT_LOG(CAT, COND, ...) \ + if (!(COND)) { \ + mLOG(CAT, FATAL, __VA_ARGS__); \ + } + +#ifdef NDEBUG +#define mASSERT_DEBUG_LOG(...) +#else +#define mASSERT_DEBUG_LOG(CAT, COND, ...) \ + if (!(COND)) { \ + mLOG(CAT, FATAL, __VA_ARGS__); \ + } +#endif + CXX_GUARD_END #endif diff --git a/src/core/tile-cache.c b/src/core/tile-cache.c index 249cd0116..d9f68066c 100644 --- a/src/core/tile-cache.c +++ b/src/core/tile-cache.c @@ -197,14 +197,8 @@ static void _regenerateTile256(struct mTileCache* cache, color_t* tile, unsigned static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { if (mTileCacheConfigurationIsShouldStore(cache->config)) { unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); -#ifndef NDEBUG - if (tileId >= tiles) { - abort(); - } - if (paletteId >= 1U << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig)) { - abort(); - } -#endif + mASSERT(tileId < tiles); + mASSERT_DEBUG(paletteId < 1U << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig)); return &cache->cache[(tileId + paletteId * tiles) << 6]; } else { return cache->temporaryTile; diff --git a/src/gba/gba.c b/src/gba/gba.c index 013dcad4e..2d10f5cc9 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -339,11 +339,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { #ifdef ENABLE_DEBUGGERS gba->timing.globalCycles += cycles < nextEvent ? nextEvent : cycles; #endif -#ifndef NDEBUG - if (cycles < 0) { - mLOG(GBA, FATAL, "Negative cycles passed: %i", cycles); - } -#endif + mASSERT_DEBUG_LOG(GBA, cycles >= 0, "Negative cycles passed: %i", cycles); nextEvent = mTimingTick(&gba->timing, cycles < nextEvent ? nextEvent : cycles); } while (gba->cpuBlocked && !gba->earlyExit); @@ -353,12 +349,9 @@ static void GBAProcessEvents(struct ARMCore* cpu) { if (!gba->memory.io[GBA_REG(IME)] || !gba->memory.io[GBA_REG(IE)]) { break; } + } else { + mASSERT_DEBUG_LOG(GBA, nextEvent >= 0, "Negative cycles will pass: %i", nextEvent); } -#ifndef NDEBUG - else if (nextEvent < 0) { - mLOG(GBA, FATAL, "Negative cycles will pass: %i", nextEvent); - } -#endif if (gba->earlyExit) { break; } diff --git a/src/script/canvas.c b/src/script/canvas.c index 5e931943d..0a0ce5b80 100644 --- a/src/script/canvas.c +++ b/src/script/canvas.c @@ -157,10 +157,8 @@ static struct mScriptValue* mScriptCanvasLayerCreate(struct mScriptCanvasContext } struct mScriptCanvasLayer* layer = &context->overlays[next]; - if (layer->image) { - // This shouldn't exist yet - abort(); - } + // This shouldn't exist yet + mASSERT(!layer->image); layer->image = mImageCreate(w, h, mCOLOR_ABGR8); layer->dirty = true; diff --git a/src/script/context.c b/src/script/context.c index ab0937500..d9afd55a1 100644 --- a/src/script/context.c +++ b/src/script/context.c @@ -458,9 +458,7 @@ bool mScriptContextActivate(struct mScriptContext* context) { void mScriptContextDeactivate(struct mScriptContext* context) { #ifndef NDEBUG struct mScriptContext* threadContext = ThreadLocalGetValue(_threadContext); - if (threadContext != context) { - abort(); - } + mASSERT(threadContext == context); #endif --context->threadDepth; diff --git a/src/script/types.c b/src/script/types.c index d860d40c0..be58a43bf 100644 --- a/src/script/types.c +++ b/src/script/types.c @@ -895,9 +895,8 @@ struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type) { } void mScriptValueRef(struct mScriptValue* val) { - if (val->refs == INT_MAX) { - abort(); - } else if (val->refs == mSCRIPT_VALUE_UNREF) { + mASSERT(val->refs != INT_MAX); + if (val->refs == mSCRIPT_VALUE_UNREF) { return; } ++val->refs; @@ -1238,12 +1237,8 @@ static void _mScriptClassInit(struct mScriptTypeClass* cls, const struct mScript member->docstring = docstring; docstring = NULL; } - if (detail->info.member.type->base != mSCRIPT_TYPE_FUNCTION) { - abort(); - } - if (detail->info.member.type->details.function.parameters.count != 3) { - abort(); - } + mASSERT(detail->info.member.type->base == mSCRIPT_TYPE_FUNCTION); + mASSERT(detail->info.member.type->details.function.parameters.count == 3); HashTableInsert(&cls->setters, detail->info.member.type->details.function.parameters.entries[2]->name, member); break; case mSCRIPT_CLASS_INIT_INTERNAL: diff --git a/src/util/audio-resampler.c b/src/util/audio-resampler.c index 5b7a069e4..3b1848190 100644 --- a/src/util/audio-resampler.c +++ b/src/util/audio-resampler.c @@ -77,9 +77,7 @@ size_t mAudioResamplerProcess(struct mAudioResampler* resampler) { }; size_t read = 0; - if (resampler->source->channels > MAX_CHANNELS) { - abort(); - } + mASSERT(resampler->source->channels <= MAX_CHANNELS); while (true) { if (timestamp + resampler->highWaterMark >= mAudioBufferAvailable(resampler->source)) { diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index ec14bfc4f..cd13c082f 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -59,11 +59,7 @@ int mCircleBufferWrite8(struct mCircleBuffer* buffer, int8_t value) { buffer->writePtr = buffer->data; } buffer->size += sizeof(int8_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 1; } @@ -89,11 +85,7 @@ int mCircleBufferWrite32(struct mCircleBuffer* buffer, int32_t value) { buffer->writePtr = buffer->data; } buffer->size += sizeof(int32_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 4; } @@ -117,11 +109,7 @@ int mCircleBufferWrite16(struct mCircleBuffer* buffer, int16_t value) { buffer->writePtr = buffer->data; } buffer->size += sizeof(int16_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 2; } @@ -145,11 +133,7 @@ size_t mCircleBufferWrite(struct mCircleBuffer* buffer, const void* input, size_ } buffer->size += length; -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return length; } @@ -174,11 +158,7 @@ int mCircleBufferRead8(struct mCircleBuffer* buffer, int8_t* value) { buffer->readPtr = buffer->data; } buffer->size -= sizeof(int8_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 1; } @@ -202,11 +182,7 @@ int mCircleBufferRead16(struct mCircleBuffer* buffer, int16_t* value) { buffer->readPtr = buffer->data; } buffer->size -= sizeof(int16_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 2; } @@ -232,11 +208,7 @@ int mCircleBufferRead32(struct mCircleBuffer* buffer, int32_t* value) { buffer->readPtr = buffer->data; } buffer->size -= sizeof(int32_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 4; } @@ -267,11 +239,7 @@ size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t leng } buffer->size -= length; -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return length; } diff --git a/src/util/sfo.c b/src/util/sfo.c index 339da1d8e..97c4e3853 100644 --- a/src/util/sfo.c +++ b/src/util/sfo.c @@ -209,9 +209,7 @@ bool SfoWrite(struct Table* sfo, struct VFile* vf) { } } - if (keysSize != ALIGN4(keysOffset) || dataSize != dataOffset) { - abort(); - } + mASSERT(keysSize == ALIGN4(keysOffset) && dataSize == dataOffset); free(sortedEntries); diff --git a/src/util/vfs/vfs-zip.c b/src/util/vfs/vfs-zip.c index 65e1c1e32..bd803d7bb 100644 --- a/src/util/vfs/vfs-zip.c +++ b/src/util/vfs/vfs-zip.c @@ -309,9 +309,7 @@ ssize_t _vfzRead(struct VFile* vf, void* buffer, size_t size) { if (!vfz->buffer) { vfz->bufferSize = BLOCK_SIZE; vfz->buffer = malloc(BLOCK_SIZE); - if (vfz->readSize) { - abort(); - } + mASSERT(!vfz->readSize); } while (bytesRead < size) { From d8375a5896e9ebf2d742f884d3229c0e8e3b61d2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2024 22:30:16 -0700 Subject: [PATCH 223/336] GBA Memory: Fix affine background timing errors --- src/gba/memory.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gba/memory.c b/src/gba/memory.c index 62b26b1e3..1ddd2eb99 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1782,42 +1782,42 @@ int32_t GBAMemoryStallVRAM(struct GBA* gba, int32_t wait, int extra) { GBA_VSTALL_T4(0) | GBA_VSTALL_A3, GBA_VSTALL_T4(1) | GBA_VSTALL_A3, GBA_VSTALL_T4(2) | GBA_VSTALL_A2, - GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T4(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T4(0) | GBA_VSTALL_A3, GBA_VSTALL_T4(1) | GBA_VSTALL_A3, GBA_VSTALL_T4(2) | GBA_VSTALL_A2, - GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T4(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_A3, GBA_VSTALL_A3, GBA_VSTALL_A2, - GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T8(0) | GBA_VSTALL_A3, GBA_VSTALL_T8(1) | GBA_VSTALL_A3, GBA_VSTALL_T8(2) | GBA_VSTALL_A2, - GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T8(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_A3, GBA_VSTALL_A3, GBA_VSTALL_A2, - GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T4(0) | GBA_VSTALL_A3, GBA_VSTALL_T4(1) | GBA_VSTALL_A3, GBA_VSTALL_T4(2) | GBA_VSTALL_A2, - GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T4(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_A3, GBA_VSTALL_A3, GBA_VSTALL_A2, - GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T8(0) | GBA_VSTALL_A3, GBA_VSTALL_T8(1) | GBA_VSTALL_A3, GBA_VSTALL_T8(2) | GBA_VSTALL_A2, - GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T8(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, }; int32_t until = mTimingUntil(&gba->timing, &gba->video.event); From e8bfaa210a2fc3112d72596989c4153dcef50d34 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2024 01:16:12 -0700 Subject: [PATCH 224/336] GBA Video: Fix VRAM access stalling even during force blanking --- src/gba/video.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/gba/video.c b/src/gba/video.c index 5a4d2c8c0..63e7115c1 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -32,7 +32,7 @@ static void GBAVideoDummyRendererPutPixels(struct GBAVideoRenderer* renderer, si static void _startHblank(struct mTiming*, void* context, uint32_t cyclesLate); static void _startHdraw(struct mTiming*, void* context, uint32_t cyclesLate); -static unsigned _calculateStallMask(struct GBA* gba); +static unsigned _calculateStallMask(struct GBA* gba, unsigned dispcnt); MGBA_EXPORT const int GBAVideoObjSizes[16][2] = { { 8, 8 }, @@ -150,7 +150,8 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) { video->p->memory.io[GBA_REG(VCOUNT)] = video->vcount; if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS) { - video->stallMask = _calculateStallMask(video->p); + unsigned dispcnt = video->p->memory.io[GBA_REG(DISPCNT)]; + video->stallMask = _calculateStallMask(video->p, dispcnt); } GBARegisterDISPSTAT dispstat = video->p->memory.io[GBA_REG(DISPSTAT)]; @@ -225,10 +226,13 @@ void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value) { // TODO: Does a VCounter IRQ trigger on write? } -static unsigned _calculateStallMask(struct GBA* gba) { +static unsigned _calculateStallMask(struct GBA* gba, unsigned dispcnt) { unsigned mask = 0; - unsigned dispcnt = gba->memory.io[GBA_REG(DISPCNT)]; + if (GBARegisterDISPCNTIsForcedBlank(dispcnt)) { + return 0; + } + switch (GBARegisterDISPCNTGetMode(dispcnt)) { case 0: if (GBARegisterDISPCNTIsBg0Enable(dispcnt)) { @@ -446,7 +450,7 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState break; case 2: video->event.callback = _startHblank; - video->stallMask = _calculateStallMask(video->p); + video->stallMask = _calculateStallMask(video->p, state->io[GBA_REG(DISPCNT)]); break; case 3: video->event.callback = _startHdraw; From 1a3873da671958901e1ea26cbef7e501f7761af9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 25 Jun 2024 03:13:33 -0700 Subject: [PATCH 225/336] GBA Serialize: Fix some minor save state edge cases There are two edge cases fixed in this commit. The first one involves audio FIFO DMA state not being properly updated if the game reconfigured it between save and load. This doesn't happen often, but it could conceivably affect custom sound engines. The second case is the extremely rare case of a save state being taken directly after a DMA ending but before an open bus read. The chances of this happening are negligible, but it's still a bug regargless. --- CHANGES | 1 + include/mgba/internal/gba/serialize.h | 14 +++++++++++--- src/gba/audio.c | 12 ++++++++++++ src/gba/io.c | 2 ++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 6119069f3..132d5ae44 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Emulation fixes: - GBA: Add baseline CP0 (Wii U VC) and CP1 (DCC) implementations - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) + - GBA Serialize: Fix some minor save state edge cases - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) Other fixes: diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index 25bd170d6..b31fd0f5a 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -20,7 +20,7 @@ extern MGBA_EXPORT const uint32_t GBASavestateVersion; mLOG_DECLARE_CATEGORY(GBA_STATE); /* Savestate format: - * 0x00000 - 0x00003: Version Magic (0x01000006) + * 0x00000 - 0x00003: Version Magic (0x01000007) * 0x00004 - 0x00007: BIOS checksum (e.g. 0xBAAE187F for official BIOS) * 0x00008 - 0x0000B: ROM CRC32 * 0x0000C - 0x0000F: Master cycles @@ -107,6 +107,9 @@ mLOG_DECLARE_CATEGORY(GBA_STATE); * | 0x001E0 - 0x001E3: Last sample * | 0x001E4 - 0x001E7: Additional audio flags * | bits 0 - 3: Current sample index + * | bits 4 - 5: Channel A DMA source + * | bits 6 - 7: Channel B DMA source + * | bits 8 - 31: Reserved * | 0x001E8 - 0x001EF: Reserved * 0x001F0 - 0x001FF: Video miscellaneous state * | 0x001F0 - 0x001F3: Reserved @@ -232,7 +235,8 @@ mLOG_DECLARE_CATEGORY(GBA_STATE); * 0x00370 - 0x0037F: Audio FIFO A samples * 0x00380 - 0x0038F: Audio FIFO B samples * 0x00390 - 0x003CF: Audio rendered samples - * 0x003D0 - 0x003FF: Reserved (leave zero) + * 0x003D0 - 0x003D3: Memory bus value + * 0x003D4 - 0x003FF: Reserved (leave zero) * 0x00400 - 0x007FF: I/O memory * 0x00800 - 0x00BFF: Palette * 0x00C00 - 0x00FFF: OAM @@ -250,6 +254,8 @@ DECL_BITS(GBASerializedAudioFlags, FIFOSamplesA, 7, 3); DECL_BITFIELD(GBASerializedAudioFlags2, uint32_t); DECL_BITS(GBASerializedAudioFlags2, SampleIndex, 0, 4); +DECL_BITS(GBASerializedAudioFlags2, ChASource, 4, 2); +DECL_BITS(GBASerializedAudioFlags2, ChBSource, 6, 2); DECL_BITFIELD(GBASerializedVideoFlags, uint32_t); DECL_BITS(GBASerializedVideoFlags, Mode, 0, 2); @@ -405,7 +411,9 @@ struct GBASerializedState { struct mStereoSample currentSamples[GBA_MAX_SAMPLES]; - uint32_t reserved[12]; + uint32_t bus; + + uint32_t reserved[11]; uint16_t io[GBA_SIZE_IO >> 1]; uint16_t pram[GBA_SIZE_PALETTE_RAM >> 1]; diff --git a/src/gba/audio.c b/src/gba/audio.c index e6b495382..aca2f2765 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -475,6 +475,10 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* GBASerializedAudioFlags2 flags2 = 0; flags2 = GBASerializedAudioFlags2SetSampleIndex(flags2, audio->sampleIndex); + // This flag was introduced in 0.11 and will only ever be 0, 1 or 2, so we + // add 1 and use a non-zero value to mark its presence in the state file + flags2 = GBASerializedAudioFlags2SetChASource(flags2, audio->chA.dmaSource + 1); + flags2 = GBASerializedAudioFlags2SetChBSource(flags2, audio->chB.dmaSource + 1); STORE_32(flags2, 0, &state->audio.gbaFlags2); STORE_32(audio->sampleEvent.when - mTimingCurrentTime(&audio->p->timing), 0, &state->audio.nextSample); @@ -526,6 +530,14 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState GBASerializedAudioFlags2 flags2; LOAD_32(flags2, 0, &state->audio.gbaFlags2); audio->sampleIndex = GBASerializedAudioFlags2GetSampleIndex(flags2); + // This flag was introduced in 0.11 and will only ever be 0, 1 or 2, so we + // add 1 and use a non-zero value to mark its presence in the state file + if (GBASerializedAudioFlags2GetChASource(flags2) > 0) { + audio->chA.dmaSource = GBASerializedAudioFlags2GetChASource(flags2) - 1; + } + if (GBASerializedAudioFlags2GetChBSource(flags2) > 0) { + audio->chB.dmaSource = GBASerializedAudioFlags2GetChBSource(flags2) - 1; + } uint32_t when; LOAD_32(when, 0, &state->audio.nextSample); diff --git a/src/gba/io.c b/src/gba/io.c index 184146511..397eb9253 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -941,6 +941,7 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) { STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister); STORE_32(gba->dmaPC, 0, &state->dmaBlockPC); + STORE_32(gba->bus, 0, &state->bus); GBAHardwareSerialize(&gba->memory.hw, state); } @@ -987,6 +988,7 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) { LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister); LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC); + LOAD_32(gba->bus, 0, &state->bus); GBADMAUpdate(gba); GBAHardwareDeserialize(&gba->memory.hw, state); From a4c2571d981a9aa9e71bbfd420e350ad3f65a044 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 25 Jun 2024 03:43:22 -0700 Subject: [PATCH 226/336] GBA Audio: Fix crash if audio FIFOs and timers get out of sync --- CHANGES | 1 + src/gba/audio.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 132d5ae44..c73b2528b 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves + - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts diff --git a/src/gba/audio.c b/src/gba/audio.c index aca2f2765..25e400b19 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -321,6 +321,9 @@ void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) { int bits = 2 << GBARegisterSOUNDBIASGetResolution(audio->soundbias); until += 1 << (9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias)); until >>= 9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias); + if (UNLIKELY(bits < until)) { + until = bits; + } int i; for (i = bits - until; i < bits; ++i) { channel->samples[i] = channel->internalSample; From 79193b914bdd2221b7d5222ab64750d54fccb339 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 25 Jun 2024 04:08:47 -0700 Subject: [PATCH 227/336] GBA Audio: Fix crash in audio subsampling if timing lockstep breaks --- CHANGES | 1 + include/mgba/internal/gba/audio.h | 2 +- src/gba/audio.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c73b2528b..a0b87e214 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Other fixes: - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves - GBA Audio: Fix crash if audio FIFOs and timers get out of sync + - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index 5b5db3a62..fba5090bf 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -80,7 +80,7 @@ struct GBAAudio { int32_t sampleInterval; int32_t lastSample; - int sampleIndex; + unsigned sampleIndex; struct mStereoSample currentSamples[GBA_MAX_SAMPLES]; bool forceDisableChA; diff --git a/src/gba/audio.c b/src/gba/audio.c index 25e400b19..a6ebafbae 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -232,6 +232,9 @@ void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) { if (oldSampleInterval != audio->sampleInterval) { timestamp -= audio->lastSample; audio->sampleIndex = timestamp >> (9 - GBARegisterSOUNDBIASGetResolution(value)); + if (audio->sampleIndex >= GBA_MAX_SAMPLES) { + audio->sampleIndex = 0; + } if (audio->p->stream && audio->p->stream->audioRateChanged) { audio->p->stream->audioRateChanged(audio->p->stream, GBA_ARM7TDMI_FREQUENCY / audio->sampleInterval); } From a824989e5a1ecf32775d7d33a0ae47a86b28c7f4 Mon Sep 17 00:00:00 2001 From: oltolm Date: Tue, 30 Apr 2024 19:01:52 +0200 Subject: [PATCH 228/336] fix shortcuts --- src/platform/qt/KeyEditor.cpp | 49 +++++------------------------------ src/platform/qt/KeyEditor.h | 2 +- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/src/platform/qt/KeyEditor.cpp b/src/platform/qt/KeyEditor.cpp index 50702da73..818b6c703 100644 --- a/src/platform/qt/KeyEditor.cpp +++ b/src/platform/qt/KeyEditor.cpp @@ -41,7 +41,7 @@ void KeyEditor::setValue(int key) { if (m_button) { updateButtonText(); } else { - if (key < 0) { + if (key == Qt::Key_unknown) { setText(tr("---")); } else { setText(keyName(key)); @@ -78,7 +78,7 @@ void KeyEditor::setValueHat(int hat, GamepadHatEvent::Direction direction) { void KeyEditor::clearButton() { m_button = true; - setValue(-1); + setValue(Qt::Key_unknown); } void KeyEditor::clearAxis() { @@ -106,48 +106,11 @@ QSize KeyEditor::sizeHint() const { void KeyEditor::keyPressEvent(QKeyEvent* event) { if (!m_button) { - if (m_key < 0 || !m_lastKey.isActive()) { - m_key = 0; + if (!m_lastKey.isActive()) { + m_key = Qt::Key_unknown; } m_lastKey.start(KEY_TIME); - if (m_key) { - if (ShortcutController::isModifierKey(m_key)) { - switch (event->key()) { - case Qt::Key_Shift: - setValue(Qt::ShiftModifier); - break; - case Qt::Key_Control: - setValue(Qt::ControlModifier); - break; - case Qt::Key_Alt: - setValue(Qt::AltModifier); - break; - case Qt::Key_Meta: - setValue(Qt::MetaModifier); - break; - } - } - if (ShortcutController::isModifierKey(event->key())) { - switch (event->key()) { - case Qt::Key_Shift: - setValue(m_key | Qt::ShiftModifier); - break; - case Qt::Key_Control: - setValue(m_key | Qt::ControlModifier); - break; - case Qt::Key_Alt: - setValue(m_key | Qt::AltModifier); - break; - case Qt::Key_Meta: - setValue(m_key | Qt::MetaModifier); - break; - } - } else { - setValue(event->key() | (m_key & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))); - } - } else { - setValue(event->key()); - } + setValue(ShortcutController::isModifierKey(event->key()) ? event->modifiers() : event->key() | event->modifiers()); } event->accept(); } @@ -213,7 +176,7 @@ void KeyEditor::updateButtonText() { break; } } - if (m_key >= 0) { + if (m_key != Qt::Key_unknown) { std::shared_ptr gamepad; if (m_controller && m_controller->gamepadDriver()) { gamepad = m_controller->gamepadDriver()->activeGamepad(); diff --git a/src/platform/qt/KeyEditor.h b/src/platform/qt/KeyEditor.h index 93af927ac..66599ad60 100644 --- a/src/platform/qt/KeyEditor.h +++ b/src/platform/qt/KeyEditor.h @@ -57,7 +57,7 @@ private: void updateButtonText(); - int m_key = -1; + int m_key = Qt::Key_unknown; int m_axis = -1; int m_hat = -1; bool m_button = false; From 916fa1dba0a0452a0db9c870f6fe7ce2133b868a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 1 Jul 2024 00:51:15 -0700 Subject: [PATCH 229/336] CMake: Fix compile flags for docgen --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1742cb805..78fddfce4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1014,6 +1014,7 @@ endif() if(ENABLE_SCRIPTING AND BUILD_DOCGEN) add_executable(docgen ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/docgen.c) target_link_libraries(docgen ${OS_LIB} ${PLATFORM_LIBRARY} ${BINARY_NAME}) + set_target_properties(docgen PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FUNCTION_DEFINES};${FEATURE_DEFINES}") endif() if(BUILD_MAINTAINER_TOOLS) From 0a57aca1a5c6c75eb68abba79d0e487968655d4a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 1 Jul 2024 20:45:26 -0700 Subject: [PATCH 230/336] Qt: Fix closure argument types --- src/platform/qt/input/SDLInputDriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index 402b92a12..620602f03 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -159,7 +159,7 @@ void SDLInputDriver::updateGamepads() { m_gamepads.removeAt(i); --i; } - std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto b) { + std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto& b) { return a->m_index < b->m_index; }); @@ -173,7 +173,7 @@ void SDLInputDriver::updateGamepads() { } m_gamepads.append(std::make_shared(this, i)); } - std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto b) { + std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto& b) { return a->m_index < b->m_index; }); } From f394c51a750b550cbfd536ef5df12d4e168b3f59 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 1 Jul 2024 20:52:04 -0700 Subject: [PATCH 231/336] Qt: Fix some controllers with multiple players (e.g. Mayflash GC adapter) getting duplicated --- src/platform/qt/input/SDLInputDriver.cpp | 6 +++--- src/platform/qt/input/SDLInputDriver.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index 620602f03..792c84834 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -249,6 +249,7 @@ SDLGamepad::SDLGamepad(SDLInputDriver* driver, int index, QObject* parent) #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), m_guid, sizeof(m_guid)); + m_id = SDL_JoystickInstanceID(joystick); #endif } @@ -395,11 +396,10 @@ QString SDLGamepad::visibleName() const { #if SDL_VERSION_ATLEAST(2, 0, 0) bool SDLGamepad::updateIndex() { - char guid[34]; for (size_t i = 0; i < SDL_JoystickListSize(&s_sdlEvents.joysticks); ++i) { SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, i)->joystick; - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), guid, sizeof(guid)); - if (memcmp(guid, m_guid, 33) == 0) { + SDL_JoystickID id = SDL_JoystickInstanceID(joystick); + if (id == m_id) { m_index = i; return true; } diff --git a/src/platform/qt/input/SDLInputDriver.h b/src/platform/qt/input/SDLInputDriver.h index 217dc40a7..70c7eed17 100644 --- a/src/platform/qt/input/SDLInputDriver.h +++ b/src/platform/qt/input/SDLInputDriver.h @@ -109,6 +109,7 @@ private: size_t m_index; #if SDL_VERSION_ATLEAST(2, 0, 0) char m_guid[34]{}; + SDL_JoystickID m_id; #endif bool verify() const; From bdffa83e6b57e879cdbe113771124f7a088e5e30 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 11:03:06 -0700 Subject: [PATCH 232/336] GB, GBA Core: Fix memory leak if reloading debug symbols Also fix loading an ELF if the current seek is not 0 --- CHANGES | 1 + src/gb/core.c | 4 +++- src/gba/core.c | 11 ++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index a0b87e214..5f82de643 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves + - GB, GBA Core: Fix memory leak if reloading debug symbols - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Memory: Let raw access read high MMIO addresses diff --git a/src/gb/core.c b/src/gb/core.c index 9dbf36bc1..4e8351fc6 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -1107,7 +1107,9 @@ static void _GBCoreDetachDebugger(struct mCore* core) { } static void _GBCoreLoadSymbols(struct mCore* core, struct VFile* vf) { - core->symbolTable = mDebuggerSymbolTableCreate(); + if (!core->symbolTable) { + core->symbolTable = mDebuggerSymbolTableCreate(); + } #ifdef ENABLE_VFS if (!vf && core->dirs.base) { vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); diff --git a/src/gba/core.c b/src/gba/core.c index 256aebdab..8e44990b5 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1243,7 +1243,14 @@ static void _GBACoreDetachDebugger(struct mCore* core) { static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { bool closeAfter = false; - core->symbolTable = mDebuggerSymbolTableCreate(); + if (!core->symbolTable) { + core->symbolTable = mDebuggerSymbolTableCreate(); + } + off_t seek; + if (vf) { + seek = vf->seek(vf, 0, SEEK_CUR); + vf->seek(vf, 0, SEEK_SET); + } #ifdef ENABLE_VFS #ifdef USE_ELF if (!vf && core->dirs.base) { @@ -1273,6 +1280,8 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { } if (closeAfter) { vf->close(vf); + } else { + vf->seek(vf, seek, SEEK_SET); } } From 5ebf3822cc22998c18acca507207f5cdeba69247 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 11:08:29 -0700 Subject: [PATCH 233/336] Debugger: Remove redundant ifdef --- src/debugger/cli-debugger.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index b5a6595d3..c21d17a72 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -1427,9 +1427,7 @@ static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv #ifdef USE_ELF struct ELF* elf = ELFOpen(vf); if (elf) { -#ifdef ENABLE_DEBUGGERS mCoreLoadELFSymbols(symbolTable, elf); -#endif ELFClose(elf); } else #endif From 4c161ff4df002e5810eb46d9af030434ca66f53e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 11:13:32 -0700 Subject: [PATCH 234/336] GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf --- CHANGES | 1 + src/gba/core.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGES b/CHANGES index 5f82de643..ff9c74489 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Other fixes: - GB, GBA Core: Fix memory leak if reloading debug symbols - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks + - GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts diff --git a/src/gba/core.c b/src/gba/core.c index 8e44990b5..6b8d15f1d 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1242,6 +1242,7 @@ static void _GBACoreDetachDebugger(struct mCore* core) { } static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { + struct GBA* gba = core->board; bool closeAfter = false; if (!core->symbolTable) { core->symbolTable = mDebuggerSymbolTableCreate(); @@ -1263,6 +1264,16 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); } #endif + if (!vf && gba->mbVf) { + vf = gba->mbVf; + seek = vf->seek(vf, 0, SEEK_CUR); + vf->seek(vf, 0, SEEK_SET); + } + if (!vf && gba->romVf) { + vf = gba->romVf; + seek = vf->seek(vf, 0, SEEK_CUR); + vf->seek(vf, 0, SEEK_SET); + } if (!vf) { return; } From 0484cd5d3162fc252720a998910ce92d0a0f2640 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 12:24:24 -0700 Subject: [PATCH 235/336] GBA: Remove unused field --- include/mgba/internal/gba/gba.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index 83246ff98..cc340d760 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -81,7 +81,6 @@ struct GBA { struct GBATimer timers[4]; - int springIRQ; struct mTimingEvent irqEvent; uint32_t biosChecksum; From 9b598d2fe4c5ae49180fd381c742e5cb8a0973f0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 11 Jul 2024 14:09:35 -0700 Subject: [PATCH 236/336] GBA Core: Fix crash after loading debug symbols (fixes #3254) --- src/gba/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gba/core.c b/src/gba/core.c index 6b8d15f1d..11b1ccfc4 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1265,11 +1265,13 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { } #endif if (!vf && gba->mbVf) { + closeAfter = false; vf = gba->mbVf; seek = vf->seek(vf, 0, SEEK_CUR); vf->seek(vf, 0, SEEK_SET); } if (!vf && gba->romVf) { + closeAfter = false; vf = gba->romVf; seek = vf->seek(vf, 0, SEEK_CUR); vf->seek(vf, 0, SEEK_SET); From d1ab52112ae82392f5afbfcd4bcf5f34f35603e8 Mon Sep 17 00:00:00 2001 From: Adam Higerd Date: Fri, 12 Jul 2024 19:15:45 -0500 Subject: [PATCH 237/336] Don't try to load non-.sym files as ARMIPS symbols --- src/gba/core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 11b1ccfc4..e05767dd6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1260,8 +1260,12 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { } #endif if (!vf && core->dirs.base) { - closeAfter = true; vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); + if (vf) { + mDebuggerLoadARMIPSSymbols(core->symbolTable, vf); + vf->close(vf); + } + return; } #endif if (!vf && gba->mbVf) { @@ -1286,11 +1290,8 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { mCoreLoadELFSymbols(core->symbolTable, elf); #endif ELFClose(elf); - } else -#endif - { - mDebuggerLoadARMIPSSymbols(core->symbolTable, vf); } +#endif if (closeAfter) { vf->close(vf); } else { From eb1b5718c3d69cc3778865a0b6b59e55a0807766 Mon Sep 17 00:00:00 2001 From: Adam Higerd Date: Fri, 12 Jul 2024 19:26:42 -0500 Subject: [PATCH 238/336] Fix misplaced return in previous PR --- src/gba/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/core.c b/src/gba/core.c index e05767dd6..1f39afea6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1264,8 +1264,8 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { if (vf) { mDebuggerLoadARMIPSSymbols(core->symbolTable, vf); vf->close(vf); + return; } - return; } #endif if (!vf && gba->mbVf) { From 09f456484cb401856d5dda1af5b80a659b7c2097 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 19 Jul 2024 19:42:38 -0700 Subject: [PATCH 239/336] GB Serialize: Prevent loading invalid states where LY >= 144 in modes other than 1 --- CHANGES | 1 + src/gb/serialize.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index ff9c74489..9af2528d9 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Other fixes: - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves - GB, GBA Core: Fix memory leak if reloading debug symbols + - GB Serialize: Prevent loading invalid states where LY >= 144 in modes other than 1 - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 0abdc1958..8f874d8eb 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -122,6 +122,13 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { mLOG(GB_STATE, WARN, "Savestate is corrupted: video y is out of range"); error = true; } + + GBSerializedVideoFlags videoFlags = state->video.flags; + if (check16 >= GB_VIDEO_VERTICAL_PIXELS && GBSerializedVideoFlagsGetMode(videoFlags) != 1) { + mLOG(GB_STATE, WARN, "Savestate is corrupted: video y is in vblank but mode is not vblank"); + error = true; + } + LOAD_16LE(ucheck16, 0, &state->memory.dmaDest); if (ucheck16 + state->memory.dmaRemaining > GB_SIZE_OAM) { mLOG(GB_STATE, WARN, "Savestate is corrupted: DMA destination is out of range"); From fde15b6e7d4fcd858ab4d59fc9e83752abe2b982 Mon Sep 17 00:00:00 2001 From: jmjoy Date: Fri, 9 Aug 2024 10:52:47 +0800 Subject: [PATCH 240/336] Remove SDL_WINDOW_OPENGL flag in mSDLSWInit --- src/platform/sdl/sw-sdl2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/sdl/sw-sdl2.c b/src/platform/sdl/sw-sdl2.c index 75ad1c2ea..734ee903c 100644 --- a/src/platform/sdl/sw-sdl2.c +++ b/src/platform/sdl/sw-sdl2.c @@ -22,7 +22,7 @@ void mSDLSWCreate(struct mSDLRenderer* renderer) { bool mSDLSWInit(struct mSDLRenderer* renderer) { unsigned width, height; renderer->core->baseVideoSize(renderer->core, &width, &height); - renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); + renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen); SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); renderer->player.window = renderer->window; renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); From ff216ad83babf27476783b14ec3131517a7aa745 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 10 Aug 2024 21:20:08 -0700 Subject: [PATCH 241/336] Res: Update nointro.dat --- res/nointro.dat | 11625 ++++++++++++++++++++++++++++------------------ 1 file changed, 7139 insertions(+), 4486 deletions(-) diff --git a/res/nointro.dat b/res/nointro.dat index d63e3f818..48047026f 100644 --- a/res/nointro.dat +++ b/res/nointro.dat @@ -1,7 +1,7 @@ clrmamepro ( name "Nintendo - Game Boy Advance" description "Nintendo - Game Boy Advance" - version 20240104-012251 + version 20240807-214821 author "aci68, Arctic Circle System, Aringon, Bent, BigFred, bikerspade, C. V. Reynolds, chillerecke, DeadSkullzJr, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, FakeShemp, Flashfire42, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, Larsenv, Lesserkuma, Madeline, MeguCocoa, Money_114, NESBrew12, niemand, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Prominos, Psychofox11, psykopat, rarenight, relax, RetroGamer, Rifu, sCZther, SonGoku, Tauwasser, Tescu, togemet2, ufocrossing, Vallaine01, Whovian9369, xprism, xuom2, zg" homepage No-Intro url "https://www.no-intro.org" @@ -597,7 +597,7 @@ game ( game ( name "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es)" description "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es)" - rom ( name "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es).gba" size 33554432 crc 0ae3637f sha1 8bc2b600a043b776bc61fe8c0f4007b4360545f9 ) + rom ( name "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es).gba" size 33554432 crc 3abc30bd sha1 1438db8336bd6204ad81011a7ed2b2e04850326a ) ) game ( @@ -648,12 +648,6 @@ game ( rom ( name "2006 FIFA World Cup - Germany 2006 (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 50ab4544 sha1 295580745787ba9593799213564484aaaa7fd463 flags verified ) ) -game ( - name "2048 Pool (World) (Aftermarket) (Unl)" - description "2048 Pool (World) (Aftermarket) (Unl)" - rom ( name "2048 Pool (World) (Aftermarket) (Unl).gba" size 203440 crc 9df6ae4f sha1 c93a9cf3502237b474e70de8dee274901ee7ecb2 ) -) - game ( name "2K Sports - Major League Baseball 2K7 (USA) (Beta)" description "2K Sports - Major League Baseball 2K7 (USA) (Beta)" @@ -711,7 +705,7 @@ game ( game ( name "3 Games in One! - Breakout + Centipede + Warlords (USA)" description "3 Games in One! - Breakout + Centipede + Warlords (USA)" - rom ( name "3 Games in One! - Breakout + Centipede + Warlords (USA).gba" size 4194304 crc 02e0cca4 sha1 e91e58c62363fb10dd4ffcaeb09c98ca6b9b5a77 ) + rom ( name "3 Games in One! - Breakout + Centipede + Warlords (USA).gba" size 4194304 crc 02e0cca4 sha1 e91e58c62363fb10dd4ffcaeb09c98ca6b9b5a77 flags verified ) ) game ( @@ -993,13 +987,13 @@ game ( game ( name "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe)" description "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe)" - rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe).gba" size 4194304 crc d59d753b sha1 16ba112f07d02484febd554f902bb18776144186 ) + rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe).gba" size 4194304 crc d59d753b sha1 16ba112f07d02484febd554f902bb18776144186 flags verified ) ) game ( name "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe)" description "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe)" - rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe).gba" size 4194304 crc 67756000 sha1 68778c93fc16d06b97462174d91035cb0d0d8bd5 ) + rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe).gba" size 4194304 crc 67756000 sha1 68778c93fc16d06b97462174d91035cb0d0d8bd5 flags verified ) ) game ( @@ -1075,9 +1069,9 @@ game ( ) game ( - name "Agoria - Ode to Fate (World) (Aftermarket) (Unl)" - description "Agoria - Ode to Fate (World) (Aftermarket) (Unl)" - rom ( name "Agoria - Ode to Fate (World) (Aftermarket) (Unl).gba" size 2725504 crc 67d3361f sha1 cb0b83b85a290c223cd3249b37ae7207d3efde06 ) + name "Agoria - Ode to Fate (World) (Unl)" + description "Agoria - Ode to Fate (World) (Unl)" + rom ( name "Agoria - Ode to Fate (World) (Unl).gba" size 2725504 crc 67d3361f sha1 cb0b83b85a290c223cd3249b37ae7207d3efde06 ) ) game ( @@ -1110,6 +1104,12 @@ game ( rom ( name "Aigle de Guerre, L' (France).gba" size 8388608 crc 36a0e152 sha1 567809bf35d62418a69e469d0cfa9993a889c030 ) ) +game ( + name "Airball (World) (v1.3) (Unl)" + description "Airball (World) (v1.3) (Unl)" + rom ( name "Airball (World) (v1.3) (Unl).gba" size 1365740 crc 52dac8c6 sha1 50c772f91fa431b8b3d01133762015e127d4f816 ) +) + game ( name "AirForce Delta II (Japan) (En,Ja,Fr,De)" description "AirForce Delta II (Japan) (En,Ja,Fr,De)" @@ -1185,7 +1185,7 @@ game ( game ( name "Alex Rider - Stormbreaker (USA)" description "Alex Rider - Stormbreaker (USA)" - rom ( name "Alex Rider - Stormbreaker (USA).gba" size 4194304 crc cca55dfd sha1 e9ba9d340701173ccd3a4d279630e1541ed96a73 ) + rom ( name "Alex Rider - Stormbreaker (USA).gba" size 4194304 crc cca55dfd sha1 e9ba9d340701173ccd3a4d279630e1541ed96a73 flags verified ) ) game ( @@ -1269,7 +1269,7 @@ game ( game ( name "American Idol (USA)" description "American Idol (USA)" - rom ( name "American Idol (USA).gba" size 16777216 crc f053ffbf sha1 13236689db1e2236673ae59c2a8ff84340a8a8c2 ) + rom ( name "American Idol (USA).gba" size 16777216 crc f053ffbf sha1 13236689db1e2236673ae59c2a8ff84340a8a8c2 flags verified ) ) game ( @@ -1302,72 +1302,6 @@ game ( rom ( name "Angelique (Japan).gba" size 4194304 crc c9d41f35 sha1 cf01dfc9f25c805b9a72524903f742f11570a8eb ) ) -game ( - name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl).gba" size 1710888 crc 3346891f sha1 270c426705df767a4ad2dc69d039842442f779b2 flags verified ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl).gba" size 1729120 crc a354d555 sha1 d7cd0ab9d622187d4ce55bf0c7f14a24ee781710 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl).gba" size 1775856 crc 41ea5b0b sha1 e351bc6a9046ec002fc2dfdee061047908bd4350 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl).gba" size 1775660 crc a234813c sha1 ad904624bf198a164ba580eea326cd30fffebac8 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl).gba" size 597104 crc 0a9098b4 sha1 0992fb6f38e49426adc834fb3831748a1caa1bc0 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl).gba" size 811840 crc 63c1cc2c sha1 faca8225ee20b8e5edb14e005af77b63c6f51446 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl).gba" size 1714000 crc eebb016f sha1 008a9d06f78bccc540ca4ece4d1982de76f95901 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl).gba" size 1710624 crc ba271987 sha1 04f1e79e79e894d8f45ed1ea2ff5aa67053f0ab3 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl).gba" size 1710624 crc df7108e3 sha1 bd267fd7e762acb8cd595e54bfd51a139864759e ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" - description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt).gba" size 1714000 crc 54ff2e56 sha1 0386315fc140db2a43a6f927c04de658bd800da9 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl).gba" size 1710952 crc cb4e2768 sha1 a7297cf4ecffc1f93f86edde68e1ff42e8099f3b ) -) - game ( name "Animal Mania - Dokidoki Aishou Check (Japan)" description "Animal Mania - Dokidoki Aishou Check (Japan)" @@ -1405,15 +1339,15 @@ game ( ) game ( - name "Another World (Europe) (En,Fr) (v2.1) (Unl)" - description "Another World (Europe) (En,Fr) (v2.1) (Unl)" - rom ( name "Another World (Europe) (En,Fr) (v2.1) (Unl).gba" size 2010358 crc 86c4f772 sha1 41d39a0c34f72469dd3fbcc90190605b8ada93e6 ) + name "Another World (World) (En,Fr) (v2.1) (Unl)" + description "Another World (World) (En,Fr) (v2.1) (Unl)" + rom ( name "Another World (World) (En,Fr) (v2.1) (Unl).gba" size 2010358 crc 86c4f772 sha1 41d39a0c34f72469dd3fbcc90190605b8ada93e6 ) ) game ( - name "Another World (Europe) (Fr) (v1.2) (Unl)" - description "Another World (Europe) (Fr) (v1.2) (Unl)" - rom ( name "Another World (Europe) (Fr) (v1.2) (Unl).gba" size 1823864 crc 1a1397de sha1 5bcc5c9a633e2226411dd41f1a191b9fcc793d92 ) + name "Another World (World) (Fr) (v1.2) (Unl)" + description "Another World (World) (Fr) (v1.2) (Unl)" + rom ( name "Another World (World) (Fr) (v1.2) (Unl).gba" size 1823864 crc 1a1397de sha1 5bcc5c9a633e2226411dd41f1a191b9fcc793d92 ) ) game ( @@ -1446,22 +1380,16 @@ game ( rom ( name "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan).gba" size 4194304 crc ad9af125 sha1 0e6c92477793ce495caa400899effb4f87384f3c ) ) -game ( - name "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" - description "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" - rom ( name "Apotris (World) (v3.4.5) (Aftermarket) (Unl).gba" size 4194304 crc 55ae4312 sha1 fb7142bcc30f71f187cc51b7fcbc5a3958374c6c ) -) - game ( name "Archer Maclean's 3D Pool (USA)" description "Archer Maclean's 3D Pool (USA)" - rom ( name "Archer Maclean's 3D Pool (USA).gba" size 4194304 crc 4202a9cd sha1 5b1dcab6984d454e3ed3f3fe107f43a645283c0f ) + rom ( name "Archer Maclean's 3D Pool (USA).gba" size 4194304 crc 4202a9cd sha1 5b1dcab6984d454e3ed3f3fe107f43a645283c0f flags verified ) ) game ( name "Arctic Tale (USA)" description "Arctic Tale (USA)" - rom ( name "Arctic Tale (USA).gba" size 4194304 crc 81397ac0 sha1 9654a5c6a40b946c35cc9e09aae48bdd47ea7692 ) + rom ( name "Arctic Tale (USA).gba" size 4194304 crc 81397ac0 sha1 9654a5c6a40b946c35cc9e09aae48bdd47ea7692 flags verified ) ) game ( @@ -1578,6 +1506,12 @@ game ( rom ( name "Atlantis - The Lost Empire (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc b3948dbc sha1 93624eaa9a80cdb791bd14955b55dd7c58c4abbd ) ) +game ( + name "Atomic Betty (USA, Europe) (Beta)" + description "Atomic Betty (USA, Europe) (Beta)" + rom ( name "Atomic Betty (USA, Europe) (Beta).gba" size 8388608 crc b79472b8 sha1 1dfa6ad1bdc0ee52b4e53c78f29d92ec208db1b1 ) +) + game ( name "Atomic Betty (USA, Europe)" description "Atomic Betty (USA, Europe)" @@ -1585,9 +1519,9 @@ game ( ) game ( - name "Atomic Betty (USA, Europe) (Beta)" - description "Atomic Betty (USA, Europe) (Beta)" - rom ( name "Atomic Betty (USA, Europe) (Beta).gba" size 8388608 crc b79472b8 sha1 1dfa6ad1bdc0ee52b4e53c78f29d92ec208db1b1 ) + name "Atomix (World) (Unl)" + description "Atomix (World) (Unl)" + rom ( name "Atomix (World) (Unl).gba" size 934600 crc fc610889 sha1 ecf3848324a25fa57988f67167f0b58e648989ce ) ) game ( @@ -1647,7 +1581,7 @@ game ( game ( name "Azumanga Daiou Advance (Japan)" description "Azumanga Daiou Advance (Japan)" - rom ( name "Azumanga Daiou Advance (Japan).gba" size 8388608 crc 216704f6 sha1 95b266e8ecdae1938cd180f597e5f21cb86d8b96 ) + rom ( name "Azumanga Daiou Advance (Japan).gba" size 8388608 crc 216704f6 sha1 95b266e8ecdae1938cd180f597e5f21cb86d8b96 flags verified ) ) game ( @@ -1737,7 +1671,7 @@ game ( game ( name "Backyard Football 2006 (USA)" description "Backyard Football 2006 (USA)" - rom ( name "Backyard Football 2006 (USA).gba" size 4194304 crc db0723e3 sha1 53d134268d2fc973388861687e50f77cc4682941 ) + rom ( name "Backyard Football 2006 (USA).gba" size 4194304 crc db0723e3 sha1 53d134268d2fc973388861687e50f77cc4682941 flags verified ) ) game ( @@ -1827,7 +1761,7 @@ game ( game ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De)" description "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De)" - rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De).gba" size 8388608 crc fb4f38e2 sha1 f335fede72cd0273fcce925a20ca272ede08c15b ) + rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De).gba" size 8388608 crc fb4f38e2 sha1 f335fede72cd0273fcce925a20ca272ede08c15b flags verified ) ) game ( @@ -1890,6 +1824,30 @@ game ( rom ( name "Barbie - The Princess and the Pauper (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 116194f2 sha1 779f2050efcd15cac8b70fedce5bd0ccb773f179 ) ) +game ( + name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-01-21)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-01-21)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-01-21).gba" size 136680 crc ae6cf631 sha1 fb0548d72eff99b7dabdd34112e55f8bea6326ec ) +) + +game ( + name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-02-18)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-02-18)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-02-18).gba" size 360672 crc bd807770 sha1 84a5686f5c5dee770e6b1bbbc1a60648387cf255 ) +) + +game ( + name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-03-18)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-03-18)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-03-18).gba" size 1502628 crc 4b58b5d6 sha1 e822173e315138443e9fec509621dc88afcbcc0b ) +) + +game ( + name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-04-15)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-04-15)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-04-15).gba" size 2837392 crc 46f21e41 sha1 74e261c56123806b8cbd31ed907fe25a5ad99b62 ) +) + game ( name "Barbie and the Magic of Pegasus (USA)" description "Barbie and the Magic of Pegasus (USA)" @@ -2046,6 +2004,18 @@ game ( rom ( name "Battle Network - Rockman EXE 2 (Japan).gba" size 8388608 crc 98e4f096 sha1 6ed31ea56328673ba9d87186a7d506c701508e28 ) ) +game ( + name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" + description "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" + rom ( name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console).gba" size 8388608 crc 44d44721 sha1 1c2416dfb86936752c5f68861f6339feac21458f ) +) + +game ( + name "Battle Network - Rockman EXE 2 (World) (Ja) (Mega Man Battle Network Legacy Collection)" + description "Battle Network - Rockman EXE 2 (World) (Ja) (Mega Man Battle Network Legacy Collection)" + rom ( name "Battle Network - Rockman EXE 2 (World) (Ja) (Mega Man Battle Network Legacy Collection).gba" size 8388608 crc 046eed8d sha1 7f6e770282718813f1115b29ec502f77422ac300 ) +) + game ( name "Battle Network - Rockman EXE 2 (Japan) (Rev 1)" description "Battle Network - Rockman EXE 2 (Japan) (Rev 1)" @@ -2053,9 +2023,9 @@ game ( ) game ( - name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" - description "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" - rom ( name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console).gba" size 8388608 crc 44d44721 sha1 1c2416dfb86936752c5f68861f6339feac21458f ) + name "Battle Network - Rockman EXE 3 (Japan) (Rev 1)" + description "Battle Network - Rockman EXE 3 (Japan) (Rev 1)" + rom ( name "Battle Network - Rockman EXE 3 (Japan) (Rev 1).gba" size 8388608 crc e48e6bc9 sha1 87e0ab10541eaaa5e9c01f7fad822a3e1bf52278 ) ) game ( @@ -2071,15 +2041,9 @@ game ( ) game ( - name "Battle Network - Rockman EXE 3 (Japan) (Rev 1)" - description "Battle Network - Rockman EXE 3 (Japan) (Rev 1)" - rom ( name "Battle Network - Rockman EXE 3 (Japan) (Rev 1).gba" size 8388608 crc e48e6bc9 sha1 87e0ab10541eaaa5e9c01f7fad822a3e1bf52278 ) -) - -game ( - name "Battle Network - Rockman EXE 3 - Black (Japan) (Promo)" - description "Battle Network - Rockman EXE 3 - Black (Japan) (Promo)" - rom ( name "Battle Network - Rockman EXE 3 - Black (Japan) (Promo).gba" size 8388608 crc 1f13c41f sha1 ff65af8fea15ecf5a556595efe414d1211a9ab4e ) + name "Battle Network - Rockman EXE 3 - Black (Japan) (Rev 1)" + description "Battle Network - Rockman EXE 3 - Black (Japan) (Rev 1)" + rom ( name "Battle Network - Rockman EXE 3 - Black (Japan) (Rev 1).gba" size 8388608 crc fd57493b sha1 e089a2254496a4791666c8122585cb785e3012fc ) ) game ( @@ -2089,9 +2053,9 @@ game ( ) game ( - name "Battle Network - Rockman EXE 3 - Black (Japan) (Rev 1)" - description "Battle Network - Rockman EXE 3 - Black (Japan) (Rev 1)" - rom ( name "Battle Network - Rockman EXE 3 - Black (Japan) (Rev 1).gba" size 8388608 crc fd57493b sha1 e089a2254496a4791666c8122585cb785e3012fc ) + name "Battle Network - Rockman EXE 3 - Black (Japan) (Promo)" + description "Battle Network - Rockman EXE 3 - Black (Japan) (Promo)" + rom ( name "Battle Network - Rockman EXE 3 - Black (Japan) (Promo).gba" size 8388608 crc 1f13c41f sha1 ff65af8fea15ecf5a556595efe414d1211a9ab4e ) ) game ( @@ -2121,7 +2085,7 @@ game ( game ( name "BattleBots - Design & Destroy (USA)" description "BattleBots - Design & Destroy (USA)" - rom ( name "BattleBots - Design & Destroy (USA).gba" size 4194304 crc 8d5ffbca sha1 635986e584ebdc347c77eb45b1370a1206fbd7d7 ) + rom ( name "BattleBots - Design & Destroy (USA).gba" size 4194304 crc 8d5ffbca sha1 635986e584ebdc347c77eb45b1370a1206fbd7d7 flags verified ) ) game ( @@ -2193,7 +2157,7 @@ game ( game ( name "Beyblade V-Force - Ultimate Blader Jam (USA)" description "Beyblade V-Force - Ultimate Blader Jam (USA)" - rom ( name "Beyblade V-Force - Ultimate Blader Jam (USA).gba" size 8388608 crc 4a49272b sha1 cd527c8c24e20e33913fc45199e64b3e6138a6e5 ) + rom ( name "Beyblade V-Force - Ultimate Blader Jam (USA).gba" size 8388608 crc 4a49272b sha1 cd527c8c24e20e33913fc45199e64b3e6138a6e5 flags verified ) ) game ( @@ -2262,6 +2226,12 @@ game ( rom ( name "Bionicle - Matoran Adventures (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc daec2264 sha1 a478f5880c484a70a5fdefc42f73aae2eb948168 flags verified ) ) +game ( + name "Bionicle - Maze of Shadows (Europe) (En,De)" + description "Bionicle - Maze of Shadows (Europe) (En,De)" + rom ( name "Bionicle - Maze of Shadows (Europe) (En,De).gba" size 8388608 crc bce2d68e sha1 7ff9811e2bd40b24da02be194213d41a0885aa34 ) +) + game ( name "Bionicle - Maze of Shadows (USA)" description "Bionicle - Maze of Shadows (USA)" @@ -2274,12 +2244,6 @@ game ( rom ( name "Bionicle - Maze of Shadows (Europe) (En,De) (Rev 1).gba" size 8388608 crc 9d66ec5e sha1 430c7dac6f7dd989294a8ac1cfdabd9e74b3e682 ) ) -game ( - name "Bionicle - Maze of Shadows (Europe) (En,De)" - description "Bionicle - Maze of Shadows (Europe) (En,De)" - rom ( name "Bionicle - Maze of Shadows (Europe) (En,De).gba" size 8388608 crc bce2d68e sha1 7ff9811e2bd40b24da02be194213d41a0885aa34 ) -) - game ( name "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" description "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" @@ -2352,6 +2316,12 @@ game ( rom ( name "Black Matrix Zero (Japan).gba" size 8388608 crc 2b2afa2e sha1 697f85513ab5704b8b1d554e087a45bfdb92ec33 ) ) +game ( + name "Black Sigil - Blade of the Exiled (USA) (Proto) (2007-02-10)" + description "Black Sigil - Blade of the Exiled (USA) (Proto) (2007-02-10)" + rom ( name "Black Sigil - Blade of the Exiled (USA) (Proto) (2007-02-10).gba" size 12478504 crc 010035a8 sha1 567e4efa496eabbf1db285e0ec02a8da8a8c07a3 ) +) + game ( name "Blackthorne (USA)" description "Blackthorne (USA)" @@ -2376,12 +2346,6 @@ game ( rom ( name "Bleach Advance - Kurenai ni Somaru Soul Society (Japan).gba" size 33554432 crc 9de5cd08 sha1 29d24c38d3ec8bbe9d81df2f5ff61c4a2dadcee4 ) ) -game ( - name "Blender Bros. (World) (Aftermarket) (Unl)" - description "Blender Bros. (World) (Aftermarket) (Unl)" - rom ( name "Blender Bros. (World) (Aftermarket) (Unl).gba" size 8388608 crc 440f2f06 sha1 8f9ca62306b7ab56d8da45673d7b7d0eb4c349c5 ) -) - game ( name "Blender Bros. (USA)" description "Blender Bros. (USA)" @@ -2415,7 +2379,7 @@ game ( game ( name "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It)" description "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It)" - rom ( name "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e5c745d8 sha1 f9a3058e55d72efdebc5e2b4d2b5d6e00e71e5ff ) + rom ( name "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e5c745d8 sha1 f9a3058e55d72efdebc5e2b4d2b5d6e00e71e5ff flags verified ) ) game ( @@ -2442,6 +2406,12 @@ game ( rom ( name "Boboboubo Boubobo - Ougi 87.5 Bakuretsu Hanage Shinken (Japan).gba" size 8388608 crc 58105f89 sha1 c93fd22bb10e26cb986161ce1cdc4c2acb38add9 ) ) +game ( + name "Boktai - The Sun Is in Your Hand (USA) (Sample)" + description "Possibly a version given out to press at E3 or an E3 demo" + rom ( name "Boktai - The Sun Is in Your Hand (USA) (Sample).gba" size 16777216 crc cf692572 sha1 f91126cd3a1bf7bf5f770d3a70229171d0d5a6ee ) +) + game ( name "Boktai - The Sun Is in Your Hand (USA)" description "Boktai - The Sun Is in Your Hand (USA)" @@ -2454,12 +2424,6 @@ game ( rom ( name "Boktai - The Sun Is in Your Hand (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 9686c36b sha1 64f7bf0f0560f6e94da33b549d3206678b29f557 flags verified ) ) -game ( - name "Boktai - The Sun Is in Your Hand (USA) (Sample)" - description "Possibly a version given out to press at E3 or an E3 demo" - rom ( name "Boktai - The Sun Is in Your Hand (USA) (Sample).gba" size 16777216 crc cf692572 sha1 f91126cd3a1bf7bf5f770d3a70229171d0d5a6ee ) -) - game ( name "Boktai 2 - Solar Boy Django (USA)" description "Boktai 2 - Solar Boy Django (USA)" @@ -2541,7 +2505,7 @@ game ( game ( name "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De)" description "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De)" - rom ( name "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De).gba" size 16777216 crc 67d2e5b8 sha1 4d514fe19b59d42be9a118c99e2008efee2aedcb ) + rom ( name "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De).gba" size 16777216 crc 67d2e5b8 sha1 4d514fe19b59d42be9a118c99e2008efee2aedcb flags verified ) ) game ( @@ -2553,7 +2517,7 @@ game ( game ( name "Bomberman Tournament (USA, Europe)" description "Bomberman Tournament (USA, Europe)" - rom ( name "Bomberman Tournament (USA, Europe).gba" size 4194304 crc 240282e6 sha1 da44a5d65f1a00d75a57e5b46e30f9e4e2d18f6c ) + rom ( name "Bomberman Tournament (USA, Europe).gba" size 4194304 crc 240282e6 sha1 da44a5d65f1a00d75a57e5b46e30f9e4e2d18f6c flags verified ) ) game ( @@ -2691,7 +2655,7 @@ game ( game ( name "Bratz - The Movie (USA)" description "Bratz - The Movie (USA)" - rom ( name "Bratz - The Movie (USA).gba" size 4194304 crc 2ef801c0 sha1 bfab6a139275b6968531a43ab34d4710e9efc7ef ) + rom ( name "Bratz - The Movie (USA).gba" size 4194304 crc 2ef801c0 sha1 bfab6a139275b6968531a43ab34d4710e9efc7ef flags verified ) ) game ( @@ -2784,12 +2748,6 @@ game ( rom ( name "Broken Circle (Europe) (En,It) (Proto).gba" size 8409344 crc e78bc690 sha1 d015a5039ff5d08eeba3ddb16470eaab259631d0 ) ) -game ( - name "Broken Circle (World) (En,It) (Aftermarket) (Unl)" - description "Broken Circle (World) (En,It) (Aftermarket) (Unl)" - rom ( name "Broken Circle (World) (En,It) (Aftermarket) (Unl).gba" size 16777216 crc 3212c09b sha1 e04a71dbe7b640cc53e81f447856e60666e64aa3 ) -) - game ( name "Broken Sword - The Shadow of the Templars (Europe) (En,Fr,De,Es,It)" description "Broken Sword - The Shadow of the Templars (Europe) (En,Fr,De,Es,It)" @@ -2805,13 +2763,13 @@ game ( game ( name "Brother Bear (USA)" description "Brother Bear (USA)" - rom ( name "Brother Bear (USA).gba" size 8388608 crc 342de1d6 sha1 89e6903500f62e11483402b76c1454af788646c0 ) + rom ( name "Brother Bear (USA).gba" size 8388608 crc 342de1d6 sha1 89e6903500f62e11483402b76c1454af788646c0 flags verified ) ) game ( name "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da)" description "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc fd814097 sha1 7e217e5f644b0333c51f3827df5fd64023ac7c0e ) + rom ( name "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc fd814097 sha1 7e217e5f644b0333c51f3827df5fd64023ac7c0e flags verified ) ) game ( @@ -2877,7 +2835,7 @@ game ( game ( name "Butt-Ugly Martians - B.K.M. Battles (USA)" description "Butt-Ugly Martians - B.K.M. Battles (USA)" - rom ( name "Butt-Ugly Martians - B.K.M. Battles (USA).gba" size 4194304 crc 74be9148 sha1 24962220f242b49231969f6d313e325148886106 ) + rom ( name "Butt-Ugly Martians - B.K.M. Battles (USA).gba" size 4194304 crc 74be9148 sha1 24962220f242b49231969f6d313e325148886106 flags verified ) ) game ( @@ -2901,7 +2859,7 @@ game ( game ( name "Cabela's Big Game Hunter (USA)" description "Cabela's Big Game Hunter (USA)" - rom ( name "Cabela's Big Game Hunter (USA).gba" size 8388608 crc 70a8a141 sha1 f6590b9f069856c1a9e43d19b4b05e3175a97e02 ) + rom ( name "Cabela's Big Game Hunter (USA).gba" size 8388608 crc 70a8a141 sha1 f6590b9f069856c1a9e43d19b4b05e3175a97e02 flags verified ) ) game ( @@ -3078,12 +3036,6 @@ game ( rom ( name "Cartoon Network Speedway (USA).gba" size 4194304 crc 066a2705 sha1 26afa157c527dcaa5a4fa0eccc772426156320d8 ) ) -game ( - name "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt)" - description "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt)" - rom ( name "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 4194304 crc ddaf8bac sha1 2321b90c04690e8e4973a4495d25c9197ab5bfcc ) -) - game ( name "Casper (USA) (En,Fr,Es)" description "Casper (USA) (En,Fr,Es)" @@ -3091,9 +3043,15 @@ game ( ) game ( - name "Castlevania (Europe) (Virtual Console)" - description "Castlevania (Europe) (Virtual Console)" - rom ( name "Castlevania (Europe) (Virtual Console).gba" size 8388608 crc dba05255 sha1 b5fa3402a8fb86786f97d08f88b3cbc790bb5d6e ) + name "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt)" + description "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt)" + rom ( name "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 4194304 crc ddaf8bac sha1 2321b90c04690e8e4973a4495d25c9197ab5bfcc ) +) + +game ( + name "Castle Master (World) (Unl)" + description "Castle Master (World) (Unl)" + rom ( name "Castle Master (World) (Unl).gba" size 259192 crc 307f7d77 sha1 bf78a4efde3b5c3bab65bd7156c69907fb86b512 ) ) game ( @@ -3102,6 +3060,12 @@ game ( rom ( name "Castlevania (Europe) (Castlevania Advance Collection).gba" size 8388608 crc 050e2164 sha1 30a2fd3fe95a8a84b02da7ddbc8b2a90e0553d9b ) ) +game ( + name "Castlevania (Europe) (Virtual Console)" + description "Castlevania (Europe) (Virtual Console)" + rom ( name "Castlevania (Europe) (Virtual Console).gba" size 8388608 crc dba05255 sha1 b5fa3402a8fb86786f97d08f88b3cbc790bb5d6e ) +) + game ( name "Castlevania (Europe)" description "Castlevania (Europe)" @@ -3138,18 +3102,6 @@ game ( rom ( name "Castlevania - Aria of Sorrow (USA) (Castlevania Advance Collection).gba" size 8388608 crc ca9b82dd sha1 f2869a861f1be637a1d1b57009cb42cc06b82e09 ) ) -game ( - name "Castlevania - Aria of Sorrow (USA) (Virtual Console)" - description "Castlevania - Aria of Sorrow (USA) (Virtual Console)" - rom ( name "Castlevania - Aria of Sorrow (USA) (Virtual Console).gba" size 8388608 crc 28baa30e sha1 b69a77970878b453e2b308fe124641f66925ae6a ) -) - -game ( - name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" - description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" - rom ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console).gba" size 8388608 crc d97dbfec sha1 458c42a6b8fd6cf18579b0f7eef9dcd12b43c12b ) -) - game ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De)" description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De)" @@ -3163,9 +3115,15 @@ game ( ) game ( - name "Castlevania - Byakuya no Concerto (Japan)" - description "Castlevania - Byakuya no Concerto (Japan)" - rom ( name "Castlevania - Byakuya no Concerto (Japan).gba" size 8388608 crc 379b3248 sha1 3aeb81ee60fa3e56a56ee069b0ce0d8bc34d9c4c ) + name "Castlevania - Aria of Sorrow (USA) (Virtual Console)" + description "Castlevania - Aria of Sorrow (USA) (Virtual Console)" + rom ( name "Castlevania - Aria of Sorrow (USA) (Virtual Console).gba" size 8388608 crc 28baa30e sha1 b69a77970878b453e2b308fe124641f66925ae6a ) +) + +game ( + name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" + description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" + rom ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console).gba" size 8388608 crc d97dbfec sha1 458c42a6b8fd6cf18579b0f7eef9dcd12b43c12b ) ) game ( @@ -3175,9 +3133,9 @@ game ( ) game ( - name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" - description "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" - rom ( name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection).gba" size 8388608 crc 14c1ab7c sha1 9483aa48b384ff3142c47fe81c13ca874a608eb0 ) + name "Castlevania - Byakuya no Concerto (Japan)" + description "Castlevania - Byakuya no Concerto (Japan)" + rom ( name "Castlevania - Byakuya no Concerto (Japan).gba" size 8388608 crc 379b3248 sha1 3aeb81ee60fa3e56a56ee069b0ce0d8bc34d9c4c ) ) game ( @@ -3192,6 +3150,12 @@ game ( rom ( name "Castlevania - Circle of the Moon (USA) (Virtual Console).gba" size 8388608 crc d5412e91 sha1 e055b4ab00e16ec39c9036ef85463c770d809c6c ) ) +game ( + name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" + description "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" + rom ( name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection).gba" size 8388608 crc 14c1ab7c sha1 9483aa48b384ff3142c47fe81c13ca874a608eb0 ) +) + game ( name "Castlevania - Harmony of Dissonance (Europe) (Castlevania Advance Collection)" description "Castlevania - Harmony of Dissonance (Europe) (Castlevania Advance Collection)" @@ -3246,12 +3210,6 @@ game ( rom ( name "Cat in the Hat, The (USA).gba" size 4194304 crc 13c2249e sha1 9340482db02bf5263429a15798d06c509017aa93 ) ) -game ( - name "Cat's Curse (World) (Aftermarket) (Unl)" - description "Cat's Curse (World) (Aftermarket) (Unl)" - rom ( name "Cat's Curse (World) (Aftermarket) (Unl).gba" size 353052 crc a35d87de sha1 4a149baad17840948c2d4ffdf068bfaf1116a024 ) -) - game ( name "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" @@ -3270,24 +3228,6 @@ game ( rom ( name "Catz (Europe) (En,Fr,De,It).gba" size 8388608 crc c3aa382d sha1 0dab5140ebc541e03dd00a8ce87cce4f0326b0e6 ) ) -game ( - name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" - description "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl).gba" size 5416932 crc f79b0d53 sha1 756f02396a150698e695ad4afd24445e2af70576 ) -) - -game ( - name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" - description "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl).gba" size 5418248 crc f5d36ad2 sha1 95a86dff641b11b4c2ed0d0fe8152c33b462d927 ) -) - -game ( - name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" - description "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl).gba" size 5418424 crc ff0e8ada sha1 08512605e5c02e81a72e24c2c8d4959d8e84e1f4 ) -) - game ( name "Chaoji Maliou 2 (China)" description "Chaoji Maliou 2 (China)" @@ -3333,19 +3273,7 @@ game ( game ( name "Cheetah Girls, The (USA)" description "Cheetah Girls, The (USA)" - rom ( name "Cheetah Girls, The (USA).gba" size 8388608 crc e2efc2aa sha1 f46296d4ab97d539dbcfa551e05ed6d58715c5b6 ) -) - -game ( - name "Chessmaster (USA)" - description "Chessmaster (USA)" - rom ( name "Chessmaster (USA).gba" size 4194304 crc 25b0e933 sha1 5e3ac500d119a2bbe67d480edc1c1dd09061e385 ) -) - -game ( - name "Chessmaster (Germany)" - description "Chessmaster (Germany)" - rom ( name "Chessmaster (Germany).gba" size 4194304 crc 06abacc5 sha1 76a69da6183239f4ab0c45ef43c3ef7e2bd96d03 ) + rom ( name "Cheetah Girls, The (USA).gba" size 8388608 crc e2efc2aa sha1 f46296d4ab97d539dbcfa551e05ed6d58715c5b6 flags verified ) ) game ( @@ -3360,6 +3288,18 @@ game ( rom ( name "Chessmaster (France).gba" size 4194304 crc 55ef8392 sha1 eb5630d7b56ebdf4609665d50bf188e3f9eac668 ) ) +game ( + name "Chessmaster (USA)" + description "Chessmaster (USA)" + rom ( name "Chessmaster (USA).gba" size 4194304 crc 25b0e933 sha1 5e3ac500d119a2bbe67d480edc1c1dd09061e385 ) +) + +game ( + name "Chessmaster (Germany)" + description "Chessmaster (Germany)" + rom ( name "Chessmaster (Germany).gba" size 4194304 crc 06abacc5 sha1 76a69da6183239f4ab0c45ef43c3ef7e2bd96d03 ) +) + game ( name "Chi Vuol Essere Milionario (Italy)" description "Chi Vuol Essere Milionario (Italy)" @@ -3414,6 +3354,12 @@ game ( rom ( name "Chinmoku no Iseki - Estpolis Gaiden (Japan) (Virtual Console).gba" size 8388608 crc 36cc41bf sha1 882cc3c71ce7025abbe0a65a2f007428887d7113 ) ) +game ( + name "Chip Advance (World) (En,Fr) (v2.1) (Unl)" + description "Chip Advance (World) (En,Fr) (v2.1) (Unl)" + rom ( name "Chip Advance (World) (En,Fr) (v2.1) (Unl).gba" size 10498128 crc 586c4345 sha1 29c889b3c25b851f590685dea03400110e98fabd ) +) + game ( name "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan)" description "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan)" @@ -3528,6 +3474,12 @@ game ( rom ( name "Cinnamoroll - Koko ni Iru yo (Japan).gba" size 4194304 crc 8376d53b sha1 f13533eb284f7321d8709df058ff28d61a031802 ) ) +game ( + name "City Connection (World) (Fr) (v1.7) (Unl)" + description "City Connection (World) (Fr) (v1.7) (Unl)" + rom ( name "City Connection (World) (Fr) (v1.7) (Unl).gba" size 1924768 crc 234a42a5 sha1 e1c6d46521310d96fedf46a39982ad1372cdc42c ) +) + game ( name "Classic NES Series - Bomberman (USA, Europe)" description "Classic NES Series - Bomberman (USA, Europe)" @@ -3573,7 +3525,7 @@ game ( game ( name "Classic NES Series - Pac-Man (USA, Europe)" description "Classic NES Series - Pac-Man (USA, Europe)" - rom ( name "Classic NES Series - Pac-Man (USA, Europe).gba" size 1048576 crc c28df82f sha1 843d853ed28a116c85a5357f9a94e9179f36a6d0 ) + rom ( name "Classic NES Series - Pac-Man (USA, Europe).gba" size 1048576 crc c28df82f sha1 843d853ed28a116c85a5357f9a94e9179f36a6d0 flags verified ) ) game ( @@ -3591,7 +3543,7 @@ game ( game ( name "Classic NES Series - Xevious (USA, Europe)" description "Classic NES Series - Xevious (USA, Europe)" - rom ( name "Classic NES Series - Xevious (USA, Europe).gba" size 1048576 crc 9cd2d5dd sha1 b2088582808480e0d70c63a777b046409d4e15c4 ) + rom ( name "Classic NES Series - Xevious (USA, Europe).gba" size 1048576 crc 9cd2d5dd sha1 b2088582808480e0d70c63a777b046409d4e15c4 flags verified ) ) game ( @@ -3624,6 +3576,12 @@ game ( rom ( name "Codename - Kids Next Door - Operation S.O.D.A. (USA).gba" size 8388608 crc 420a81b7 sha1 bbd176cc9a5331fdfdb332ad037d869610e4b3fb ) ) +game ( + name "Coin Adventure (World) (Unl)" + description "Coin Adventure (World) (Unl)" + rom ( name "Coin Adventure (World) (Unl).gba" size 677920 crc bb3a4566 sha1 088aeb8d40927969c690a66321d7006751a73e20 ) +) + game ( name "Colin McRae Rally 2.0 (Europe) (En,Fr,De)" description "Colin McRae Rally 2.0 (Europe) (En,Fr,De)" @@ -3759,7 +3717,7 @@ game ( game ( name "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA)" description "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA)" - rom ( name "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA).gba" size 33554432 crc 5940906e sha1 95b5a68962ce552a71d8212850e85d90d2844b40 ) + rom ( name "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA).gba" size 33554432 crc 9b76b90b sha1 a14854c2189516501a51d9e3fce7f10f3593fc9a ) ) game ( @@ -3777,7 +3735,7 @@ game ( game ( name "Crash Bandicoot 2 - N-Tranced (USA)" description "Crash Bandicoot 2 - N-Tranced (USA)" - rom ( name "Crash Bandicoot 2 - N-Tranced (USA).gba" size 8388608 crc 2e16184a sha1 972158859ea08aa5746ab2e0d4c81ac43728adff ) + rom ( name "Crash Bandicoot 2 - N-Tranced (USA).gba" size 8388608 crc 2e16184a sha1 972158859ea08aa5746ab2e0d4c81ac43728adff flags verified ) ) game ( @@ -3873,7 +3831,7 @@ game ( game ( name "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan)" description "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan)" - rom ( name "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan).gba" size 33554432 crc 45c84466 sha1 e17baa57d339f7d85f562441111696e88088fcdd ) + rom ( name "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan).gba" size 33554432 crc 52f463fe sha1 10aa9bd3b72ed918e7c59fdbc0cc05e5b48dcc70 ) ) game ( @@ -3966,6 +3924,18 @@ game ( rom ( name "Croket! Great - Toki no Boukensha (Japan).gba" size 16777216 crc f0e81971 sha1 410fb8fe2fe07be146c8454122d874287f92fbac ) ) +game ( + name "Cross Town Heroes (USA)" + description "Cross Town Heroes (USA)" + rom ( name "Cross Town Heroes (USA).gba" size 4194304 crc 0fffb458 sha1 6baa6bfe76b077f365bedffa52346b94689b61d7 ) +) + +game ( + name "Cross Town Heroes (Europe)" + description "Cross Town Heroes (Europe)" + rom ( name "Cross Town Heroes (Europe).gba" size 4194304 crc c9ea02f5 sha1 13310b7f25a0332a8e09e722587ec79aee11c373 ) +) + game ( name "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es)" description "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es)" @@ -3979,15 +3949,15 @@ game ( ) game ( - name "Crouching Tiger, Hidden Dragon (USA) (Beta)" - description "Crouching Tiger, Hidden Dragon (USA) (Beta)" - rom ( name "Crouching Tiger, Hidden Dragon (USA) (Beta).gba" size 8388608 crc 204ff8d5 sha1 af24d128b28758a8a1bda45b5a24a299e1e14b90 ) + name "Crouching Tiger, Hidden Dragon (USA) (Beta 2)" + description "Crouching Tiger, Hidden Dragon (USA) (Beta 2)" + rom ( name "Crouching Tiger, Hidden Dragon (USA) (Beta 2).gba" size 8388608 crc 204ff8d5 sha1 af24d128b28758a8a1bda45b5a24a299e1e14b90 ) ) game ( - name "Cruis'n Velocity (USA, Europe) (Beta)" - description "Cruis'n Velocity (USA, Europe) (Beta)" - rom ( name "Cruis'n Velocity (USA, Europe) (Beta).gba" size 8388608 crc 5436d5da sha1 d1716d4603dd8db7ae8715d5142a60230d17e1d2 ) + name "Crouching Tiger, Hidden Dragon (USA) (Beta 1)" + description "Crouching Tiger, Hidden Dragon (USA) (Beta 1)" + rom ( name "Crouching Tiger, Hidden Dragon (USA) (Beta 1).gba" size 3353604 crc a1d2d006 sha1 3d554e4e33563211865b9c5481444b0b8b4e6127 ) ) game ( @@ -3996,6 +3966,12 @@ game ( rom ( name "Cruis'n Velocity (USA, Europe).gba" size 4194304 crc adf14db5 sha1 762aabc26501dee4aa566e8327600433c8edbf7a ) ) +game ( + name "Cruis'n Velocity (USA, Europe) (Beta)" + description "Cruis'n Velocity (USA, Europe) (Beta)" + rom ( name "Cruis'n Velocity (USA, Europe) (Beta).gba" size 8388608 crc 5436d5da sha1 d1716d4603dd8db7ae8715d5142a60230d17e1d2 ) +) + game ( name "Crushed Baseball (USA)" description "Crushed Baseball (USA)" @@ -4008,18 +3984,18 @@ game ( rom ( name "CT Special Forces (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc aea22ae0 sha1 ab151206c142dbcdb4f2ea9877d6bcd2c89b8b55 ) ) -game ( - name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl)" - description "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc a20d9adb sha1 e178192ba2c78759245541bd54d96d83a8d5d9c6 flags verified ) -) - game ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl) (Beta)" description "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl) (Beta)" rom ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc 40a0e1c9 sha1 fab8b62a141865f12c69334f4db14c837d9d94af ) ) +game ( + name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl)" + description "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc a20d9adb sha1 e178192ba2c78759245541bd54d96d83a8d5d9c6 flags verified ) +) + game ( name "CT Special Forces - Back to Hell (Europe) (En,Fr,De,Es,It,Nl)" description "CT Special Forces - Back to Hell (Europe) (En,Fr,De,Es,It,Nl)" @@ -4107,7 +4083,7 @@ game ( game ( name "Dancing Sword - Senkou (Japan)" description "Dancing Sword - Senkou (Japan)" - rom ( name "Dancing Sword - Senkou (Japan).gba" size 8388608 crc e2316d47 sha1 5c5f33e0453cba1a60039160564daa53a82db8aa ) + rom ( name "Dancing Sword - Senkou (Japan).gba" size 8388608 crc e2316d47 sha1 5c5f33e0453cba1a60039160564daa53a82db8aa flags verified ) ) game ( @@ -4248,6 +4224,12 @@ game ( rom ( name "Deal or No Deal (USA).gba" size 4194304 crc b6c00edb sha1 3691000350db3b36311439c5d9c9879ee756fea6 ) ) +game ( + name "Decoder Cart (Japan) (En) (Pirate)" + description "Decoder Cart (Japan) (En) (Pirate)" + rom ( name "Decoder Cart (Japan) (En) (Pirate).gba" size 8388608 crc 80aa9cc5 sha1 20c6f5aaf8299dfcdeb76bd633f12da209625b97 ) +) + game ( name "Defender (USA)" description "Defender (USA)" @@ -4272,6 +4254,12 @@ game ( rom ( name "Defender of the Crown (Europe).gba" size 4194304 crc 6968959a sha1 4e37071533e946efd4166efc409562cc21af83d2 ) ) +game ( + name "Deflektor (World) (v1.1) (Unl)" + description "Deflektor (World) (v1.1) (Unl)" + rom ( name "Deflektor (World) (v1.1) (Unl).gba" size 386508 crc 5ec91001 sha1 92682b2404be3b2fd48f96cad0c51f51d07c8159 ) +) + game ( name "DemiKids - Dark Version (USA)" description "DemiKids - Dark Version (USA)" @@ -4338,18 +4326,18 @@ game ( rom ( name "Densetsu no Stafy 3 (Japan) (Rev 1) (Virtual Console).gba" size 16777216 crc 59ca95c6 sha1 5506cbcfa1a275441f365099822a583c80397fde ) ) -game ( - name "Densetsu no Stafy 3 (Japan)" - description "Densetsu no Stafy 3 (Japan)" - rom ( name "Densetsu no Stafy 3 (Japan).gba" size 16777216 crc fcaf1aa8 sha1 a7a742e779d314f6909f1350db2da8a63445c433 flags verified ) -) - game ( name "Densetsu no Stafy 3 (Japan) (Rev 1)" description "Densetsu no Stafy 3 (Japan) (Rev 1)" rom ( name "Densetsu no Stafy 3 (Japan) (Rev 1).gba" size 16777216 crc 2d6e4c3b sha1 dae5354bfe4ccafc92d22b1389265dbf1f79b636 ) ) +game ( + name "Densetsu no Stafy 3 (Japan)" + description "Densetsu no Stafy 3 (Japan)" + rom ( name "Densetsu no Stafy 3 (Japan).gba" size 16777216 crc fcaf1aa8 sha1 a7a742e779d314f6909f1350db2da8a63445c433 flags verified ) +) + game ( name "Derby Stallion Advance (Japan)" description "Derby Stallion Advance (Japan)" @@ -4368,12 +4356,6 @@ game ( rom ( name "Deutschland Sucht den Superstar (Germany).gba" size 16777216 crc 51f50f7d sha1 ce5253e82671569500af3d5df9d3131916fbe23d ) ) -game ( - name "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es)" - description "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es)" - rom ( name "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es).gba" size 8388608 crc f5436f5d sha1 e04dbb5e0534cf241e8fee85d17b1cc8a0032f14 ) -) - game ( name "Dexter's Laboratory - Chess Challenge (USA)" description "Dexter's Laboratory - Chess Challenge (USA)" @@ -4381,9 +4363,15 @@ game ( ) game ( - name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It)" - description "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It)" - rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e948d412 sha1 f230375ba4b0346d749e50117fe701d8c1cbfffa ) + name "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es)" + description "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es)" + rom ( name "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es).gba" size 8388608 crc f5436f5d sha1 e04dbb5e0534cf241e8fee85d17b1cc8a0032f14 ) +) + +game ( + name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" + description "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" + rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 6bf168e6 sha1 b838b5bb37bfeb3315a68b6d372f29a5de635444 flags verified ) ) game ( @@ -4393,9 +4381,9 @@ game ( ) game ( - name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" - description "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" - rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 6bf168e6 sha1 b838b5bb37bfeb3315a68b6d372f29a5de635444 flags verified ) + name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It)" + description "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It)" + rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e948d412 sha1 f230375ba4b0346d749e50117fe701d8c1cbfffa ) ) game ( @@ -4419,7 +4407,7 @@ game ( game ( name "Diddy Kong Pilot (Unknown) (Proto) (2001)" description "Diddy Kong Pilot (Unknown) (Proto) (2001)" - rom ( name "Diddy Kong Pilot (Unknown) (Proto) (2001).gba" size 7509167 crc 8903cc5f sha1 e14bfb4d63c6bd35c3a1a4aad4eb91e94d0402b3 ) + rom ( name "Diddy Kong Pilot (Unknown) (Proto) (2001).gba" size 5080644 crc 5c206101 sha1 6a76def610829ac1502afb58740e38b5e6926b3d ) ) game ( @@ -4695,7 +4683,7 @@ game ( game ( name "Dogz (USA)" description "Dogz (USA)" - rom ( name "Dogz (USA).gba" size 8388608 crc 124f27c0 sha1 462f05c18534cb22fffc65d47351a29f10a3f254 ) + rom ( name "Dogz (USA).gba" size 8388608 crc 124f27c0 sha1 462f05c18534cb22fffc65d47351a29f10a3f254 flags verified ) ) game ( @@ -4872,12 +4860,6 @@ game ( rom ( name "Donkey Kong Country 3 (USA).gba" size 16777216 crc fe03e5af sha1 c50982b4c26e25ba3538be97b585d95737d7ade7 flags verified ) ) -game ( - name "Donsol (World) (Aftermarket) (Unl)" - description "Donsol (World) (Aftermarket) (Unl)" - rom ( name "Donsol (World) (Aftermarket) (Unl).gba" size 52520 crc aec144b3 sha1 751675b0d77c341f2265b0edd38858b0dbdb7b50 ) -) - game ( name "Doom (USA, Europe)" description "Doom (USA, Europe)" @@ -4905,7 +4887,7 @@ game ( game ( name "Dora the Explorer - Super Spies (USA)" description "Dora the Explorer - Super Spies (USA)" - rom ( name "Dora the Explorer - Super Spies (USA).gba" size 4194304 crc 650fdfdb sha1 fa51e2102ce0a0e70c5db2f8776d2237c8d7db7d ) + rom ( name "Dora the Explorer - Super Spies (USA).gba" size 4194304 crc 650fdfdb sha1 fa51e2102ce0a0e70c5db2f8776d2237c8d7db7d flags verified ) ) game ( @@ -4923,7 +4905,7 @@ game ( game ( name "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA)" description "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA)" - rom ( name "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA).gba" size 4194304 crc 9439541c sha1 10d1df1cb3fd94a14fff239083968b5182772a4d ) + rom ( name "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA).gba" size 4194304 crc 9439541c sha1 10d1df1cb3fd94a14fff239083968b5182772a4d flags verified ) ) game ( @@ -5082,6 +5064,12 @@ game ( rom ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It) (Beta) (2005-02-25).gba" size 16777216 crc 2b136906 sha1 fe190755f05994f1c796286ad767d7da49c36385 ) ) +game ( + name "Dragon Ball GT - Transformation (USA) (Beta) (2005-04-27)" + description "Dragon Ball GT - Transformation (USA) (Beta) (2005-04-27)" + rom ( name "Dragon Ball GT - Transformation (USA) (Beta) (2005-04-27).gba" size 8388608 crc 431bc807 sha1 58875496c9ab89ba3b769dc47d89ac2839b7cb7f ) +) + game ( name "Dragon Ball GT - Transformation (USA)" description "Dragon Ball GT - Transformation (USA)" @@ -5178,6 +5166,18 @@ game ( rom ( name "Dragon Ball Z - The Legacy of Goku II (USA).gba" size 8388608 crc 204142e1 sha1 18e0715dec419f3501c301511530d2edcd590f8b flags verified ) ) +game ( + name "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-23)" + description "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-23)" + rom ( name "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-23).gba" size 7282372 crc 3c30f5b3 sha1 16f4c593a0ab0e243fbeca7cc1033ac88501e387 ) +) + +game ( + name "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-31)" + description "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-31)" + rom ( name "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-31).gba" size 7279012 crc 25f34dbc sha1 fc76f3477f19af7415a42a6f38bd5bda43c640d2 ) +) + game ( name "Dragon Ball Z - The Legacy of Goku II International (Japan)" description "Dragon Ball Z - The Legacy of Goku II International (Japan)" @@ -5418,6 +5418,12 @@ game ( rom ( name "Duel Masters 3 (Japan) (Rev 1).gba" size 8388608 crc d2b9cfb6 sha1 05ad843564c663a050e137ae0ec07d09f585c714 ) ) +game ( + name "Duke Nukem Advance (World) (En,Fr,De,It) (Evercade) (Unl)" + description "Duke Nukem Advance (World) (En,Fr,De,It) (Evercade) (Unl)" + rom ( name "Duke Nukem Advance (World) (En,Fr,De,It) (Evercade) (Unl).gba" size 8388608 crc 2b077058 sha1 926b6c74d408cb3ff37a5276ddc3be8e2512c0b3 ) +) + game ( name "Duke Nukem Advance (USA)" description "Duke Nukem Advance (USA)" @@ -5568,6 +5574,12 @@ game ( rom ( name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 0b2961ce sha1 5514d090d08643a07457e4698d848657ae5cd179 ) ) +game ( + name "Elements of Darkness (World) (Demo) (Unl)" + description "Elements of Darkness (World) (Demo) (Unl)" + rom ( name "Elements of Darkness (World) (Demo) (Unl).gba" size 3039348 crc 5f3b0637 sha1 f425b0a88c46bca220bf47c2067020b57e96f736 ) +) + game ( name "Elemix! (Japan)" description "Elemix! (Japan)" @@ -5599,9 +5611,9 @@ game ( ) game ( - name "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl)" - description "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl)" - rom ( name "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl).gba" size 4016344 crc e3128bcb sha1 67617136f205fa071d9fc239df09471e603c675c ) + name "Elite - The New Kind (World) (v1.7.1) (Unl)" + description "Elite - The New Kind (World) (v1.7.1) (Unl)" + rom ( name "Elite - The New Kind (World) (v1.7.1) (Unl).gba" size 546392 crc 5f9b4211 sha1 d3e6c12e6475ffb21617e3be7158d60ac535e74b ) ) game ( @@ -5637,7 +5649,7 @@ game ( game ( name "ESPN Final Round Golf 2002 (USA)" description "ESPN Final Round Golf 2002 (USA)" - rom ( name "ESPN Final Round Golf 2002 (USA).gba" size 8388608 crc c9bc75a5 sha1 ecee20b629a38bab7edbc972c70b2c968f50c23c ) + rom ( name "ESPN Final Round Golf 2002 (USA).gba" size 8388608 crc c9bc75a5 sha1 ecee20b629a38bab7edbc972c70b2c968f50c23c flags verified ) ) game ( @@ -5985,7 +5997,7 @@ game ( game ( name "F24 Stealth Fighter (USA)" description "F24 Stealth Fighter (USA)" - rom ( name "F24 Stealth Fighter (USA).gba" size 4194304 crc 9387ea7c sha1 ac9188c7836dd388b488d02e8774dc61b1d30b4a ) + rom ( name "F24 Stealth Fighter (USA).gba" size 4194304 crc 9387ea7c sha1 ac9188c7836dd388b488d02e8774dc61b1d30b4a flags verified ) ) game ( @@ -6165,7 +6177,7 @@ game ( game ( name "Famicom Mini 22 - Nazo no Murasame Jou (Japan)" description "Famicom Mini 22 - Nazo no Murasame Jou (Japan)" - rom ( name "Famicom Mini 22 - Nazo no Murasame Jou (Japan).gba" size 4194304 crc 8233349c sha1 0100d4e94c30adf73cd6082b89911dedf723ecd5 ) + rom ( name "Famicom Mini 22 - Nazo no Murasame Jou (Japan).gba" size 4194304 crc 8233349c sha1 0100d4e94c30adf73cd6082b89911dedf723ecd5 flags verified ) ) game ( @@ -6321,7 +6333,7 @@ game ( game ( name "Fear Factor - Unleashed (USA)" description "Fear Factor - Unleashed (USA)" - rom ( name "Fear Factor - Unleashed (USA).gba" size 8388608 crc 1289639c sha1 bf933c51bdcb52ae54d518e80129c687b751f836 ) + rom ( name "Fear Factor - Unleashed (USA).gba" size 8388608 crc bf91c27d sha1 d6f60f7d1707dca21c61f50db2b6324b7d680012 ) ) game ( @@ -6367,15 +6379,15 @@ game ( ) game ( - name "FILA Decathlon (Europe) (Beta)" - description "FILA Decathlon (Europe) (Beta)" - rom ( name "FILA Decathlon (Europe) (Beta).gba" size 4194304 crc 07434e3a sha1 1dc940dda8da59ade503c1e8901a0e44285f4e9b ) + name "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv)" + description "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv)" + rom ( name "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv).gba" size 4194304 crc 628355b5 sha1 41efd4b2fc8be52a12aadd1e4bf696fcc98230ca flags verified ) ) game ( - name "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv)" - description "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv)" - rom ( name "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv).gba" size 4194304 crc 628355b5 sha1 41efd4b2fc8be52a12aadd1e4bf696fcc98230ca ) + name "FILA Decathlon (Europe) (Beta)" + description "FILA Decathlon (Europe) (Beta)" + rom ( name "FILA Decathlon (Europe) (Beta).gba" size 4194304 crc 07434e3a sha1 1dc940dda8da59ade503c1e8901a0e44285f4e9b ) ) game ( @@ -6438,24 +6450,6 @@ game ( rom ( name "Final Fantasy Tactics Advance (USA) (Virtual Console).gba" size 16777216 crc 5964df89 sha1 3ca7cffe302e733501a4777a576928ea159b89e4 ) ) -game ( - name "Final Fantasy Tactics Advance (USA)" - description "Final Fantasy Tactics Advance (USA)" - rom ( name "Final Fantasy Tactics Advance (USA).gba" size 16777216 crc 5645e56c sha1 4ac05441f4de70a4ec3dd932116346c61b8783d9 flags verified ) -) - -game ( - name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It)" - description "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ba5de047 sha1 9efaf328cbbcbc830be14940e42e4b92d90dfb58 flags verified ) -) - -game ( - name "Final Fantasy Tactics Advance (Japan)" - description "Final Fantasy Tactics Advance (Japan)" - rom ( name "Final Fantasy Tactics Advance (Japan).gba" size 16777216 crc a57b0034 sha1 fa9d23ee88c7fe24374337aca03eb864b5b991f4 flags verified ) -) - game ( name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It) (Virtual Console)" description "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It) (Virtual Console)" @@ -6468,6 +6462,24 @@ game ( rom ( name "Final Fantasy Tactics Advance (Japan) (Virtual Console).gba" size 16777216 crc ee31422a sha1 8e90027e0831b27fa174e446e6a773f2a421aed1 ) ) +game ( + name "Final Fantasy Tactics Advance (Japan)" + description "Final Fantasy Tactics Advance (Japan)" + rom ( name "Final Fantasy Tactics Advance (Japan).gba" size 16777216 crc a57b0034 sha1 fa9d23ee88c7fe24374337aca03eb864b5b991f4 flags verified ) +) + +game ( + name "Final Fantasy Tactics Advance (USA)" + description "Final Fantasy Tactics Advance (USA)" + rom ( name "Final Fantasy Tactics Advance (USA).gba" size 16777216 crc 5645e56c sha1 4ac05441f4de70a4ec3dd932116346c61b8783d9 flags verified ) +) + +game ( + name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It)" + description "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It)" + rom ( name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ba5de047 sha1 9efaf328cbbcbc830be14940e42e4b92d90dfb58 flags verified ) +) + game ( name "Final Fantasy V Advance (Japan) (Virtual Console)" description "Final Fantasy V Advance (Japan) (Virtual Console)" @@ -6573,7 +6585,7 @@ game ( game ( name "Findet Nemo (Germany)" description "Findet Nemo (Germany)" - rom ( name "Findet Nemo (Germany).gba" size 8388608 crc 6b6b0908 sha1 5c5ee51c4bc8196bea226b3bf4750c8de1ee7f38 ) + rom ( name "Findet Nemo (Germany).gba" size 8388608 crc 6b6b0908 sha1 5c5ee51c4bc8196bea226b3bf4750c8de1ee7f38 flags verified ) ) game ( @@ -6780,6 +6792,12 @@ game ( rom ( name "Flintstones, The - Big Trouble in Bedrock (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 39782c26 sha1 3eb5a53a395acfaae672d8b8e3c79fc4442a00ab ) ) +game ( + name "Flood (World) (v0.9) (Proto) (Unl)" + description "Flood (World) (v0.9) (Proto) (Unl)" + rom ( name "Flood (World) (v0.9) (Proto) (Unl).gba" size 485108 crc 46ad658a sha1 c3e6dfaca1570fb7d2af45a25fd93e94e11beb1e ) +) + game ( name "Flushed Away (USA)" description "Flushed Away (USA)" @@ -6873,7 +6891,7 @@ game ( game ( name "Freekstyle (USA)" description "Freekstyle (USA)" - rom ( name "Freekstyle (USA).gba" size 8388608 crc 72434345 sha1 dcecce5ebc93cfc421094ecb00a50dfe371bad24 ) + rom ( name "Freekstyle (USA).gba" size 8388608 crc 72434345 sha1 dcecce5ebc93cfc421094ecb00a50dfe371bad24 flags verified ) ) game ( @@ -7008,6 +7026,12 @@ game ( rom ( name "Futari wa Pretty Cure Max Heart - Maji Maji! Fight de IN Janai (Japan).gba" size 8388608 crc 541c18f9 sha1 fb6b864b13f41af2521c7e9c7bec0b490962452f ) ) +game ( + name "Fuzz & Rocket (USA) (Proto) (2005-01-18)" + description "Fuzz & Rocket (USA) (Proto) (2005-01-18)" + rom ( name "Fuzz & Rocket (USA) (Proto) (2005-01-18).gba" size 4124984 crc fd239437 sha1 e6dab28aa3e9a5b1417bbf3929c45ff7260803b0 ) +) + game ( name "Gachasute! Dino Device - Blue (Japan)" description "Gachasute! Dino Device - Blue (Japan)" @@ -7170,6 +7194,12 @@ game ( rom ( name "Gang del Bosco, La (Italy).gba" size 8388608 crc 52a5b59d sha1 75e7060b7dce72d01fbd6a6d1d8e1d752bfc92d0 ) ) +game ( + name "Gap-Man (World) (Unl)" + description "Gap-Man (World) (Unl)" + rom ( name "Gap-Man (World) (Unl).gba" size 122052 crc 05e327d1 sha1 839b1115f11192864e90637c964e79872c6b4b88 ) +) + game ( name "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It)" description "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It)" @@ -7237,9 +7267,15 @@ game ( ) game ( - name "GBA Movie Player 2 CF (Spain) (Unl)" - description "GBA Movie Player 2 CF (Spain) (Unl)" - rom ( name "GBA Movie Player 2 CF (Spain) (Unl).gba" size 1048576 crc c879b340 sha1 55cf23d0b941b68fb89e35d5ee57a78d30b54827 ) + name "GBA Movie Player - 2nd Version (World) (V2.00) (Unl)" + description "GBA Movie Player - 2nd Version (World) (V2.00) (Unl)" + rom ( name "GBA Movie Player - 2nd Version (World) (V2.00) (Unl).gba" size 524288 crc 3fc91d4f sha1 36739e9467204c6b2a64211dcda7370af23972ed ) +) + +game ( + name "GBA Movie Player - 2nd Version (World) (Unl) [b]" + description "GBA Movie Player - 2nd Version (World) (Unl) [b]" + rom ( name "GBA Movie Player - 2nd Version (World) (Unl) [b].gba" size 1048576 crc c879b340 sha1 55cf23d0b941b68fb89e35d5ee57a78d30b54827 flags baddump ) ) game ( @@ -7350,12 +7386,6 @@ game ( rom ( name "Ghost Trap (Japan).gba" size 8388608 crc 81ea54e2 sha1 00efb5ed50127f91e2a2827926cf2d4491e4b1b3 ) ) -game ( - name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" - description "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" - rom ( name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl).gba" size 1210608 crc ab5ae65b sha1 e35037ff9cc24f8a7043d9a9d378e86d2ef80f9b ) -) - game ( name "Global Star - Sudoku Fever (USA)" description "Global Star - Sudoku Fever (USA)" @@ -7407,7 +7437,7 @@ game ( game ( name "Golden Nugget Casino (USA, Europe)" description "Golden Nugget Casino (USA, Europe)" - rom ( name "Golden Nugget Casino (USA, Europe).gba" size 4194304 crc 56b9e9e1 sha1 5ecf4ead4b22a5916086a34bbf2abf299aaf3401 ) + rom ( name "Golden Nugget Casino (USA, Europe).gba" size 4194304 crc 56b9e9e1 sha1 5ecf4ead4b22a5916086a34bbf2abf299aaf3401 flags verified ) ) game ( @@ -7476,96 +7506,6 @@ game ( rom ( name "Golden Sun - The Lost Age (USA, Europe) (Virtual Console).gba" size 16777216 crc 726bb764 sha1 3c15317369ecafcd3c018d13c297d9107790f14f flags verified ) ) -game ( - name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13224124 crc 19ba7d80 sha1 1bf95f8730ecdfa6665b85bea8764f42a88e8e3d ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13219728 crc d4621e3e sha1 5bd59fac58c5f9a375216e9d1cf85fa5262f21f7 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13225068 crc 21512022 sha1 8832d38f787f3e1da620fcae7514d7387445ccf2 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223944 crc c1811c9b sha1 9d413bce82708df137215a2968306a5196b1638b ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13269108 crc 3360e114 sha1 50186922ff77714b9ac638948b464cdbf80ab5fb ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223696 crc 3477ef15 sha1 4b447de09a23fbfdaa6d640824f8ceb5bbe56fab ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13250016 crc a4054c2b sha1 c3cd833b9bdf87a8481c9b05251bba782bc3527e ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220676 crc ab179d6e sha1 2ad1c4840f2f6c2138ed44b1a7aa36071c227a0a ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221620 crc 3aa591f1 sha1 2548615eeaecd7498e32d02b5c758b713ada27f4 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221368 crc d02cdb6a sha1 1e579e15bdc8dc1def99bcb3c30acfc185e0476b ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220496 crc 906717a5 sha1 31857a9ab4daa537322f80faa77482a4b8120483 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220252 crc d12372bd sha1 89ea5ea41133419c317fd28e7c7f172f5bb53ec3 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13216280 crc d3c8dffd sha1 c41c0596a4c52b0e26bb9ffe5c9f7f1c064e0be6 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13265660 crc 119f9ddc sha1 d6c23ff47b21a7bf2f8238ac916aeea3866042b5 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13246576 crc b14cd1b4 sha1 0d15bd0584148b1658f7d47a2dda604a936ea166 ) -) - game ( name "GP-1 Racing (USA) (Proto)" description "GP-1 Racing (USA) (Proto)" @@ -7614,18 +7554,6 @@ game ( rom ( name "Green Eggs and Ham by Dr. Seuss (USA).gba" size 4194304 crc e4ae2cd1 sha1 be062fa28db26ec37ec96e5a7e6dc77cf4ad6907 ) ) -game ( - name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" - description "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" - rom ( name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl).gba" size 6639328 crc 78b81bbc sha1 fb090890bd767a22afe07b3323dd0992d698c906 ) -) - -game ( - name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" - description "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" - rom ( name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl).gba" size 6937384 crc 9fa9f00f sha1 005f4dc0d615d36d32bbe36e9cc9007b22be2ecd ) -) - game ( name "Greg Hastings' Tournament Paintball Max'd (USA)" description "Greg Hastings' Tournament Paintball Max'd (USA)" @@ -7638,18 +7566,18 @@ game ( rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta).gba" size 4194304 crc 68ae6bbb sha1 6aa43d0624af03214473f329fda6334dc9c63009 ) ) -game ( - name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt)" - description "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc b6225186 sha1 a2c4bf97785e717ef45e4b73a6c66a2d4ae18192 ) -) - game ( name "Gremlins - Stripe vs Gizmo (USA)" description "Gremlins - Stripe vs Gizmo (USA)" rom ( name "Gremlins - Stripe vs Gizmo (USA).gba" size 4194304 crc 5e72899a sha1 ee32e704598d2b6a21b3db271f9cf94578b94744 ) ) +game ( + name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt)" + description "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt)" + rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc b6225186 sha1 a2c4bf97785e717ef45e4b73a6c66a2d4ae18192 ) +) + game ( name "Grim Adventures of Billy & Mandy, The (USA)" description "Grim Adventures of Billy & Mandy, The (USA)" @@ -7695,7 +7623,7 @@ game ( game ( name "GT Advance 3 - Pro Concept Racing (Europe)" description "GT Advance 3 - Pro Concept Racing (Europe)" - rom ( name "GT Advance 3 - Pro Concept Racing (Europe).gba" size 8388608 crc 03898e7f sha1 1e81d7ad7a9d8c179ef9f1a2e334a155799fe788 ) + rom ( name "GT Advance 3 - Pro Concept Racing (Europe).gba" size 8388608 crc 03898e7f sha1 1e81d7ad7a9d8c179ef9f1a2e334a155799fe788 flags verified ) ) game ( @@ -7728,18 +7656,6 @@ game ( rom ( name "Gu Huo Lang 4 (Taiwan) (Unl).gba" size 33554432 crc 1608f6db sha1 8c40ce7a06f741fb11aa717b7ce2f151279fa2e2 ) ) -game ( - name "Guilty Gear X - Advance Edition (Japan) (Beta)" - description "Guilty Gear X - Advance Edition (Japan) (Beta)" - rom ( name "Guilty Gear X - Advance Edition (Japan) (Beta).gba" size 8388608 crc 4506ada8 sha1 85915ecf10ce73afe9fffbbc8cd7a449dfe802c4 ) -) - -game ( - name "Guilty Gear X - Advance Edition (USA)" - description "Guilty Gear X - Advance Edition (USA)" - rom ( name "Guilty Gear X - Advance Edition (USA).gba" size 8388608 crc 70db3f96 sha1 bb064410c57324b25de96d297338cc5e73262fe6 ) -) - game ( name "Guilty Gear X - Advance Edition (Japan)" description "Guilty Gear X - Advance Edition (Japan)" @@ -7752,6 +7668,18 @@ game ( rom ( name "Guilty Gear X - Advance Edition (Europe).gba" size 8388608 crc ba95861d sha1 8236a650a18dfedc22da7c00b5affd3e752ec5de ) ) +game ( + name "Guilty Gear X - Advance Edition (USA)" + description "Guilty Gear X - Advance Edition (USA)" + rom ( name "Guilty Gear X - Advance Edition (USA).gba" size 8388608 crc 70db3f96 sha1 bb064410c57324b25de96d297338cc5e73262fe6 ) +) + +game ( + name "Guilty Gear X - Advance Edition (Japan) (Beta)" + description "Guilty Gear X - Advance Edition (Japan) (Beta)" + rom ( name "Guilty Gear X - Advance Edition (Japan) (Beta).gba" size 8388608 crc 4506ada8 sha1 85915ecf10ce73afe9fffbbc8cd7a449dfe802c4 ) +) + game ( name "Gumby vs. the Astrobots (USA)" description "Gumby vs. the Astrobots (USA)" @@ -7789,9 +7717,9 @@ game ( ) game ( - name "Guru Logic Champ (Japan)" - description "Guru Logic Champ (Japan)" - rom ( name "Guru Logic Champ (Japan).gba" size 4194304 crc 30d04ad9 sha1 77588b6e802de57d1d826c4d43e4c3b0e3aebdae ) + name "Guru Logichamp (Japan)" + description "Guru Logichamp (Japan)" + rom ( name "Guru Logichamp (Japan).gba" size 4194304 crc 30d04ad9 sha1 77588b6e802de57d1d826c4d43e4c3b0e3aebdae ) ) game ( @@ -7959,7 +7887,7 @@ game ( game ( name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29)" description "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29)" - rom ( name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29).gba" size 16777216 crc fd630f6c sha1 14cf38e86f019572393f0109680ff2db345f9f50 ) + rom ( name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29).gba" size 8388608 crc 5c5b934d sha1 b081395415fae9cd59963a5b85bc7cc0d5623cb9 ) ) game ( @@ -7977,13 +7905,13 @@ game ( game ( name "Happy Feet (Europe) (En,Fr,De,Es,It)" description "Happy Feet (Europe) (En,Fr,De,Es,It)" - rom ( name "Happy Feet (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 7a53173c sha1 cbccce77bb727efa7ab4805509773121239faf13 ) + rom ( name "Happy Feet (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc b8653e59 sha1 1eabcfe84bd7558f64197e890a0eda8e76cdbc2c ) ) game ( name "Happy Feet (USA) (En,Fr)" description "Happy Feet (USA) (En,Fr)" - rom ( name "Happy Feet (USA) (En,Fr).gba" size 33554432 crc 682617cf sha1 e7c95cbc076e97ed2a414abc9f8d419e47174505 ) + rom ( name "Happy Feet (USA) (En,Fr).gba" size 33554432 crc 98235433 sha1 be8373ca6b9969af85303b1ec910ceb28b4f59f6 flags verified ) ) game ( @@ -8067,7 +7995,7 @@ game ( game ( name "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 33554432 crc ffa9f4fb sha1 a0e1a8f0c31ffd6e82ef99c95f903347a6eae623 ) + rom ( name "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 33554432 crc 4f39c174 sha1 1af909d2e9604501b094da95dd3e4d96e72778e8 ) ) game ( @@ -8220,6 +8148,12 @@ game ( rom ( name "Hi Hi Puffy AmiYumi - Kaznapped! (Europe) (En,De).gba" size 8388608 crc e5531d04 sha1 4060be81c5a0bc741d759f75cd83823106e5b6b9 ) ) +game ( + name "Hi Hi Puffy AmiYumi - Puffy Ami Yumi and the Manga Madman! (USA) (Proto)" + description "Hi Hi Puffy AmiYumi - Puffy Ami Yumi and the Manga Madman! (USA) (Proto)" + rom ( name "Hi Hi Puffy AmiYumi - Puffy Ami Yumi and the Manga Madman! (USA) (Proto).gba" size 8388608 crc d048ec49 sha1 f0a5e83593a3dd2c32166e6a6e48d550d7de9ecb ) +) + game ( name "Higanbana (Japan) (Rev 1)" description "Higanbana (Japan) (Rev 1)" @@ -8337,7 +8271,7 @@ game ( game ( name "Home on the Range (USA) (En,Fr)" description "Home on the Range (USA) (En,Fr)" - rom ( name "Home on the Range (USA) (En,Fr).gba" size 8388608 crc dbd4a6cb sha1 321bce711714f718ac3882acdc3c0f659db5191d ) + rom ( name "Home on the Range (USA) (En,Fr).gba" size 8388608 crc dbd4a6cb sha1 321bce711714f718ac3882acdc3c0f659db5191d flags verified ) ) game ( @@ -8520,18 +8454,18 @@ game ( rom ( name "Hugo 2 in 1 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl).gba" size 8388608 crc 8eae8860 sha1 ba780a01415ac4b814e5376c077fda21d493f396 ) ) -game ( - name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan)" - description "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan)" - rom ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan).gba" size 16777216 crc af22a5ea sha1 e752cad1fa3ffec56c9f6ca5886f37da0dc74240 ) -) - game ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan) (Rev 1)" description "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan) (Rev 1)" rom ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan) (Rev 1).gba" size 16777216 crc 86c21aeb sha1 5a327073c67ee6a29bdd595f0c4031f055804e32 ) ) +game ( + name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan)" + description "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan)" + rom ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan).gba" size 16777216 crc af22a5ea sha1 e752cad1fa3ffec56c9f6ca5886f37da0dc74240 ) +) + game ( name "Huo-Wen Zhanji - Fengyin Zhi Jian (China) (Proto)" description "Huo-Wen Zhanji - Fengyin Zhi Jian (China) (Proto)" @@ -8550,6 +8484,12 @@ game ( rom ( name "I Spy Challenger! (USA).gba" size 8388608 crc 946d2cbb sha1 532934239ea1151927fd45298d918e0646a6bea4 ) ) +game ( + name "I-Ninja (USA) (Proto)" + description "I-Ninja (USA) (Proto)" + rom ( name "I-Ninja (USA) (Proto).gba" size 8388608 crc 8f31e9c6 sha1 c5ca0f7d1d836285202fbd674ef914a7da87b024 ) +) + game ( name "Ice Age (USA) (En,Fr,Es)" description "Ice Age (USA) (En,Fr,Es)" @@ -8652,30 +8592,12 @@ game ( rom ( name "Increibles, Los (Spain).gba" size 8388608 crc fc6ccadb sha1 c87047934ae328f52ef6b01083a57c65cbbab514 ) ) -game ( - name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" - description "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl).gba" size 10592124 crc a9014760 sha1 2430c6c0784912ad2f0b51e633bf577f087f189f ) -) - -game ( - name "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl)" - description "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl)" - rom ( name "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl).gba" size 25516708 crc 965a1a75 sha1 ae23cfba1f53a9bbde025490f3d7bdf52c3970e4 ) -) - game ( name "Initial D - Another Stage (Japan)" description "Initial D - Another Stage (Japan)" rom ( name "Initial D - Another Stage (Japan).gba" size 8388608 crc 23110a94 sha1 abc8a136e00e38132bf07d38cf28e52a2719fab9 ) ) -game ( - name "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl)" - description "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl).gba" size 3145728 crc 7ee7ae7f sha1 73d870fad3caa86b6f659e13b57eddac80db2f37 ) -) - game ( name "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl)" description "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl)" @@ -8748,12 +8670,6 @@ game ( rom ( name "iQue Video & Audio (China).gba" size 16777216 crc 92852a72 sha1 79c7494c116e276f85a5f62d59f3a4588bd88391 ) ) -game ( - name "Iridion 3D (USA) (Aftermarket) (Unl)" - description "Iridion 3D (USA) (Aftermarket) (Unl)" - rom ( name "Iridion 3D (USA) (Aftermarket) (Unl).gba" size 4194304 crc 4c7ebe42 sha1 6f1c77ab88351d2d50da412e4788fc7ca8a6714d ) -) - game ( name "Iridion 3D (USA, Europe)" description "Iridion 3D (USA, Europe)" @@ -8778,12 +8694,6 @@ game ( rom ( name "Iridion II (USA) (Beta).gba" size 8388608 crc 9c63d17c sha1 3e951fd97bacd4f258bf30785af22934f7697a91 ) ) -game ( - name "Iridion II (USA) (Aftermarket) (Unl)" - description "Iridion II (USA) (Aftermarket) (Unl)" - rom ( name "Iridion II (USA) (Aftermarket) (Unl).gba" size 8388608 crc b371f070 sha1 cc788b38a047ff5ec8c445ce11efcd1852ad7c4d ) -) - game ( name "Iron Kid (Korea)" description "Iron Kid (Korea)" @@ -8793,7 +8703,7 @@ game ( game ( name "Island Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "Island Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Island Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc 3beb5446 sha1 4eec876994bdea873188fe10033c48c924d129ec ) + rom ( name "Island Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc 3beb5446 sha1 4eec876994bdea873188fe10033c48c924d129ec flags verified ) ) game ( @@ -8907,7 +8817,7 @@ game ( game ( name "Jimmy Neutron - Boy Genius (USA)" description "Jimmy Neutron - Boy Genius (USA)" - rom ( name "Jimmy Neutron - Boy Genius (USA).gba" size 4194304 crc d3ee0c51 sha1 31ed7659e2e072d1c00baf95c0ee9c770e949900 ) + rom ( name "Jimmy Neutron - Boy Genius (USA).gba" size 4194304 crc d3ee0c51 sha1 31ed7659e2e072d1c00baf95c0ee9c770e949900 flags verified ) ) game ( @@ -9300,6 +9210,12 @@ game ( rom ( name "Kien (USA) (Proto).gba" size 8388608 crc 185c2eca sha1 da1673ec5ec35f8ececa3f04cb6a92d61237ce72 ) ) +game ( + name "Kien (World) (Proto) (Incub8 Games)" + description "Kien (World) (Proto) (Incub8 Games)" + rom ( name "Kien (World) (Proto) (Incub8 Games).gba" size 8350032 crc 5a64b473 sha1 3cf07cd95e5a83b65c773111051a50d9bef367eb flags verified ) +) + game ( name "Kikaika Guntai - Mech Platoon (Japan)" description "Kikaika Guntai - Mech Platoon (Japan)" @@ -9396,6 +9312,12 @@ game ( rom ( name "King of Fighters EX 2, The - Howling Blood (USA) (Beta) (2003-04-03).gba" size 8388608 crc 7704ff39 sha1 b859122c1813a5ec9fb565dcca815a9f0a52bf18 ) ) +game ( + name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" + description "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" + rom ( name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1).gba" size 8388608 crc dc5beacd sha1 2b7ec55de56d7f7f0932a53a0d3fcc3f36a0af8e ) +) + game ( name "King of Fighters EX 2, The - Howling Blood (Europe)" description "King of Fighters EX 2, The - Howling Blood (Europe)" @@ -9409,9 +9331,15 @@ game ( ) game ( - name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" - description "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" - rom ( name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1).gba" size 8388608 crc dc5beacd sha1 2b7ec55de56d7f7f0932a53a0d3fcc3f36a0af8e ) + name "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" + description "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" + rom ( name "King of Fighters EX, The - NeoBlood (USA) (Rev 1).gba" size 8388608 crc 0f960e70 sha1 3031264c4b27cac55c2df38ab5f2bfcafa7c301d ) +) + +game ( + name "King of Fighters EX, The - NeoBlood (Japan) (Beta)" + description "King of Fighters EX, The - NeoBlood (Japan) (Beta)" + rom ( name "King of Fighters EX, The - NeoBlood (Japan) (Beta).gba" size 8388608 crc 811ffcfa sha1 cde8454951d3509f0b2bf9de98221eef248f5f8d ) ) game ( @@ -9432,18 +9360,6 @@ game ( rom ( name "King of Fighters EX, The - NeoBlood (Europe).gba" size 8388608 crc 17e66b52 sha1 48c85734164d4d83a232b5aca6bb9a2c5b7f5317 ) ) -game ( - name "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" - description "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" - rom ( name "King of Fighters EX, The - NeoBlood (USA) (Rev 1).gba" size 8388608 crc 0f960e70 sha1 3031264c4b27cac55c2df38ab5f2bfcafa7c301d ) -) - -game ( - name "King of Fighters EX, The - NeoBlood (Japan) (Beta)" - description "King of Fighters EX, The - NeoBlood (Japan) (Beta)" - rom ( name "King of Fighters EX, The - NeoBlood (Japan) (Beta).gba" size 8388608 crc 811ffcfa sha1 cde8454951d3509f0b2bf9de98221eef248f5f8d ) -) - game ( name "Kingdom Hearts - Chain of Memories (Japan)" description "Kingdom Hearts - Chain of Memories (Japan)" @@ -9487,9 +9403,9 @@ game ( ) game ( - name "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" - description "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" - rom ( name "Kirby - Nightmare in Dream Land (USA) (Virtual Console).gba" size 8388608 crc 1af07ac8 sha1 3d142008d50a64c315fd2d7cbd86ba94dffa2e12 ) + name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" + description "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" + rom ( name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 3b7a7477 sha1 39b00beee4558e6738859cfa250e4e0fcaae626e flags verified ) ) game ( @@ -9499,9 +9415,15 @@ game ( ) game ( - name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" - description "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" - rom ( name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 3b7a7477 sha1 39b00beee4558e6738859cfa250e4e0fcaae626e flags verified ) + name "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" + description "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" + rom ( name "Kirby - Nightmare in Dream Land (USA) (Virtual Console).gba" size 8388608 crc 1af07ac8 sha1 3d142008d50a64c315fd2d7cbd86ba94dffa2e12 ) +) + +game ( + name "Kirby & The Amazing Mirror (USA) (Virtual Console)" + description "Kirby & The Amazing Mirror (USA) (Virtual Console)" + rom ( name "Kirby & The Amazing Mirror (USA) (Virtual Console).gba" size 16777216 crc f70ebb99 sha1 a7b758c2abf4f0ef722922eab4d394a1579b52e8 ) ) game ( @@ -9516,12 +9438,6 @@ game ( rom ( name "Kirby & The Amazing Mirror (USA).gba" size 16777216 crc 9f2a3048 sha1 274b102b6d940f46861a92b4e65f89a51815c12c flags verified ) ) -game ( - name "Kirby & The Amazing Mirror (USA) (Virtual Console)" - description "Kirby & The Amazing Mirror (USA) (Virtual Console)" - rom ( name "Kirby & The Amazing Mirror (USA) (Virtual Console).gba" size 16777216 crc f70ebb99 sha1 a7b758c2abf4f0ef722922eab4d394a1579b52e8 ) -) - game ( name "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It) (Virtual Console)" description "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It) (Virtual Console)" @@ -9555,13 +9471,7 @@ game ( game ( name "Klonoa - Empire of Dreams (Europe)" description "Klonoa - Empire of Dreams (Europe)" - rom ( name "Klonoa - Empire of Dreams (Europe).gba" size 4194304 crc 69492530 sha1 e4a81713b134e0b7409708843dad2a4948b903ef ) -) - -game ( - name "Klonoa 2 - Dream Champ Tournament (USA)" - description "Klonoa 2 - Dream Champ Tournament (USA)" - rom ( name "Klonoa 2 - Dream Champ Tournament (USA).gba" size 4194304 crc 8bd23a7f sha1 35c05676e65fd4c92220861662cd3709342f36e2 ) + rom ( name "Klonoa - Empire of Dreams (Europe).gba" size 4194304 crc 69492530 sha1 e4a81713b134e0b7409708843dad2a4948b903ef flags verified ) ) game ( @@ -9570,6 +9480,12 @@ game ( rom ( name "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console).gba" size 4194304 crc 766c7f9a sha1 455c6f19a703b2bd54a9a3a9588964239965e6db ) ) +game ( + name "Klonoa 2 - Dream Champ Tournament (USA)" + description "Klonoa 2 - Dream Champ Tournament (USA)" + rom ( name "Klonoa 2 - Dream Champ Tournament (USA).gba" size 4194304 crc 8bd23a7f sha1 35c05676e65fd4c92220861662cd3709342f36e2 ) +) + game ( name "Klonoa Heroes - Densetsu no Star Medal (Japan)" description "Klonoa Heroes - Densetsu no Star Medal (Japan)" @@ -9648,12 +9564,6 @@ game ( rom ( name "Konami Krazy Racers (Europe).gba" size 4194304 crc cfec0650 sha1 90a0035818ba0ab2a0c6ea45dc7eff2eb7296970 flags verified ) ) -game ( - name "Konami Krazy Racers (USA) (Beta)" - description "Konami Krazy Racers (USA) (Beta)" - rom ( name "Konami Krazy Racers (USA) (Beta).gba" size 4194304 crc 5f2ae8fe sha1 329b82282d633d1162f9afb3334c035b10b91e72 ) -) - game ( name "Konami Krazy Racers (USA) (Virtual Console)" description "Konami Krazy Racers (USA) (Virtual Console)" @@ -9667,9 +9577,9 @@ game ( ) game ( - name "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" - description "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" - rom ( name "Konami Wai Wai Racing Advance (Japan) (Virtual Console).gba" size 4194304 crc f424858f sha1 29f850ea1a9900446a0e1ce8ef1c2fd85341f242 ) + name "Konami Krazy Racers (USA) (Beta)" + description "Konami Krazy Racers (USA) (Beta)" + rom ( name "Konami Krazy Racers (USA) (Beta).gba" size 4194304 crc 5f2ae8fe sha1 329b82282d633d1162f9afb3334c035b10b91e72 ) ) game ( @@ -9678,6 +9588,12 @@ game ( rom ( name "Konami Wai Wai Racing Advance (Japan).gba" size 4194304 crc aa039a8a sha1 e3549b9b7d7208b88e368e7b7a59e31eec8b1da6 ) ) +game ( + name "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" + description "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" + rom ( name "Konami Wai Wai Racing Advance (Japan) (Virtual Console).gba" size 4194304 crc f424858f sha1 29f850ea1a9900446a0e1ce8ef1c2fd85341f242 ) +) + game ( name "Konchuu Monster - Battle Master (Japan)" description "Konchuu Monster - Battle Master (Japan)" @@ -9765,7 +9681,7 @@ game ( game ( name "Korokoro Puzzle - Happy Panecchu! (Japan)" description "Korokoro Puzzle - Happy Panecchu! (Japan)" - rom ( name "Korokoro Puzzle - Happy Panecchu! (Japan).gba" size 4194304 crc 0bfe46e9 sha1 40cb751d119a49be0cd44cf0491c93ebc8795ef0 ) + rom ( name "Korokoro Puzzle - Happy Panecchu! (Japan).gba" size 4194304 crc 0bfe46e9 sha1 40cb751d119a49be0cd44cf0491c93ebc8795ef0 flags verified ) ) game ( @@ -9951,13 +9867,13 @@ game ( game ( name "Legend of Spyro, The - The Eternal Night (USA) (En,Fr)" description "Legend of Spyro, The - The Eternal Night (USA) (En,Fr)" - rom ( name "Legend of Spyro, The - The Eternal Night (USA) (En,Fr).gba" size 33554432 crc bd2751e6 sha1 4bc88f2c7325937bbe0f16dfebda10f279d5ed20 ) + rom ( name "Legend of Spyro, The - The Eternal Night (USA) (En,Fr).gba" size 33554432 crc 8d780224 sha1 6cfa38d08b735e8b6b1c3763aee8a8ed5da52977 ) ) game ( name "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl)" description "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 93b18353 sha1 4bce80310b43882f57c7bb5b202e09ce23687473 ) + rom ( name "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc a3eed091 sha1 0fced99190bce676e83bed31134e2f165ef997b8 ) ) game ( @@ -10176,10 +10092,16 @@ game ( rom ( name "Lilo & Stitch 2 - Haemsterviel Havoc (USA).gba" size 8388608 crc 021a5755 sha1 70e0dc5a8dcdf876b5dd87a4c1bbca03b6e30148 ) ) +game ( + name "Lindsi Luna Blast (World) (v1.01) (Unl)" + description "Lindsi Luna Blast (World) (v1.01) (Unl)" + rom ( name "Lindsi Luna Blast (World) (v1.01) (Unl).gba" size 4981720 crc e6fadd1a sha1 6786c08957251b3a5ab2534b15f5b2def2ee9d86 ) +) + game ( name "Lion King 1 1-2, The (USA)" description "Lion King 1 1-2, The (USA)" - rom ( name "Lion King 1 1-2, The (USA).gba" size 8388608 crc ea5ed4c0 sha1 382de6da61c5dc5c2844f5ffa28a1827d15319b1 ) + rom ( name "Lion King 1 1-2, The (USA).gba" size 8388608 crc ea5ed4c0 sha1 382de6da61c5dc5c2844f5ffa28a1827d15319b1 flags verified ) ) game ( @@ -10233,7 +10155,7 @@ game ( game ( name "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr)" description "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr)" - rom ( name "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr).gba" size 4194304 crc f11009f9 sha1 7ace37aec21c058aa98e3de12140cb691c070e00 ) + rom ( name "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr).gba" size 4194304 crc f11009f9 sha1 7ace37aec21c058aa98e3de12140cb691c070e00 flags verified ) ) game ( @@ -10368,12 +10290,6 @@ game ( rom ( name "Lufia - The Ruins of Lore (USA).gba" size 8388608 crc de5ffcbc sha1 a2b7e80a6c7d586ebeec77c8a2c2545fe27e0592 ) ) -game ( - name "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" - description "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" - rom ( name "Luggage Retrieval Officer (World) (Aftermarket) (Unl).gba" size 3336260 crc 5aa30d90 sha1 84c9b2d50c8af74b8b04f88af367d9fac1a24ef6 ) -) - game ( name "Lunar Legend (Japan)" description "Lunar Legend (Japan)" @@ -10657,9 +10573,9 @@ game ( ) game ( - name "Mandrake the Magician (Italy) (It) (Proto)" - description "Mandrake the Magician (Italy) (It) (Proto)" - rom ( name "Mandrake the Magician (Italy) (It) (Proto).gba" size 8388608 crc 7cfe1889 sha1 ddb5f0cdd5db80c22a448650c1b05d02feb0b831 ) + name "Mandrake the Magician (Italy) (Proto)" + description "Mandrake the Magician (Italy) (Proto)" + rom ( name "Mandrake the Magician (Italy) (Proto).gba" size 8388608 crc 7cfe1889 sha1 ddb5f0cdd5db80c22a448650c1b05d02feb0b831 ) ) game ( @@ -11013,13 +10929,13 @@ game ( game ( name "Mary-Kate and Ashley - Girls Night Out (USA, Europe)" description "Mary-Kate and Ashley - Girls Night Out (USA, Europe)" - rom ( name "Mary-Kate and Ashley - Girls Night Out (USA, Europe).gba" size 4194304 crc 8af3f3ad sha1 4b46751b6deb8064d58a0786d62b37206c9529ac ) + rom ( name "Mary-Kate and Ashley - Girls Night Out (USA, Europe).gba" size 4194304 crc 8af3f3ad sha1 4b46751b6deb8064d58a0786d62b37206c9529ac flags verified ) ) game ( name "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe)" description "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe)" - rom ( name "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe).gba" size 4194304 crc 5fe092c6 sha1 284059f03f0dda9ce511d3c57bf0607706b9fca3 ) + rom ( name "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe).gba" size 4194304 crc 5fe092c6 sha1 284059f03f0dda9ce511d3c57bf0607706b9fca3 flags verified ) ) game ( @@ -11058,18 +10974,6 @@ game ( rom ( name "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan) (Rev 1).gba" size 8388608 crc d647ab18 sha1 3489569fa8a3c6a750c5cb0048915da78c5f40ab ) ) -game ( - name "Matchbox Cross Town Heroes (USA)" - description "Matchbox Cross Town Heroes (USA)" - rom ( name "Matchbox Cross Town Heroes (USA).gba" size 4194304 crc 0fffb458 sha1 6baa6bfe76b077f365bedffa52346b94689b61d7 ) -) - -game ( - name "Matchbox Cross Town Heroes (Europe)" - description "Matchbox Cross Town Heroes (Europe)" - rom ( name "Matchbox Cross Town Heroes (Europe).gba" size 4194304 crc c9ea02f5 sha1 13310b7f25a0332a8e09e722587ec79aee11c373 ) -) - game ( name "Math Patrol - The Kleptoid Threat (USA)" description "Math Patrol - The Kleptoid Threat (USA)" @@ -11142,6 +11046,12 @@ game ( rom ( name "Medabots - Metabee (Europe).gba" size 8388608 crc 50927f3e sha1 cd3d674e88f40a0707b150c4293588a659001d29 ) ) +game ( + name "Medabots - Metabee (USA)" + description "Medabots - Metabee (USA)" + rom ( name "Medabots - Metabee (USA).gba" size 8388608 crc 59f208fc sha1 ca185b65ab50ef89a10c8db00d9cd76626b81610 ) +) + game ( name "Medabots - Metabee (Spain)" description "Medabots - Metabee (Spain)" @@ -11155,15 +11065,9 @@ game ( ) game ( - name "Medabots - Metabee (USA)" - description "Medabots - Metabee (USA)" - rom ( name "Medabots - Metabee (USA).gba" size 8388608 crc 59f208fc sha1 ca185b65ab50ef89a10c8db00d9cd76626b81610 ) -) - -game ( - name "Medabots - Rokusho (USA)" - description "Medabots - Rokusho (USA)" - rom ( name "Medabots - Rokusho (USA).gba" size 8388608 crc e144ded2 sha1 c4572428ea97b302f699a3b4eba2a1f0e87c1c9c ) + name "Medabots - Rokusho (Spain)" + description "Medabots - Rokusho (Spain)" + rom ( name "Medabots - Rokusho (Spain).gba" size 8388608 crc 046d86c4 sha1 90fe7f2927c592aabc9b33d0df00d92046c5cb92 ) ) game ( @@ -11185,15 +11089,9 @@ game ( ) game ( - name "Medabots - Rokusho (Spain)" - description "Medabots - Rokusho (Spain)" - rom ( name "Medabots - Rokusho (Spain).gba" size 8388608 crc 046d86c4 sha1 90fe7f2927c592aabc9b33d0df00d92046c5cb92 ) -) - -game ( - name "Medabots AX - Metabee Ver. (USA)" - description "Medabots AX - Metabee Ver. (USA)" - rom ( name "Medabots AX - Metabee Ver. (USA).gba" size 8388608 crc 03294511 sha1 80c024df6d40e499776665d7f0c494a252973048 ) + name "Medabots - Rokusho (USA)" + description "Medabots - Rokusho (USA)" + rom ( name "Medabots - Rokusho (USA).gba" size 8388608 crc e144ded2 sha1 c4572428ea97b302f699a3b4eba2a1f0e87c1c9c ) ) game ( @@ -11202,6 +11100,12 @@ game ( rom ( name "Medabots AX - Metabee Ver. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5f1e5a48 sha1 130c908d24ba3e422fd8db84e683bacc87235e78 flags verified ) ) +game ( + name "Medabots AX - Metabee Ver. (USA)" + description "Medabots AX - Metabee Ver. (USA)" + rom ( name "Medabots AX - Metabee Ver. (USA).gba" size 8388608 crc 03294511 sha1 80c024df6d40e499776665d7f0c494a252973048 ) +) + game ( name "Medabots AX - Metabee Ver. (USA) (Virtual Console)" description "Medabots AX - Metabee Ver. (USA) (Virtual Console)" @@ -11244,12 +11148,6 @@ game ( rom ( name "Medal of Honor - Infiltrator (USA, Europe) (En,Fr,De).gba" size 16777216 crc f23150a4 sha1 47761911475e9548c81fed78e3d3336ddae89a58 flags verified ) ) -game ( - name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" - description "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" - rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital).gba" size 8388608 crc 72b4cf20 sha1 abb26d759ef729d21e41a913fc6c1ce4ab77149f ) -) - game ( name "Medal of Honor - Underground (USA)" description "Medal of Honor - Underground (USA)" @@ -11262,6 +11160,12 @@ game ( rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Ubi Soft).gba" size 8388608 crc 9db145b8 sha1 e43aaba3f925443cfccf9294b870024a9c71a9a9 ) ) +game ( + name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" + description "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" + rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital).gba" size 8388608 crc 72b4cf20 sha1 abb26d759ef729d21e41a913fc6c1ce4ab77149f ) +) + game ( name "Medal of Honor Advance (Japan)" description "Medal of Honor Advance (Japan)" @@ -11550,18 +11454,6 @@ game ( rom ( name "Megaman - Battle Network 5 - Team Colonel (Europe) (Virtual Console).gba" size 8388608 crc 5247772c sha1 061c291b29629d5ce44011d2d83931f2e35044ed ) ) -game ( - name "Megaman - Battle Network 5 - Team Protoman (Europe)" - description "Megaman - Battle Network 5 - Team Protoman (Europe)" - rom ( name "Megaman - Battle Network 5 - Team Protoman (Europe).gba" size 8388608 crc 79f45ed8 sha1 3d017ed23535e42174299ff89fff44678eb553c3 ) -) - -game ( - name "Megaman - Battle Network 5 - Team Protoman (USA)" - description "Megaman - Battle Network 5 - Team Protoman (USA)" - rom ( name "Megaman - Battle Network 5 - Team Protoman (USA).gba" size 8388608 crc a73e83a4 sha1 b3774e96b1f107bb8b1db79b216be41b9bc5bac0 ) -) - game ( name "Megaman - Battle Network 5 - Team Protoman (USA) (Virtual Console)" description "Megaman - Battle Network 5 - Team Protoman (USA) (Virtual Console)" @@ -11574,6 +11466,18 @@ game ( rom ( name "Megaman - Battle Network 5 - Team Protoman (Europe) (Virtual Console).gba" size 8388608 crc 7e5bc83d sha1 b68b310e3106e7fa6a47d4155239be2e43959da4 ) ) +game ( + name "Megaman - Battle Network 5 - Team Protoman (Europe)" + description "Megaman - Battle Network 5 - Team Protoman (Europe)" + rom ( name "Megaman - Battle Network 5 - Team Protoman (Europe).gba" size 8388608 crc 79f45ed8 sha1 3d017ed23535e42174299ff89fff44678eb553c3 ) +) + +game ( + name "Megaman - Battle Network 5 - Team Protoman (USA)" + description "Megaman - Battle Network 5 - Team Protoman (USA)" + rom ( name "Megaman - Battle Network 5 - Team Protoman (USA).gba" size 8388608 crc a73e83a4 sha1 b3774e96b1f107bb8b1db79b216be41b9bc5bac0 ) +) + game ( name "Megaman - Battle Network 6 - Cybeast Falzar (Europe)" description "Megaman - Battle Network 6 - Cybeast Falzar (Europe)" @@ -11628,12 +11532,6 @@ game ( rom ( name "Megaman & Bass (USA) (Virtual Console).gba" size 8388608 crc b61f99d4 sha1 37db963a52aecec8018057cef3811860c3e889ed ) ) -game ( - name "Megaman & Bass (Europe)" - description "Megaman & Bass (Europe)" - rom ( name "Megaman & Bass (Europe).gba" size 8388608 crc 01b4d95e sha1 5d6f8fb1f52803a54e9857e53d0b88173cf8f48a flags verified ) -) - game ( name "Megaman & Bass (Europe) (Virtual Console)" description "Megaman & Bass (Europe) (Virtual Console)" @@ -11647,9 +11545,9 @@ game ( ) game ( - name "Megaman Zero (USA, Europe)" - description "Megaman Zero (USA, Europe)" - rom ( name "Megaman Zero (USA, Europe).gba" size 8388608 crc 9707d2a1 sha1 193b14120119162518a73c70876f0b8bffdbd96e flags verified ) + name "Megaman & Bass (Europe)" + description "Megaman & Bass (Europe)" + rom ( name "Megaman & Bass (Europe).gba" size 8388608 crc 01b4d95e sha1 5d6f8fb1f52803a54e9857e53d0b88173cf8f48a flags verified ) ) game ( @@ -11659,9 +11557,9 @@ game ( ) game ( - name "Megaman Zero 2 (USA) (Virtual Console)" - description "Megaman Zero 2 (USA) (Virtual Console)" - rom ( name "Megaman Zero 2 (USA) (Virtual Console).gba" size 8388608 crc 30d051fe sha1 d7a1edd912f8e01bc442809b922bceaf5a1f0176 ) + name "Megaman Zero (USA, Europe)" + description "Megaman Zero (USA, Europe)" + rom ( name "Megaman Zero (USA, Europe).gba" size 8388608 crc 9707d2a1 sha1 193b14120119162518a73c70876f0b8bffdbd96e flags verified ) ) game ( @@ -11683,9 +11581,9 @@ game ( ) game ( - name "Megaman Zero 3 (Europe) (Virtual Console)" - description "Megaman Zero 3 (Europe) (Virtual Console)" - rom ( name "Megaman Zero 3 (Europe) (Virtual Console).gba" size 8388608 crc 87e8656e sha1 8245ecb895caf0e0a2914f46bb79e4c9c5ba8c4a ) + name "Megaman Zero 2 (USA) (Virtual Console)" + description "Megaman Zero 2 (USA) (Virtual Console)" + rom ( name "Megaman Zero 2 (USA) (Virtual Console).gba" size 8388608 crc 30d051fe sha1 d7a1edd912f8e01bc442809b922bceaf5a1f0176 ) ) game ( @@ -11706,6 +11604,12 @@ game ( rom ( name "Megaman Zero 3 (USA).gba" size 8388608 crc 2784f3f2 sha1 403a78f2cad93d41e4b0f2e520ce08026531664b ) ) +game ( + name "Megaman Zero 3 (Europe) (Virtual Console)" + description "Megaman Zero 3 (Europe) (Virtual Console)" + rom ( name "Megaman Zero 3 (Europe) (Virtual Console).gba" size 8388608 crc 87e8656e sha1 8245ecb895caf0e0a2914f46bb79e4c9c5ba8c4a ) +) + game ( name "Megaman Zero 4 (Europe) (Virtual Console)" description "Megaman Zero 4 (Europe) (Virtual Console)" @@ -11784,6 +11688,12 @@ game ( rom ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichitto Live Start! (Japan).gba" size 33554432 crc 7a4fdec3 sha1 d6bd3140b83fb9b1c2d84b6faf21c7286e29d129 ) ) +game ( + name "Metal Gear Solid 2D - Sensible (World) (v0.31) (Demo) (Unl)" + description "Metal Gear Solid 2D - Sensible (World) (v0.31) (Demo) (Unl)" + rom ( name "Metal Gear Solid 2D - Sensible (World) (v0.31) (Demo) (Unl).gba" size 149668 crc c797641c sha1 e8a32fbd80f644e9828369603c1a926392a4c105 ) +) + game ( name "Metal Max 2 Kai (Japan)" description "Metal Max 2 Kai (Japan)" @@ -11826,12 +11736,6 @@ game ( rom ( name "Metal Slug Advance (Europe).gba" size 8388608 crc 3806f4ae sha1 0719aee29b0da365e7ad52bb0ae9545bcd377152 flags verified ) ) -game ( - name "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl)" - description "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl).gba" size 524288 crc 7ec3485e sha1 729592141bc160ead0af51d4322c7f9f17da0b82 ) -) - game ( name "Metalgun Slinger (Japan)" description "Metalgun Slinger (Japan)" @@ -11844,6 +11748,24 @@ game ( rom ( name "Metroid - Zero Mission (Japan) (Virtual Console).gba" size 8388608 crc 220b68f5 sha1 24d99f32875464dbcef5ca8ec231ec42073ff1e8 ) ) +game ( + name "Metroid - Zero Mission (USA)" + description "Metroid - Zero Mission (USA)" + rom ( name "Metroid - Zero Mission (USA).gba" size 8388608 crc 5c61a844 sha1 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8 flags verified ) +) + +game ( + name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" + description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" + rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f1d92e63 sha1 0fd107445a42e6f3a3e5ce8c865f412583179903 flags verified ) +) + +game ( + name "Metroid - Zero Mission (Japan)" + description "Metroid - Zero Mission (Japan)" + rom ( name "Metroid - Zero Mission (Japan).gba" size 8388608 crc 44b79e2b sha1 096f07685a3dc9286e71aa0b761f233b5efa2fcd ) +) + game ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Beta)" description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Beta)" @@ -11869,21 +11791,27 @@ game ( ) game ( - name "Metroid - Zero Mission (USA)" - description "Metroid - Zero Mission (USA)" - rom ( name "Metroid - Zero Mission (USA).gba" size 8388608 crc 5c61a844 sha1 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8 flags verified ) + name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11)" + description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11).gba" size 16777216 crc 3acbd239 sha1 a45b539becbf10f3913255d6d624ee954dcc5593 ) ) game ( - name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" - description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" - rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f1d92e63 sha1 0fd107445a42e6f3a3e5ce8c865f412583179903 flags verified ) + name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16)" + description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16).gba" size 8388608 crc 1605e4f7 sha1 f688f2d3186a0a90040abb214efd1e8e93a424cd ) ) game ( - name "Metroid - Zero Mission (Japan)" - description "Metroid - Zero Mission (Japan)" - rom ( name "Metroid - Zero Mission (Japan).gba" size 8388608 crc 44b79e2b sha1 096f07685a3dc9286e71aa0b761f233b5efa2fcd ) + name "Metroid Fusion (USA) (Virtual Console)" + description "Metroid Fusion (USA) (Virtual Console)" + rom ( name "Metroid Fusion (USA) (Virtual Console).gba" size 8388608 crc 162a46b8 sha1 c63419a4ee7c2a5e412fa16645ee04cb24027724 ) +) + +game ( + name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" + description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc eee01b78 sha1 82e507863f647dc566bbf45227e8cd284052ecba ) ) game ( @@ -11910,30 +11838,6 @@ game ( rom ( name "Metroid Fusion (Japan).gba" size 8388608 crc 817a7e9e sha1 5d21c668baa84da4a5b745be56809bb277f947a3 flags verified ) ) -game ( - name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11)" - description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11)" - rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11).gba" size 16777216 crc 3acbd239 sha1 a45b539becbf10f3913255d6d624ee954dcc5593 ) -) - -game ( - name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16)" - description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16)" - rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16).gba" size 8388608 crc 1605e4f7 sha1 f688f2d3186a0a90040abb214efd1e8e93a424cd ) -) - -game ( - name "Metroid Fusion (USA) (Virtual Console)" - description "Metroid Fusion (USA) (Virtual Console)" - rom ( name "Metroid Fusion (USA) (Virtual Console).gba" size 8388608 crc 162a46b8 sha1 c63419a4ee7c2a5e412fa16645ee04cb24027724 ) -) - -game ( - name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" - description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" - rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc eee01b78 sha1 82e507863f647dc566bbf45227e8cd284052ecba ) -) - game ( name "Mezase! Koushien (Japan)" description "Mezase! Koushien (Japan)" @@ -12036,24 +11940,6 @@ game ( rom ( name "Mini Moni. - Onegai Ohoshi-sama! (Japan).gba" size 8388608 crc f11c35cc sha1 d34795cf3679c6f259177db52a138c0d6e9fcdfd ) ) -game ( - name "Minicraft (World) (v1.0) (Aftermarket) (Unl)" - description "Minicraft (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Minicraft (World) (v1.0) (Aftermarket) (Unl).gba" size 131072 crc e852c9e9 sha1 06faa5be11978666db6995d8fce40ce2c3641ce8 ) -) - -game ( - name "Minicraft (World) (v1.1) (Aftermarket) (Unl)" - description "Minicraft (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Minicraft (World) (v1.1) (Aftermarket) (Unl).gba" size 131072 crc 07595773 sha1 fee5cfa5b9e1f3383780432772f29764ac0fc443 ) -) - -game ( - name "Minicraft (World) (v1.2) (Aftermarket) (Unl)" - description "Minicraft (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Minicraft (World) (v1.2) (Aftermarket) (Unl).gba" size 131072 crc 37e7ee7d sha1 dc7faa4952986d5c5f0e3b32203936cd717f97eb ) -) - game ( name "Minna de Puyo Puyo (Japan) (En,Ja)" description "Minna de Puyo Puyo (Japan) (En,Ja)" @@ -12162,12 +12048,6 @@ game ( rom ( name "Mirakuru! Panzou - 7-tsu no Hoshi no Uchuu Kaizoku (Japan).gba" size 4194304 crc 3a87f78b sha1 ad916495bbb9c3ee34b68c13f118a4cbcdb18b3b ) ) -game ( - name "Misfortune Advance (World) (Aftermarket) (Unl)" - description "Misfortune Advance (World) (Aftermarket) (Unl)" - rom ( name "Misfortune Advance (World) (Aftermarket) (Unl).gba" size 5125100 crc 18f2166d sha1 68e215025ac963220f16ea3c100e51698f97c4eb ) -) - game ( name "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It)" description "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It)" @@ -12420,18 +12300,6 @@ game ( rom ( name "Monsters, Inc. (Europe) (En,Es,Nl).gba" size 4194304 crc d13177e0 sha1 36645b8de074f0b27dbe61528e70ae3af28fb3b9 ) ) -game ( - name "Mooncat's Trio (World) (Aftermarket) (Unl)" - description "Mooncat's Trio (World) (Aftermarket) (Unl)" - rom ( name "Mooncat's Trio (World) (Aftermarket) (Unl).gba" size 1175680 crc b05d5339 sha1 890de7d73723d235d9762e4866d569d3554d1480 flags verified ) -) - -game ( - name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" - description "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" - rom ( name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl).gba" size 504220 crc cd3328ee sha1 c3ea5247f32c428bbcfd5c087218fc56779e3106 ) -) - game ( name "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It)" description "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It)" @@ -12699,7 +12567,7 @@ game ( game ( name "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It)" description "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It)" - rom ( name "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 16c0e028 sha1 e85cea8428d51e40cf1b7a90643e94604973679f ) + rom ( name "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc d4f6c94d sha1 0f4f86e0c2243d847d16488e42b07e26679dc0ae ) ) game ( @@ -12765,7 +12633,7 @@ game ( game ( name "Namco Museum (Europe)" description "Namco Museum (Europe)" - rom ( name "Namco Museum (Europe).gba" size 4194304 crc bb82460a sha1 3e84508a0d2362a0abf31dede1d55b865566213c ) + rom ( name "Namco Museum (Europe).gba" size 4194304 crc bb82460a sha1 3e84508a0d2362a0abf31dede1d55b865566213c flags verified ) ) game ( @@ -12900,6 +12768,18 @@ game ( rom ( name "NBA Jam 2002 (USA, Europe).gba" size 4194304 crc ca428a7a sha1 38de98758669b120b895661bec3882c3474cf47e ) ) +game ( + name "Nebulus (World) (v1.2) (Unl)" + description "Nebulus (World) (v1.2) (Unl)" + rom ( name "Nebulus (World) (v1.2) (Unl).gba" size 557936 crc 77e2d5f0 sha1 086f7d7e86cfbaff43a4ce35c179e43adbccc4f6 ) +) + +game ( + name "Nebulus (World) (GBAX 2004) (Unl)" + description "Nebulus (World) (GBAX 2004) (Unl)" + rom ( name "Nebulus (World) (GBAX 2004) (Unl).gba" size 544372 crc fb414ccc sha1 4c25014b29e87dd53f3677339f89dd18d316d2f0 ) +) + game ( name "Need for Speed - Carbon - Own the City (USA, Europe) (En,Fr,De,Es,It)" description "Need for Speed - Carbon - Own the City (USA, Europe) (En,Fr,De,Es,It)" @@ -12936,12 +12816,6 @@ game ( rom ( name "Need for Speed - Underground 2 (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc 9a0c5090 sha1 f772000fbdfb84d8d5de9f69bd9c0de551389929 flags verified ) ) -game ( - name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" - description "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" - rom ( name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl).gba" size 508972 crc 55a0734d sha1 79d6977803cd7ee6b1c97ee149cc1bc037c50fb2 ) -) - game ( name "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" description "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" @@ -13008,12 +12882,6 @@ game ( rom ( name "Nicktoons - Freeze Frame Frenzy (USA).gba" size 4194304 crc a8b6766e sha1 a200cdaf66606bd724ce7073fd7990ea3fe6bcdd ) ) -game ( - name "Nicktoons Racing (USA) (Beta)" - description "Nicktoons Racing (USA) (Beta)" - rom ( name "Nicktoons Racing (USA) (Beta).gba" size 4194304 crc 4ed6e860 sha1 d553a265d1405bb073034e16ea97e1a2df899025 ) -) - game ( name "Nicktoons Racing (USA)" description "Nicktoons Racing (USA)" @@ -13026,6 +12894,12 @@ game ( rom ( name "Nicktoons Racing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc babccefd sha1 55b145de1810a4a6a8b5716ef4c9e9333a93e3ba ) ) +game ( + name "Nicktoons Racing (USA) (Beta)" + description "Nicktoons Racing (USA) (Beta)" + rom ( name "Nicktoons Racing (USA) (Beta).gba" size 4194304 crc 4ed6e860 sha1 d553a265d1405bb073034e16ea97e1a2df899025 ) +) + game ( name "Nicktoons Unite! (USA)" description "Nicktoons Unite! (USA)" @@ -13242,18 +13116,18 @@ game ( rom ( name "Oriental Blue - Ao no Tengai (Japan).gba" size 16777216 crc 05e80ecc sha1 414cad1aee67ab20f3c133f0259da7e8c3073bbc flags verified ) ) -game ( - name "Oshaberi Inko Club (Japan)" - description "Oshaberi Inko Club (Japan)" - rom ( name "Oshaberi Inko Club (Japan).gba" size 8388608 crc df6901f0 sha1 82e48090b9615282c58747a1f7b105196866f8c9 ) -) - game ( name "Oshaberi Inko Club (Japan) (Beta)" description "Oshaberi Inko Club (Japan) (Beta)" rom ( name "Oshaberi Inko Club (Japan) (Beta).gba" size 8388608 crc f896bb9e sha1 e293d18a8a0fb856edafafa03b33454b2d04efd9 ) ) +game ( + name "Oshaberi Inko Club (Japan)" + description "Oshaberi Inko Club (Japan)" + rom ( name "Oshaberi Inko Club (Japan).gba" size 8388608 crc df6901f0 sha1 82e48090b9615282c58747a1f7b105196866f8c9 ) +) + game ( name "Oshare Princess (Japan)" description "Oshare Princess (Japan)" @@ -13461,7 +13335,7 @@ game ( game ( name "Paws & Claws - Pet Vet (USA)" description "Paws & Claws - Pet Vet (USA)" - rom ( name "Paws & Claws - Pet Vet (USA).gba" size 8388608 crc efee1ddf sha1 c121eea8f816c4f8cbab32058d6b9bac57f0d7e3 ) + rom ( name "Paws & Claws - Pet Vet (USA).gba" size 8388608 crc efee1ddf sha1 c121eea8f816c4f8cbab32058d6b9bac57f0d7e3 flags verified ) ) game ( @@ -13597,9 +13471,9 @@ game ( ) game ( - name "Phantom, The (Italy) (It) (Proto)" - description "Phantom, The (Italy) (It) (Proto)" - rom ( name "Phantom, The (Italy) (It) (Proto).gba" size 8388608 crc 5833169c sha1 ccd8e9d092a9ded9c3785ac776d40df66512b9b5 ) + name "Phantom, The (Italy) (Proto)" + description "Phantom, The (Italy) (Proto)" + rom ( name "Phantom, The (Italy) (Proto).gba" size 8388608 crc 5833169c sha1 ccd8e9d092a9ded9c3785ac776d40df66512b9b5 ) ) game ( @@ -13674,12 +13548,6 @@ game ( rom ( name "Pinball Tycoon (USA).gba" size 4194304 crc 1c4d3fdf sha1 fac76a646d112a775f9877b53f1386716d968a79 ) ) -game ( - name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" - description "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" - rom ( name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl).gba" size 1048576 crc 9ec140d3 sha1 9e19e8f97e8619a4755c3ceb482fa3e2ad5a4529 ) -) - game ( name "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" description "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" @@ -13830,12 +13698,6 @@ game ( rom ( name "Pocket Dogs (USA).gba" size 8388608 crc beddc67f sha1 79a90b119ea84c5812575d20ba6107be7edbfee7 ) ) -game ( - name "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" - description "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" - rom ( name "Pocket Meat (World) (Proto) (Aftermarket) (Unl).gba" size 861952 crc 0b029da3 sha1 9958d9a66742cc00e234a96c311b2acec40f69d1 ) -) - game ( name "Pocket Monsters - Emerald (Japan)" description "Pocket Monsters - Emerald (Japan)" @@ -14700,6 +14562,12 @@ game ( rom ( name "Punch King - Arcade Boxing (USA).gba" size 8388608 crc 540b6cc1 sha1 021fdd9420a81a3aa8f37de884ac2b8f42e691ed ) ) +game ( + name "Punch King - Arcade Boxing (World) (Evercade) (Unl)" + description "Punch King - Arcade Boxing (World) (Evercade) (Unl)" + rom ( name "Punch King - Arcade Boxing (World) (Evercade) (Unl).gba" size 8388608 crc 2afd6ff9 sha1 9e145758d3727c664c0612407f4b4d04f7b1733d ) +) + game ( name "Puppy Luv - Spa and Resort (USA)" description "Puppy Luv - Spa and Resort (USA)" @@ -14803,15 +14671,15 @@ game ( ) game ( - name "Racing Fever (Europe) (En,De,Es,It)" - description "Racing Fever (Europe) (En,De,Es,It)" - rom ( name "Racing Fever (Europe) (En,De,Es,It).gba" size 4194304 crc e40ec737 sha1 9bb5c036bca8f0d2e06013cac7ea6148a4f7f512 ) + name "Racing Fever (World) (En,De,Es,It) (Evercade) (Unl)" + description "Racing Fever (World) (En,De,Es,It) (Evercade) (Unl)" + rom ( name "Racing Fever (World) (En,De,Es,It) (Evercade) (Unl).gba" size 4194304 crc dbd09923 sha1 b10861c12a08826c58dffdbd3071ff72f753b76e ) ) game ( - name "Racing Gears Advance (USA) (Beta)" - description "Racing Gears Advance (USA) (Beta)" - rom ( name "Racing Gears Advance (USA) (Beta).gba" size 8388608 crc 7a3820b3 sha1 ff18dfe7d75a8154c0dcc3970e5d0d4cb75c3568 ) + name "Racing Fever (Europe) (En,De,Es,It)" + description "Racing Fever (Europe) (En,De,Es,It)" + rom ( name "Racing Fever (Europe) (En,De,Es,It).gba" size 4194304 crc e40ec737 sha1 9bb5c036bca8f0d2e06013cac7ea6148a4f7f512 ) ) game ( @@ -14826,6 +14694,12 @@ game ( rom ( name "Racing Gears Advance (USA).gba" size 8388608 crc bf648e5c sha1 3f053865f9a687a75927172cd281390b2560201c ) ) +game ( + name "Racing Gears Advance (USA) (Beta)" + description "Racing Gears Advance (USA) (Beta)" + rom ( name "Racing Gears Advance (USA) (Beta).gba" size 8388608 crc 7a3820b3 sha1 ff18dfe7d75a8154c0dcc3970e5d0d4cb75c3568 ) +) + game ( name "Rampage - Puzzle Attack (USA, Europe)" description "Rampage - Puzzle Attack (USA, Europe)" @@ -14838,6 +14712,12 @@ game ( rom ( name "Rapala Pro Fishing (USA, Europe).gba" size 4194304 crc 964d39a7 sha1 e3df6fe7a447ab30faf6fd7d4c57e88f987a5639 ) ) +game ( + name "Ratatouille (Australia, Greece) (En)" + description "Ratatouille (Australia, Greece) (En)" + rom ( name "Ratatouille (Australia, Greece) (En).gba" size 8388608 crc 3e1711c7 sha1 58f2fa1d7e531c7345b11db268e1bbc10372bebc flags verified ) +) + game ( name "Ratatouille (USA)" description "Ratatouille (USA)" @@ -14862,12 +14742,6 @@ game ( rom ( name "Ratatouille (Europe) (En,It,Sv,No,Da).gba" size 8388608 crc 82f9c596 sha1 a5c4a636979c06670a81428c778ff76ed2c65eee ) ) -game ( - name "Ratatouille (Australia, Greece) (En)" - description "Ratatouille (Australia, Greece) (En)" - rom ( name "Ratatouille (Australia, Greece) (En).gba" size 8388608 crc 3e1711c7 sha1 58f2fa1d7e531c7345b11db268e1bbc10372bebc flags verified ) -) - game ( name "Rave Master - Special Attack Force! (USA)" description "Rave Master - Special Attack Force! (USA)" @@ -15006,12 +14880,6 @@ game ( rom ( name "Ready 2 Rumble Boxing - Round 2 (Europe) (En,Fr,De).gba" size 4194304 crc e418e962 sha1 57d06e405b281f68800b986bd9ff1257e4466939 flags verified ) ) -game ( - name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta)" - description "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta).gba" size 4194304 crc 2189021c sha1 b6e2167272a68bd4e3833cccd68929d50a27a426 ) -) - game ( name "Rebelstar - Tactical Command (USA)" description "Rebelstar - Tactical Command (USA)" @@ -15024,6 +14892,12 @@ game ( rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e448c5d4 sha1 669c47e62f2388ce0ba676f3dc641b5ad2ddb5c5 flags verified ) ) +game ( + name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta)" + description "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta)" + rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta).gba" size 4194304 crc 2189021c sha1 b6e2167272a68bd4e3833cccd68929d50a27a426 ) +) + game ( name "Recca no Honoo - The Game (Japan)" description "Recca no Honoo - The Game (Japan)" @@ -15198,6 +15072,12 @@ game ( rom ( name "Robot Wars - Advanced Destruction (USA).gba" size 4194304 crc e6cb567d sha1 952adf4e17865abc2b983c79ad4080e9b4867370 ) ) +game ( + name "Robot Wars - Advanced Destruction (USA) (Beta) (2001-03-20)" + description "Robot Wars - Advanced Destruction (USA) (Beta) (2001-03-20)" + rom ( name "Robot Wars - Advanced Destruction (USA) (Beta) (2001-03-20).gba" size 585104 crc ce95bbd6 sha1 e045c21b0fef1959c1207bb46e509089b03fd6db ) +) + game ( name "Robot Wars - Extreme Destruction (Europe) (En,Fr,De,Es,It,Nl)" description "Robot Wars - Extreme Destruction (Europe) (En,Fr,De,Es,It,Nl)" @@ -15210,6 +15090,12 @@ game ( rom ( name "Robotech - The Macross Saga (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 325a6596 sha1 3dbfe433a2376589a24754bb7337306c43176b34 flags verified ) ) +game ( + name "Robots (Japan)" + description "Robots (Japan)" + rom ( name "Robots (Japan).gba" size 16777216 crc 1beb9e91 sha1 b1a670daf53d47f237a4078388178c16c843d4dc ) +) + game ( name "Robots (USA)" description "Robots (USA)" @@ -15222,12 +15108,6 @@ game ( rom ( name "Robots (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 2acbdb64 sha1 26be826817f35433b3609d13ee75a3872e94d616 flags verified ) ) -game ( - name "Robots (Japan)" - description "Robots (Japan)" - rom ( name "Robots (Japan).gba" size 16777216 crc 1beb9e91 sha1 b1a670daf53d47f237a4078388178c16c843d4dc ) -) - game ( name "Rock 'N Roll Racing (USA)" description "Rock 'N Roll Racing (USA)" @@ -15279,7 +15159,7 @@ game ( game ( name "Rocket Power - Zero Gravity Zone (USA)" description "Rocket Power - Zero Gravity Zone (USA)" - rom ( name "Rocket Power - Zero Gravity Zone (USA).gba" size 8388608 crc 26d62d32 sha1 2e8fcf7afe49b57c2527f31288198a4b93df8bec ) + rom ( name "Rocket Power - Zero Gravity Zone (USA).gba" size 8388608 crc 26d62d32 sha1 2e8fcf7afe49b57c2527f31288198a4b93df8bec flags verified ) ) game ( @@ -15759,7 +15639,7 @@ game ( game ( name "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It)" description "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It)" - rom ( name "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc d5410d32 sha1 9a483e98d72b1d7d8579511cc9344e5d27bcee61 ) + rom ( name "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc d5410d32 sha1 9a483e98d72b1d7d8579511cc9344e5d27bcee61 flags verified ) ) game ( @@ -15981,7 +15861,7 @@ game ( game ( name "Shamu's Deep Sea Adventures (USA)" description "Shamu's Deep Sea Adventures (USA)" - rom ( name "Shamu's Deep Sea Adventures (USA).gba" size 33554432 crc 4e9426eb sha1 0bca9c4dd35d02c52a5db98b2097a50ef159de32 ) + rom ( name "Shamu's Deep Sea Adventures (USA).gba" size 33554432 crc 7ecb7529 sha1 1927b344bba21bcd80544a55734234610972f373 flags verified ) ) game ( @@ -16518,12 +16398,6 @@ game ( rom ( name "Sims, The - Bustin' Out (USA) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 16777216 crc d1183501 sha1 7038fa0e4cb8aeac9e48a0b45574db66cba39e73 flags verified ) ) -game ( - name "Sips (World) (Aftermarket) (Unl)" - description "Sips (World) (Aftermarket) (Unl)" - rom ( name "Sips (World) (Aftermarket) (Unl).gba" size 6235380 crc 5c1fb22d sha1 bb725df7226307d55df04365f85e5698b199c3c9 ) -) - game ( name "Sister Princess - RePure (Japan)" description "Sister Princess - RePure (Japan)" @@ -16572,30 +16446,6 @@ game ( rom ( name "Sky Dancers - They Magically Fly! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3af1063b sha1 df749ac7e33a1c7ede3faadb6648a8e53fa77048 ) ) -game ( - name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl).gba" size 15887876 crc c798529d sha1 ea4a6494bcec25757f657c69550c91190e46cebd ) -) - -game ( - name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl).gba" size 15894868 crc af572de8 sha1 997bf192369d48433a7c35187c7e1d0b5fcc16e0 ) -) - -game ( - name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl).gba" size 15900084 crc df05edff sha1 1328d17668480b4e9bea338662532ace332c74a9 ) -) - -game ( - name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl).gba" size 16075456 crc d271c516 sha1 0dbdf16b23afb70229eff2de269fd5d73659d745 ) -) - game ( name "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" description "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" @@ -16653,7 +16503,7 @@ game ( game ( name "Snood (USA)" description "Snood (USA)" - rom ( name "Snood (USA).gba" size 4194304 crc f1f1f148 sha1 2c09548ae924ac0c1a3e15412d9a7aae7707a753 ) + rom ( name "Snood (USA).gba" size 4194304 crc f1f1f148 sha1 2c09548ae924ac0c1a3e15412d9a7aae7707a753 flags verified ) ) game ( @@ -16884,6 +16734,12 @@ game ( rom ( name "Space Invaders EX (Japan) (En).gba" size 4194304 crc 297b9854 sha1 ae8cace77baccdb8f25c9b44ea3cf64d881b91a8 ) ) +game ( + name "Space Twins (World) (Proto) (Unl)" + description "Space Twins (World) (Proto) (Unl)" + rom ( name "Space Twins (World) (Proto) (Unl).gba" size 1350536 crc 0edc97d9 sha1 4a9848cc2262b30aba7e87013c0a197e01cc9617 ) +) + game ( name "Speedball 2 (Europe) (En,Fr,De,Es,It)" description "Speedball 2 (Europe) (En,Fr,De,Es,It)" @@ -17070,6 +16926,18 @@ game ( rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (Europe) (En,Fr,De,Es,It,Nl,Sv).gba" size 8388608 crc c189013d sha1 09d945acc251000c49539a3f18b21e48520ec8ad flags verified ) ) +game ( + name "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-03)" + description "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-03)" + rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-03).gba" size 4291500 crc 52fd3771 sha1 72d84f52c796cbb06c2cd9291ca7952093d9b7dc ) +) + +game ( + name "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-05)" + description "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-05)" + rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-05).gba" size 4519932 crc e1461b58 sha1 b30dc120107a70796250b831e7174fc4c03ae58a ) +) + game ( name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" description "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" @@ -17166,6 +17034,24 @@ game ( rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-07-31).gba" size 4194304 crc f2f67f40 sha1 bb298d490ec9d8657cbd2fc402ae1e0a5792d406 ) ) +game ( + name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-03-28)" + description "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-03-28)" + rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-03-28).gba" size 4646712 crc 1407d86e sha1 2608c985c8ab5bffeae0687421bb21a46e34b681 ) +) + +game ( + name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-03)" + description "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-03)" + rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-03).gba" size 5477108 crc 0bc6dfaf sha1 c617321d405f4a5bb07c4fa769321df46a944bb8 ) +) + +game ( + name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-04)" + description "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-04)" + rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-04).gba" size 5477244 crc 23d7ba77 sha1 0177808f1bcd65738c10fd0fba477ecdd46a791f ) +) + game ( name "SpongeBob SquarePants and Friends - Battle for Volcano Island (Europe) (En,Fr,De,Es,It,Nl)" description "SpongeBob SquarePants and Friends - Battle for Volcano Island (Europe) (En,Fr,De,Es,It,Nl)" @@ -17277,7 +17163,7 @@ game ( game ( name "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It)" description "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It)" - rom ( name "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc afd25827 sha1 854e788e5e1316b7d5cdf6b961d0969e5cd62119 ) + rom ( name "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc afd25827 sha1 854e788e5e1316b7d5cdf6b961d0969e5cd62119 flags verified ) ) game ( @@ -17349,7 +17235,7 @@ game ( game ( name "SSX 3 (USA, Europe)" description "SSX 3 (USA, Europe)" - rom ( name "SSX 3 (USA, Europe).gba" size 8388608 crc 8232f58a sha1 4f2bd55bcd3118e10520179e285aae897aa21898 ) + rom ( name "SSX 3 (USA, Europe).gba" size 8388608 crc 8232f58a sha1 4f2bd55bcd3118e10520179e285aae897aa21898 flags verified ) ) game ( @@ -17385,7 +17271,7 @@ game ( game ( name "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl)" description "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc fd49236b sha1 4ba5e5a6174bad9369f088f801c743f88616c5f4 ) + rom ( name "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc fd49236b sha1 4ba5e5a6174bad9369f088f801c743f88616c5f4 flags verified ) ) game ( @@ -17439,7 +17325,7 @@ game ( game ( name "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl)" description "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc c9f0c492 sha1 51ffd3684d9bd8140d8c7969d7eb2096dd2424a5 ) + rom ( name "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc c9f0c492 sha1 51ffd3684d9bd8140d8c7969d7eb2096dd2424a5 flags verified ) ) game ( @@ -17571,7 +17457,7 @@ game ( game ( name "Stuart Little 2 (USA, Europe)" description "Stuart Little 2 (USA, Europe)" - rom ( name "Stuart Little 2 (USA, Europe).gba" size 8388608 crc 6eb7c688 sha1 fdb6d8098340966456cd05c7babe77b5a204608c ) + rom ( name "Stuart Little 2 (USA, Europe).gba" size 8388608 crc 6eb7c688 sha1 fdb6d8098340966456cd05c7babe77b5a204608c flags verified ) ) game ( @@ -17676,6 +17562,12 @@ game ( rom ( name "Super Bubble Pop (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv).gba" size 4194304 crc 25123d97 sha1 f62396b5502437651d26e1ad27a8ec8c18b4268e ) ) +game ( + name "Super Bubble Pop (World) (Evercade) (Unl)" + description "Super Bubble Pop (World) (Evercade) (Unl)" + rom ( name "Super Bubble Pop (World) (Evercade) (Unl).gba" size 4194304 crc 940f385e sha1 fa2c3b84014a84143f519609a8808d13ca33bf22 ) +) + game ( name "Super Bust-A-Move (Europe) (En,Fr,De,Es,It)" description "Super Bust-A-Move (Europe) (En,Fr,De,Es,It)" @@ -17701,15 +17593,9 @@ game ( ) game ( - name "Super Dodge Ball Advance (USA)" - description "Super Dodge Ball Advance (USA)" - rom ( name "Super Dodge Ball Advance (USA).gba" size 4194304 crc 1d31dc6b sha1 5fc95814ea7695d1301df4b545614a1ffae95218 ) -) - -game ( - name "Super Dodge Ball Advance (Europe)" - description "Super Dodge Ball Advance (Europe)" - rom ( name "Super Dodge Ball Advance (Europe).gba" size 4194304 crc 4ca4f528 sha1 a0ac6be19f385eef6bc48bca8d54520d4e8a00e7 flags verified ) + name "Super Dodge Ball Advance (USA) (Rev 1)" + description "Super Dodge Ball Advance (USA) (Rev 1)" + rom ( name "Super Dodge Ball Advance (USA) (Rev 1).gba" size 4194304 crc 63ca5050 sha1 29561789fcb3bcd106a5d27dea47f29b393191f6 ) ) game ( @@ -17719,9 +17605,15 @@ game ( ) game ( - name "Super Dodge Ball Advance (USA) (Rev 1)" - description "Super Dodge Ball Advance (USA) (Rev 1)" - rom ( name "Super Dodge Ball Advance (USA) (Rev 1).gba" size 4194304 crc 63ca5050 sha1 29561789fcb3bcd106a5d27dea47f29b393191f6 ) + name "Super Dodge Ball Advance (USA)" + description "Super Dodge Ball Advance (USA)" + rom ( name "Super Dodge Ball Advance (USA).gba" size 4194304 crc 1d31dc6b sha1 5fc95814ea7695d1301df4b545614a1ffae95218 ) +) + +game ( + name "Super Dodge Ball Advance (Europe)" + description "Super Dodge Ball Advance (Europe)" + rom ( name "Super Dodge Ball Advance (Europe).gba" size 4194304 crc 4ca4f528 sha1 a0ac6be19f385eef6bc48bca8d54520d4e8a00e7 flags verified ) ) game ( @@ -17775,7 +17667,7 @@ game ( game ( name "Super Hornet FA 18F (USA, Europe)" description "Super Hornet FA 18F (USA, Europe)" - rom ( name "Super Hornet FA 18F (USA, Europe).gba" size 4194304 crc 9653bac5 sha1 038b533bb09845ade7b0a13c7ca9923348eb1100 ) + rom ( name "Super Hornet FA 18F (USA, Europe).gba" size 4194304 crc 9653bac5 sha1 038b533bb09845ade7b0a13c7ca9923348eb1100 flags verified ) ) game ( @@ -18169,9 +18061,9 @@ game ( ) game ( - name "Sushi the Cat (World) (Aftermarket) (Unl)" - description "Sushi the Cat (World) (Aftermarket) (Unl)" - rom ( name "Sushi the Cat (World) (Aftermarket) (Unl).gba" size 540296 crc 6f019a88 sha1 f6d523a073c21639e15d615947167bba3871c67a ) + name "Sushi the Cat (World) (Unl)" + description "Sushi the Cat (World) (Unl)" + rom ( name "Sushi the Cat (World) (Unl).gba" size 540296 crc 6f019a88 sha1 f6d523a073c21639e15d615947167bba3871c67a ) ) game ( @@ -18249,7 +18141,7 @@ game ( game ( name "Tak - The Great Juju Challenge (USA, Europe)" description "Tak - The Great Juju Challenge (USA, Europe)" - rom ( name "Tak - The Great Juju Challenge (USA, Europe).gba" size 8388608 crc 881c8416 sha1 0999a8ee2bae78a223c992408e987422ba0c0af9 ) + rom ( name "Tak - The Great Juju Challenge (USA, Europe).gba" size 8388608 crc 881c8416 sha1 0999a8ee2bae78a223c992408e987422ba0c0af9 flags verified ) ) game ( @@ -18261,7 +18153,7 @@ game ( game ( name "Tak 2 - The Staff of Dreams (USA)" description "Tak 2 - The Staff of Dreams (USA)" - rom ( name "Tak 2 - The Staff of Dreams (USA).gba" size 8388608 crc 8f7eb026 sha1 f90219db6359332eb997a2717986a8c66eaded2b ) + rom ( name "Tak 2 - The Staff of Dreams (USA).gba" size 8388608 crc 8f7eb026 sha1 f90219db6359332eb997a2717986a8c66eaded2b flags verified ) ) game ( @@ -18537,7 +18429,7 @@ game ( game ( name "Tetris Worlds (Europe) (En,Fr,De,Nl)" description "Tetris Worlds (Europe) (En,Fr,De,Nl)" - rom ( name "Tetris Worlds (Europe) (En,Fr,De,Nl).gba" size 4194304 crc ad97eb3f sha1 4a1297b44208366a178cc1f2541f5ea8386f6f3e ) + rom ( name "Tetris Worlds (Europe) (En,Fr,De,Nl).gba" size 4194304 crc ad97eb3f sha1 4a1297b44208366a178cc1f2541f5ea8386f6f3e flags verified ) ) game ( @@ -18549,7 +18441,7 @@ game ( game ( name "Texas Hold 'em Poker (USA)" description "Texas Hold 'em Poker (USA)" - rom ( name "Texas Hold 'em Poker (USA).gba" size 4194304 crc 78b59aac sha1 5fcc9958210d8bde94a429516b15ca669427fe6d ) + rom ( name "Texas Hold 'em Poker (USA).gba" size 4194304 crc 78b59aac sha1 5fcc9958210d8bde94a429516b15ca669427fe6d flags verified ) ) game ( @@ -18609,13 +18501,13 @@ game ( game ( name "Thunder Alley (USA)" description "Thunder Alley (USA)" - rom ( name "Thunder Alley (USA).gba" size 4194304 crc 25e8e649 sha1 d63aaf9ac4468f1d0ead35606d9a4f56327b2537 ) + rom ( name "Thunder Alley (USA).gba" size 4194304 crc 25e8e649 sha1 d63aaf9ac4468f1d0ead35606d9a4f56327b2537 flags verified ) ) game ( name "Thunderbirds (USA, Europe)" description "Thunderbirds (USA, Europe)" - rom ( name "Thunderbirds (USA, Europe).gba" size 4194304 crc f09b7bb0 sha1 08c4b9b924f5cf0404cab5cd7fb6064fca872250 ) + rom ( name "Thunderbirds (USA, Europe).gba" size 4194304 crc f09b7bb0 sha1 08c4b9b924f5cf0404cab5cd7fb6064fca872250 flags verified ) ) game ( @@ -18633,7 +18525,7 @@ game ( game ( name "Tiger Woods PGA Tour Golf (USA, Europe)" description "Tiger Woods PGA Tour Golf (USA, Europe)" - rom ( name "Tiger Woods PGA Tour Golf (USA, Europe).gba" size 8388608 crc f3f26acc sha1 88b204b7b51995e41459b532580b3956d7db55ad ) + rom ( name "Tiger Woods PGA Tour Golf (USA, Europe).gba" size 8388608 crc f3f26acc sha1 88b204b7b51995e41459b532580b3956d7db55ad flags verified ) ) game ( @@ -18675,7 +18567,7 @@ game ( game ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" description "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" - rom ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4ac770b6 sha1 cd9d810b29070d9f37df219bfd7e52ce9d52d2b0 ) + rom ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4ac770b6 sha1 cd9d810b29070d9f37df219bfd7e52ce9d52d2b0 flags verified ) ) game ( @@ -18798,6 +18690,12 @@ game ( rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6863ce1a sha1 092179cd51657a4572fa855eb3e5bc3f46c1d76f ) ) +game ( + name "Tom Clancy's Rainbow Six - Rogue Spear (USA, Europe) (En,Fr,De,Es,It) (Beta) (2001-10-25)" + description "Tom Clancy's Rainbow Six - Rogue Spear (USA, Europe) (En,Fr,De,Es,It) (Beta) (2001-10-25)" + rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (USA, Europe) (En,Fr,De,Es,It) (Beta) (2001-10-25).gba" size 7963152 crc 666e31b5 sha1 d8426022537149670871817ff9336261b31172b5 ) +) + game ( name "Tom Clancy's Splinter Cell (USA) (En,Fr,Es)" description "Tom Clancy's Splinter Cell (USA) (En,Fr,Es)" @@ -19047,7 +18945,7 @@ game ( game ( name "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube)" description "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube)" - rom ( name "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 7cd6839c sha1 ace1d3587636d17fd9ebfe7a7cfd3ee36bc51b43 flags verified ) + rom ( name "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 7cd6839c sha1 ace1d3587636d17fd9ebfe7a7cfd3ee36bc51b43 ) ) game ( @@ -19119,37 +19017,7 @@ game ( game ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl)" description "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc d52ddce1 sha1 d89a2515f4fe0d0ac90b20e4633a80a2549175fc ) -) - -game ( - name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl).gba" size 16239516 crc ce85ba07 sha1 b09b600bfc222c2d92829d8883feab700b013953 ) -) - -game ( - name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16229600 crc bd57344d sha1 a2fcfe94c9b8b0feff31c1245c8b033222c9f668 ) -) - -game ( - name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - description "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16204024 crc fa43669e sha1 a57392fa7cee61913b20a840fe8b2ee27f11d808 ) -) - -game ( - name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl).gba" size 16777216 crc ff5d64ab sha1 645ab8d4dacb6666d8eb549d491f77d8cd63ce97 ) -) - -game ( - name "Tremblay Island (World) (Aftermarket) (Unl)" - description "Tremblay Island (World) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (Aftermarket) (Unl).gba" size 16225608 crc 95503690 sha1 634ea6be3df5ebd85c9c60871e34fc3c72ae5140 ) + rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc d52ddce1 sha1 d89a2515f4fe0d0ac90b20e4633a80a2549175fc flags verified ) ) game ( @@ -19461,7 +19329,7 @@ game ( game ( name "Unfabulous (USA)" description "Unfabulous (USA)" - rom ( name "Unfabulous (USA).gba" size 4194304 crc 2547f3a1 sha1 a56e96a46ed7264bddbfc132925d291e3e8f0e38 ) + rom ( name "Unfabulous (USA).gba" size 4194304 crc 2547f3a1 sha1 a56e96a46ed7264bddbfc132925d291e3e8f0e38 flags verified ) ) game ( @@ -19494,6 +19362,36 @@ game ( rom ( name "Uno 52 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 315360d0 sha1 f85709ec7a97c8b40504f2097497bd961531272d ) ) +game ( + name "Uranus (World) (Unl)" + description "Uranus (World) (Unl)" + rom ( name "Uranus (World) (Unl).gba" size 4194304 crc 8152384d sha1 2c99b0c66cea1ce8d203aaa0985baa43fcdd82bd ) +) + +game ( + name "Uranus 2 - Sun Tear (World) (En,Fr) (Unl)" + description "Uranus 2 - Sun Tear (World) (En,Fr) (Unl)" + rom ( name "Uranus 2 - Sun Tear (World) (En,Fr) (Unl).gba" size 4194304 crc f1c63552 sha1 7c68363212a7fb424429281a658cbadfe37de035 ) +) + +game ( + name "Uranus Zero - Sun Tear (World) (En,Fr) (Unl)" + description "Uranus Zero - Sun Tear (World) (En,Fr) (Unl)" + rom ( name "Uranus Zero - Sun Tear (World) (En,Fr) (Unl).gba" size 8388608 crc 117183cc sha1 258058fb9ca44a93478220e19d0cf09cde527003 ) +) + +game ( + name "Uranus Zero EV (World) (En,Fr) (v1.1) (Unl)" + description "Uranus Zero EV (World) (En,Fr) (v1.1) (Unl)" + rom ( name "Uranus Zero EV (World) (En,Fr) (v1.1) (Unl).gba" size 7609632 crc 1b463c9e sha1 bb2536ae8c6b625f3abfb66add7c1b3b74b942ee ) +) + +game ( + name "Uranus Zero EV (World) (En,Fr) (Unl)" + description "Uranus Zero EV (World) (En,Fr) (Unl)" + rom ( name "Uranus Zero EV (World) (En,Fr) (Unl).gba" size 7610684 crc adbcba92 sha1 405fb8cefb7ab0262a5f3bb7d290b9b60128db9b ) +) + game ( name "Urban Yeti! (USA, Europe)" description "Urban Yeti! (USA, Europe)" @@ -19611,7 +19509,7 @@ game ( game ( name "W.i.t.c.h. (Europe) (En,Fr,De,Es,It)" description "W.i.t.c.h. (Europe) (En,Fr,De,Es,It)" - rom ( name "W.i.t.c.h. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ca4f6d5d sha1 dce3603206745f3d9288f35eab33cc0f890c3751 ) + rom ( name "W.i.t.c.h. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ca4f6d5d sha1 dce3603206745f3d9288f35eab33cc0f890c3751 flags verified ) ) game ( @@ -19656,12 +19554,6 @@ game ( rom ( name "Wagamama Fairy Mirumo de Pon! - Yume no Kakera (Japan).gba" size 8388608 crc a606c803 sha1 0429693de0ff6e020b01807047dbb07b70b42529 ) ) -game ( - name "Waimanu - Grinding Blocks Adventure (World) (Homebrew)" - description "Waimanu - Grinding Blocks Adventure (World) (Homebrew)" - rom ( name "Waimanu - Grinding Blocks Adventure (World) (Homebrew).gba" size 1739504 crc 0fe153c5 sha1 c4ce156b04fb257875bc5f539f3d64accbc08451 ) -) - game ( name "Wakeboarding Unleashed Featuring Shaun Murray (Europe)" description "Wakeboarding Unleashed Featuring Shaun Murray (Europe)" @@ -19716,12 +19608,6 @@ game ( rom ( name "Wanwan Meitantei (Japan).gba" size 8388608 crc 5f41c9fe sha1 d438e3b030a814818ed7e96777ac3e46043922f9 ) ) -game ( - name "Wario Land 4 (USA, Europe)" - description "Wario Land 4 (USA, Europe)" - rom ( name "Wario Land 4 (USA, Europe).gba" size 8388608 crc d6141609 sha1 b9fe05a8080e124b67bce6a623234ee3b518a2c1 flags verified ) -) - game ( name "Wario Land 4 (USA, Europe) (Virtual Console)" description "Wario Land 4 (USA, Europe) (Virtual Console)" @@ -19729,9 +19615,9 @@ game ( ) game ( - name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" - description "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" - rom ( name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console).gba" size 8388608 crc a8cd90f9 sha1 2d3e6b124c84877520b482ba1016b8e3c36bab14 ) + name "Wario Land 4 (USA, Europe)" + description "Wario Land 4 (USA, Europe)" + rom ( name "Wario Land 4 (USA, Europe).gba" size 8388608 crc d6141609 sha1 b9fe05a8080e124b67bce6a623234ee3b518a2c1 flags verified ) ) game ( @@ -19741,15 +19627,15 @@ game ( ) game ( - name "WarioWare - Twisted! (USA, Australia)" - description "WarioWare - Twisted! (USA, Australia)" - rom ( name "WarioWare - Twisted! (USA, Australia).gba" size 16777216 crc cb4e844b sha1 f0102d0d6f7596fe853d5d0a94682718278e083a flags verified ) + name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" + description "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" + rom ( name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console).gba" size 8388608 crc a8cd90f9 sha1 2d3e6b124c84877520b482ba1016b8e3c36bab14 ) ) game ( - name "WarioWare, Inc. - Mega Microgame$! (USA)" - description "WarioWare, Inc. - Mega Microgame$! (USA)" - rom ( name "WarioWare, Inc. - Mega Microgame$! (USA).gba" size 8388608 crc 785d8b8c sha1 3f556448d290fa5406d6ed367fee16cc02387ad3 flags verified ) + name "WarioWare - Twisted! (USA, Australia)" + description "WarioWare - Twisted! (USA, Australia)" + rom ( name "WarioWare - Twisted! (USA, Australia).gba" size 16777216 crc cb4e844b sha1 f0102d0d6f7596fe853d5d0a94682718278e083a flags verified ) ) game ( @@ -19765,9 +19651,9 @@ game ( ) game ( - name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" - description "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" - rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc 1fe34e43 sha1 dca921c60b3686be6b3a5feeec7a4f37a921aee3 ) + name "WarioWare, Inc. - Mega Microgame$! (USA)" + description "WarioWare, Inc. - Mega Microgame$! (USA)" + rom ( name "WarioWare, Inc. - Mega Microgame$! (USA).gba" size 8388608 crc 785d8b8c sha1 3f556448d290fa5406d6ed367fee16cc02387ad3 flags verified ) ) game ( @@ -19776,6 +19662,12 @@ game ( rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 500ca178 sha1 aad81e722aa88f98913c0354e559f845c4689cce flags verified ) ) +game ( + name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" + description "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" + rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc 1fe34e43 sha1 dca921c60b3686be6b3a5feeec7a4f37a921aee3 ) +) + game ( name "Weekend Miljonairs (Netherlands)" description "Weekend Miljonairs (Netherlands)" @@ -19908,18 +19800,18 @@ game ( rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 2).gba" size 4194304 crc 9fb4af0a sha1 9151cf54475c4f773bdd9ab86a42d3e1ba462afa ) ) -game ( - name "Winning Post for Game Boy Advance (Japan)" - description "Winning Post for Game Boy Advance (Japan)" - rom ( name "Winning Post for Game Boy Advance (Japan).gba" size 4194304 crc 5ada60f6 sha1 cc7e9c2a9e1df985aed3dc4a018c93140d7a1b2c ) -) - game ( name "Winning Post for Game Boy Advance (Japan) (Rev 1)" description "Winning Post for Game Boy Advance (Japan) (Rev 1)" rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 1).gba" size 4194304 crc f6180af5 sha1 0f395a384b9db2415196edc2f911ccc67eb5e038 ) ) +game ( + name "Winning Post for Game Boy Advance (Japan)" + description "Winning Post for Game Boy Advance (Japan)" + rom ( name "Winning Post for Game Boy Advance (Japan).gba" size 4194304 crc 5ada60f6 sha1 cc7e9c2a9e1df985aed3dc4a018c93140d7a1b2c ) +) + game ( name "Winter Sports (Europe) (En,Fr,De,Es,It)" description "Winter Sports (Europe) (En,Fr,De,Es,It)" @@ -19950,18 +19842,6 @@ game ( rom ( name "WinX Club - Quest for the Codex (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 9eb09c77 sha1 84951f8baabc405eee8a1fb94d420397623265ad ) ) -game ( - name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" - description "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" - rom ( name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl).gba" size 1449956 crc 4ffa611d sha1 89bbeb3fbce1533acf2f2113642ebe2a4f9f79a8 ) -) - -game ( - name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" - description "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" - rom ( name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl).gba" size 1449956 crc 27055186 sha1 b9ce91d55870e07434509f6e2e91c2f90b4afc97 ) -) - game ( name "Wizardry Summoner (Japan) (Rev 1)" description "Wizardry Summoner (Japan) (Rev 1)" @@ -20011,15 +19891,15 @@ game ( ) game ( - name "World Championship Poker (Europe) (En,Fr,De,Es,It)" - description "World Championship Poker (Europe) (En,Fr,De,Es,It)" - rom ( name "World Championship Poker (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4776f86e sha1 731ef2646ad83750aff729cb2286de6ee60f8260 ) + name "World Championship Poker (USA)" + description "World Championship Poker (USA)" + rom ( name "World Championship Poker (USA).gba" size 4194304 crc 07f15152 sha1 1d72864021f88f8db2686c57cfc5176b33ce2015 flags verified ) ) game ( - name "World Championship Poker (USA)" - description "World Championship Poker (USA)" - rom ( name "World Championship Poker (USA).gba" size 4194304 crc 07f15152 sha1 1d72864021f88f8db2686c57cfc5176b33ce2015 ) + name "World Championship Poker (Europe) (En,Fr,De,Es,It)" + description "World Championship Poker (Europe) (En,Fr,De,Es,It)" + rom ( name "World Championship Poker (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4776f86e sha1 731ef2646ad83750aff729cb2286de6ee60f8260 ) ) game ( @@ -20041,9 +19921,9 @@ game ( ) game ( - name "World Reborn (USA) (Aftermarket) (Unl)" - description "World Reborn (USA) (Aftermarket) (Unl)" - rom ( name "World Reborn (USA) (Aftermarket) (Unl).gba" size 4194304 crc eefb32ff sha1 c7ec2f8d7d3dec40a893cdfe2a41a8ed43ed71c4 ) + name "World Tennis Stars (Europe)" + description "World Tennis Stars (Europe)" + rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc b5830f5f sha1 2a93449943e85b7c5d75d0d7a9e1d8ad67c7a706 ) ) game ( @@ -20053,9 +19933,9 @@ game ( ) game ( - name "World Tennis Stars (Europe)" - description "World Tennis Stars (Europe)" - rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc b5830f5f sha1 2a93449943e85b7c5d75d0d7a9e1d8ad67c7a706 ) + name "Worms - World Party (USA) (En,Fr,De,Es,It)" + description "Worms - World Party (USA) (En,Fr,De,Es,It)" + rom ( name "Worms - World Party (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e8789c18 sha1 7b078976d9056aba7f81bb1ff33e5a36357f5f0b ) ) game ( @@ -20064,18 +19944,18 @@ game ( rom ( name "Worms - World Party (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8ee32cbe sha1 5e0abe3d94d1489fadebe897df1ed5a5c0212901 ) ) -game ( - name "Worms - World Party (USA) (En,Fr,De,Es,It)" - description "Worms - World Party (USA) (En,Fr,De,Es,It)" - rom ( name "Worms - World Party (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e8789c18 sha1 7b078976d9056aba7f81bb1ff33e5a36357f5f0b ) -) - game ( name "Worms Blast (Europe) (En,Fr,De,Es,It)" description "Worms Blast (Europe) (En,Fr,De,Es,It)" rom ( name "Worms Blast (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 5223f5aa sha1 0da4ff24b61ae8b6d67ef59377770fd958517f2f ) ) +game ( + name "Worms Blast (World) (En,Fr,De,Es,It) (Evercade) (Unl)" + description "Worms Blast (World) (En,Fr,De,Es,It) (Evercade) (Unl)" + rom ( name "Worms Blast (World) (En,Fr,De,Es,It) (Evercade) (Unl).gba" size 4194304 crc 55c25c4a sha1 da4e430b5fef43bdb8a4c52a8fdec5ae98243ddb ) +) + game ( name "WTA Tour Tennis (USA)" description "WTA Tour Tennis (USA)" @@ -20118,18 +19998,18 @@ game ( rom ( name "X Zhan Jing (Taiwan) (Unl).gba" size 33554432 crc 652a2ebe sha1 a35c891af070819fd14e0704984197c8e04ae127 ) ) -game ( - name "X-Bladez - Inline Skater (USA)" - description "X-Bladez - Inline Skater (USA)" - rom ( name "X-Bladez - Inline Skater (USA).gba" size 4194304 crc 09fdd665 sha1 a8354a51738c6b28660ab74acc7f8445a9a570a1 ) -) - game ( name "X-Bladez - Inline Skater (Europe)" description "X-Bladez - Inline Skater (Europe)" rom ( name "X-Bladez - Inline Skater (Europe).gba" size 4194304 crc c05f9907 sha1 8a5dc506fd6e000116be2ca923a056bc15d5b553 ) ) +game ( + name "X-Bladez - Inline Skater (USA)" + description "X-Bladez - Inline Skater (USA)" + rom ( name "X-Bladez - Inline Skater (USA).gba" size 4194304 crc 09fdd665 sha1 a8354a51738c6b28660ab74acc7f8445a9a570a1 ) +) + game ( name "X-Man - Armour of Might (Russia) (Unl)" description "X-Man - Armour of Might (Russia) (Unl)" @@ -20217,19 +20097,19 @@ game ( game ( name "Yggdra Union (Japan)" description "Yggdra Union (Japan)" - rom ( name "Yggdra Union (Japan).gba" size 33554432 crc a86f844a sha1 4ac5874b98f0fa3c3aad4c3ebe927f7fbc5b3267 ) + rom ( name "Yggdra Union (Japan).gba" size 33554432 crc bf53a3d2 sha1 b55d786fd8f80e71d24097ae45f5fcc5948f395b ) ) game ( name "Yggdra Union - We'll Never Fight Alone (USA)" description "Yggdra Union - We'll Never Fight Alone (USA)" - rom ( name "Yggdra Union - We'll Never Fight Alone (USA).gba" size 33554432 crc 3bfa68f7 sha1 b289083b01f2f8fc726c664cf872d72b3f4986e3 ) + rom ( name "Yggdra Union - We'll Never Fight Alone (USA).gba" size 33554432 crc 84b5666c sha1 75697060a9c262fd00552ddd06faec82fc310282 ) ) game ( name "Yggdra Union - We'll Never Fight Alone (Europe)" description "Yggdra Union - We'll Never Fight Alone (Europe)" - rom ( name "Yggdra Union - We'll Never Fight Alone (Europe).gba" size 33554432 crc 3e0df130 sha1 e419c835200457f67d5ab7e3c236583980b922d9 ) + rom ( name "Yggdra Union - We'll Never Fight Alone (Europe).gba" size 33554432 crc 2931d6a8 sha1 7b65074cb5d75d8f12692a21e2be77fa963f10e2 ) ) game ( @@ -20268,6 +20148,12 @@ game ( rom ( name "Youkaidou (Japan).gba" size 8388608 crc 2a4a92b4 sha1 ed6578bb6a4f201ae5b269df5ce842158a34a421 ) ) +game ( + name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" + description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" + rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta).gba" size 16777216 crc 8cbfa66b sha1 d3906650386872a94b83c417ecef2369ece5b978 ) +) + game ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA)" description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA)" @@ -20280,12 +20166,6 @@ game ( rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 208d77ec sha1 66dc426b71195c11761f7ce58ffef231e8e227b1 ) ) -game ( - name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" - description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" - rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta).gba" size 16777216 crc 8cbfa66b sha1 d3906650386872a94b83c417ecef2369ece5b978 ) -) - game ( name "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe)" description "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe)" @@ -20343,7 +20223,7 @@ game ( game ( name "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It)" description "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 460e073f sha1 1d33877dcc5ec94cc0d68460163208c7ebfb6ad3 ) + rom ( name "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 460e073f sha1 1d33877dcc5ec94cc0d68460163208c7ebfb6ad3 flags verified ) ) game ( @@ -20721,7 +20601,7 @@ game ( clrmamepro ( name "Nintendo - Game Boy Advance (Multiboot)" description "Nintendo - Game Boy Advance (Multiboot)" - version 20220808-164416 + version 20240221-035028 author "Arctic Circle System, C. V. Reynolds, chillerecke, DeriLoko3, Hiccup, hking0036, niemand, norkmetnoil577, omonim2007, relax" homepage No-Intro url "https://www.no-intro.org" @@ -21311,8 +21191,8 @@ game ( clrmamepro ( name "Nintendo - Game Boy Advance (Video)" description "Nintendo - Game Boy Advance (Video)" - version 20230804-201325 - author "BigFred, C. V. Reynolds, DeadSkullzJr, Hiccup, kazumi213, omonim2007, relax, SonGoku, xuom2" + version 20240727-194101 + author "BigFred, C. V. Reynolds, DeadSkullzJr, Hiccup, kazumi213, omonim2007, Psychofox11, psykopat, relax, SonGoku, xuom2" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -21364,18 +21244,18 @@ game ( rom ( name "Game Boy Advance Video - Cartoon Network Collection - Premium Edition (USA, Europe).gba" size 33554432 crc f2825729 sha1 d0fe380fcdf5b1bb99188ed95c8c3272cbb65ce8 flags verified ) ) -game ( - name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" - description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5).gba" size 33554432 crc 1baf372d sha1 86f257c7b8d8feaee0a7e7dd5f5ba48053fd633e flags verified ) -) - game ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe)" rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe).gba" size 33554432 crc e9b7b8a4 sha1 5f17d2ec1a3ba1d605d486b6f6abcde6d82df767 ) ) +game ( + name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" + description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5).gba" size 33554432 crc 1baf372d sha1 86f257c7b8d8feaee0a7e7dd5f5ba48053fd633e flags verified ) +) + game ( name "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA, Europe)" @@ -21460,18 +21340,18 @@ game ( rom ( name "Game Boy Advance Video - Pokemon - Volume 4 (USA).gba" size 33554432 crc be468496 sha1 fd79b821ff601e0091f19ab9c86b08f1c39ea2f3 ) ) -game ( - name "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" - description "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" - rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 5).gba" size 67108864 crc 01468820 sha1 6128a476edb10e6839ac5bd2697e83b9b7a9b234 ) -) - game ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" description "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 6).gba" size 67108864 crc d2cf417a sha1 9bc5b60793b8a6de3b80eb2c213cd125e1fa468e flags verified ) ) +game ( + name "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" + description "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 5).gba" size 67108864 crc 01468820 sha1 6128a476edb10e6839ac5bd2697e83b9b7a9b234 flags verified ) +) + game ( name "Game Boy Advance Video - Shrek (USA) (Rev 5)" description "Game Boy Advance Video - Shrek (USA) (Rev 5)" @@ -21490,18 +21370,18 @@ game ( rom ( name "Game Boy Advance Video - Shrek + Shark Tale (USA) (Rev 5).gba" size 67108864 crc aadb3e3d sha1 f23390b7a62c605fbce6730addc29d381488e076 flags verified ) ) -game ( - name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" - description "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" - rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6).gba" size 67108864 crc 925b6c02 sha1 3bcb4acc5da539bc1b91c9537bf7ffa081ded1d4 ) -) - game ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" description "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5).gba" size 67108864 crc 0d353654 sha1 5cd627e205020297b25d707131883be5850515fe flags verified ) ) +game ( + name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" + description "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" + rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6).gba" size 67108864 crc 925b6c02 sha1 3bcb4acc5da539bc1b91c9537bf7ffa081ded1d4 ) +) + game ( name "Game Boy Advance Video - Sonic X - Volume 1 (USA)" description "Game Boy Advance Video - Sonic X - Volume 1 (USA)" @@ -21574,23 +21454,1203 @@ game ( rom ( name "Game Boy Advance Video - The Proud Family - Volume 1 (USA).gba" size 33554432 crc c6a91365 sha1 31a2cbb9b1b5adf7de399eecf2a9cec4f5412767 ) ) -game ( - name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France)" - description "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France)" - rom ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France).gba" size 33554432 crc c9b6ccf1 sha1 8fb43e5018cf2d4b1a2aa2d1693862ce248ab6b0 ) -) - game ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (USA, Europe)" description "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (USA, Europe)" rom ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (USA, Europe).gba" size 33554432 crc 8d631f4e sha1 6daf15bb61a10d1bbf94009886d6a76f9c937f8b flags verified ) ) +game ( + name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France)" + description "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France)" + rom ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France).gba" size 33554432 crc c9b6ccf1 sha1 8fb43e5018cf2d4b1a2aa2d1693862ce248ab6b0 flags verified ) +) + +clrmamepro ( + name "Nintendo - Game Boy Advance (Aftermarket)" + description "Nintendo - Game Boy Advance (Aftermarket)" + version 20240807-214821 + author "aci68, Arctic Circle System, Aringon, Bent, BigFred, bikerspade, C. V. Reynolds, chillerecke, DeadSkullzJr, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, FakeShemp, Flashfire42, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, Larsenv, Lesserkuma, Madeline, MeguCocoa, Money_114, NESBrew12, niemand, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Prominos, Psychofox11, psykopat, rarenight, relax, RetroGamer, Rifu, sCZther, SonGoku, Tauwasser, Tescu, togemet2, ufocrossing, Vallaine01, Whovian9369, xprism, xuom2, zg" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "2-in-1 - Smickeonn the Game + Smickeonn the Game Deluxe (World) (Demo) (Aftermarket) (Unl)" + description "2-in-1 - Smickeonn the Game + Smickeonn the Game Deluxe (World) (Demo) (Aftermarket) (Unl)" + rom ( name "2-in-1 - Smickeonn the Game + Smickeonn the Game Deluxe (World) (Demo) (Aftermarket) (Unl).gba" size 1648884 crc 8ad5b73f sha1 eb85e372f15299cde6fefa8a2967e7e2886c9c56 ) +) + +game ( + name "2048 Pool (World) (Aftermarket) (Unl)" + description "2048 Pool (World) (Aftermarket) (Unl)" + rom ( name "2048 Pool (World) (Aftermarket) (Unl).gba" size 203440 crc 9df6ae4f sha1 c93a9cf3502237b474e70de8dee274901ee7ecb2 ) +) + +game ( + name "Advanced Ghost Wranglin' (World) (Demo) (Aftermarket) (Unl)" + description "Advanced Ghost Wranglin' (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Advanced Ghost Wranglin' (World) (Demo) (Aftermarket) (Unl).gba" size 354992 crc 739eb5ce sha1 9cf53301404407aae24ac7735006f594ca0fe969 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl).gba" size 1710888 crc 3346891f sha1 270c426705df767a4ad2dc69d039842442f779b2 flags verified ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl).gba" size 1729120 crc a354d555 sha1 d7cd0ab9d622187d4ce55bf0c7f14a24ee781710 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl).gba" size 1775856 crc 41ea5b0b sha1 e351bc6a9046ec002fc2dfdee061047908bd4350 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl).gba" size 1775660 crc a234813c sha1 ad904624bf198a164ba580eea326cd30fffebac8 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl).gba" size 597104 crc 0a9098b4 sha1 0992fb6f38e49426adc834fb3831748a1caa1bc0 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl).gba" size 811840 crc 63c1cc2c sha1 faca8225ee20b8e5edb14e005af77b63c6f51446 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl).gba" size 1714000 crc eebb016f sha1 008a9d06f78bccc540ca4ece4d1982de76f95901 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl).gba" size 1710624 crc ba271987 sha1 04f1e79e79e894d8f45ed1ea2ff5aa67053f0ab3 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl).gba" size 1710624 crc df7108e3 sha1 bd267fd7e762acb8cd595e54bfd51a139864759e ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" + description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt).gba" size 1714000 crc 54ff2e56 sha1 0386315fc140db2a43a6f927c04de658bd800da9 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl).gba" size 1710952 crc cb4e2768 sha1 a7297cf4ecffc1f93f86edde68e1ff42e8099f3b ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (Evercade) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (Evercade) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (Evercade) (Aftermarket) (Unl).gba" size 1693656 crc 7d8c00d3 sha1 9fffd28c933ac88a441a2e262156c66a3a763829 ) +) + +game ( + name "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" + description "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" + rom ( name "Apotris (World) (v3.4.5) (Aftermarket) (Unl).gba" size 4194304 crc 55ae4312 sha1 fb7142bcc30f71f187cc51b7fcbc5a3958374c6c ) +) + +game ( + name "Armadillo Run (World) (Demo) (Aftermarket) (Unl)" + description "Armadillo Run (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Armadillo Run (World) (Demo) (Aftermarket) (Unl).gba" size 1260068 crc 5151babd sha1 dfb706257d598a5ae845ddf6485e59a88c16d210 ) +) + +game ( + name "Attack on Voxelburg (World) (Demo) (GBA Jam 2022) (Aftermarket) (Unl)" + description "Attack on Voxelburg (World) (Demo) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "Attack on Voxelburg (World) (Demo) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 827676 crc 941c1fe0 sha1 cb3823420a6e2399db7fa4805fefd1b5366c778e ) +) + +game ( + name "Battery Chad - Shock the World (World) (Demo) (Aftermarket) (Unl)" + description "Battery Chad - Shock the World (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Battery Chad - Shock the World (World) (Demo) (Aftermarket) (Unl).gba" size 609400 crc e0a4bc38 sha1 3274c915fb78d10541efa69dfbb8f9391f974ffe ) +) + +game ( + name "Blender Bros. (World) (Aftermarket) (Unl)" + description "Blender Bros. (World) (Aftermarket) (Unl)" + rom ( name "Blender Bros. (World) (Aftermarket) (Unl).gba" size 8388608 crc 440f2f06 sha1 8f9ca62306b7ab56d8da45673d7b7d0eb4c349c5 ) +) + +game ( + name "Blind Jump (World) (En,Ja,Fr,It,Ru) (v2021.11.20.0) (Proto) (Aftermarket) (Unl)" + description "Blind Jump (World) (En,Ja,Fr,It,Ru) (v2021.11.20.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Blind Jump (World) (En,Ja,Fr,It,Ru) (v2021.11.20.0) (Proto) (Aftermarket) (Unl).gba" size 16565008 crc 2342e91e sha1 2e5758789f7e109839ea302424c385c1247eab38 ) +) + +game ( + name "Blood Drive (World) (GBA Jam Week) (Aftermarket) (Unl)" + description "Blood Drive (World) (GBA Jam Week) (Aftermarket) (Unl)" + rom ( name "Blood Drive (World) (GBA Jam Week) (Aftermarket) (Unl).gba" size 1523780 crc 3444a7ae sha1 12a3c114563684fdca4a4ee1b3fea43ceaf226c0 ) +) + +game ( + name "Broken Circle (World) (En,It) (Aftermarket) (Unl)" + description "Broken Circle (World) (En,It) (Aftermarket) (Unl)" + rom ( name "Broken Circle (World) (En,It) (Aftermarket) (Unl).gba" size 16777216 crc 3212c09b sha1 e04a71dbe7b640cc53e81f447856e60666e64aa3 ) +) + +game ( + name "Brush Rush (World) (Proto) (GBA WinterJam 2023) (Aftermarket) (Unl)" + description "Brush Rush (World) (Proto) (GBA WinterJam 2023) (Aftermarket) (Unl)" + rom ( name "Brush Rush (World) (Proto) (GBA WinterJam 2023) (Aftermarket) (Unl).gba" size 371136 crc afdf2c03 sha1 d36f7bd6d0420597ba0f12f746f8ec8a628b3658 ) +) + +game ( + name "Butano Fighter (World) (Aftermarket) (Unl)" + description "Butano Fighter (World) (Aftermarket) (Unl)" + rom ( name "Butano Fighter (World) (Aftermarket) (Unl).gba" size 3482456 crc 3c31501c sha1 36efe397badf199c0339222dc825013c06b86423 ) +) + +game ( + name "Cat's Curse (World) (Aftermarket) (Unl)" + description "Cat's Curse (World) (Aftermarket) (Unl)" + rom ( name "Cat's Curse (World) (Aftermarket) (Unl).gba" size 353052 crc a35d87de sha1 4a149baad17840948c2d4ffdf068bfaf1116a024 ) +) + +game ( + name "CCCP (World) (Aftermarket) (Unl)" + description "CCCP (World) (Aftermarket) (Unl)" + rom ( name "CCCP (World) (Aftermarket) (Unl).gba" size 499440 crc ad634c54 sha1 324f0375e3f4f89455122e2663b831917013bfc3 ) +) + +game ( + name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" + description "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl).gba" size 5416932 crc f79b0d53 sha1 756f02396a150698e695ad4afd24445e2af70576 ) +) + +game ( + name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" + description "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl).gba" size 5418248 crc f5d36ad2 sha1 95a86dff641b11b4c2ed0d0fe8152c33b462d927 ) +) + +game ( + name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" + description "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl).gba" size 5418424 crc ff0e8ada sha1 08512605e5c02e81a72e24c2c8d4959d8e84e1f4 ) +) + +game ( + name "Codename Hacker (World) (En,Fr) (Aftermarket) (Unl)" + description "Codename Hacker (World) (En,Fr) (Aftermarket) (Unl)" + rom ( name "Codename Hacker (World) (En,Fr) (Aftermarket) (Unl).gba" size 4058684 crc 1ccfbe29 sha1 fbc6a366f773204b031b589aab4125e15a70dc9b ) +) + +game ( + name "Collie Defense (World) (Demo) (Aftermarket) (Unl)" + description "Collie Defense (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Collie Defense (World) (Demo) (Aftermarket) (Unl).gba" size 3714268 crc 08feb1ed sha1 4dce7b29bca3f8588cccb548c698d5d2ba53e188 ) +) + +game ( + name "DCPR (World) (Demo) (Aftermarket) (Unl)" + description "DCPR (World) (Demo) (Aftermarket) (Unl)" + rom ( name "DCPR (World) (Demo) (Aftermarket) (Unl).gba" size 107512 crc 6c27348a sha1 43d11a2e42aa56fa8851bb00a5467211ac195feb ) +) + +game ( + name "Donsol (World) (Aftermarket) (Unl)" + description "Donsol (World) (Aftermarket) (Unl)" + rom ( name "Donsol (World) (Aftermarket) (Unl).gba" size 52520 crc aec144b3 sha1 751675b0d77c341f2265b0edd38858b0dbdb7b50 ) +) + +game ( + name "Drawing a Leviathan (World) (Aftermarket) (Unl)" + description "Drawing a Leviathan (World) (Aftermarket) (Unl)" + rom ( name "Drawing a Leviathan (World) (Aftermarket) (Unl).gba" size 9437768 crc 1eb0f64d sha1 745636d636b44a67ad078dae5416636fa58236ab ) +) + +game ( + name "Eliminator GBA (World) (v0.91) (Proto) (Aftermarket) (Unl)" + description "Eliminator GBA (World) (v0.91) (Proto) (Aftermarket) (Unl)" + rom ( name "Eliminator GBA (World) (v0.91) (Proto) (Aftermarket) (Unl).gba" size 747872 crc 637dc1aa sha1 13a4d5c2c647945cbbf17423afd45a25c4057527 ) +) + +game ( + name "Elite AGB (World) (v1.4.1) (Aftermarket) (Unl)" + description "Elite AGB (World) (v1.4.1) (Aftermarket) (Unl)" + rom ( name "Elite AGB (World) (v1.4.1) (Aftermarket) (Unl).gba" size 960088 crc 28985872 sha1 803095500e47772452433144f2cd7630d515a41b ) +) + +game ( + name "Elite AGB (World) (v0.5.2) (Beta) (Aftermarket) (Unl)" + description "Elite AGB (World) (v0.5.2) (Beta) (Aftermarket) (Unl)" + rom ( name "Elite AGB (World) (v0.5.2) (Beta) (Aftermarket) (Unl).gba" size 327360 crc f00c939f sha1 ce5a236608c629c99d4ec7b35e3ccaf211e6bb60 ) +) + +game ( + name "Feline (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Feline (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Feline (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 1504920 crc 09b777ea sha1 34b5aff6a7a3d752027ea1d2fd53e03bb8964529 ) +) + +game ( + name "Flappy Bird (World) (Aftermarket) (Unl)" + description "Flappy Bird (World) (Aftermarket) (Unl)" + rom ( name "Flappy Bird (World) (Aftermarket) (Unl).gba" size 575204 crc 4d099541 sha1 55f611567e7ac2ad8f96529f4d7eac70ad283601 ) +) + +game ( + name "GBA Tactics (World) (Proto) (NEO Coding Compo 2006) (Aftermarket) (Unl)" + description "GBA Tactics (World) (Proto) (NEO Coding Compo 2006) (Aftermarket) (Unl)" + rom ( name "GBA Tactics (World) (Proto) (NEO Coding Compo 2006) (Aftermarket) (Unl).gba" size 251816 crc 81b449a6 sha1 803834d8843a6689fe43c77921eaaea6bdaf6ed4 ) +) + +game ( + name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" + description "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" + rom ( name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl).gba" size 1210608 crc ab5ae65b sha1 e35037ff9cc24f8a7043d9a9d378e86d2ef80f9b ) +) + +game ( + name "Goldrunner (World) (Aftermarket) (Unl)" + description "Goldrunner (World) (Aftermarket) (Unl)" + rom ( name "Goldrunner (World) (Aftermarket) (Unl).gba" size 527040 crc 53f4cac1 sha1 517a400150a6ebca126b0a95aa3497c637cc8161 ) +) + +game ( + name "Goodboy Galaxy (World) (En,Ja,Fr,De,Es,Pt-BR,Zh,Ar) (Evercade) (Aftermarket) (Unl)" + description "Goodboy Galaxy (World) (En,Ja,Fr,De,Es,Pt-BR,Zh,Ar) (Evercade) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy (World) (En,Ja,Fr,De,Es,Pt-BR,Zh,Ar) (Evercade) (Aftermarket) (Unl).gba" size 32524164 crc ebb81069 sha1 273bae3d794f2b5a6bea637f67f7d5163ae4bb62 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13224124 crc 19ba7d80 sha1 1bf95f8730ecdfa6665b85bea8764f42a88e8e3d ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13219728 crc d4621e3e sha1 5bd59fac58c5f9a375216e9d1cf85fa5262f21f7 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13225068 crc 21512022 sha1 8832d38f787f3e1da620fcae7514d7387445ccf2 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223944 crc c1811c9b sha1 9d413bce82708df137215a2968306a5196b1638b ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13269108 crc 3360e114 sha1 50186922ff77714b9ac638948b464cdbf80ab5fb ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223696 crc 3477ef15 sha1 4b447de09a23fbfdaa6d640824f8ceb5bbe56fab ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13250016 crc a4054c2b sha1 c3cd833b9bdf87a8481c9b05251bba782bc3527e ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220676 crc ab179d6e sha1 2ad1c4840f2f6c2138ed44b1a7aa36071c227a0a ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221620 crc 3aa591f1 sha1 2548615eeaecd7498e32d02b5c758b713ada27f4 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221368 crc d02cdb6a sha1 1e579e15bdc8dc1def99bcb3c30acfc185e0476b ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220496 crc 906717a5 sha1 31857a9ab4daa537322f80faa77482a4b8120483 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220252 crc d12372bd sha1 89ea5ea41133419c317fd28e7c7f172f5bb53ec3 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13216280 crc d3c8dffd sha1 c41c0596a4c52b0e26bb9ffe5c9f7f1c064e0be6 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13265660 crc 119f9ddc sha1 d6c23ff47b21a7bf2f8238ac916aeea3866042b5 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13246576 crc b14cd1b4 sha1 0d15bd0584148b1658f7d47a2dda604a936ea166 ) +) + +game ( + name "Google Dino Advance (World) (v1.0.1) (Aftermarket) (Unl)" + description "Google Dino Advance (World) (v1.0.1) (Aftermarket) (Unl)" + rom ( name "Google Dino Advance (World) (v1.0.1) (Aftermarket) (Unl).gba" size 109072 crc 6534185e sha1 33cc0afc7fbac8948deb75c66b8e097c1d05b2e3 ) +) + +game ( + name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl).gba" size 6639328 crc 78b81bbc sha1 fb090890bd767a22afe07b3323dd0992d698c906 ) +) + +game ( + name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl).gba" size 6937384 crc 9fa9f00f sha1 005f4dc0d615d36d32bbe36e9cc9007b22be2ecd ) +) + +game ( + name "Green Memories (World) (v1.4.4) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.4.4) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.4.4) (Aftermarket) (Unl).gba" size 6937812 crc 702b46c6 sha1 61f8ff01247e45888b8fd5da791176ff2c88f7f5 ) +) + +game ( + name "Hero Core (World) (Aftermarket) (Unl)" + description "Hero Core (World) (Aftermarket) (Unl)" + rom ( name "Hero Core (World) (Aftermarket) (Unl).gba" size 23642396 crc a58bfa21 sha1 fa96ba52c2573add583cb051b387f6bbb3edf02e ) +) + +game ( + name "Hero Core (World) (v0.1.2) (Beta) (GBA Jam 2022) (Aftermarket) (Unl)" + description "Hero Core (World) (v0.1.2) (Beta) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "Hero Core (World) (v0.1.2) (Beta) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 22209300 crc 0a3fcad6 sha1 3b7b91c474a225d96118c4a4263007218a8ee2de ) +) + +game ( + name "Hexa Virus (World) (Aftermarket) (Unl)" + description "Hexa Virus (World) (Aftermarket) (Unl)" + rom ( name "Hexa Virus (World) (Aftermarket) (Unl).gba" size 1414244 crc 92243509 sha1 358640dc9972dd839d0b527177e05d030ec12d79 ) +) + +game ( + name "Hexes (World) (Aftermarket) (Unl)" + description "Hexes (World) (Aftermarket) (Unl)" + rom ( name "Hexes (World) (Aftermarket) (Unl).gba" size 10436680 crc d8d17420 sha1 d5686671caa7ec17b811476c982f81147073f0ed ) +) + +game ( + name "Holy Hell (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + description "Holy Hell (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + rom ( name "Holy Hell (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl).gba" size 5956804 crc 09e21865 sha1 98db9220dffb07fc14a729931e7197a678d92d21 ) +) + +game ( + name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" + description "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl).gba" size 10592124 crc a9014760 sha1 2430c6c0784912ad2f0b51e633bf577f087f189f ) +) + +game ( + name "Inheritors of the Oubliette (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Inheritors of the Oubliette (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Inheritors of the Oubliette (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 25516708 crc 965a1a75 sha1 ae23cfba1f53a9bbde025490f3d7bdf52c3970e4 ) +) + +game ( + name "Inky and the Alien Aquarium (World) (Demo 1) (Aftermarket) (Unl)" + description "Inky and the Alien Aquarium (World) (Demo 1) (Aftermarket) (Unl)" + rom ( name "Inky and the Alien Aquarium (World) (Demo 1) (Aftermarket) (Unl).gba" size 3145728 crc 7ee7ae7f sha1 73d870fad3caa86b6f659e13b57eddac80db2f37 ) +) + +game ( + name "Inky and the Alien Aquarium (World) (Demo 2) (Aftermarket) (Unl)" + description "Inky and the Alien Aquarium (World) (Demo 2) (Aftermarket) (Unl)" + rom ( name "Inky and the Alien Aquarium (World) (Demo 2) (Aftermarket) (Unl).gba" size 3145728 crc 36f8ba9c sha1 3c05e1b3f40d9c16b85b05315472267b94e76471 ) +) + +game ( + name "Iridion 3D (USA) (Aftermarket) (Unl)" + description "Iridion 3D (USA) (Aftermarket) (Unl)" + rom ( name "Iridion 3D (USA) (Aftermarket) (Unl).gba" size 4194304 crc 4c7ebe42 sha1 6f1c77ab88351d2d50da412e4788fc7ca8a6714d ) +) + +game ( + name "Iridion II (USA) (Aftermarket) (Unl)" + description "Iridion II (USA) (Aftermarket) (Unl)" + rom ( name "Iridion II (USA) (Aftermarket) (Unl).gba" size 8388608 crc b371f070 sha1 cc788b38a047ff5ec8c445ce11efcd1852ad7c4d ) +) + +game ( + name "Join 4 Together (World) (Proto) (Aftermarket) (Unl)" + description "Join 4 Together (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Join 4 Together (World) (Proto) (Aftermarket) (Unl).gba" size 1048576 crc 97d3c875 sha1 f9ffabd386d4d76d09e147f87f73de2638f875bb ) +) + +game ( + name "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" + description "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" + rom ( name "Luggage Retrieval Officer (World) (Aftermarket) (Unl).gba" size 3336260 crc 5aa30d90 sha1 84c9b2d50c8af74b8b04f88af367d9fac1a24ef6 ) +) + +game ( + name "Magic & Legend - Time Knights (World) (Beta) (Aftermarket) (Unl)" + description "Magic & Legend - Time Knights (World) (Beta) (Aftermarket) (Unl)" + rom ( name "Magic & Legend - Time Knights (World) (Beta) (Aftermarket) (Unl).gba" size 533996 crc 17af9e42 sha1 616342e07fa4c18a21e6b5de46b032c93bbbf34d ) +) + +game ( + name "Mandarin 2, The - Limoncello's Revenge (World) (Aftermarket) (Unl)" + description "Mandarin 2, The - Limoncello's Revenge (World) (Aftermarket) (Unl)" + rom ( name "Mandarin 2, The - Limoncello's Revenge (World) (Aftermarket) (Unl).gba" size 213684 crc cc2cb6a8 sha1 1937d06c2282152d6a9748c0e741c41c09583b77 ) +) + +game ( + name "MazezaM (World) (v1.1) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "MazezaM (World) (v1.1) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "MazezaM (World) (v1.1) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 569944 crc f7bc9db0 sha1 4517fbb7c44e9e93b0f5e89661e5cf979c624658 ) +) + +game ( + name "MazezaM (World) (v1.0) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "MazezaM (World) (v1.0) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "MazezaM (World) (v1.0) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 569704 crc 7c200ed5 sha1 46053717cf638c428ce92186e6a51a4a08e15ffd ) +) + +game ( + name "Metal Warrior 4 - Agents of Metal (World) (v1.3) (Aftermarket) (Unl)" + description "Metal Warrior 4 - Agents of Metal (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Metal Warrior 4 - Agents of Metal (World) (v1.3) (Aftermarket) (Unl).gba" size 524288 crc 7ec3485e sha1 729592141bc160ead0af51d4322c7f9f17da0b82 ) +) + +game ( + name "Metal Warrior 4 - Agents of Metal (World) (v1.1) (Aftermarket) (Unl)" + description "Metal Warrior 4 - Agents of Metal (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Metal Warrior 4 - Agents of Metal (World) (v1.1) (Aftermarket) (Unl).gba" size 524288 crc 5be69b8d sha1 5252dd4b67b56f591e9f8559d328433d5cf08f31 ) +) + +game ( + name "Minicraft (World) (v1.0) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.0) (Aftermarket) (Unl).gba" size 131072 crc e852c9e9 sha1 06faa5be11978666db6995d8fce40ce2c3641ce8 ) +) + +game ( + name "Minicraft (World) (v1.1) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.1) (Aftermarket) (Unl).gba" size 131072 crc 07595773 sha1 fee5cfa5b9e1f3383780432772f29764ac0fc443 ) +) + +game ( + name "Minicraft (World) (v1.2) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.2) (Aftermarket) (Unl).gba" size 131072 crc 37e7ee7d sha1 dc7faa4952986d5c5f0e3b32203936cd717f97eb ) +) + +game ( + name "Minicraft (World) (v1.3) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.3) (Aftermarket) (Unl).gba" size 131072 crc cc48e03a sha1 7fe080bf9cc110aa78ce7248ff92ff3185083247 ) +) + +game ( + name "Misfortune Advance (World) (Aftermarket) (Unl)" + description "Misfortune Advance (World) (Aftermarket) (Unl)" + rom ( name "Misfortune Advance (World) (Aftermarket) (Unl).gba" size 5125100 crc 18f2166d sha1 68e215025ac963220f16ea3c100e51698f97c4eb ) +) + +game ( + name "Mooncat's Trio (World) (Aftermarket) (Unl)" + description "Mooncat's Trio (World) (Aftermarket) (Unl)" + rom ( name "Mooncat's Trio (World) (Aftermarket) (Unl).gba" size 1175680 crc b05d5339 sha1 890de7d73723d235d9762e4866d569d3554d1480 flags verified ) +) + +game ( + name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" + description "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" + rom ( name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl).gba" size 504220 crc cd3328ee sha1 c3ea5247f32c428bbcfd5c087218fc56779e3106 ) +) + +game ( + name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" + description "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" + rom ( name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl).gba" size 508972 crc 55a0734d sha1 79d6977803cd7ee6b1c97ee149cc1bc037c50fb2 ) +) + +game ( + name "Notebook Adventure (World) (v1.3) (Aftermarket) (Unl)" + description "Notebook Adventure (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Notebook Adventure (World) (v1.3) (Aftermarket) (Unl).gba" size 476392 crc cc110502 sha1 b730e401214fb348edcd2908cc9842e720f908d1 ) +) + +game ( + name "notenogram (World) (v1.1) (Aftermarket) (Unl)" + description "notenogram (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "notenogram (World) (v1.1) (Aftermarket) (Unl).gba" size 807876 crc 28108d5e sha1 426a19598624132356ff5d63a48eb874f19ead6b ) +) + +game ( + name "notenogram (World) (GBA Jam 2022) (Aftermarket) (Unl)" + description "notenogram (World) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "notenogram (World) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 784216 crc 3b936e97 sha1 fb2fadad0d41979df75e49ff09b67fa42b54fc79 ) +) + +game ( + name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" + description "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" + rom ( name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl).gba" size 1048576 crc 9ec140d3 sha1 9e19e8f97e8619a4755c3ceb482fa3e2ad5a4529 ) +) + +game ( + name "Pipe Spin (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Pipe Spin (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Pipe Spin (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 3126100 crc 09d723e2 sha1 d4b4b99e644ca1d8202147a8c7ae0309a6f07e74 ) +) + +game ( + name "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" + description "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Pocket Meat (World) (Proto) (Aftermarket) (Unl).gba" size 861952 crc 0b029da3 sha1 9958d9a66742cc00e234a96c311b2acec40f69d1 ) +) + +game ( + name "Powder (World) (v1.18) (Aftermarket) (Unl)" + description "Powder (World) (v1.18) (Aftermarket) (Unl)" + rom ( name "Powder (World) (v1.18) (Aftermarket) (Unl).gba" size 2278832 crc 44ea10fa sha1 3e0addefc22440c76b0eed06c91bc855f59838bf ) +) + +game ( + name "Powerpig (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "Powerpig (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "Powerpig (World) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 2308528 crc 318f1504 sha1 af5e459df42d5317ce552bdb3062fcff53a9da8e ) +) + +game ( + name "Rick Dangerous (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "Rick Dangerous (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "Rick Dangerous (World) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 4238368 crc 7edb6e6e sha1 62c9b12c3790a7c1a28edd2043ef61706357ed41 ) +) + +game ( + name "Rick Dangerous (World) (Aftermarket) (Unl)" + description "Rick Dangerous (World) (Aftermarket) (Unl)" + rom ( name "Rick Dangerous (World) (Aftermarket) (Unl).gba" size 4237460 crc 53d4f7c5 sha1 ed5a9eb155388f19c28a7f5069d32532a5c9a494 ) +) + +game ( + name "Rick Dangerous 2 (World) (Aftermarket) (Unl)" + description "Rick Dangerous 2 (World) (Aftermarket) (Unl)" + rom ( name "Rick Dangerous 2 (World) (Aftermarket) (Unl).gba" size 4934608 crc 65a8d986 sha1 5dd0cff0f112c43ee44db642b4bfdb38ca6355b7 ) +) + +game ( + name "Rushed Hack Job, A (World) (GBA Jam 2022) (Aftermarket) (Unl)" + description "Rushed Hack Job, A (World) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "Rushed Hack Job, A (World) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 332724 crc 730a5dd6 sha1 d8e03f4b1a12cf7a26813fb07aae2c4b503e2970 ) +) + +game ( + name "Shadow - A Parable (World) (Audio) (Aftermarket) (Unl)" + description "Shadow - A Parable (World) (Audio) (Aftermarket) (Unl)" + rom ( name "Shadow - A Parable (World) (Audio) (Aftermarket) (Unl).gba" size 1352899 crc 3178488f sha1 dd90e7d76b751a0e748aae83777d449d963b774b ) +) + +game ( + name "Shoot for the Moon (World) (Aftermarket) (Unl)" + description "Shoot for the Moon (World) (Aftermarket) (Unl)" + rom ( name "Shoot for the Moon (World) (Aftermarket) (Unl).gba" size 7374924 crc f3bd4f90 sha1 cf99dd8670a3af704b6994898fa521667aba09a6 ) +) + +game ( + name "Sips (World) (GBA WinterJam 2023) (Aftermarket) (Unl)" + description "Sips (World) (GBA WinterJam 2023) (Aftermarket) (Unl)" + rom ( name "Sips (World) (GBA WinterJam 2023) (Aftermarket) (Unl).gba" size 6235380 crc 5c1fb22d sha1 bb725df7226307d55df04365f85e5698b199c3c9 ) +) + +game ( + name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl).gba" size 15887876 crc c798529d sha1 ea4a6494bcec25757f657c69550c91190e46cebd ) +) + +game ( + name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl).gba" size 15894868 crc af572de8 sha1 997bf192369d48433a7c35187c7e1d0b5fcc16e0 ) +) + +game ( + name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl).gba" size 15900084 crc df05edff sha1 1328d17668480b4e9bea338662532ace332c74a9 ) +) + +game ( + name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl).gba" size 16075456 crc d271c516 sha1 0dbdf16b23afb70229eff2de269fd5d73659d745 ) +) + +game ( + name "Skyland (World) (v2024.5.24.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2024.5.24.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2024.5.24.0) (Proto) (Aftermarket) (Unl).gba" size 16250380 crc 4cfb40d2 sha1 d9936c4a776ce61ede6241a018683e3efc0fe12b ) +) + +game ( + name "Spout GBA (World) (Aftermarket) (Unl)" + description "Spout GBA (World) (Aftermarket) (Unl)" + rom ( name "Spout GBA (World) (Aftermarket) (Unl).gba" size 752448 crc ab42f086 sha1 87654f792d847bb8f642c0fc754eb70419a57859 ) +) + +game ( + name "Tiger Rescue (World) (Aftermarket) (Unl)" + description "Tiger Rescue (World) (Aftermarket) (Unl)" + rom ( name "Tiger Rescue (World) (Aftermarket) (Unl).gba" size 1575852 crc 34e118e5 sha1 8cc652cb0aee8649643386c8ffcc77fe6e5b0126 ) +) + +game ( + name "Toadally Awesome (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Toadally Awesome (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Toadally Awesome (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 964504 crc fa6f976c sha1 098f9e2ba7ba15225768eae3585591b9b09ef2d6 ) +) + +game ( + name "Toadally Awesome (World) (GBA Jam 2021) (Unlocked) (Aftermarket) (Unl)" + description "Toadally Awesome (World) (GBA Jam 2021) (Unlocked) (Aftermarket) (Unl)" + rom ( name "Toadally Awesome (World) (GBA Jam 2021) (Unlocked) (Aftermarket) (Unl).gba" size 964520 crc 11044eb3 sha1 ac83f9815f4bf3a9c6690c4437d7f2256b36dd40 ) +) + +game ( + name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl).gba" size 16239516 crc ce85ba07 sha1 b09b600bfc222c2d92829d8883feab700b013953 ) +) + +game ( + name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16229600 crc bd57344d sha1 a2fcfe94c9b8b0feff31c1245c8b033222c9f668 ) +) + +game ( + name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + description "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16204024 crc fa43669e sha1 a57392fa7cee61913b20a840fe8b2ee27f11d808 ) +) + +game ( + name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl).gba" size 16777216 crc ff5d64ab sha1 645ab8d4dacb6666d8eb549d491f77d8cd63ce97 ) +) + +game ( + name "Tremblay Island (World) (Aftermarket) (Unl)" + description "Tremblay Island (World) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (Aftermarket) (Unl).gba" size 16225608 crc 95503690 sha1 634ea6be3df5ebd85c9c60871e34fc3c72ae5140 ) +) + +game ( + name "Tristam Island (World) (v9) (Digital) (Aftermarket) (Unl)" + description "Tristam Island (World) (v9) (Digital) (Aftermarket) (Unl)" + rom ( name "Tristam Island (World) (v9) (Digital) (Aftermarket) (Unl).gba" size 286184 crc 4baa947c sha1 4a90a81991d38ce08ded5da017d0567ecd00c1df flags verified ) +) + +game ( + name "uCity Advance (World) (v1.0.1) (GBA Jam 2021) (Aftermarket) (Unl)" + description "uCity Advance (World) (v1.0.1) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "uCity Advance (World) (v1.0.1) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 1925124 crc a6e47443 sha1 c3e8f7fe01e05eda8bdb52a35db0d6dc92554e42 ) +) + +game ( + name "Varooom 3D (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Varooom 3D (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Varooom 3D (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 7957428 crc 3f127891 sha1 cc7e45a680f9a8701fe35a64c764d5e106bd9096 ) +) + +game ( + name "Waimanu - Grinding Blocks Adventure (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "Waimanu - Grinding Blocks Adventure (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "Waimanu - Grinding Blocks Adventure (World) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 1739504 crc 0fe153c5 sha1 c4ce156b04fb257875bc5f539f3d64accbc08451 ) +) + +game ( + name "Werewolf Tale, A (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + description "Werewolf Tale, A (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + rom ( name "Werewolf Tale, A (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl).gba" size 7359860 crc fa1a22d3 sha1 631fa1b513e1e4a45a5a60b10b7822b47832b866 ) +) + +game ( + name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" + description "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" + rom ( name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl).gba" size 1449956 crc 4ffa611d sha1 89bbeb3fbce1533acf2f2113642ebe2a4f9f79a8 ) +) + +game ( + name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" + description "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" + rom ( name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl).gba" size 1449956 crc 27055186 sha1 b9ce91d55870e07434509f6e2e91c2f90b4afc97 ) +) + +game ( + name "World Reborn (USA) (Aftermarket) (Unl)" + description "World Reborn (USA) (Aftermarket) (Unl)" + rom ( name "World Reborn (USA) (Aftermarket) (Unl).gba" size 4194304 crc eefb32ff sha1 c7ec2f8d7d3dec40a893cdfe2a41a8ed43ed71c4 ) +) + +game ( + name "xniq (World) (Proto) (GBA Jam 2021) (Aftermarket) (Unl)" + description "xniq (World) (Proto) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "xniq (World) (Proto) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 1436448 crc ddb5205d sha1 47dabc2d526aefc41cc82eeec315c986e3a9b8bc ) +) + +clrmamepro ( + name "Nintendo - Game Boy Advance (Video) (Aftermarket)" + description "Nintendo - Game Boy Advance (Video) (Aftermarket)" + version 20240727-194101 + author "BigFred, C. V. Reynolds, DeadSkullzJr, Hiccup, kazumi213, omonim2007, Psychofox11, psykopat, relax, SonGoku, xuom2" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "Dinosaur Office (World) (Aftermarket) (Unl)" + description "Dinosaur Office (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office (World) (Aftermarket) (Unl).gba" size 15237120 crc d8aae820 sha1 24feb8a0f36428461be8ecbb7add65f43dc1366e ) +) + +game ( + name "Dinosaur Office - Bring Your Child to Work Day (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Bring Your Child to Work Day (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Bring Your Child to Work Day (World) (Aftermarket) (Unl).gba" size 12222464 crc 3de24b84 sha1 63938be2d2e357b9644de8dc452f6f4195911618 ) +) + +game ( + name "Dinosaur Office - Computer Problems (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Computer Problems (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Computer Problems (World) (Aftermarket) (Unl).gba" size 15990784 crc 8a05677f sha1 664c1568e601bf6e51920bca85d096aa6e06f5e2 ) +) + +game ( + name "Dinosaur Office - Gym (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Gym (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Gym (World) (Aftermarket) (Unl).gba" size 12419072 crc 9dc8f035 sha1 062fcb78d9f9058ff9427f123fbb36db77fca20b ) +) + +game ( + name "Dinosaur Office - Office Party (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Office Party (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Office Party (World) (Aftermarket) (Unl).gba" size 12484608 crc 34c1df88 sha1 9ee6ca14c78a7e1949d8af9d52e6bfa4d09b7f9f ) +) + +game ( + name "Dinosaur Office - Office Romance (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Office Romance (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Office Romance (World) (Aftermarket) (Unl).gba" size 13828096 crc c202e426 sha1 4a66f3db5bde55a33f4b9ca55ba231f806c8d2b9 ) +) + +game ( + name "Dinosaur Office - Team Building (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Team Building (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Team Building (World) (Aftermarket) (Unl).gba" size 17334272 crc 9cd0566e sha1 9dc93f4c8d25a0e5d52deb8c7edf656b8f0c059d ) +) + +game ( + name "Dinosaur Office - Traffic (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Traffic (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Traffic (World) (Aftermarket) (Unl).gba" size 13107200 crc 96d90be9 sha1 879d9c7f0951235607cedb9c8fd85e4fc9a1d452 ) +) + +game ( + name "Dinosaur Office - Viral Videos (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Viral Videos (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Viral Videos (World) (Aftermarket) (Unl).gba" size 13139968 crc e7338b7c sha1 e6f089034f30757f8dce2eb6568e8f5d2d122d49 ) +) + +game ( + name "Eek! The Cat - A Sharkwork Orange (World) (Aftermarket) (Unl)" + description "Eek! The Cat - A Sharkwork Orange (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - A Sharkwork Orange (World) (Aftermarket) (Unl).gba" size 31129600 crc 4feab397 sha1 0bb061759804b46f201c39ccf9e7722a4407909e ) +) + +game ( + name "Eek! The Cat - Chariots of Fur (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Chariots of Fur (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Chariots of Fur (World) (Aftermarket) (Unl).gba" size 30998528 crc 5ea13d5a sha1 7022193f78fcb89988483cca1bacb8e66182ac55 ) +) + +game ( + name "Eek! The Cat - Eek Space-9 (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eek Space-9 (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eek Space-9 (World) (Aftermarket) (Unl).gba" size 30801920 crc cfbb43d3 sha1 1b056d1449282c08eae0ed49ffc33f56346304fe ) +) + +game ( + name "Eek! The Cat - Eek's Funny Thing That He Does (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eek's Funny Thing That He Does (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eek's Funny Thing That He Does (World) (Aftermarket) (Unl).gba" size 31064064 crc 3773b28d sha1 b13c1d3ae7f993deee10542390ac416b6c5cd1c6 ) +) + +game ( + name "Eek! The Cat - Eekscaliber (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eekscaliber (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eekscaliber (World) (Aftermarket) (Unl).gba" size 31227904 crc ed5792d4 sha1 2a903b53a371ef4132291452f5d192dace6dc5e8 ) +) + +game ( + name "Eek! The Cat - Eekstremely Dull (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eekstremely Dull (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eekstremely Dull (World) (Aftermarket) (Unl).gba" size 31162368 crc 28f73fe4 sha1 3ea9bfa0d937150574affdb8de271cf7873ab042 ) +) + +game ( + name "Eek! The Cat - Eeksy Rider (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eeksy Rider (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eeksy Rider (World) (Aftermarket) (Unl).gba" size 31096832 crc ec1f5d37 sha1 1359f5e802862b0a6f01e37fd5843a5b12edb7d4 ) +) + +game ( + name "Eek! The Cat - Fatal Eektraction (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Fatal Eektraction (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Fatal Eektraction (World) (Aftermarket) (Unl).gba" size 31096832 crc 494997c3 sha1 52e63ca7e162fe3a0296709b924b0dc4b19ce693 ) +) + +game ( + name "Eek! The Cat - Honey I Shrunk the Cat (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Honey I Shrunk the Cat (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Honey I Shrunk the Cat (World) (Aftermarket) (Unl).gba" size 15597568 crc 8bae90ef sha1 8ee80c6e4f54081c6b796983ab51d8c03e36c2d0 ) +) + +game ( + name "Eek! The Cat - Natural Bored Kittens (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Natural Bored Kittens (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Natural Bored Kittens (World) (Aftermarket) (Unl).gba" size 31129600 crc 941da25e sha1 8fa3d5d5f305ac32653527860caf153c97d20a24 ) +) + +game ( + name "Eek! The Cat - OutbrEek (World) (Aftermarket) (Unl)" + description "Eek! The Cat - OutbrEek (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - OutbrEek (World) (Aftermarket) (Unl).gba" size 30834688 crc 4fea7a72 sha1 344cdff52d4820932c3ba8ad5c57c91d61d93751 ) +) + +game ( + name "Eek! The Cat - Rock-Eek 6 (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Rock-Eek 6 (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Rock-Eek 6 (World) (Aftermarket) (Unl).gba" size 31096832 crc 7a05eb25 sha1 6b3789fd599bf7d30788be38872f5832cb5edfaa ) +) + +game ( + name "Eek! The Cat - Shark Doggy Dog (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Shark Doggy Dog (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Shark Doggy Dog (World) (Aftermarket) (Unl).gba" size 30965760 crc f8f2e313 sha1 f169a86d11602d84181fd0161bc7ec6747d5c750 ) +) + +game ( + name "Eek! The Cat - Shark Therapy (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Shark Therapy (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Shark Therapy (World) (Aftermarket) (Unl).gba" size 30998528 crc 81bc6107 sha1 9cca9b282e9441364e5acd7379c251674165eb13 ) +) + +game ( + name "Eek! The Cat - The Sound of MusEek (World) (Aftermarket) (Unl)" + description "Eek! The Cat - The Sound of MusEek (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - The Sound of MusEek (World) (Aftermarket) (Unl).gba" size 31129600 crc 923aafde sha1 1f1071ba3a6e056357c04f653cc48d2333a6bff1 ) +) + +game ( + name "GBA Groove - LoFi Lullabies (World) (Aftermarket) (Unl)" + description "GBA Groove - LoFi Lullabies (World) (Aftermarket) (Unl)" + rom ( name "GBA Groove - LoFi Lullabies (World) (Aftermarket) (Unl).gba" size 33128448 crc ff858ea8 sha1 e42166ed389ba80a38b91019b80b00fdca3252bd ) +) + +game ( + name "Legend of Lofi - High Quality - Part 1 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 1 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 1 (World) (v2.0) (Aftermarket) (Unl).gba" size 33095680 crc a29a4d08 sha1 5c5ba15aef8cf86fbfee102dd3d667c09a024215 ) +) + +game ( + name "Legend of Lofi - High Quality - Part 2 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 2 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 2 (World) (v2.0) (Aftermarket) (Unl).gba" size 33292288 crc d30b0a69 sha1 1d0f5640c62823100802a9d99991c81321fd6a7e ) +) + +game ( + name "Legend of Lofi - High Quality - Part 3 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 3 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 3 (World) (v2.0) (Aftermarket) (Unl).gba" size 33226752 crc 5514a608 sha1 0b942ca93b86a61710e437995fbe9b051b49f33b ) +) + +game ( + name "Legend of Lofi - High Quality - Part 4 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 4 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 4 (World) (v2.0) (Aftermarket) (Unl).gba" size 33226752 crc 996086fb sha1 cdae6017134b235c4b939c3718fef5c68c932046 ) +) + +game ( + name "Legend of Lofi - High Quality - Part 5 (World) (v2.1) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 5 (World) (v2.1) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 5 (World) (v2.1) (Aftermarket) (Unl).gba" size 33062912 crc 30394a33 sha1 677e3fbd22eac9661365f798e141844628869f09 ) +) + +game ( + name "Legend of Lofi - Low Quality - Part 1 (World) (Aftermarket) (Unl)" + description "Legend of Lofi - Low Quality - Part 1 (World) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - Low Quality - Part 1 (World) (Aftermarket) (Unl).gba" size 33456128 crc ec98d515 sha1 02d89347e83d030168916b1d5b5cb39f436564cf ) +) + +game ( + name "Legend of Lofi - Low Quality - Part 2 (World) (Aftermarket) (Unl)" + description "Legend of Lofi - Low Quality - Part 2 (World) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - Low Quality - Part 2 (World) (Aftermarket) (Unl).gba" size 33488896 crc 9a3ad572 sha1 90a4fefd48cc5024b88591a29a79c5a720593dcf ) +) + +game ( + name "Lizard of Aaaahs (World) (Aftermarket) (Unl)" + description "Lizard of Aaaahs (World) (Aftermarket) (Unl)" + rom ( name "Lizard of Aaaahs (World) (Aftermarket) (Unl).gba" size 30801920 crc 45d496d3 sha1 65b0a763932517d504abb0e39e9db316b2500c0a ) +) + +game ( + name "Lofi Radio (World) (Aftermarket) (Unl)" + description "Lofi Radio (World) (Aftermarket) (Unl)" + rom ( name "Lofi Radio (World) (Aftermarket) (Unl).gba" size 30965760 crc 4643636f sha1 7657efc85a8414a2d2065549e66bc0e0804a0153 ) +) + +game ( + name "Popeye The Sailor Meets Ali Baba's Forty Thieves (World) (Aftermarket) (Unl)" + description "Popeye The Sailor Meets Ali Baba's Forty Thieves (World) (Aftermarket) (Unl)" + rom ( name "Popeye The Sailor Meets Ali Baba's Forty Thieves (World) (Aftermarket) (Unl).gba" size 25067520 crc 3d2b7e9a sha1 7ed0b27ce1537610d62e3265ee1d8e7aa09ac649 ) +) + +game ( + name "Sleepy Time (World) (Aftermarket) (Unl)" + description "Sleepy Time (World) (Aftermarket) (Unl)" + rom ( name "Sleepy Time (World) (Aftermarket) (Unl).gba" size 33554432 crc b4a8e893 sha1 ba0a790b18de15009d711474aa25f29875e7f9fd ) +) + +game ( + name "Sonic Boom - Aim Low (World) (Aftermarket) (Unl)" + description "Sonic Boom - Aim Low (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Aim Low (World) (Aftermarket) (Unl).gba" size 32899072 crc a4b992a4 sha1 321716a5cc8035d2f3c834db70e21024b26e01ec ) +) + +game ( + name "Sonic Boom - Anything You Can Do, I Can Do Worse-er (World) (Aftermarket) (Unl)" + description "Sonic Boom - Anything You Can Do, I Can Do Worse-er (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Anything You Can Do, I Can Do Worse-er (World) (Aftermarket) (Unl).gba" size 32669696 crc 3e19389e sha1 bd9e8e22ddde7426d8eb77772480c822a099044f ) +) + +game ( + name "Sonic Boom - Blue with Envy (World) (Aftermarket) (Unl)" + description "Sonic Boom - Blue with Envy (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Blue with Envy (World) (Aftermarket) (Unl).gba" size 33488896 crc c847a712 sha1 44c4d7a6ba6b3bea7f452f22ec7c419cf6cf6965 ) +) + +game ( + name "Sonic Boom - Cabin Fever (World) (Aftermarket) (Unl)" + description "Sonic Boom - Cabin Fever (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Cabin Fever (World) (Aftermarket) (Unl).gba" size 32145408 crc 6a916ed9 sha1 e422c79d1b85942fcd9bae26105151c4e8a8352c ) +) + +game ( + name "Sonic Boom - Curse of the Cross Eyed Moose (World) (Aftermarket) (Unl)" + description "Sonic Boom - Curse of the Cross Eyed Moose (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Curse of the Cross Eyed Moose (World) (Aftermarket) (Unl).gba" size 32636928 crc 751a7c3c sha1 393a023540a261e14ab96ee341505fd6852e5040 ) +) + +game ( + name "Sonic Boom - Double Doomsday (World) (Aftermarket) (Unl)" + description "Sonic Boom - Double Doomsday (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Double Doomsday (World) (Aftermarket) (Unl).gba" size 33095680 crc e43df55f sha1 b0f7feb5f1b012ce4a486e6ad1331d83372a52e8 ) +) + +game ( + name "Sonic Boom - Eggheads (World) (Aftermarket) (Unl)" + description "Sonic Boom - Eggheads (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Eggheads (World) (Aftermarket) (Unl).gba" size 32964608 crc 7be59036 sha1 6afd6a0e39a792422767f40d96d28683fe3f010b ) +) + +game ( + name "Sonic Boom - Fortress of Squalitude (World) (Aftermarket) (Unl)" + description "Sonic Boom - Fortress of Squalitude (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Fortress of Squalitude (World) (Aftermarket) (Unl).gba" size 32964608 crc 2732961a sha1 db37f535660f66d947ccd2fdb05631d6c3b53157 ) +) + +game ( + name "Sonic Boom - Guilt Tripping (World) (Aftermarket) (Unl)" + description "Sonic Boom - Guilt Tripping (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Guilt Tripping (World) (Aftermarket) (Unl).gba" size 33095680 crc eb433ebc sha1 29648e120e9fd97f9c8b279b29246f165df3b9e6 ) +) + +game ( + name "Sonic Boom - It Takes a Village to Defeat a Hedgehog (World) (Aftermarket) (Unl)" + description "Sonic Boom - It Takes a Village to Defeat a Hedgehog (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - It Takes a Village to Defeat a Hedgehog (World) (Aftermarket) (Unl).gba" size 33062912 crc 087a17bf sha1 5cfd8eb8d832d21d64fc150bcc6d26b52da86911 ) +) + +game ( + name "Sonic Boom - Let's Play Musical Friends (World) (Aftermarket) (Unl)" + description "Sonic Boom - Let's Play Musical Friends (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Let's Play Musical Friends (World) (Aftermarket) (Unl).gba" size 33226752 crc 4f7e8a97 sha1 ad7d4f4833878ccc7055e65efbcb62fba20cd340 ) +) + +game ( + name "Sonic Boom - Nutwork (World) (Aftermarket) (Unl)" + description "Sonic Boom - Nutwork (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Nutwork (World) (Aftermarket) (Unl).gba" size 32768000 crc ed3ead6a sha1 f89d6acee3095419d2eda71c1d79e73ba3dcf5e4 ) +) + +game ( + name "Sonic Boom - The Evil Dr. Orbot (World) (Aftermarket) (Unl)" + description "Sonic Boom - The Evil Dr. Orbot (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - The Evil Dr. Orbot (World) (Aftermarket) (Unl).gba" size 33095680 crc e8c0b3b3 sha1 175126d3946e61295993982cb04758a5761233b1 ) +) + +game ( + name "Sonic Boom - The Meteor (World) (Aftermarket) (Unl)" + description "Sonic Boom - The Meteor (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - The Meteor (World) (Aftermarket) (Unl).gba" size 32931840 crc d3c8e3bc sha1 84a91ed46f4e055ef075b4e110091dd1510c6bab ) +) + +game ( + name "Sonic Boom - The Sidekick (World) (Aftermarket) (Unl)" + description "Sonic Boom - The Sidekick (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - The Sidekick (World) (Aftermarket) (Unl).gba" size 32964608 crc bca89ca3 sha1 93d24392e31fa7fa1b017eae2efbbb3d198739b7 ) +) + +game ( + name "Super Mario World - Episode 1 - Fire Sale (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 1 - Fire Sale (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 1 - Fire Sale (World) (Aftermarket) (Unl).gba" size 31522816 crc 5af74124 sha1 c715e8adff312d3ade93185d6cebcb2d493cc41e ) +) + +game ( + name "Super Mario World - Episode 10 - Rock TV (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 10 - Rock TV (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 10 - Rock TV (World) (Aftermarket) (Unl).gba" size 30179328 crc ccb80716 sha1 3f05bfc29688ab70cc728bbe609d5b976730490e ) +) + +game ( + name "Super Mario World - Episode 11 - The Yoshi Shuffle (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 11 - The Yoshi Shuffle (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 11 - The Yoshi Shuffle (World) (Aftermarket) (Unl).gba" size 31129600 crc 733bb9b0 sha1 45875207d24653aa81c2bdd60bde639783c5c387 ) +) + +game ( + name "Super Mario World - Episode 12 - A Little Learning (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 12 - A Little Learning (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 12 - A Little Learning (World) (Aftermarket) (Unl).gba" size 31227904 crc dd8717c1 sha1 26fcf34d2fd9f87f287d14fdeda9d8e234306db5 ) +) + +game ( + name "Super Mario World - Episode 13 - Mama Luigi (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 13 - Mama Luigi (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 13 - Mama Luigi (World) (Aftermarket) (Unl).gba" size 32112640 crc 3d2bf1b0 sha1 4a897d3de60f1bd3991803196f5b96c5916f9e8c ) +) + +game ( + name "Super Mario World - Episode 2 - The Wheel Thing (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 2 - The Wheel Thing (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 2 - The Wheel Thing (World) (Aftermarket) (Unl).gba" size 32145408 crc 9c5140d6 sha1 30b6b51d60ba9213e5c472bf52070eab98b43c74 ) +) + +game ( + name "Super Mario World - Episode 3 - Send in the Clown (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 3 - Send in the Clown (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 3 - Send in the Clown (World) (Aftermarket) (Unl).gba" size 32112640 crc 88888a8c sha1 26c791180a1b35d8ab9cf7947d8db6c0367d7eb9 ) +) + +game ( + name "Super Mario World - Episode 4 - Ghosts 'R' Us (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 4 - Ghosts 'R' Us (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 4 - Ghosts 'R' Us (World) (Aftermarket) (Unl).gba" size 32079872 crc ca0d9b45 sha1 a15fb94a371d783f78c069038c350e569ea9c370 ) +) + +game ( + name "Super Mario World - Episode 5 - The Night Before Cave Christmas (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 5 - The Night Before Cave Christmas (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 5 - The Night Before Cave Christmas (World) (Aftermarket) (Unl).gba" size 31981568 crc 564582fa sha1 ce8b3589a67dcd930d2e437efa0bf754f438cfa7 ) +) + +game ( + name "Super Mario World - Episode 6 - King Scoopa Koopa (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 6 - King Scoopa Koopa (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 6 - King Scoopa Koopa (World) (Aftermarket) (Unl).gba" size 32112640 crc edcb04de sha1 1e8e89daf7faed9660f2dc3b6aa113df6de527c0 ) +) + +game ( + name "Super Mario World - Episode 7 - Born to Ride (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 7 - Born to Ride (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 7 - Born to Ride (World) (Aftermarket) (Unl).gba" size 32145408 crc 0044466e sha1 105f0d0a500ea542f87b10b7c671b6c93e312f4a ) +) + +game ( + name "Super Mario World - Episode 8 - Party Line (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 8 - Party Line (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 8 - Party Line (World) (Aftermarket) (Unl).gba" size 28672000 crc ed103f04 sha1 df5e947880b634482081ee82f79f37d5ff7d009c ) +) + +game ( + name "Super Mario World - Episode 9 - Gopher Bash (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 9 - Gopher Bash (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 9 - Gopher Bash (World) (Aftermarket) (Unl).gba" size 31031296 crc 3a8f46ad sha1 160895e7953a3323647c0c9d2d00eeff17b57db5 ) +) + clrmamepro ( name "Nintendo - Game Boy" description "Nintendo - Game Boy" - version 20240106-192522 - author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Psychofox11, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xprism, xuom2" + version 20240809-004429 + author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Psychofox11, psykopat, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xprism, xuom2" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -21630,12 +22690,6 @@ game ( rom ( name "10-Pin Bowling (USA) (Proto).gb" size 131072 crc 9a024415 sha1 952d154dd2c6189ef4b786ae37bd7887c8ca9037 ) ) -game ( - name "14 Juillet (World) (Fr) (Aftermarket) (Unl)" - description "14 Juillet (World) (Fr) (Aftermarket) (Unl)" - rom ( name "14 Juillet (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 7b66bee4 sha1 02f387457a779cbd2f493e52743cd32c169c098e ) -) - game ( name "3 Choume no Tama - Tama and Friends - 3 Choume Obake Panic!! (Japan)" description "3 Choume no Tama - Tama and Friends - 3 Choume Obake Panic!! (Japan)" @@ -21739,9 +22793,9 @@ game ( ) game ( - name "Action Replay Pro (World)" - description "Action Replay Pro (World)" - rom ( name "Action Replay Pro (World).gb" size 16384 crc 2ea05daa sha1 e947b9264092168950ad1ce23bbe3d8ccfed765e ) + name "Action Replay Pro (World) (Unl)" + description "Action Replay Pro (World) (Unl)" + rom ( name "Action Replay Pro (World) (Unl).gb" size 16384 crc 2ea05daa sha1 e947b9264092168950ad1ce23bbe3d8ccfed765e ) ) game ( @@ -21768,12 +22822,6 @@ game ( rom ( name "Addams Family, The - Pugsley's Scavenger Hunt (USA, Europe).gb" size 131072 crc 7e054a88 sha1 f9020e3d104cb5c5347e28f45ed9e24e6c0ebddd flags verified ) ) -game ( - name "Adulting! (World) (v2.0) (Aftermarket) (Unl)" - description "Adulting! (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Adulting! (World) (v2.0) (Aftermarket) (Unl).gb" size 524288 crc e56d1244 sha1 d107bd8bf32d0d94a988466885fe1a44aae32c9a flags verified ) -) - game ( name "Adventure Island (USA, Europe)" description "Adventure Island (USA, Europe)" @@ -21948,12 +22996,6 @@ game ( rom ( name "Alleyway (World).gb" size 32768 crc 5cc01586 sha1 0cf2b8d0428f389f5361f67a0cd1ace05a1c75cc flags verified ) ) -game ( - name "Alphamax (World) (Aftermarket) (Unl)" - description "Alphamax (World) (Aftermarket) (Unl)" - rom ( name "Alphamax (World) (Aftermarket) (Unl).gb" size 131072 crc 8b493b41 sha1 798dda34d04a06dcee32f44f8a4a045caf734927 ) -) - game ( name "Altered Space - A 3-D Alien Adventure (Europe)" description "Altered Space - A 3-D Alien Adventure (Europe)" @@ -21978,6 +23020,12 @@ game ( rom ( name "Amazing Penguin (USA, Europe).gb" size 65536 crc 3011d5ca sha1 84cc6452823eb05ee38679aec86e3cc6e4a50e6f ) ) +game ( + name "Amazing Penguin (World) (Limited Run Games)" + description "Amazing Penguin (World) (Limited Run Games)" + rom ( name "Amazing Penguin (World) (Limited Run Games).gb" size 65536 crc 82d4664c sha1 01f11e0746a511b35b2c873d6a190f6e10204676 ) +) + game ( name "Amazing Spider-Man, The (USA, Europe)" description "Amazing Spider-Man, The (USA, Europe)" @@ -22116,30 +23164,6 @@ game ( rom ( name "Aretha III (Japan).gb" size 262144 crc 430d3d6b sha1 f57ff26d31283c88cc4c414b18ef6f182d07da9d ) ) -game ( - name "Art School Pocket (World) (En) (Aftermarket) (Unl)" - description "Art School Pocket (World) (En) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (En) (Aftermarket) (Unl).gb" size 1048576 crc b4eab528 sha1 c482cfc6ec40b1f33c4ba48ecdc45fef4730b653 ) -) - -game ( - name "Art School Pocket (World) (Es) (Aftermarket) (Unl)" - description "Art School Pocket (World) (Es) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (Es) (Aftermarket) (Unl).gb" size 1048576 crc 240067df sha1 c8a75895c87b11f9493f629c19c54d0c607505bd ) -) - -game ( - name "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" - description "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 49a5b74d sha1 73ecffaee185eb2caf1db385d04b863676c777fb ) -) - -game ( - name "Art School Pocket (World) (De) (Aftermarket) (Unl)" - description "Art School Pocket (World) (De) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (De) (Aftermarket) (Unl).gb" size 1048576 crc 82b73e5b sha1 7772e2b9d5e722e54d19fc6283ccb1fa5d19b641 ) -) - game ( name "Asmik-kun World 2 (Japan)" description "Asmik-kun World 2 (Japan)" @@ -22200,30 +23224,12 @@ game ( rom ( name "Asteroids (USA, Europe) (Beta).gb" size 32768 crc eb31e472 sha1 28f4e2a076bfe5f7a77f695332705ea0085fccfb ) ) -game ( - name "Asteroids Chasers (World) (Aftermarket) (Unl)" - description "Asteroids Chasers (World) (Aftermarket) (Unl)" - rom ( name "Asteroids Chasers (World) (Aftermarket) (Unl).gb" size 131072 crc 58d8b1b8 sha1 f93a4e6788eaf0231a6ca269cca297f0d45ec830 flags verified ) -) - game ( name "Astro Rabby (Japan)" description "Astro Rabby (Japan)" rom ( name "Astro Rabby (Japan).gb" size 65536 crc 61e48eef sha1 3e53fd25f350c78a29e0642ee6de80208930d469 ) ) -game ( - name "Astro-Jump (World) (Aftermarket) (Unl)" - description "Astro-Jump (World) (Aftermarket) (Unl)" - rom ( name "Astro-Jump (World) (Aftermarket) (Unl).gb" size 262144 crc c35a3b39 sha1 1bcb4be684626ce061aad105701548fa3a77e254 ) -) - -game ( - name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - description "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc afc128f2 sha1 956be9371990b18e351f2e10848b2ea8bb70c2b7 ) -) - game ( name "Atomic Punk (USA)" description "Atomic Punk (USA)" @@ -22242,12 +23248,6 @@ game ( rom ( name "Attack of the Killer Tomatoes (USA, Europe).gb" size 131072 crc b5b38860 sha1 cbbba5d4f80f2b4ab3e882ceb4f79c293a17904f flags verified ) ) -game ( - name "Auto Zone (World) (Aftermarket) (Unl)" - description "Auto Zone (World) (Aftermarket) (Unl)" - rom ( name "Auto Zone (World) (Aftermarket) (Unl).gb" size 524288 crc cee73c14 sha1 3070ec215014633dac5dbbb487aade2e2993c049 ) -) - game ( name "Avenging Spirit (USA, Europe)" description "Avenging Spirit (USA, Europe)" @@ -22621,9 +23621,9 @@ game ( ) game ( - name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" - description "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" - rom ( name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl).gb" size 32768 crc bf922249 sha1 187782720d4f7c0986a0d916b0c7efa2c488612e ) + name "Binary Monsters II - Adventure of Hell (Taiwan) (En) (Unl)" + description "Binary Monsters II - Adventure of Hell (Taiwan) (En) (Unl)" + rom ( name "Binary Monsters II - Adventure of Hell (Taiwan) (En) (Unl).gb" size 131072 crc 3bf1e911 sha1 5a7ea252cc344f239e48eee0eba6a9ba97d799ea ) ) game ( @@ -22650,12 +23650,6 @@ game ( rom ( name "Bionic Commando (USA).gb" size 262144 crc 41dbb5fb sha1 e0ef47568a017ccdd3dbe0db5d7654822b4e5ce1 ) ) -game ( - name "Birdie Bartender (World) (Aftermarket) (Unl)" - description "Birdie Bartender (World) (Aftermarket) (Unl)" - rom ( name "Birdie Bartender (World) (Aftermarket) (Unl).gb" size 262144 crc 0bf2a1c8 sha1 aa1325fc7160b84745b076de9b976a1b368da50e ) -) - game ( name "Bishoujo Senshi Sailor Moon (Japan)" description "Bishoujo Senshi Sailor Moon (Japan)" @@ -22674,12 +23668,6 @@ game ( rom ( name "Black Bass - Lure Fishing (USA).gb" size 262144 crc 2db3dace sha1 d9524ac9f7788172a55cc8ceb6e199f8a12e033d ) ) -game ( - name "Black Castle (World) (Aftermarket) (Unl)" - description "Black Castle (World) (Aftermarket) (Unl)" - rom ( name "Black Castle (World) (Aftermarket) (Unl).gb" size 65536 crc 10f577c7 sha1 45d979be572bb820835d2ecd4e990cd1eadbf5a6 ) -) - game ( name "Blade Warrior (Europe) (Proto)" description "Blade Warrior (Europe) (Proto)" @@ -22716,24 +23704,12 @@ game ( rom ( name "Blaster Master Jr. (Europe).gb" size 131072 crc e9f9016f sha1 6a6deae1942e7cf048ce35d18e9540363c226727 ) ) -game ( - name "Blitz Bomber (World) (Aftermarket) (Unl)" - description "Blitz Bomber (World) (Aftermarket) (Unl)" - rom ( name "Blitz Bomber (World) (Aftermarket) (Unl).gb" size 262144 crc 5e9956de sha1 b72cbc6bfa6ceef940f49c9c82024071c6f82b90 ) -) - game ( name "Block Kuzushi GB (Japan) (SGB Enhanced)" description "Block Kuzushi GB (Japan) (SGB Enhanced)" rom ( name "Block Kuzushi GB (Japan) (SGB Enhanced).gb" size 131072 crc 54b67501 sha1 7540fe9af69d8c7d48f50c2d5fe6d3ce07421f74 ) ) -game ( - name "Blockade (World) (Aftermarket) (Unl)" - description "Blockade (World) (Aftermarket) (Unl)" - rom ( name "Blockade (World) (Aftermarket) (Unl).gb" size 262144 crc b8cfab16 sha1 9e753048a0eb036ac17c08f5a64d860abd1aaaf5 ) -) - game ( name "Blodia (Japan)" description "Blodia (Japan)" @@ -22890,18 +23866,6 @@ game ( rom ( name "Boomer's Adventure in ASMIK World (USA).gb" size 65536 crc 105bc1c0 sha1 3d8a6fcc644290c9d88fe2918bfa6007ee811de8 flags verified ) ) -game ( - name "Bork Paw Kisses (World) (Aftermarket) (Unl)" - description "Bork Paw Kisses (World) (Aftermarket) (Unl)" - rom ( name "Bork Paw Kisses (World) (Aftermarket) (Unl).gb" size 262144 crc c29f0d35 sha1 8f1efe6982d2b4ebc1fbeb3ade68dd9b9aabb7a6 ) -) - -game ( - name "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" - description "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" - rom ( name "Borruga - Neo Pinball (World) (Aftermarket) (Unl).gb" size 32768 crc 2bb55ca5 sha1 269f12091d5ab87362a2cb2cf5484f14bfcbd537 flags verified ) -) - game ( name "Bouken! Puzzle Road (Japan)" description "Bouken! Puzzle Road (Japan)" @@ -22920,24 +23884,6 @@ game ( rom ( name "Boulder Dash (Japan).gb" size 65536 crc b5b3f85b sha1 f5a4a5ccda4f559ce85567c4b68f758216aee2d4 ) ) -game ( - name "Bounce (World) (v1.1) (Aftermarket) (Unl)" - description "Bounce (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Bounce (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc 827f2bd5 sha1 e9abf64de3faeb48151003ac8bb77dea61e838b5 ) -) - -game ( - name "Bouncing Ball, The (World) (Aftermarket)" - description "Bouncing Ball, The (World) (Aftermarket)" - rom ( name "Bouncing Ball, The (World) (Aftermarket).gb" size 65536 crc 42ddf53e sha1 5d331f2e66d7d3f4b4b0fcbaf6ab4b1a0147db3e ) -) - -game ( - name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" - description "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" - rom ( name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl).gb" size 262144 crc 98222a4a sha1 0bdb8ad04469a329c8cee2fb0c55da35f7752042 ) -) - game ( name "Boxing (Japan)" description "Boxing (Japan)" @@ -22981,9 +23927,9 @@ game ( ) game ( - name "Brain Drain (Japan) (SGB Enhanced)" - description "Brain Drain (Japan) (SGB Enhanced)" - rom ( name "Brain Drain (Japan) (SGB Enhanced).gb" size 131072 crc e558aacd sha1 225c25d94854f509611b8c0b4b415daf48d51310 ) + name "Brain Drain (Japan) (En) (SGB Enhanced)" + description "Brain Drain (Japan) (En) (SGB Enhanced)" + rom ( name "Brain Drain (Japan) (En) (SGB Enhanced).gb" size 131072 crc e558aacd sha1 225c25d94854f509611b8c0b4b415daf48d51310 ) ) game ( @@ -23058,12 +24004,6 @@ game ( rom ( name "Bubsy II (USA).gb" size 262144 crc 600a6ad5 sha1 1ac9bf5043caf428994bca3e80158ca697e94c58 ) ) -game ( - name "Bug Bites! (World) (Aftermarket) (Unl)" - description "Bug Bites! (World) (Aftermarket) (Unl)" - rom ( name "Bug Bites! (World) (Aftermarket) (Unl).gb" size 262144 crc bb473d7a sha1 8d601612ac262e4548d8b8f6ac19a04cb92ecfb7 ) -) - game ( name "Bugs Bunny Collection (Japan) (SGB Enhanced)" description "Bugs Bunny Collection (Japan) (SGB Enhanced)" @@ -23148,12 +24088,6 @@ game ( rom ( name "Buster Bros. (USA).gb" size 131072 crc b4245ca3 sha1 0d1692ff60ef1f6a97bbfd2bf8c1548f1f7439ed ) ) -game ( - name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" - description "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" - rom ( name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl).gb" size 1048576 crc d0ed199c sha1 a1cbaacdf32cb8fb9a9c59fcb624c729e0ca17bf ) -) - game ( name "Cadillac II (Japan)" description "Cadillac II (Japan)" @@ -23175,7 +24109,7 @@ game ( game ( name "Caesars Palace (USA)" description "Caesars Palace (USA)" - rom ( name "Caesars Palace (USA).gb" size 131072 crc d9f901a9 sha1 c1ed80f33fc3603edaba1bdf5c317f1a205da3dc ) + rom ( name "Caesars Palace (USA).gb" size 131072 crc d9f901a9 sha1 c1ed80f33fc3603edaba1bdf5c317f1a205da3dc flags verified ) ) game ( @@ -23286,12 +24220,6 @@ game ( rom ( name "Castle Quest (Europe) (Beta).gb" size 131072 crc 8a5636ea sha1 356c8510b0647e56a558aba9d5dc4cc9d3ccd94c ) ) -game ( - name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" - description "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" - rom ( name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 3c492b31 sha1 0861af0039dab4b4f5bce747c6fcd586eced401a ) -) - game ( name "Castlevania - The Adventure (USA) (Castlevania Anniversary Collection)" description "Castlevania - The Adventure (USA) (Castlevania Anniversary Collection)" @@ -23328,12 +24256,6 @@ game ( rom ( name "Castlevania Legends (USA, Europe) (SGB Enhanced).gb" size 262144 crc ad9c17fb sha1 91a8e49bf6eac5fe62ec2cc5e6decbd08ce9b515 flags verified ) ) -game ( - name "Catrap (USA)" - description "Catrap (USA)" - rom ( name "Catrap (USA).gb" size 32768 crc adb96150 sha1 171e4d54f22f8dc137d12828fcc2da9874c56970 ) -) - game ( name "Catrap (USA) (Beta)" description "Catrap (USA) (Beta)" @@ -23341,9 +24263,9 @@ game ( ) game ( - name "Cave Fighter (World) (Aftermarket) (Unl)" - description "Cave Fighter (World) (Aftermarket) (Unl)" - rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gb" size 262144 crc e8f91f6a sha1 290048717d0a8cabb3cc591161339550eb53c161 ) + name "Catrap (USA)" + description "Catrap (USA)" + rom ( name "Catrap (USA).gb" size 32768 crc adb96150 sha1 171e4d54f22f8dc137d12828fcc2da9874c56970 ) ) game ( @@ -23394,18 +24316,6 @@ game ( rom ( name "Chase H.Q. (USA, Europe).gb" size 131072 crc 67a45d19 sha1 cbcd6254b1b0227ba6aa8d95c979abb7fe8e4d38 flags verified ) ) -game ( - name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" - description "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" - rom ( name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 3e20c1a8 sha1 f76645a2830fcc733b7392a52112df628f0b7a4a ) -) - -game ( - name "Cherry Rescue! (World) (Aftermarket) (Unl)" - description "Cherry Rescue! (World) (Aftermarket) (Unl)" - rom ( name "Cherry Rescue! (World) (Aftermarket) (Unl).gb" size 524288 crc ba65812a sha1 740dba1827c730cc5d8bf67495bcede3a5352643 ) -) - game ( name "Chessmaster, The (Europe)" description "Chessmaster, The (Europe)" @@ -23526,42 +24436,12 @@ game ( rom ( name "Chousoku Spinner (Japan) (SGB Enhanced).gb" size 524288 crc b4fa9cf2 sha1 057a3251bbb7eb4e04b01f786bd2986af5eabc58 ) ) -game ( - name "Christmas Carols (World) (Aftermarket) (Unl)" - description "Christmas Carols (World) (Aftermarket) (Unl)" - rom ( name "Christmas Carols (World) (Aftermarket) (Unl).gb" size 262144 crc a00bb310 sha1 e19b0a698d8194467d57c00664f00f9898ee5368 ) -) - game ( name "Chuck Rock (USA, Europe)" description "Chuck Rock (USA, Europe)" rom ( name "Chuck Rock (USA, Europe).gb" size 131072 crc c5951d9e sha1 601453f98ba7d92ebe71f3e86952a584cbea090c ) ) -game ( - name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 2165f2e4 sha1 f8e5020298183c3f47836da3890b6bb398e2ecab ) -) - -game ( - name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 6afee818 sha1 602709c8655febb42899881a8ef598fb4b3da0c9 ) -) - -game ( - name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl).gb" size 1048576 crc 225ce296 sha1 45aebfe4e7f5382a4b31c3db270b75d2c458d1b2 ) -) - -game ( - name "Ciao Nonna (World) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (Aftermarket) (Unl).gb" size 1048576 crc dd7576d6 sha1 0556eb6160fdca6e7959bba1a619b8e34d974375 ) -) - game ( name "Cliffhanger (USA, Europe)" description "Cliffhanger (USA, Europe)" @@ -23580,12 +24460,6 @@ game ( rom ( name "College Slam (USA).gb" size 524288 crc a549a572 sha1 84dc6269fbe4ee4c157f940b0a9630412e099cc6 ) ) -game ( - name "Commando (World) (Aftermarket) (Unl)" - description "Commando (World) (Aftermarket) (Unl)" - rom ( name "Commando (World) (Aftermarket) (Unl).gb" size 262144 crc 48173941 sha1 c861858e9f2cf7470e739c26ae9f17d3834ce464 ) -) - game ( name "Contra (World) (Contra Anniversary Collection)" description "Contra (World) (Contra Anniversary Collection)" @@ -23646,12 +24520,6 @@ game ( rom ( name "Cool World (USA, Europe).gb" size 131072 crc a193c0d0 sha1 1919495cc83c4126c90d6cfa2e14427b6364da3a flags verified ) ) -game ( - name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" - description "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" - rom ( name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl).gb" size 262144 crc fd304687 sha1 7df11ec2946099d49dd62928118b6d76703dc57c ) -) - game ( name "Cosmo Tank (Japan) (Beta)" description "Cosmo Tank (Japan) (Beta)" @@ -23676,18 +24544,6 @@ game ( rom ( name "Cosmo Tank (USA).gb" size 131072 crc 2e767d25 sha1 48a8f5c50a237f11c8e18efd03a5282f493312bc ) ) -game ( - name "Coucou (World) (Aftermarket) (Unl)" - description "Coucou (World) (Aftermarket) (Unl)" - rom ( name "Coucou (World) (Aftermarket) (Unl).gb" size 32768 crc e6aabd72 sha1 5283268e3640e2924d00aea3b12b2d3930bef43c ) -) - -game ( - name "Counting Sheep (World) (Aftermarket) (Unl)" - description "Counting Sheep (World) (Aftermarket) (Unl)" - rom ( name "Counting Sheep (World) (Aftermarket) (Unl).GB" size 65536 crc 6e97c837 sha1 e7e251ad86fa00803837cf871de62d3f100c83ce ) -) - game ( name "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced)" description "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced)" @@ -23736,12 +24592,6 @@ game ( rom ( name "Cult Master - Ultraman ni Miserarete (Japan).gb" size 262144 crc c3eb82ef sha1 f0e63a0a4e7b576c7460e810eb6f50d4c5b68769 ) ) -game ( - name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gb" size 262144 crc 10838580 sha1 c740bc995adf2bb638bb125a36edc416558fd4c6 ) -) - game ( name "CutThroat Island (Japan) (En) (Proto)" description "CutThroat Island (Japan) (En) (Proto)" @@ -23754,12 +24604,6 @@ game ( rom ( name "CutThroat Island (USA, Europe).gb" size 262144 crc eebdd360 sha1 5e99ea51b383cdcd53874eb027ebd59d2a3156b9 flags verified ) ) -game ( - name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" - description "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" - rom ( name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl).gb" size 1048576 crc e3a78253 sha1 45c9c6a7a4ec985146a4a616a49dba45decc6d3e ) -) - game ( name "Cyraid (USA)" description "Cyraid (USA)" @@ -23814,18 +24658,6 @@ game ( rom ( name "Daisenryaku (Japan).gb" size 131072 crc c8f80d90 sha1 79e724619d21ebb3cd5de5438535a7ee25009de0 ) ) -game ( - name "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" - description "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Dangan GB (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 5359d6db sha1 10029774046dabec2d8c0533caf94091f6e19071 ) -) - -game ( - name "Dangan GB (World) (Aftermarket) (Unl)" - description "Dangan GB (World) (Aftermarket) (Unl)" - rom ( name "Dangan GB (World) (Aftermarket) (Unl).gb" size 262144 crc daa59c9c sha1 8375d845fcfe4c236cd68f3d56a290f8c7b76c06 ) -) - game ( name "Darkman (USA, Europe)" description "Darkman (USA, Europe)" @@ -23863,9 +24695,9 @@ game ( ) game ( - name "Dash (World) (Aftermarket) (Unl)" - description "Dash (World) (Aftermarket) (Unl)" - rom ( name "Dash (World) (Aftermarket) (Unl).gb" size 262144 crc 73868683 sha1 c1ffe7c25a34d65ed166293bc7d2b48b65ca922b ) + name "David Crane's The Rescue of Princess Blobette (World) (Limited Run Games)" + description "David Crane's The Rescue of Princess Blobette (World) (Limited Run Games)" + rom ( name "David Crane's The Rescue of Princess Blobette (World) (Limited Run Games).gb" size 65536 crc 0c24923e sha1 e1f391102aba5ea75572b04180b31bcaaa47e593 ) ) game ( @@ -23898,36 +24730,12 @@ game ( rom ( name "Dead Heat Scramble (USA).gb" size 65536 crc 9e3e3656 sha1 71e560dd2b5f5c4f4dcca0837c74bb1b843a15aa ) ) -game ( - name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" - description "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" - rom ( name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl).gb" size 1048576 crc 7da95971 sha1 23cff594ef4b0bb21883b422940526c7fe81f1fd flags verified ) -) - -game ( - name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" - description "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" - rom ( name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl).gb" size 1048576 crc 9e2bf649 sha1 3feeba5c438880f70cdfdc4ea7e29f77e645e9be flags verified ) -) - -game ( - name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" - description "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" - rom ( name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl).gb" size 1048576 crc 818a7db7 sha1 43a93dc6f7bef002271e583edaeaf2e7162b8af4 ) -) - game ( name "Death Track (Europe) (Proto)" description "Death Track (Europe) (Proto)" rom ( name "Death Track (Europe) (Proto).gb" size 524288 crc c495a707 sha1 abc95b27be454405a6a22fb9e048537d1df60d75 ) ) -game ( - name "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" - description "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Deep Forest (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 3ddf177d sha1 517302d20cb5140975e6cd1b3c495786b6390aaf ) -) - game ( name "Dennis (Europe) (Beta) (1993-09-13)" description "Dennis (Europe) (Beta) (1993-09-13)" @@ -23970,12 +24778,6 @@ game ( rom ( name "Diablo (USA) (Proto).gb" size 131072 crc aaaad0b6 sha1 8982410ac627618628a8b823c0608cc8b5653f41 ) ) -game ( - name "DiaMaze (World) (Aftermarket) (Unl)" - description "DiaMaze (World) (Aftermarket) (Unl)" - rom ( name "DiaMaze (World) (Aftermarket) (Unl).gb" size 262144 crc 956fa901 sha1 f41b98ac4669920ffede1736ddbd9e1f62d4cb0d ) -) - game ( name "Dick Tracy (USA)" description "Dick Tracy (USA)" @@ -23994,12 +24796,6 @@ game ( rom ( name "Dig Dug (USA).gb" size 131072 crc 6c742478 sha1 951753904389332412d4b0a80b48d7ac61a494fc ) ) -game ( - name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" - description "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" - rom ( name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc b230b782 sha1 f1796dcbfb6f0f5e01c60222c376cc1c46945806 ) -) - game ( name "Dino Breeder (Japan) (SGB Enhanced)" description "Dino Breeder (Japan) (SGB Enhanced)" @@ -24018,12 +24814,6 @@ game ( rom ( name "Dino Breeder 2 (Japan) (SGB Enhanced).gb" size 524288 crc 05a3ab7a sha1 ac4b1fe0e917298d81725d7a9bdf46c285502ac7 flags verified ) ) -game ( - name "Dino's Offline Adventure (World) (Aftermarket) (Unl)" - description "Dino's Offline Adventure (World) (Aftermarket) (Unl)" - rom ( name "Dino's Offline Adventure (World) (Aftermarket) (Unl).gb" size 32768 crc d6bd0e6a sha1 6d11c145606f8e7ab25b2b07c299e36c8b442d23 ) -) - game ( name "Dirty Racing (Europe) (Proto)" description "Dirty Racing (Europe) (Proto)" @@ -24036,42 +24826,6 @@ game ( rom ( name "Dirty Racing (Japan).gb" size 131072 crc 43af45b1 sha1 5b58b4d02987ce3a16774bc4a6707d12ac404c1c ) ) -game ( - name "DMG Deals Damage (World) (Aftermarket) (Unl)" - description "DMG Deals Damage (World) (Aftermarket) (Unl)" - rom ( name "DMG Deals Damage (World) (Aftermarket) (Unl).gb" size 32768 crc 250e0cbd sha1 a15539199e4b6bd2a71d1ac0e7c61ae4f19a65e7 flags verified ) -) - -game ( - name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc f339fa82 sha1 bdbc082017bdf2e4caa84e7d00dad9707727e9d4 ) -) - -game ( - name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl).gb" size 1048576 crc cfb44d68 sha1 6dde71bbec8b807af5132d1ef2e99c6bb6af3a1c ) -) - -game ( - name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl).gb" size 1048576 crc 62e0c3a2 sha1 e1b516e472e0c681b4ad1c7f4aeda55c91e7f340 ) -) - -game ( - name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" - description "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl).gb" size 1048576 crc e393d4aa sha1 d45dfcab4a76b62ea1e10730d01f755e12137484 ) -) - -game ( - name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl).gb" size 1048576 crc 3890e0a4 sha1 6998e1bbf2ccb9db3d661ddac2d7edf7571d0af7 ) -) - game ( name "Doctor GB Card 16M Loader (World) (Unl)" description "Doctor GB Card 16M Loader (World) (Unl)" @@ -24102,18 +24856,6 @@ game ( rom ( name "Dodge Boy (Japan).gb" size 131072 crc f58dc358 sha1 b48eb2bdc34588847728936491dadda67394f9b7 ) ) -game ( - name "Dog's Muck Island (World) (Aftermarket) (Unl)" - description "Dog's Muck Island (World) (Aftermarket) (Unl)" - rom ( name "Dog's Muck Island (World) (Aftermarket) (Unl).gb" size 262144 crc 79a7a06c sha1 eb4cea3b9db770bf3b586578af1ad7427d88ee8e ) -) - -game ( - name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" - description "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 83247308 sha1 4579eaa45e2bf8f17f4dc99bdfb0b98270b871f5 ) -) - game ( name "Donkey Kong (Japan, USA) (En) (SGB Enhanced)" description "Donkey Kong (Japan, USA) (En) (SGB Enhanced)" @@ -24384,12 +25126,6 @@ game ( rom ( name "Dragon Ball Z 3 (USA) (SGB Enhanced) (Unl).gb" size 1048576 crc 71b8ea17 sha1 c43eb3906f77dda5fee94a0fce0b6d783461238c ) ) -game ( - name "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" - description "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Dragon Battle (World) (Demo) (Aftermarket) (Unl).gb" size 4194304 crc c1e1e52c sha1 c5ac56e266c421a1c5b82de46859a44f75d03359 ) -) - game ( name "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" description "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" @@ -24426,18 +25162,6 @@ game ( rom ( name "Dragon's Lair - The Legend (USA).gb" size 131072 crc 7a38b5c3 sha1 4e947908fde7ef9892c59021c6eea0607771f6d2 ) ) -game ( - name "Dragonborne (World) (Aftermarket) (Unl)" - description "Dragonborne (World) (Aftermarket) (Unl)" - rom ( name "Dragonborne (World) (Aftermarket) (Unl).gb" size 2097152 crc 0ae28712 sha1 e3cd09069ee59ed3f7915a79af0667de4ebd7d50 ) -) - -game ( - name "Dragonborne (World) (Demo) (Aftermarket) (Unl)" - description "Dragonborne (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Dragonborne (World) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc eda66890 sha1 3a5bcd9daa830842da60d8ebf35fa7036a259d76 ) -) - game ( name "DragonHeart (France)" description "DragonHeart (France)" @@ -24564,12 +25288,6 @@ game ( rom ( name "Eddie's Puzzle Time (USA) (Proto).gb" size 65536 crc f2600f02 sha1 cd2695295831737d0f8a7eb825bbfe870b9c0bfd ) ) -game ( - name "Elden Ring GB (World) (Aftermarket) (Unl)" - description "Elden Ring GB (World) (Aftermarket) (Unl)" - rom ( name "Elden Ring GB (World) (Aftermarket) (Unl).gb" size 524288 crc e7a420f3 sha1 2e0bec6acf1a94ae3f2f6cf2040323862933d95a ) -) - game ( name "Elevator Action (Japan)" description "Elevator Action (Japan)" @@ -24630,12 +25348,6 @@ game ( rom ( name "F-15 Strike Eagle II (USA, Europe) (Beta) (July, 1992).gb" size 131072 crc d80bdbba sha1 298c07ef596ab3a3c4a320b2f2d7e2c0dbaf764d ) ) -game ( - name "F-Zero - Project (World) (Aftermarket) (Unl)" - description "F-Zero - Project (World) (Aftermarket) (Unl)" - rom ( name "F-Zero - Project (World) (Aftermarket) (Unl).gb" size 1048576 crc 4c707059 sha1 5b823ee17691d286a45f0667cddd59ccaaab5d8b ) -) - game ( name "F1 Boy (Japan)" description "F1 Boy (Japan)" @@ -24660,12 +25372,6 @@ game ( rom ( name "Faceball 2000 (USA).gb" size 131072 crc 7d890cd0 sha1 b0bd15bace04e0a3eb89773f231ac3a532181a0a flags verified ) ) -game ( - name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" - description "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" - rom ( name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 4f04cdfc sha1 591980cb5e17104d826c2a915f53bfc8a21affca ) -) - game ( name "Family Jockey (Japan)" description "Family Jockey (Japan)" @@ -24696,12 +25402,6 @@ game ( rom ( name "Famista 3 (Japan).gb" size 262144 crc bdc4ccc3 sha1 ac4b03e11e2ba135d0427c8b1da7de57c006b4a6 ) ) -game ( - name "Farm, The (World) (Aftermarket) (Unl)" - description "Farm, The (World) (Aftermarket) (Unl)" - rom ( name "Farm, The (World) (Aftermarket) (Unl).gb" size 524288 crc fbc1b5e8 sha1 d0fe06920f7e771d76507f60881904370ffbc145 ) -) - game ( name "Fastest Lap (USA)" description "Fastest Lap (USA)" @@ -24834,24 +25534,12 @@ game ( rom ( name "Final Fantasy Legend, The (USA).gb" size 131072 crc 8046148f sha1 901dfc83c72e172d35a376835807fc788444a9bb flags verified ) ) -game ( - name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" - description "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" - rom ( name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc 6cfb4669 sha1 339fd673509a5ac8f25426af25b4ccc96e8d2880 ) -) - game ( name "Final Reverse (Japan)" description "Final Reverse (Japan)" rom ( name "Final Reverse (Japan).gb" size 65536 crc e94a6942 sha1 e4b08e702f3b6c575b31dbd62615619126e03af5 ) ) -game ( - name "Finders Keepers (World) (Aftermarket) (Unl)" - description "Finders Keepers (World) (Aftermarket) (Unl)" - rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gb" size 524288 crc 6a98ac61 sha1 e40dd804388df8c08d3890d79eeafd8542cc8805 ) -) - game ( name "Fire Fighter (Europe)" description "Fire Fighter (Europe)" @@ -24924,12 +25612,6 @@ game ( rom ( name "Flipull - An Exciting Cube Game (Japan).gb" size 32768 crc 198f147d sha1 090c88ae19892c35608f4fa844a6e9efcbe23893 ) ) -game ( - name "Fly O'Clock (World) (Aftermarket) (Unl)" - description "Fly O'Clock (World) (Aftermarket) (Unl)" - rom ( name "Fly O'Clock (World) (Aftermarket) (Unl).gb" size 32768 crc 93df7f55 sha1 83dc8498bdbabc14a8f81a715c9da19970c1f0b9 ) -) - game ( name "Football International (Europe)" description "Football International (Europe)" @@ -25014,30 +25696,12 @@ game ( rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB - Tsukikage Mura no Kaibutsu (Japan) (SGB Enhanced).gb" size 524288 crc 2962afb4 sha1 920ef94c05ac741047a266cb1668c881eab2937c flags verified ) ) -game ( - name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" - description "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" - rom ( name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl).gb" size 32768 crc 36e2ca02 sha1 fd985703b296dd0bf74225c72155ea9e51dd6853 ) -) - game ( name "G Arms - Operation Gundam (Japan)" description "G Arms - Operation Gundam (Japan)" rom ( name "G Arms - Operation Gundam (Japan).gb" size 131072 crc 39058153 sha1 7d8011636fe36266b5f716e78e3e29006f024992 ) ) -game ( - name "G-Man (World) (Aftermarket) (Unl)" - description "G-Man (World) (Aftermarket) (Unl)" - rom ( name "G-Man (World) (Aftermarket) (Unl).gb" size 524288 crc 7296da69 sha1 fdc9933d46a063575c175453b1da8042fd28b135 ) -) - -game ( - name "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" - description "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" - rom ( name "G-ZERO (World) (v2.6) (Aftermarket) (Unl).gb" size 65536 crc 7dd0c878 sha1 929d25a612308614ac3ac2ee5a19a9cd4a9968d6 ) -) - game ( name "Galaga & Galaxian (Japan) (SGB Enhanced)" description "Galaga & Galaxian (Japan) (SGB Enhanced)" @@ -25059,7 +25723,7 @@ game ( game ( name "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced)" description "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced)" - rom ( name "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced).gb" size 262144 crc 9e6cdc96 sha1 4e4da0ed89c2baaed64600f7eaca90aeeadc084e ) + rom ( name "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced).gb" size 262144 crc 9e6cdc96 sha1 4e4da0ed89c2baaed64600f7eaca90aeeadc084e flags verified ) ) game ( @@ -25182,12 +25846,6 @@ game ( rom ( name "Game of Harmony, The (USA).gb" size 32768 crc b0074acb sha1 b0bc752e3ad25fcb83d8ca04a82a0f5e35381db2 ) ) -game ( - name "GameBoy WORDLE (World) (Aftermarket) (Unl)" - description "GameBoy WORDLE (World) (Aftermarket) (Unl)" - rom ( name "GameBoy WORDLE (World) (Aftermarket) (Unl).gb" size 32768 crc cc971c0f sha1 ba93939b93ab3f3aa5f7aa451d50d9b89220adbc ) -) - game ( name "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" description "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" @@ -25326,18 +25984,6 @@ game ( rom ( name "Gem Gem (Japan).gb" size 65536 crc a64a8710 sha1 90a29d7a56f64b596cda1c64c8998b63d12c321e ) ) -game ( - name "Genesis (World) (Aftermarket) (Unl)" - description "Genesis (World) (Aftermarket) (Unl)" - rom ( name "Genesis (World) (Aftermarket) (Unl).gb" size 65536 crc 74b3ec78 sha1 ca43f82d73ba0b3e43ec17f6bc6761c09ca23626 ) -) - -game ( - name "Genesis II (World) (Demo) (Aftermarket) (Unl)" - description "Genesis II (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Genesis II (World) (Demo) (Aftermarket) (Unl).gb" size 262144 crc d7aec1cc sha1 9700ea1278850df004ded7553253cfdd354f4ada ) -) - game ( name "Genjin Collection (Japan) (SGB Enhanced)" description "Genjin Collection (Japan) (SGB Enhanced)" @@ -25374,12 +26020,6 @@ game ( rom ( name "Getaway, The - High Speed II (USA).gb" size 262144 crc 8f2bf517 sha1 a0ca7187b55135150f348d44544d3a6e6d51394e ) ) -game ( - name "Ghost Town (World) (Aftermarket) (Unl)" - description "Ghost Town (World) (Aftermarket) (Unl)" - rom ( name "Ghost Town (World) (Aftermarket) (Unl).gb" size 262144 crc 2d27cdf2 sha1 af526273cdaa6423b92d0484fb27af56fe355a5d ) -) - game ( name "Ghostbusters II (USA, Europe) (Beta)" description "Ghostbusters II (USA, Europe) (Beta)" @@ -25410,18 +26050,6 @@ game ( rom ( name "Ginga - Card & Puzzle Collection (Japan) (En,Ja).gb" size 65536 crc 87d0637b sha1 14f4f14caee081dceadb9d31ae26fd8968c432ea ) ) -game ( - name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" - description "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" - rom ( name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 4b19366d sha1 77f3b561bf28a81f38dbedc351752e10ff4c23dc ) -) - -game ( - name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" - description "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" - rom ( name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 3f34ff66 sha1 a0bff49b6917186d27dc24773da0674a18a6212c ) -) - game ( name "Gluecksrad (Germany)" description "Gluecksrad (Germany)" @@ -25788,24 +26416,6 @@ game ( rom ( name "Gremlins 2 - The New Batch (World).gb" size 131072 crc 3579e297 sha1 0cb722d9d4e349bea1b1afa85d8d3b93f2dc2aad flags verified ) ) -game ( - name "Gun Law (World) (Aftermarket) (Unl)" - description "Gun Law (World) (Aftermarket) (Unl)" - rom ( name "Gun Law (World) (Aftermarket) (Unl).gb" size 262144 crc b0d53211 sha1 ef6e3d287e99bd61861a333165c92b306238a45f ) -) - -game ( - name "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" - description "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Gunman Clive (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc 11f5fded sha1 ec03763db2c0d754e2eb7e98384ed92fc8aeeb1d ) -) - -game ( - name "Gunship (World) (Aftermarket) (Unl)" - description "Gunship (World) (Aftermarket) (Unl)" - rom ( name "Gunship (World) (Aftermarket) (Unl).gb" size 131072 crc bd31eef8 sha1 a801977c3746799cfb4d8bdfd679e45cccd3b719 ) -) - game ( name "HAL Wrestling (USA)" description "HAL Wrestling (USA)" @@ -25830,12 +26440,6 @@ game ( rom ( name "Hammerin' Harry - Ghost Building Company (USA) (Proto).gb" size 262144 crc 6c4d0377 sha1 c5f73b09f001fc4d7eaa40ffee00234ca6a41a41 ) ) -game ( - name "Harbour Attack (World) (Aftermarket) (Unl)" - description "Harbour Attack (World) (Aftermarket) (Unl)" - rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 4018ebf7 sha1 5bbbe727ebc6a489f1a498d067e4f05d0d69b60f ) -) - game ( name "Harvest Moon GB (USA) (SGB Enhanced)" description "Harvest Moon GB (USA) (SGB Enhanced)" @@ -25860,12 +26464,6 @@ game ( rom ( name "Head On (Japan).gb" size 65536 crc 78830daf sha1 76261091adb7def20a4f76aa6c062c60c6d9761c ) ) -game ( - name "Heart Knight (World) (Aftermarket) (Unl)" - description "Heart Knight (World) (Aftermarket) (Unl)" - rom ( name "Heart Knight (World) (Aftermarket) (Unl).gb" size 32768 crc c7ecac73 sha1 dedcab41f58c58834e3534e877c494669a0d8952 ) -) - game ( name "Heavyweight Championship Boxing (USA)" description "Heavyweight Championship Boxing (USA)" @@ -25908,12 +26506,6 @@ game ( rom ( name "Hercules (USA, Europe) (SGB Enhanced).gb" size 524288 crc 00a9001e sha1 215cceaccd4a33a2da6205f33a2803ff4004e2b1 flags verified ) ) -game ( - name "Hermano (World) (v1.1) (Aftermarket) (Unl)" - description "Hermano (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Hermano (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 74a0419b sha1 c42cfe91a1ec593a76291e031c47137bd794ffda ) -) - game ( name "Hero Shuugou!! Pinball Party (Japan)" description "Hero Shuugou!! Pinball Party (Japan)" @@ -26082,12 +26674,6 @@ game ( rom ( name "Hudson Hawk (Europe) (Proto).gb" size 131072 crc d4cd525d sha1 07c6a49f7c340d3cc78ca688eb1591853255a6c6 ) ) -game ( - name "Hugo (World) (Aftermarket) (Unl)" - description "Hugo (World) (Aftermarket) (Unl)" - rom ( name "Hugo (World) (Aftermarket) (Unl).gb" size 262144 crc 8cc87f60 sha1 53fac2774b29a32501788e1eac65db23bf5c7b8f ) -) - game ( name "Hugo (Europe) (SGB Enhanced)" description "Hugo (Europe) (SGB Enhanced)" @@ -26160,12 +26746,6 @@ game ( rom ( name "Hyper Lode Runner (Japan) (En) (Possible Proto).gb" size 32768 crc 3fc21b74 sha1 37d0f2cbac0f95af8b22dea0c882612681ec5cc8 ) ) -game ( - name "If (World) (Aftermarket) (Unl)" - description "If (World) (Aftermarket) (Unl)" - rom ( name "If (World) (Aftermarket) (Unl).gb" size 1048576 crc be7e4454 sha1 c11d8dc9ce96133f679678b07822a82f985e16f9 ) -) - game ( name "Ikari no Yousai (Japan)" description "Ikari no Yousai (Japan)" @@ -26178,12 +26758,6 @@ game ( rom ( name "Ikari no Yousai 2 (Japan).gb" size 131072 crc 6d4fd9aa sha1 ae437d4fb39d7438fc9eb98c91820aa2b5161b4f ) ) -game ( - name "Impossible Gameboy (World) (Aftermarket) (Unl)" - description "Impossible Gameboy (World) (Aftermarket) (Unl)" - rom ( name "Impossible Gameboy (World) (Aftermarket) (Unl).gb" size 131072 crc ab65b738 sha1 d31cedd6227b23cf3d8ef81c73f133ab0b57e4f4 ) -) - game ( name "In Your Face (USA)" description "In Your Face (USA)" @@ -26268,24 +26842,12 @@ game ( rom ( name "Initial D Gaiden (Japan) (SGB Enhanced).gb" size 262144 crc 6cc56612 sha1 1b3c4c1c4dfca46a009eb2e5cd45b343d7ee6681 ) ) -game ( - name "Interblocked (World) (Aftermarket) (Unl)" - description "Interblocked (World) (Aftermarket) (Unl)" - rom ( name "Interblocked (World) (Aftermarket) (Unl).gb" size 262144 crc 5c208855 sha1 8e46486533a3de9ee87cc07bf8efaf818752a61a ) -) - game ( name "International Superstar Soccer (USA, Europe) (SGB Enhanced)" description "International Superstar Soccer (USA, Europe) (SGB Enhanced)" rom ( name "International Superstar Soccer (USA, Europe) (SGB Enhanced).gb" size 262144 crc 94757be8 sha1 13f2fc0945fb7a90f4d87d8c4e310dec9af6b792 ) ) -game ( - name "Into the Blue (World) (Aftermarket) (Unl)" - description "Into the Blue (World) (Aftermarket) (Unl)" - rom ( name "Into the Blue (World) (Aftermarket) (Unl).gb" size 131072 crc 7714e96e sha1 5ac7a349bb37c8767c9db264ed8ae7b7647fa8ea ) -) - game ( name "Ippatsu Gyakuten! DX Bakenou (Japan)" description "Ippatsu Gyakuten! DX Bakenou (Japan)" @@ -26346,12 +26908,6 @@ game ( rom ( name "J.League Winning Goal (Japan).gb" size 131072 crc adb46f9c sha1 b8630f06e8b9682e667b7b1f2139162e2f022561 ) ) -game ( - name "Jabberwocky (World) (Aftermarket) (Unl)" - description "Jabberwocky (World) (Aftermarket) (Unl)" - rom ( name "Jabberwocky (World) (Aftermarket) (Unl).gb" size 1048576 crc cfc51717 sha1 b4e447f2197688c740a45dce27879a62c742fb96 ) -) - game ( name "Jack Nicklaus Golf (France)" description "Jack Nicklaus Golf (France)" @@ -26376,12 +26932,6 @@ game ( rom ( name "James Bond 007 (USA, Europe) (SGB Enhanced).gb" size 524288 crc ca3bc3ce sha1 e03754173a5d62cb9da7d2306bc41b0e23e3d519 flags verified ) ) -game ( - name "Jane in the Jungle (World) (Aftermarket) (Unl)" - description "Jane in the Jungle (World) (Aftermarket) (Unl)" - rom ( name "Jane in the Jungle (World) (Aftermarket) (Unl).gb" size 262144 crc c68e751a sha1 dfc65dcf700a26b273d705b7cfececbc44b80587 ) -) - game ( name "Jankenman (Japan)" description "Jankenman (Japan)" @@ -26466,12 +27016,6 @@ game ( rom ( name "Jet Pak Man (Europe) (Proto).gb" size 32768 crc e40dfc1b sha1 0080f76961164810d6c0543d951a465cfa1cab54 ) ) -game ( - name "Jet Set Willy (World) (Aftermarket) (Unl)" - description "Jet Set Willy (World) (Aftermarket) (Unl)" - rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gb" size 262144 crc 1686d7ed sha1 0e594224506fd087e36c66bb66905d4c91b02461 ) -) - game ( name "Jetsons, The - Robot Panic (USA, Europe)" description "Jetsons, The - Robot Panic (USA, Europe)" @@ -26550,12 +27094,6 @@ game ( rom ( name "Joe & Mac - Caveman Ninja (Europe) (En,Fr,De,Es,It,Nl,Sv) (Beta).gb" size 262144 crc 381c62ee sha1 979e36765291153b82025b1f036c08fe9c23cfa5 ) ) -game ( - name "Joe Blade 2 (World) (Aftermarket) (Unl)" - description "Joe Blade 2 (World) (Aftermarket) (Unl)" - rom ( name "Joe Blade 2 (World) (Aftermarket) (Unl).gb" size 524288 crc 09f75c70 sha1 f001dffcd16be670c36a98dd9136f6f9fbf5b85d ) -) - game ( name "John Madden Football (USA) (Proto 2) (SGB Enhanced)" description "John Madden Football (USA) (Proto 2) (SGB Enhanced)" @@ -26772,12 +27310,6 @@ game ( rom ( name "Kenyuu Densetsu Yaiba (Japan).gb" size 262144 crc cc19768e sha1 c2b71ceee21f66f462df18233f7622d8ec95fcca ) ) -game ( - name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" - description "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" - rom ( name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl).gb" size 1048576 crc 986bfd75 sha1 6d15b5bc33d7c7771ba62d56ae7f25fa081bc564 ) -) - game ( name "Kick Attack (Japan) (Proto)" description "Kick Attack (Japan) (Proto)" @@ -27078,12 +27610,6 @@ game ( rom ( name "Krusty's Fun House (USA, Europe).gb" size 131072 crc 1cedb141 sha1 e61039c52c053a8ae1bdfffa3f694934569bb570 flags verified ) ) -game ( - name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" - description "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" - rom ( name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 0610049a sha1 a6fbe1a524547bebabc5e6b3baff1dff8f13dbd0 ) -) - game ( name "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced)" description "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced)" @@ -27138,36 +27664,12 @@ game ( rom ( name "Lasama Chuanqi - Story of Lasama (Taiwan) (Unl) (Alt).gb" size 65536 crc 997fa9eb sha1 ded742d50ed553ffea524d7deec628c354c74cc4 ) ) -game ( - name "Laser Squad Alter (World) (Aftermarket) (Unl)" - description "Laser Squad Alter (World) (Aftermarket) (Unl)" - rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gb" size 1048576 crc a39b3a5a sha1 1620e585e77a2457cffde82453bec0c7a04e07cf ) -) - game ( name "Last Action Hero (USA, Europe)" description "Last Action Hero (USA, Europe)" rom ( name "Last Action Hero (USA, Europe).gb" size 131072 crc 10499af6 sha1 010eb2cbab987ec242cd0792c789a07c00106f48 ) ) -game ( - name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 2c430576 sha1 0e290b387a45b6ea85c6d49bf18bce3ce94951b7 ) -) - -game ( - name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 5cf1a6f9 sha1 9fac1324e863f719674219eb41e45f1f745c67a9 ) -) - -game ( - name "Lawn Mower Land (World) (Aftermarket) (Unl)" - description "Lawn Mower Land (World) (Aftermarket) (Unl)" - rom ( name "Lawn Mower Land (World) (Aftermarket) (Unl).gb" size 32768 crc 11c62e39 sha1 1d6aa817ebf2a7e5d22285b906540272b67169da ) -) - game ( name "Lawnmower Man, The (USA) (Proto 1) (1993-10-11) (Not For Resale)" description "Lawnmower Man, The (USA) (Proto 1) (1993-10-11) (Not For Resale)" @@ -27192,12 +27694,6 @@ game ( rom ( name "Lazlos' Leap (USA).gb" size 65536 crc 31fb404b sha1 c111470fcdadf191cf843e50c8f3d3dbb995a5c5 ) ) -game ( - name "Leak, The (World) (Aftermarket) (Unl)" - description "Leak, The (World) (Aftermarket) (Unl)" - rom ( name "Leak, The (World) (Aftermarket) (Unl).GB" size 65536 crc ba3cfeae sha1 98de2d8be75e6d9cb4e87afe14b1380c033de797 ) -) - game ( name "Learn and Play - Blackjack & Solitaire (USA) (1994-08-09) (Proto)" description "Learn and Play - Blackjack & Solitaire (USA) (1994-08-09) (Proto)" @@ -27228,6 +27724,12 @@ game ( rom ( name "Legend of the River King GB (Australia) (SGB Enhanced).gb" size 524288 crc 51627213 sha1 87274e8c0d2daaac2e0dda94651c35d6a0617c0f ) ) +game ( + name "Legend of the Sea King GB (USA) (Proto) (SGB Enhanced)" + description "Legend of the Sea King GB (USA) (Proto) (SGB Enhanced)" + rom ( name "Legend of the Sea King GB (USA) (Proto) (SGB Enhanced).gb" size 1048576 crc a45ef889 sha1 26bebc2394b5da850be55e409b9efcb4d2d29d87 ) +) + game ( name "Legend of Zelda, The - Link's Awakening (Canada) (Fr)" description "Legend of Zelda, The - Link's Awakening (Canada) (Fr)" @@ -27277,9 +27779,9 @@ game ( ) game ( - name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17)" - description "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17).gb" size 524288 crc f7c59f5c sha1 d1a10a3f129bf060f16d1fb5f991ef6e2f28b97c ) + name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16)" + description "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16).gb" size 524288 crc f7c59f5c sha1 d1a10a3f129bf060f16d1fb5f991ef6e2f28b97c ) ) game ( @@ -27318,12 +27820,6 @@ game ( rom ( name "Lemmings 2 - The Tribes (Europe).gb" size 524288 crc 9800bd49 sha1 76ccf9ac82faebc7f9c4a4c8b5cd47ddea46c486 flags verified ) ) -game ( - name "Lethal Weapon (USA, Europe)" - description "Lethal Weapon (USA, Europe)" - rom ( name "Lethal Weapon (USA, Europe).gb" size 131072 crc 1f8d207c sha1 8b4621471b376a6262fbed70c1191416ab3be915 ) -) - game ( name "Lethal Weapon (USA, Europe) (Beta)" description "Lethal Weapon (USA, Europe) (Beta)" @@ -27331,15 +27827,9 @@ game ( ) game ( - name "Life's Too Short (World) (Aftermarket) (Unl)" - description "Life's Too Short (World) (Aftermarket) (Unl)" - rom ( name "Life's Too Short (World) (Aftermarket) (Unl).gb" size 262144 crc 458174cc sha1 7b704cd999cbeeb9991d675e2b1e67a906fa766d ) -) - -game ( - name "Linea, La (World) (Aftermarket) (Unl)" - description "Linea, La (World) (Aftermarket) (Unl)" - rom ( name "Linea, La (World) (Aftermarket) (Unl).gb" size 262144 crc c8750c01 sha1 00348fec54b5d3ebb762484bdcc015881bb9e95b ) + name "Lethal Weapon (USA, Europe)" + description "Lethal Weapon (USA, Europe)" + rom ( name "Lethal Weapon (USA, Europe).gb" size 131072 crc 1f8d207c sha1 8b4621471b376a6262fbed70c1191416ab3be915 ) ) game ( @@ -27403,57 +27893,9 @@ game ( ) game ( - name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc 9c4f03fd sha1 288cb53b4782df4409ee683e9aa11b4dd2a3a53e ) -) - -game ( - name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc e5988949 sha1 08d033c7ef20fd4d24d1f07b3ebb177fb9b78673 ) -) - -game ( - name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc 59568248 sha1 6571db155f6f25eeeec86d28b105bf8fef156322 ) -) - -game ( - name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc a26345b8 sha1 641110cb187657fd15ea254440e1c74ab4a88856 ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc d70f1d25 sha1 02e2fb6cbc5cff05ed775c9e1cd9acc07fa2e036 ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc ae07c093 sha1 9f40b8719b3fdd2f7e6c59a4f616e9eb712d538d ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc 34671dc6 sha1 377d22d54e6e1fa4fcd4b4576d5886774f9f6c97 ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc a8fb0d7a sha1 26803ba3413c7c52a8a58393f63472bc87ec3c6b ) -) - -game ( - name "Lock n' Chase ~ Lock 'n' Chase (World)" - description "Lock n' Chase ~ Lock 'n' Chase (World)" - rom ( name "Lock n' Chase ~ Lock 'n' Chase (World).gb" size 65536 crc dab91c7a sha1 643cbd566d35ce8dbe0f24627e4862c09805a04c flags verified ) + name "Lock n' Chase (World)" + description "Lock n' Chase (World)" + rom ( name "Lock n' Chase (World).gb" size 65536 crc dab91c7a sha1 643cbd566d35ce8dbe0f24627e4862c09805a04c flags verified ) ) game ( @@ -27528,12 +27970,6 @@ game ( rom ( name "Lucle (Japan, Europe) (En).gb" size 524288 crc a3d5c8d7 sha1 2fef16fac95ec4ffd252e9974eccfce538e5f797 ) ) -game ( - name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" - description "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" - rom ( name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl).gb" size 524288 crc 1a5106a2 sha1 f56c1b324b8c1e17da86e40c5e9a887ec19b0c80 ) -) - game ( name "Lunar Chase (USA) (Proto 1)" description "Lunar Chase (USA) (Proto 1)" @@ -27558,18 +27994,6 @@ game ( rom ( name "Mach Go Go Go (Japan) (SGB Enhanced).gb" size 262144 crc 016d230b sha1 baea8b49ce2402c5c094ddae0320a382c0d95d86 ) ) -game ( - name "Machine, The (World) (Aftermarket) (Unl)" - description "Machine, The (World) (Aftermarket) (Unl)" - rom ( name "Machine, The (World) (Aftermarket) (Unl).gb" size 2097152 crc b06036a9 sha1 50c5d1eb7c8946ac2d7e2c566b1ea4a9b0d58e90 ) -) - -game ( - name "Mad Monster (World) (Aftermarket) (Unl)" - description "Mad Monster (World) (Aftermarket) (Unl)" - rom ( name "Mad Monster (World) (Aftermarket) (Unl).gb" size 524288 crc c3fd371c sha1 9f4bea7ca7d26080110f54392314c60761236638 ) -) - game ( name "Madden 95 (USA, Europe) (SGB Enhanced)" description "Madden 95 (USA, Europe) (SGB Enhanced)" @@ -27618,18 +28042,6 @@ game ( rom ( name "Magical Taruruuto-kun 2 - Raibaa Zone Panic!! (Japan).gb" size 131072 crc 0aad5217 sha1 3be6c6b8cec80a0fe0f6edbbe40496f4d077c750 ) ) -game ( - name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" - description "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" - rom ( name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 76fcbc30 sha1 7a759372bd013dcdb59c9131a2908085fc04d648 ) -) - -game ( - name "Magipanels (World) (Aftermarket) (Unl)" - description "Magipanels (World) (Aftermarket) (Unl)" - rom ( name "Magipanels (World) (Aftermarket) (Unl).gb" size 131072 crc 0b66561b sha1 c9513f6769098f2185f632f87386788f0f0b6ad8 ) -) - game ( name "Magnetic Soccer (Europe)" description "Magnetic Soccer (Europe)" @@ -27666,12 +28078,6 @@ game ( rom ( name "Makaimura Gaiden - The Demon Darkness (Japan).gb" size 262144 crc cfa358de sha1 961d05e91288d7ad1f2e6a1c996059d7ab96fe98 ) ) -game ( - name "Make Way (World) (Aftermarket) (Unl)" - description "Make Way (World) (Aftermarket) (Unl)" - rom ( name "Make Way (World) (Aftermarket) (Unl).gb" size 1048576 crc edeee5a8 sha1 19fd02e9318ed81ec968a2fca31ea0c3d8d94a7b ) -) - game ( name "Malibu Beach Volleyball (USA)" description "Malibu Beach Volleyball (USA)" @@ -27738,30 +28144,12 @@ game ( rom ( name "Marmalade Boy (Japan) (SGB Enhanced).gb" size 262144 crc 0f3ff7da sha1 60125690b7a354ff8e72f497c8a88ecd691e7e4b ) ) -game ( - name "Marron Helps a Friend (World) (Aftermarket) (Unl)" - description "Marron Helps a Friend (World) (Aftermarket) (Unl)" - rom ( name "Marron Helps a Friend (World) (Aftermarket) (Unl).gb" size 1048576 crc 08a3a987 sha1 adcd56fa3eba93edd20be25ae5cb349070cd0323 flags verified ) -) - game ( name "Maru's Mission (USA)" description "Maru's Mission (USA)" rom ( name "Maru's Mission (USA).gb" size 131072 crc 6e4f1eb3 sha1 91446b1cc6dbf3b98b81f13e35ffe7bfaaa027aa flags verified ) ) -game ( - name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" - description "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl).gb" size 262144 crc dccaeb60 sha1 1e4fc83bfe9c9063975a3862770e4afee3f947a4 ) -) - -game ( - name "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" - description "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" - rom ( name "Marzipan Beef Reverser (World) (Aftermarket) (Unl).gb" size 131072 crc 4c3e0d15 sha1 6cbfb0390ee555718b5b0c3a5437b7d3d4ee0008 ) -) - game ( name "Masakari Densetsu - Kintarou Action Hen (Japan)" description "Masakari Densetsu - Kintarou Action Hen (Japan)" @@ -27979,9 +28367,9 @@ game ( ) game ( - name "Meteorite (World) (Aftermarket) (Unl)" - description "Meteorite (World) (Aftermarket) (Unl)" - rom ( name "Meteorite (World) (Aftermarket) (Unl).gb" size 262144 crc 50cf593d sha1 0e88a47faf3273f87c1ead7f789faeb06d5333f3 ) + name "Metal Masters (World) (Limited Run Games)" + description "Metal Masters (World) (Limited Run Games)" + rom ( name "Metal Masters (World) (Limited Run Games).gb" size 131072 crc 7de862fa sha1 9d4896a198904365ebc348c557b7c15f87b5e3c5 ) ) game ( @@ -28350,12 +28738,6 @@ game ( rom ( name "Missile Command (USA, Europe).gb" size 32768 crc 3a6cd4d8 sha1 ed529062ae3d1feb4defbf54c2cc759211e3aeaa flags verified ) ) -game ( - name "Mission Mars (World) (Aftermarket) (Unl)" - description "Mission Mars (World) (Aftermarket) (Unl)" - rom ( name "Mission Mars (World) (Aftermarket) (Unl).gb" size 262144 crc cb3a9ab8 sha1 31625a90b61d28ac782909ed8b00b3a48df7742e ) -) - game ( name "Mofa Qiu - Magic Ball (Taiwan) (Multicart Rip) (Unl)" description "Mofa Qiu - Magic Ball (Taiwan) (Multicart Rip) (Unl)" @@ -28434,12 +28816,6 @@ game ( rom ( name "Momotarou Dentetsu jr. - Zenkoku Ramen Meguri no Maki (Japan) (SGB Enhanced).gb" size 524288 crc 218265b3 sha1 30edf17fc9ddd9db7613c8f78b0ebc340cc89eb0 ) ) -game ( - name "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" - description "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" - rom ( name "Mona and the Witch's Hat (World) (Aftermarket) (Unl).gb" size 65536 crc 32ed7f4a sha1 625d3664d99dee075021b03ea6ff074ae2e49204 ) -) - game ( name "Monde Perdu, Le - Jurassic Park (France) (En) (SGB Enhanced)" description "Monde Perdu, Le - Jurassic Park (France) (En) (SGB Enhanced)" @@ -28530,12 +28906,6 @@ game ( rom ( name "Montezuma's Return! (Europe) (En,Fr,De,Es,It).gb" size 262144 crc e7ac155b sha1 a6b90cc58aeb5b44ef674c503a55a58278b1b6fa flags verified ) ) -game ( - name "Monty on the Run (World) (Aftermarket) (Unl)" - description "Monty on the Run (World) (Aftermarket) (Unl)" - rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gb" size 524288 crc e2ebb406 sha1 41ac5993fbff58be0712b554aae5e4367b68677b ) -) - game ( name "Mortal Kombat (USA, Europe) (Beta)" description "Mortal Kombat (USA, Europe) (Beta)" @@ -28680,24 +29050,12 @@ game ( rom ( name "Mulan (USA) (SGB Enhanced).gb" size 524288 crc bfcf71a1 sha1 7832fcc373ff752e757550079519b39583665c82 ) ) -game ( - name "Muncher (World) (Aftermarket) (Unl)" - description "Muncher (World) (Aftermarket) (Unl)" - rom ( name "Muncher (World) (Aftermarket) (Unl).gb" size 262144 crc 444d3d5e sha1 c3e09aff66c7e395bf95a1864963fbe979d5cb9b ) -) - game ( name "MVP Baseball (Japan)" description "MVP Baseball (Japan)" rom ( name "MVP Baseball (Japan).gb" size 262144 crc 38c126aa sha1 f0d921d13689d2afe7838eee127bf670439c8d8d ) ) -game ( - name "Mysterium (USA) (Beta)" - description "Mysterium (USA) (Beta)" - rom ( name "Mysterium (USA) (Beta).gb" size 131072 crc 004c1af7 sha1 82e058a7608a04a2837d0d8fe810270f804b43f3 ) -) - game ( name "Mysterium (Japan)" description "Mysterium (Japan)" @@ -28711,21 +29069,9 @@ game ( ) game ( - name "Mystic Quest (Europe)" - description "Mystic Quest (Europe)" - rom ( name "Mystic Quest (Europe).gb" size 262144 crc 57d95c92 sha1 3513310426c6ae88f9beb588f71c666e003273be flags verified ) -) - -game ( - name "Mystic Quest (France)" - description "Mystic Quest (France)" - rom ( name "Mystic Quest (France).gb" size 262144 crc b6e134af sha1 b52d82248849f1ead9bf22954b3cbf7bf8e02907 flags verified ) -) - -game ( - name "Mystic Quest (Germany)" - description "Mystic Quest (Germany)" - rom ( name "Mystic Quest (Germany).gb" size 262144 crc 0351b9a6 sha1 7cb65cb314e3f26b92549ddc7f4fc275186c6170 flags verified ) + name "Mysterium (USA) (Beta)" + description "Mysterium (USA) (Beta)" + rom ( name "Mysterium (USA) (Beta).gb" size 131072 crc 004c1af7 sha1 82e058a7608a04a2837d0d8fe810270f804b43f3 ) ) game ( @@ -28746,6 +29092,24 @@ game ( rom ( name "Mystic Quest (World) (De) (Collection of Mana).gb" size 262144 crc a9d7e152 sha1 69235c3494ea650db3b66d6393264f03f0022194 flags verified ) ) +game ( + name "Mystic Quest (Europe)" + description "Mystic Quest (Europe)" + rom ( name "Mystic Quest (Europe).gb" size 262144 crc 57d95c92 sha1 3513310426c6ae88f9beb588f71c666e003273be flags verified ) +) + +game ( + name "Mystic Quest (France)" + description "Mystic Quest (France)" + rom ( name "Mystic Quest (France).gb" size 262144 crc b6e134af sha1 b52d82248849f1ead9bf22954b3cbf7bf8e02907 flags verified ) +) + +game ( + name "Mystic Quest (Germany)" + description "Mystic Quest (Germany)" + rom ( name "Mystic Quest (Germany).gb" size 262144 crc 0351b9a6 sha1 7cb65cb314e3f26b92549ddc7f4fc275186c6170 flags verified ) +) + game ( name "Mystical Ninja Starring Goemon (Europe) (SGB Enhanced)" description "Mystical Ninja Starring Goemon (Europe) (SGB Enhanced)" @@ -28914,24 +29278,6 @@ game ( rom ( name "Nekketsu! Beach Volley Da yo Kunio-kun (Japan) (SGB Enhanced).gb" size 262144 crc abfb84df sha1 d3ad43c40c21d9825b4879dbf28ca58835da658a ) ) -game ( - name "Neko Can Dream (World) (Aftermarket) (Unl)" - description "Neko Can Dream (World) (Aftermarket) (Unl)" - rom ( name "Neko Can Dream (World) (Aftermarket) (Unl).gb" size 2097152 crc 6e76ef25 sha1 55686fde78d17d00adfc831eca2c699274a82273 ) -) - -game ( - name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" - description "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" - rom ( name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc a0ad7a18 sha1 5fb1a09e04cf1704b059468de8855dfa7e23043b ) -) - -game ( - name "Neko Can Dream (World) (Demo) (Aftermarket) (Unl)" - description "Neko Can Dream (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Neko Can Dream (World) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc dc011d07 sha1 43312b149355d20944e8a366584c69e5cb3be868 ) -) - game ( name "Nekojara Monogatari (Japan)" description "Nekojara Monogatari (Japan)" @@ -29262,60 +29608,18 @@ game ( rom ( name "Noobow (Japan).gb" size 262144 crc 8bbcc8bb sha1 b571d9051e3a9f1a55533b4f43941cae907aedff ) ) -game ( - name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" - description "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl).gb" size 262144 crc d6166c62 sha1 fa2198c5308a15195adbda004f09646589860d11 ) -) - -game ( - name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc 42b47080 sha1 08484b0f98e72d6577d9b7cde8c49908012d1fc5 ) -) - -game ( - name "Oblique Strategies (World) (Aftermarket) (Unl)" - description "Oblique Strategies (World) (Aftermarket) (Unl)" - rom ( name "Oblique Strategies (World) (Aftermarket) (Unl).gb" size 524288 crc 30eca8d3 sha1 6a09aabf30e2ebab2e31ae845cd2e8796c84797f ) -) - game ( name "Oddworld Adventures (USA, Europe)" description "Oddworld Adventures (USA, Europe)" rom ( name "Oddworld Adventures (USA, Europe).gb" size 524288 crc 6510c0e2 sha1 be3f69371b6959dab34014cb1d3672f4f3377c3a flags verified ) ) -game ( - name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" - description "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" - rom ( name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl).gb" size 524288 crc d3eba01d sha1 8cf234bbcb68ca2b676a4ccec89814b0cbce1c07 ) -) - -game ( - name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" - description "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" - rom ( name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 71f34822 sha1 f24da97f44d280f27f8ebe3acdc33fea758d2255 ) -) - -game ( - name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" - description "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" - rom ( name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 76baab68 sha1 cd76da35541535dd244ad60d10eb998f7692f07a ) -) - game ( name "Oira Jajamaru! Sekai Daibouken (Japan)" description "Oira Jajamaru! Sekai Daibouken (Japan)" rom ( name "Oira Jajamaru! Sekai Daibouken (Japan).gb" size 131072 crc 2d08d27f sha1 5e13eeb635b41589689fc1b495ee077125b7e8c1 ) ) -game ( - name "Olympic Skier (World) (Aftermarket) (Unl)" - description "Olympic Skier (World) (Aftermarket) (Unl)" - rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gb" size 524288 crc 93174431 sha1 7bcdf10533f8fe053e22534c4962ed4b1a5cf2e2 ) -) - game ( name "Olympic Summer Games (USA, Europe) (SGB Enhanced)" description "Olympic Summer Games (USA, Europe) (SGB Enhanced)" @@ -29424,12 +29728,6 @@ game ( rom ( name "Out of Gas (USA).gb" size 131072 crc 1b67e8b1 sha1 770ac35c0780cf432235593bd5674e72edd6cf7d ) ) -game ( - name "Out on a Limb (World) (Aftermarket) (Unl)" - description "Out on a Limb (World) (Aftermarket) (Unl)" - rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gb" size 262144 crc be197f87 sha1 2ddc2378539316cf7a10e2cf8b562f17e1cf7a6a ) -) - game ( name "Outburst (Japan) (Demo)" description "Outburst (Japan) (Demo)" @@ -29661,7 +29959,7 @@ game ( game ( name "Pang (Europe)" description "Pang (Europe)" - rom ( name "Pang (Europe).gb" size 131072 crc ea9615b4 sha1 7ca64a45ea6a68770658ae39ef21c41f806988c5 ) + rom ( name "Pang (Europe).gb" size 131072 crc ea9615b4 sha1 7ca64a45ea6a68770658ae39ef21c41f806988c5 flags verified ) ) game ( @@ -29670,12 +29968,6 @@ game ( rom ( name "Pang (Europe) (Beta).gb" size 131072 crc 54d2754a sha1 b57d436d8a83f2fb1e42bad3150893ef8ffab0d4 ) ) -game ( - name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" - description "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" - rom ( name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl).gb" size 524288 crc ce707b9a sha1 b5757b268a09d9085d469eda0676991f7361ad8c ) -) - game ( name "Paperboy (USA, Europe)" description "Paperboy (USA, Europe)" @@ -29694,12 +29986,6 @@ game ( rom ( name "Parasol Henbee (Japan).gb" size 65536 crc ae97ec53 sha1 8f319d3d1929d953934e32ce900249ecf6b55fbd ) ) -game ( - name "Parasol Islands (World) (Aftermarket) (Unl)" - description "Parasol Islands (World) (Aftermarket) (Unl)" - rom ( name "Parasol Islands (World) (Aftermarket) (Unl).gb" size 1048576 crc b1d79c80 sha1 381f76af67f77e575beae2f45aefd21f079709e6 ) -) - game ( name "Parasol Stars - Rainbow Islands II (Europe)" description "Parasol Stars - Rainbow Islands II (Europe)" @@ -29754,18 +30040,6 @@ game ( rom ( name "Penta Dragon (Japan).gb" size 262144 crc 1e2efaee sha1 fd75d43258e79f14d104fb4756e219141882c837 ) ) -game ( - name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" - description "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" - rom ( name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl).gb" size 262144 crc 9b4bacaa sha1 09b0691f6823c54f1515dd3b66f135ac45a7dbc3 ) -) - -game ( - name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" - description "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" - rom ( name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl).gb" size 262144 crc 1e8b2a29 sha1 a25dfc43408080ac116479fa55c9e7320e5cc82a ) -) - game ( name "PGA European Tour (USA, Europe) (SGB Enhanced)" description "PGA European Tour (USA, Europe) (SGB Enhanced)" @@ -29796,18 +30070,6 @@ game ( rom ( name "Philip & Marlowe in Bloomland (USA) (Proto).gb" size 131072 crc 32bae420 sha1 2f9e5cee29d0d578b2642ce8637f02fc567aebc5 ) ) -game ( - name "Phobos Dere .GB (World) (Aftermarket) (Unl)" - description "Phobos Dere .GB (World) (Aftermarket) (Unl)" - rom ( name "Phobos Dere .GB (World) (Aftermarket) (Unl).gb" size 1048576 crc ae97f4f8 sha1 e541505078ee5e7e5c897b4621cc693ce71e35ba flags verified ) -) - -game ( - name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" - description "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" - rom ( name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 58362b86 sha1 b4cc3c3735bc134e34b97e08ed24c57aef5c5ccf flags verified ) -) - game ( name "Picross 2 (Japan) (SGB Enhanced)" description "Picross 2 (Japan) (SGB Enhanced)" @@ -29862,18 +30124,6 @@ game ( rom ( name "Pinball Mania (Europe).gb" size 262144 crc edc8d122 sha1 0541161b4b93fffc3c75708aca86ea0873747ced ) ) -game ( - name "Pineapple Kid (World) (Aftermarket) (Unl)" - description "Pineapple Kid (World) (Aftermarket) (Unl)" - rom ( name "Pineapple Kid (World) (Aftermarket) (Unl).gb" size 131072 crc 9541488b sha1 fd574b5d407f3654db3227900a8ed7eff4fe48ae ) -) - -game ( - name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" - description "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 9d9102d9 sha1 105e78f740d6bc517ef0079f867e9fdce8d012d2 ) -) - game ( name "Pingu - Sekai de 1ban Genki na Penguin (Japan)" description "Pingu - Sekai de 1ban Genki na Penguin (Japan)" @@ -29916,28 +30166,10 @@ game ( rom ( name "Pitman (Japan).gb" size 32768 crc a0b68136 sha1 a698d4bccd69d2ca51cb48877bde5d1f83d4317f ) ) -game ( - name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" - description "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" - rom ( name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl).gb" size 1048576 crc f41cf2a7 sha1 c07378c774602060f1f93f18fbfd3f0d552fe2d2 ) -) - -game ( - name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" - description "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl).gb" size 524288 crc 60c84f2e sha1 c39ec5e6a9a0be0970b56e788c3f60e9821dbbd3 ) -) - game ( name "Play Action Football (USA)" description "Play Action Football (USA)" - rom ( name "Play Action Football (USA).gb" size 131072 crc 983caf46 sha1 dc2981baf1bb4d0a65ec45fb22d44a5ca4c06254 ) -) - -game ( - name "Pluto's Corner (World) (Aftermarket) (Unl)" - description "Pluto's Corner (World) (Aftermarket) (Unl)" - rom ( name "Pluto's Corner (World) (Aftermarket) (Unl).gb" size 65536 crc 21fc06b3 sha1 94e4a442205079d85d5ca37042eaec555f7f49db ) + rom ( name "Play Action Football (USA).gb" size 131072 crc 983caf46 sha1 dc2981baf1bb4d0a65ec45fb22d44a5ca4c06254 flags verified ) ) game ( @@ -30141,7 +30373,7 @@ game ( game ( name "Pocket Sonar (Japan)" description "Pocket Sonar (Japan)" - rom ( name "Pocket Sonar (Japan).gb" size 524288 crc d68c9f79 sha1 788cdf148431b82b5308c68b3e45b133a7074196 ) + rom ( name "Pocket Sonar (Japan).gb" size 524288 crc d68c9f79 sha1 788cdf148431b82b5308c68b3e45b133a7074196 flags verified ) ) game ( @@ -30150,12 +30382,6 @@ game ( rom ( name "Pocket Stadium (Japan).gb" size 65536 crc c7bd9228 sha1 7ba422f2b48ff09673f7f1a258be6ecc1ff6a8d7 ) ) -game ( - name "Pogo Pete (World) (Aftermarket) (Unl)" - description "Pogo Pete (World) (Aftermarket) (Unl)" - rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gb" size 262144 crc 185ce1d5 sha1 74021e84c1d095b2401302e26352e810dbc432d8 ) -) - game ( name "Pokemon - Blaue Edition (Germany) (SGB Enhanced)" description "Pokemon - Blaue Edition (Germany) (SGB Enhanced)" @@ -30219,7 +30445,7 @@ game ( game ( name "Pokemon - Version Bleue (France) (SGB Enhanced)" description "Pokemon - Version Bleue (France) (SGB Enhanced)" - rom ( name "Pokemon - Version Bleue (France) (SGB Enhanced).gb" size 1048576 crc 50e2fc1d sha1 47faa910d0e073c600665bf9c83b6bd17babdf8a ) + rom ( name "Pokemon - Version Bleue (France) (SGB Enhanced).gb" size 1048576 crc 50e2fc1d sha1 47faa910d0e073c600665bf9c83b6bd17babdf8a flags verified ) ) game ( @@ -30336,12 +30562,6 @@ game ( rom ( name "Pop'n TwinBee (Europe).gb" size 131072 crc d07db274 sha1 0206230b55c15a8c18fbb85f852967e44b33a0a4 ) ) -game ( - name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" - description "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc ead528f9 sha1 909d3421747d211a2dc70918d2c952db953e49b2 ) -) - game ( name "Popeye (Japan)" description "Popeye (Japan)" @@ -30396,24 +30616,6 @@ game ( rom ( name "Populous Gaiden (Japan).gb" size 131072 crc f327167e sha1 fde1789eb253309cae80faf4fe7241c6f9d72f29 ) ) -game ( - name "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" - description "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" - rom ( name "Porklike (World) (v1.0.3) (Aftermarket) (Unl).gb" size 65536 crc 6c57e55e sha1 143f31656a5007f65b19d6e32967698bb8f72a66 ) -) - -game ( - name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" - description "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 7aaa853a sha1 0868bffd52b2bdc5601ab6cf1e25f40924ca643d ) -) - -game ( - name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" - description "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 801f097b sha1 5da110a88799765707e027bcedec0875a637509b ) -) - game ( name "Power Mission (Japan)" description "Power Mission (Japan)" @@ -30624,18 +30826,6 @@ game ( rom ( name "Purikura Pocket 3 - Talent Debut Daisakusen (Japan) (Rev 1) (SGB Enhanced) (NP).gb" size 1048576 crc 458dd05d sha1 7779a103a7ae3e382c8ffa3a6830160af36bb3b4 ) ) -game ( - name "Purple Turtles (World) (Aftermarket) (Unl)" - description "Purple Turtles (World) (Aftermarket) (Unl)" - rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gb" size 262144 crc f7041a97 sha1 d2d7eff063104c8f205c192a902a53092c0b5f4a ) -) - -game ( - name "Pushingo (World) (Aftermarket) (Unl)" - description "Pushingo (World) (Aftermarket) (Unl)" - rom ( name "Pushingo (World) (Aftermarket) (Unl).gb" size 262144 crc a8541ed0 sha1 1ac1e22b191a95fdfa00c34ccba7387c991c827b ) -) - game ( name "Puyo Puyo (Japan) (SGB Enhanced)" description "Puyo Puyo (Japan) (SGB Enhanced)" @@ -30732,12 +30922,6 @@ game ( rom ( name "Quarth (USA, Europe).gb" size 65536 crc bfb112ad sha1 89448b17700a6016a3f81de09a15e097c060d103 flags verified ) ) -game ( - name "Quick Draw (World) (Aftermarket) (Unl)" - description "Quick Draw (World) (Aftermarket) (Unl)" - rom ( name "Quick Draw (World) (Aftermarket) (Unl).gb" size 262144 crc 7704671f sha1 75f96ce54ed8739d58153780e9b573a65f1c5880 ) -) - game ( name "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan)" description "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan)" @@ -30822,12 +31006,6 @@ game ( rom ( name "Radar Mission (USA, Europe).gb" size 131072 crc 581da9c9 sha1 5ab5998a84eebc769f75c482cb0a5586ed97e888 ) ) -game ( - name "Raffles (World) (Aftermarket) (Unl)" - description "Raffles (World) (Aftermarket) (Unl)" - rom ( name "Raffles (World) (Aftermarket) (Unl).gb" size 262144 crc 0b400a91 sha1 aadfe3fd0720696547b73b272354b592b96f98f7 ) -) - game ( name "Raging Fighter (USA, Europe)" description "Raging Fighter (USA, Europe)" @@ -30894,12 +31072,6 @@ game ( rom ( name "Red October o Oe! (Japan).gb" size 131072 crc c2e7be35 sha1 48d5f02a126c32423569065f31d2c5695e39fd2f ) ) -game ( - name "Remute - Living Electronics (World) (Aftermarket) (Unl)" - description "Remute - Living Electronics (World) (Aftermarket) (Unl)" - rom ( name "Remute - Living Electronics (World) (Aftermarket) (Unl).gb" size 2097152 crc 1ced0a62 sha1 bc4bf12344d3b9d028a7013c84b94aea515be196 flags verified ) -) - game ( name "Ren & Stimpy Show, The - Space Cadet Adventures (USA)" description "Ren & Stimpy Show, The - Space Cadet Adventures (USA)" @@ -30930,30 +31102,6 @@ game ( rom ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 2d33e175 sha1 08dad9ac1f045d1c9e403c4ea1368aee991e0094 ) ) -game ( - name "Retroid (World) (Aftermarket) (Unl)" - description "Retroid (World) (Aftermarket) (Unl)" - rom ( name "Retroid (World) (Aftermarket) (Unl).gb" size 262144 crc 9f759f25 sha1 4c7323d6a10852fe416c7bd581d6ffdd2d473bb5 ) -) - -game ( - name "Rewind Time (World) (Aftermarket) (Unl)" - description "Rewind Time (World) (Aftermarket) (Unl)" - rom ( name "Rewind Time (World) (Aftermarket) (Unl).gb" size 262144 crc d8ad184a sha1 903ef8074e58a52bc98dcb9e3f2c88b52fc1335b ) -) - -game ( - name "Rhythm Land (World) (Aftermarket) (Unl)" - description "Rhythm Land (World) (Aftermarket) (Unl)" - rom ( name "Rhythm Land (World) (Aftermarket) (Unl).gb" size 131072 crc 4312c7ff sha1 c79f26ce187edea18cf92be8340ec0a0c8beec87 ) -) - -game ( - name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" - description "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" - rom ( name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl).gb" size 131072 crc fbf98400 sha1 1b831806d32e1ec35bc94a84384c6989433a274d ) -) - game ( name "Riddick Bowe Boxing (Europe)" description "Riddick Bowe Boxing (Europe)" @@ -30972,12 +31120,6 @@ game ( rom ( name "Riddick Bowe Boxing (USA) (Beta).gb" size 131072 crc a07512a6 sha1 69685eaffa523bf199be0c540d9eb561bb27d584 ) ) -game ( - name "Rig Attack (World) (Aftermarket) (Unl)" - description "Rig Attack (World) (Aftermarket) (Unl)" - rom ( name "Rig Attack (World) (Aftermarket) (Unl).gb" size 262144 crc dea8749d sha1 6f0fbac6b6c2e8f2d8df0a0a0e2f0c947e37b39a ) -) - game ( name "Ring Rage (Japan)" description "Ring Rage (Japan)" @@ -31008,12 +31150,6 @@ game ( rom ( name "Roadster (Japan).gb" size 131072 crc 04453e78 sha1 685c31496de738c27160d1f75408da6b95daaae8 ) ) -game ( - name "Robby's Day Out (World) (Aftermarket) (Unl)" - description "Robby's Day Out (World) (Aftermarket) (Unl)" - rom ( name "Robby's Day Out (World) (Aftermarket) (Unl).gb" size 262144 crc c3c89cd9 sha1 9d38b69ab9a4ff7bf387c88f2afed410d450f2e0 ) -) - game ( name "Robin Hood - Prince of Thieves (Europe)" description "Robin Hood - Prince of Thieves (Europe)" @@ -31170,18 +31306,6 @@ game ( rom ( name "Rolan's Curse II (USA).gb" size 131072 crc 2754f360 sha1 7632e23853dd2579012489f75bd370473f0f2c46 flags verified ) ) -game ( - name "Roommate Simulator (World) (Aftermarket) (Unl)" - description "Roommate Simulator (World) (Aftermarket) (Unl)" - rom ( name "Roommate Simulator (World) (Aftermarket) (Unl).gb" size 131072 crc 3c95b1aa sha1 d5c99106c3bd4d46aeb75f513fd4314c19c734b2 ) -) - -game ( - name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" - description "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" - rom ( name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 51d09337 sha1 9e935cca00cb4c3aad7b1dfce9fe59f5d913bdff ) -) - game ( name "Rubble Saver (Japan)" description "Rubble Saver (Japan)" @@ -31230,24 +31354,6 @@ game ( rom ( name "Sa-Ga 3 - Jikuu no Hasha (World) (Ja) (Collection of SaGa).gb" size 262144 crc dc4f4e34 sha1 8125677ee63e9abb4b956ed0bee18fae3e04193b ) ) -game ( - name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" - description "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl).gb" size 2097152 crc 6669f0be sha1 25bcf936e8dadb10d288473989891e4f2ec6c605 ) -) - -game ( - name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" - description "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl).gb" size 2097152 crc 1c4b7eb0 sha1 5cd15f4629fdbcfd6f752d89be755d5ac02b9435 ) -) - -game ( - name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" - description "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 03f2dd1a sha1 78fe9c7cd6d0d7f1157c8c7716642d17c4b80303 ) -) - game ( name "Sagaia (Japan)" description "Sagaia (Japan)" @@ -31272,12 +31378,6 @@ game ( rom ( name "Sakigake!! Otoko Juku - Meioutou Kessen (Japan).gb" size 131072 crc 2f0f7f63 sha1 c731f8be269d74748ae54fe5ce5faea89a825e0f ) ) -game ( - name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" - description "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 1048576 crc 994a2edd sha1 0132f0311d8478d4f45b3b8e2728698570091d69 ) -) - game ( name "Same Game (Japan) (SGB Enhanced)" description "Same Game (Japan) (SGB Enhanced)" @@ -31392,12 +31492,6 @@ game ( rom ( name "Sea Battle (Europe) (En,Fr,De,Es).gb" size 131072 crc ba091b91 sha1 560d62b96a1b9820e3fd953f76e33b4f5fdc9e2f ) ) -game ( - name "Sea King GB (USA) (Proto) (SGB Enhanced)" - description "Sea King GB (USA) (Proto) (SGB Enhanced)" - rom ( name "Sea King GB (USA) (Proto) (SGB Enhanced).gb" size 1048576 crc a45ef889 sha1 26bebc2394b5da850be55e409b9efcb4d2d29d87 ) -) - game ( name "seaQuest DSV (USA, Europe) (SGB Enhanced)" description "seaQuest DSV (USA, Europe) (SGB Enhanced)" @@ -31464,12 +31558,6 @@ game ( rom ( name "Serpent (USA).gb" size 32768 crc 74d466d7 sha1 3122b3c12c2580c3a81d70c5648f767bf3590aaf flags verified ) ) -game ( - name "Severen (World) (Demo) (Aftermarket) (Unl)" - description "Severen (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Severen (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 642f2244 sha1 d9692aa569820db3f38458819cba21846a2e06f4 ) -) - game ( name "Shadow Warriors (Europe)" description "Shadow Warriors (Europe)" @@ -31500,30 +31588,12 @@ game ( rom ( name "Shanghai Pocket (Japan) (SGB Enhanced).gb" size 262144 crc 6b8eff2c sha1 82fe97442aa625fd36cf865d82f78b07108ede7f ) ) -game ( - name "Shapeshifter, The (World) (Aftermarket) (Unl)" - description "Shapeshifter, The (World) (Aftermarket) (Unl)" - rom ( name "Shapeshifter, The (World) (Aftermarket) (Unl).gb" size 1048576 crc ef735794 sha1 179e69199f19b403b4c1a9675a3ee431ee570797 ) -) - game ( name "Shaq Fu (USA) (SGB Enhanced)" description "Shaq Fu (USA) (SGB Enhanced)" rom ( name "Shaq Fu (USA) (SGB Enhanced).gb" size 524288 crc 7ed43fe6 sha1 5e9e68d9235cf8149232b85fd6080ba8796cb85e ) ) -game ( - name "Shark Attack (World) (Aftermarket) (Unl)" - description "Shark Attack (World) (Aftermarket) (Unl)" - rom ( name "Shark Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 3032025a sha1 6cc65bb719af53128bb04c9ee7c6abbf4ff1c3cf ) -) - -game ( - name "Sheep it Up (World) (Digital) (Aftermarket) (Unl)" - description "Sheep it Up (World) (Digital) (Aftermarket) (Unl)" - rom ( name "Sheep it Up (World) (Digital) (Aftermarket) (Unl).gb" size 32768 crc fa6de2e4 sha1 9ad365ed7d4e07041c0147831a9bb1c496ea0bc8 ) -) - game ( name "Shikinjou (Japan)" description "Shikinjou (Japan)" @@ -31590,24 +31660,6 @@ game ( rom ( name "Shisenshou - Match-Mania (Japan).gb" size 32768 crc 0cdd8b04 sha1 6e84a906f9e1ce43272db84c63f1b037096ac34f flags verified ) ) -game ( - name "Shock Lobster (World) (Aftermarket) (Unl)" - description "Shock Lobster (World) (Aftermarket) (Unl)" - rom ( name "Shock Lobster (World) (Aftermarket) (Unl).gb" size 32768 crc 7a0622e6 sha1 10c1816724cd6e332d2a5aeed4e546e7bd764ebf ) -) - -game ( - name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" - description "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl).gb" size 32768 crc 8f244e86 sha1 7b8c8a9ec4758c6880598b9d508bc5805293dd87 ) -) - -game ( - name "Shootris (World) (Aftermarket) (Unl)" - description "Shootris (World) (Aftermarket) (Unl)" - rom ( name "Shootris (World) (Aftermarket) (Unl).gb" size 262144 crc 50180f64 sha1 5d978e6fc4bd5d9717d022360122458e95fffc29 ) -) - game ( name "Shougi (Japan)" description "Shougi (Japan)" @@ -31692,12 +31744,6 @@ game ( rom ( name "Skate or Die - Tour de Thrash (USA).gb" size 131072 crc 02b77c09 sha1 6e1610450da0c836983a1c310524639fefcc304f ) ) -game ( - name "Sloth Story (World) (Aftermarket) (Unl)" - description "Sloth Story (World) (Aftermarket) (Unl)" - rom ( name "Sloth Story (World) (Aftermarket) (Unl).gb" size 262144 crc c873f232 sha1 369d2afec4ffb59d4f3a59ee684c5bfec0b34ff8 ) -) - game ( name "Small Soldiers (USA, Europe) (SGB Enhanced)" description "Small Soldiers (USA, Europe) (SGB Enhanced)" @@ -31734,24 +31780,6 @@ game ( rom ( name "Smurfs, The (USA, Europe) (En,Fr,De) (Rev 1) (SGB Enhanced).gb" size 131072 crc 8b5bcde7 sha1 a0d6a85331fb034f68f05629a5ff85e13adab205 flags verified ) ) -game ( - name "Snail, The (World) (v1.3) (Aftermarket) (Unl)" - description "Snail, The (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Snail, The (World) (v1.3) (Aftermarket) (Unl).gb" size 262144 crc 422a7b44 sha1 776f7578d747f935ebccda93d6487ffa4dc4bce3 ) -) - -game ( - name "Snakebird (World) (Aftermarket) (Unl)" - description "Snakebird (World) (Aftermarket) (Unl)" - rom ( name "Snakebird (World) (Aftermarket) (Unl).gb" size 131072 crc 4627f98e sha1 99cc82279d65b86b4366bf61db9bf67a78e051dc ) -) - -game ( - name "Snaky Pocket (World) (Aftermarket) (Unl)" - description "Snaky Pocket (World) (Aftermarket) (Unl)" - rom ( name "Snaky Pocket (World) (Aftermarket) (Unl).gb" size 32768 crc 7209370d sha1 f5eab31a499f33b3ae1f7b5b006dcca1df3ac2b9 ) -) - game ( name "Sneaky Snakes (USA, Europe)" description "Sneaky Snakes (USA, Europe)" @@ -31807,9 +31835,15 @@ game ( ) game ( - name "Soccer Boy (Japan)" - description "Soccer Boy (Japan)" - rom ( name "Soccer Boy (Japan).gb" size 65536 crc 23f64e82 sha1 7554b42d1c38508fd615828c96ab58ea8f41de4d ) + name "Soccer Boy (Japan) (En)" + description "Soccer Boy (Japan) (En)" + rom ( name "Soccer Boy (Japan) (En).gb" size 65536 crc 23f64e82 sha1 7554b42d1c38508fd615828c96ab58ea8f41de4d ) +) + +game ( + name "Soccer Boy (Japan) (En) (Beta)" + description "Soccer Boy (Japan) (En) (Beta)" + rom ( name "Soccer Boy (Japan) (En) (Beta).gb" size 65536 crc a46f98d1 sha1 22db7c6096f285222aefbfe413efa1d21de59731 ) ) game ( @@ -31860,24 +31894,6 @@ game ( rom ( name "Solomon's Club (USA).gb" size 65536 crc cea9622a sha1 36abf2be4a16df8e9fe30307cbd8cb949a9b9bdb ) ) -game ( - name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" - description "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" - rom ( name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 665ad70a sha1 c5b6eb610caa2213d8db7ab204bad44d60f7d63a ) -) - -game ( - name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" - description "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" - rom ( name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl).gb" size 262144 crc feed93e0 sha1 721d78d4ef167acfcc00baf909db4c94d522d681 ) -) - -game ( - name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" - description "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" - rom ( name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl).gb" size 262144 crc 6547e5c8 sha1 53a42f45b7ed368d7af9d41f2442fe463c26e545 ) -) - game ( name "Sonic 6 (USA) (Pirate)" description "Sonic 6 (USA) (Pirate)" @@ -31938,12 +31954,6 @@ game ( rom ( name "Space Invaders (Europe) (Beta) (SGB Enhanced).gb" size 131072 crc 2d03dc38 sha1 6a2af41de10dbf6496b18963d904cc41d04bb970 ) ) -game ( - name "Space Trouble (World) (Proto) (Aftermarket) (Unl)" - description "Space Trouble (World) (Proto) (Aftermarket) (Unl)" - rom ( name "Space Trouble (World) (Proto) (Aftermarket) (Unl).gb" size 524288 crc f015931c sha1 ec7bc27387d4d2ac01127bc24e1adf45b6ebc936 ) -) - game ( name "Spanky's Quest (Europe)" description "Spanky's Quest (Europe)" @@ -32010,12 +32020,6 @@ game ( rom ( name "Spider-Man 3 - Invasion of the Spider-Slayers (USA, Europe) (Beta 2) (1993-04-11).gb" size 131072 crc bf2d1f10 sha1 34740dc60663ef33c42573a26e7b207f2cfe4a16 ) ) -game ( - name "Spiky Harold (World) (Aftermarket) (Unl)" - description "Spiky Harold (World) (Aftermarket) (Unl)" - rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gb" size 524288 crc 2ac1b945 sha1 b8f37a64524bde4c2b6e9a1938ed6e5c0a5aad7c ) -) - game ( name "Spirit of F-1, The (Europe)" description "Spirit of F-1, The (Europe)" @@ -32202,6 +32206,12 @@ game ( rom ( name "Star Wars (USA, Europe) (Rev 1).gb" size 131072 crc 5d8deb5b sha1 f6563f526fc786c8666d75dfba9e6d42d787ea89 flags verified ) ) +game ( + name "Star Wars (World) (Limited Run Games)" + description "Star Wars (World) (Limited Run Games)" + rom ( name "Star Wars (World) (Limited Run Games).gb" size 131072 crc 08838397 sha1 02bfb690ce171214bfee900069192e0daafc010d ) +) + game ( name "Star Wars - The Empire Strikes Back (USA, Europe)" description "Star Wars - The Empire Strikes Back (USA, Europe)" @@ -32215,9 +32225,9 @@ game ( ) game ( - name "Stardiver (World) (Aftermarket) (Unl)" - description "Stardiver (World) (Aftermarket) (Unl)" - rom ( name "Stardiver (World) (Aftermarket) (Unl).gb" size 1048576 crc 25ff97f7 sha1 d609b8de2c7a61b7281fec5c761e3504aa4d94e9 ) + name "Star Wars - The Empire Strikes Back (World) (Limited Run Games)" + description "Star Wars - The Empire Strikes Back (World) (Limited Run Games)" + rom ( name "Star Wars - The Empire Strikes Back (World) (Limited Run Games).gb" size 131072 crc 799e4ae8 sha1 dc819b082f671699ac189a49075854d8ff7a2b8f ) ) game ( @@ -32238,6 +32248,12 @@ game ( rom ( name "StarHawk (Europe).gb" size 131072 crc e032e502 sha1 4c22e06cb98119923126f6500568ce9f136a33c5 flags verified ) ) +game ( + name "StarHawk (World) (Limited Run Games)" + description "StarHawk (World) (Limited Run Games)" + rom ( name "StarHawk (World) (Limited Run Games).gb" size 131072 crc 00da50e2 sha1 bf64c1b1071bd243417b6c29fd8a4dd559d3f63a ) +) + game ( name "Stop That Roach! (USA)" description "Stop That Roach! (USA)" @@ -32400,12 +32416,6 @@ game ( rom ( name "Super Chinese Land 3 (Japan) (SGB Enhanced).gb" size 262144 crc e01caf0b sha1 6d8ef3fdd1702d629c679636698e1d483fc3723b flags verified ) ) -game ( - name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" - description "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" - rom ( name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl).gb" size 262144 crc 51946e8d sha1 cac4917d56da02cf88ba68e0c5189a18c2c234ac ) -) - game ( name "Super Donkey Kong 3 (Taiwan) (Unl)" description "Super Donkey Kong 3 (Taiwan) (Unl)" @@ -32598,12 +32608,6 @@ game ( rom ( name "Superman (USA, Europe) (SGB Enhanced).gb" size 131072 crc 358e0091 sha1 3a987cb4ba6f33717ea70d7388ec1dfe6ab934e8 flags verified ) ) -game ( - name "Sushi Gun (World) (Aftermarket) (Unl)" - description "Sushi Gun (World) (Aftermarket) (Unl)" - rom ( name "Sushi Gun (World) (Aftermarket) (Unl).gb" size 262144 crc a9d405d6 sha1 c075856939d4fe3cd250083b527b3e09be70052d ) -) - game ( name "Sutte Hakkun (Japan) (Proto) (SGB Enhanced)" description "Sutte Hakkun (Japan) (Proto) (SGB Enhanced)" @@ -32628,12 +32632,6 @@ game ( rom ( name "Swamp Thing (USA, Europe).gb" size 131072 crc 76ae62c8 sha1 1ff322b5f44d21c951dcdf8d062d99ffa65827e3 flags verified ) ) -game ( - name "Swaplatformer (World) (Aftermarket) (Unl)" - description "Swaplatformer (World) (Aftermarket) (Unl)" - rom ( name "Swaplatformer (World) (Aftermarket) (Unl).gb" size 1048576 crc babe7935 sha1 3df0c37862b7c391a0d091a55db0d305341529c2 ) -) - game ( name "Sword of Hope II, The (USA)" description "Sword of Hope II, The (USA)" @@ -32694,6 +32692,12 @@ game ( rom ( name "Tail 'Gator (USA, Europe).gb" size 65536 crc c5acce7c sha1 ed5f1110a9db4c48d26d53af0973e8b46fe7e4e1 ) ) +game ( + name "Tail 'Gator (World) (Limited Run Games)" + description "Tail 'Gator (World) (Limited Run Games)" + rom ( name "Tail 'Gator (World) (Limited Run Games).gb" size 65536 crc e35cd748 sha1 203f6e20e4d44792c727fe78aaa65e354d014175 ) +) + game ( name "Taito Chase H.Q. (Japan)" description "Taito Chase H.Q. (Japan)" @@ -32730,12 +32734,6 @@ game ( rom ( name "Takahashi Meijin no Bouken-jima III (Japan).gb" size 262144 crc f8fc0b41 sha1 e3fe857a1b7f00a6f7862d7dd401063f98fd0cb6 ) ) -game ( - name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" - description "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 5898c134 sha1 bd3468395deb0009b190d0b5d487962ae65adbee ) -) - game ( name "Takeda Nobuhiro no Ace Striker (Japan)" description "Takeda Nobuhiro no Ace Striker (Japan)" @@ -32808,12 +32806,6 @@ game ( rom ( name "Taz-Mania 2 (USA).gb" size 131072 crc 4ccb65e0 sha1 60116a304e85f04209dc7eb64d9649dc41c963f6 ) ) -game ( - name "Tech and Blood (World) (Aftermarket) (Unl)" - description "Tech and Blood (World) (Aftermarket) (Unl)" - rom ( name "Tech and Blood (World) (Aftermarket) (Unl).gb" size 262144 crc 3da2a358 sha1 40a00fce49b16cb36793df30e5156e5bf3e47778 ) -) - game ( name "Tecmo Bowl (USA)" description "Tecmo Bowl (USA)" @@ -33066,24 +33058,6 @@ game ( rom ( name "Tetris Plus (USA, Europe) (SGB Enhanced).gb" size 262144 crc dafc3bff sha1 dfab75ab6bdc0765ba9a5d33a93ffdb114a49cbf flags verified ) ) -game ( - name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" - description "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" - rom ( name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl).gb" size 1048576 crc 173b549a sha1 e000fbecda9ea6bbbd0c0370cf8c3faaa54bf64e ) -) - -game ( - name "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" - description "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" - rom ( name "Thin Ice Rescue, The (World) (Aftermarket) (Unl).gb" size 32768 crc 3e0483d6 sha1 b789ced0fe26785e7bce765a9d6ee783f9d967d8 ) -) - -game ( - name "TimberMan (World) (Aftermarket) (Unl)" - description "TimberMan (World) (Aftermarket) (Unl)" - rom ( name "TimberMan (World) (Aftermarket) (Unl).gb" size 32768 crc e0b8459c sha1 e3f4b4c4816cc0dda2885519f1386385e6a5e817 ) -) - game ( name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" description "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" @@ -33174,12 +33148,6 @@ game ( rom ( name "Titus the Fox (USA, Europe).gb" size 262144 crc 814fa146 sha1 ba0037aeb21de0bbba3f9294a7861d90aefa5008 flags verified ) ) -game ( - name "Tobu Tobu Girl (World) (Aftermarket) (Unl)" - description "Tobu Tobu Girl (World) (Aftermarket) (Unl)" - rom ( name "Tobu Tobu Girl (World) (Aftermarket) (Unl).gb" size 262144 crc ed12be6c sha1 8a8f3c1f21f903ea5a7df8fc8b0a6aa5a602e150 ) -) - game ( name "Tokio Senki - Eiyuu Retsuden (Japan)" description "Tokio Senki - Eiyuu Retsuden (Japan)" @@ -33342,36 +33310,12 @@ game ( rom ( name "Trappers Tengoku - Spy vs Spy (Japan).gb" size 131072 crc afefd085 sha1 c9eb687f6de7b821255fdd0cbf14f68ad789f97f ) ) -game ( - name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl).gb" size 2097152 crc 15afd765 sha1 c12e603492f8bcfffd28dd4733c7bc445c507642 ) -) - -game ( - name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl).gb" size 2097152 crc e1bdf67f sha1 ba492778121622b5288d4188edc344aa41aa6803 ) -) - -game ( - name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl).gb" size 1048576 crc 42bb7dab sha1 70fded7ce1edc54de85b020460f779feb9bdbc01 ) -) - game ( name "Trax (USA, Europe)" description "Trax (USA, Europe)" rom ( name "Trax (USA, Europe).gb" size 131072 crc 4a38be7d sha1 3f3a31ed7e47319c5815dd6e31ca27a52377423c flags verified ) ) -game ( - name "Treasure Island (World) (Aftermarket) (Unl)" - description "Treasure Island (World) (Aftermarket) (Unl)" - rom ( name "Treasure Island (World) (Aftermarket) (Unl).gb" size 262144 crc cbdec393 sha1 adeaba2723d286d143e0987f51ce9c8ad2f5e839 ) -) - game ( name "Trip World (Europe)" description "Trip World (Europe)" @@ -33384,6 +33328,12 @@ game ( rom ( name "Trip World (Japan).gb" size 262144 crc 11568e64 sha1 ac19d49906e72aaebeffa9ab7106eb346a5efa07 ) ) +game ( + name "Trip World (World) (Limited Run Games)" + description "Trip World (World) (Limited Run Games)" + rom ( name "Trip World (World) (Limited Run Games).gb" size 262144 crc ec67f1e6 sha1 16bb82fa8708cbd159388c55e702b9fb9ed5a41f ) +) + game ( name "TripleA (USA) (Proto)" description "TripleA (USA) (Proto)" @@ -33654,12 +33604,6 @@ game ( rom ( name "V-Rally - Championship Edition (Europe) (En,Fr,De).gb" size 262144 crc d149652b sha1 67d2a6e41b6a1d8372808535ac8c8222d7c53480 flags verified ) ) -game ( - name "Vampire Night Shift (World) (Aftermarket) (Unl)" - description "Vampire Night Shift (World) (Aftermarket) (Unl)" - rom ( name "Vampire Night Shift (World) (Aftermarket) (Unl).gb" size 262144 crc 88acbc1a sha1 ef617803c2cdb14cfe3b3b2111aa239a3744e29e ) -) - game ( name "Vattle Giuce (Japan)" description "Vattle Giuce (Japan)" @@ -33714,12 +33658,6 @@ game ( rom ( name "VS Battler (Japan).gb" size 65536 crc 20ae389a sha1 5f99c7767cbbf5ad9164805214875d7054f49f14 ) ) -game ( - name "Waifu Clicker (World) (Aftermarket) (Unl)" - description "Waifu Clicker (World) (Aftermarket) (Unl)" - rom ( name "Waifu Clicker (World) (Aftermarket) (Unl).gb" size 65536 crc 155f85dc sha1 bb571ed69c3a33e45ba33fbb03a066ba98ae0b20 ) -) - game ( name "Wario Blast Featuring Bomberman! (USA, Europe) (SGB Enhanced)" description "Wario Blast Featuring Bomberman! (USA, Europe) (SGB Enhanced)" @@ -33780,16 +33718,10 @@ game ( rom ( name "Welcome Nakayoshi Park (Japan).gb" size 262144 crc f6e2baae sha1 8779a1557ba0de3c5c8b770413f30bd31717b2ef ) ) -game ( - name "What Friends Are For (World) (Aftermarket) (Unl)" - description "What Friends Are For (World) (Aftermarket) (Unl)" - rom ( name "What Friends Are For (World) (Aftermarket) (Unl).gb" size 262144 crc cbed3dd6 sha1 58538084a964f779c2f756fbe732656f3f7bef66 ) -) - game ( name "Wheel of Fortune (USA)" description "Wheel of Fortune (USA)" - rom ( name "Wheel of Fortune (USA).gb" size 131072 crc 8408fe48 sha1 43de94eda492bfabbdc6e232af9cbd9df080dfd5 ) + rom ( name "Wheel of Fortune (USA).gb" size 131072 crc 8408fe48 sha1 43de94eda492bfabbdc6e232af9cbd9df080dfd5 flags verified ) ) game ( @@ -33822,12 +33754,6 @@ game ( rom ( name "Wily & Right no Rockboard - That's Paradise (Japan) (Proto).gb" size 262144 crc af84dc97 sha1 cc917f113c5cdd1afc3340feb8bf2094d0902cec ) ) -game ( - name "Windows93 Adventure (World) (Aftermarket) (Unl)" - description "Windows93 Adventure (World) (Aftermarket) (Unl)" - rom ( name "Windows93 Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc e1ad0b6f sha1 3ad7327f6f94976c3d12054cf6deb2666ba9fa66 ) -) - game ( name "Winner's Horse (Japan)" description "Winner's Horse (Japan)" @@ -33852,12 +33778,6 @@ game ( rom ( name "Winter Olympic Games (USA) (Rev 1) (Beta).gb" size 131072 crc 1510305e sha1 6f66dc2ab6f302251591a1252be12367a8e8dfe4 ) ) -game ( - name "Wizard of Wor (World) (Aftermarket) (Unl)" - description "Wizard of Wor (World) (Aftermarket) (Unl)" - rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gb" size 524288 crc bfb1563e sha1 108eefa154412e3422dce4e63bf34f5826ec1baa ) -) - game ( name "Wizardry Gaiden I - Joou no Junan (Japan)" description "Wizardry Gaiden I - Joou no Junan (Japan)" @@ -33882,12 +33802,6 @@ game ( rom ( name "Wizards & Warriors X - The Fortress of Fear (USA, Europe).gb" size 65536 crc 104eb503 sha1 22a514056e58263dc08602778bc3bf2c0ca6e681 flags verified ) ) -game ( - name "Woolball's Backyard (World) (Aftermarket) (Unl)" - description "Woolball's Backyard (World) (Aftermarket) (Unl)" - rom ( name "Woolball's Backyard (World) (Aftermarket) (Unl).gb" size 65536 crc 69e26eb6 sha1 28795c4b829440549b3ac2afe3282d85a439f7d7 ) -) - game ( name "Wordtris (USA)" description "Wordtris (USA)" @@ -34104,6 +34018,12 @@ game ( rom ( name "Xin Nushen Zhuansheng Waizhuan - Zuihou de Shengjing (Taiwan) (Pirate).gb" size 524288 crc 2298585c sha1 f33091c0bfd840e0ce4c4f99c463cfb92f823a64 ) ) +game ( + name "Xin Shuma Baobei Huang (China) (Pirate)" + description "Xin Shuma Baobei Huang (China) (Pirate)" + rom ( name "Xin Shuma Baobei Huang (China) (Pirate).gb" size 2097152 crc 86869520 sha1 b341efb4831b0fe066fd035ba9f7f876efa3cd50 ) +) + game ( name "Yakuman (Japan)" description "Yakuman (Japan)" @@ -34122,18 +34042,6 @@ game ( rom ( name "Yannick Noah Tennis (France) (En).gb" size 65536 crc 402d4d47 sha1 5bc39c44da587a89bef7478617c402855a1b5b24 flags verified ) ) -game ( - name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" - description "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc 4e463a1a sha1 5d84f53f38aa24f54a6f897ca69ffc5d978805af ) -) - -game ( - name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" - description "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc fbc50ee8 sha1 52c27e64fb37412c97a53d5dde52c3803fd1e4f7 ) -) - game ( name "Yelu Wangzi (Prince Yeh Rude) (Taiwan) (En) (Unl)" description "Yelu Wangzi (Prince Yeh Rude) (Taiwan) (En) (Unl)" @@ -34224,30 +34132,12 @@ game ( rom ( name "Yu-Gi-Oh! Duel Monsters (Japan) (SGB Enhanced).gb" size 1048576 crc 8875ec54 sha1 07ae4a6437f00f6af462bf84fd0ac1cf345c8365 flags verified ) ) -game ( - name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" - description "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" - rom ( name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl).gb" size 524288 crc 8a667058 sha1 e765d6915f543a5a65e8be440b3f29eb674a5448 ) -) - -game ( - name "Zagan Warrior (World) (Aftermarket) (Unl)" - description "Zagan Warrior (World) (Aftermarket) (Unl)" - rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gb" size 262144 crc 97fe7a94 sha1 88f76297a4ccf0e3a5ba16ca15237c88346c134a ) -) - game ( name "ZAS (Europe) (Proto)" description "ZAS (Europe) (Proto)" rom ( name "ZAS (Europe) (Proto).gb" size 131072 crc ae282077 sha1 a480d3a205f4c6fe7da41637180459fb2cff9139 ) ) -game ( - name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" - description "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" - rom ( name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl).gb" size 524288 crc f86c2766 sha1 ee86a28cf271be43739e406135e4d8bd4edf7686 ) -) - game ( name "Zelda no Densetsu - Yume o Miru Shima (Japan)" description "Zelda no Densetsu - Yume o Miru Shima (Japan)" @@ -34266,12 +34156,6 @@ game ( rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1) (Demo) (Special Version).gb" size 524288 crc bcc0199a sha1 5fc7b8185096c4203536e0d8a302064e63511086 ) ) -game ( - name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" - description "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" - rom ( name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl).gb" size 2097152 crc 0b10adaf sha1 12f9ba0a4673dd2f59ba38e636332333a199dea5 ) -) - game ( name "Zen - Intergalactic Ninja (Europe)" description "Zen - Intergalactic Ninja (Europe)" @@ -34333,9 +34217,9 @@ game ( ) game ( - name "Zoop (Japan)" - description "Zoop (Japan)" - rom ( name "Zoop (Japan).gb" size 65536 crc 10e1a10c sha1 89a74970761700d591c2affc47c9306f49d22ba8 ) + name "Zoop (Japan) (En)" + description "Zoop (Japan) (En)" + rom ( name "Zoop (Japan) (En).gb" size 65536 crc 10e1a10c sha1 89a74970761700d591c2affc47c9306f49d22ba8 ) ) game ( @@ -34362,11 +34246,1573 @@ game ( rom ( name "Zuigao Jimi (Top Secret) (Taiwan) (Unl).gb" size 65536 crc 46402abe sha1 7afcc6dd82bb236f1ebe01c9b5ccad4d713ccbcf ) ) +clrmamepro ( + name "Nintendo - Game Boy (Aftermarket)" + description "Nintendo - Game Boy (Aftermarket)" + version 20240809-004429 + author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Psychofox11, psykopat, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xprism, xuom2" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "14 Juillet (World) (Fr) (Aftermarket) (Unl)" + description "14 Juillet (World) (Fr) (Aftermarket) (Unl)" + rom ( name "14 Juillet (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 7b66bee4 sha1 02f387457a779cbd2f493e52743cd32c169c098e ) +) + +game ( + name "Adulting! (World) (v2.0) (Aftermarket) (Unl)" + description "Adulting! (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Adulting! (World) (v2.0) (Aftermarket) (Unl).gb" size 524288 crc e56d1244 sha1 d107bd8bf32d0d94a988466885fe1a44aae32c9a flags verified ) +) + +game ( + name "Alley (World) (Aftermarket) (Unl)" + description "Alley (World) (Aftermarket) (Unl)" + rom ( name "Alley (World) (Aftermarket) (Unl).gb" size 32768 crc 2a26f8dd sha1 34bc4f54c0577f55bd40ce1155b6cc74a72ec4e2 ) +) + +game ( + name "Alphamax (World) (Aftermarket) (Unl)" + description "Alphamax (World) (Aftermarket) (Unl)" + rom ( name "Alphamax (World) (Aftermarket) (Unl).gb" size 131072 crc 8b493b41 sha1 798dda34d04a06dcee32f44f8a4a045caf734927 ) +) + +game ( + name "Anctrayl (World) (Aftermarket) (Unl)" + description "Anctrayl (World) (Aftermarket) (Unl)" + rom ( name "Anctrayl (World) (Aftermarket) (Unl).gb" size 65536 crc c6eca93a sha1 403a40761eec80cf7938bcae3a6deeaf17838311 ) +) + +game ( + name "Another Push Game (World) (v1.07) (Proto) (Aftermarket) (Unl)" + description "Another Push Game (World) (v1.07) (Proto) (Aftermarket) (Unl)" + rom ( name "Another Push Game (World) (v1.07) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 8c40cbc9 sha1 6b84d7322d30e9c06a4fdac0050f2c22babaaa7d ) +) + +game ( + name "Aqua (World) (v1.1) (Aftermarket) (Unl)" + description "Aqua (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Aqua (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc f9ad0e12 sha1 cb5871dc5bca8b6fd5888b9d3a591fbfe082c11d ) +) + +game ( + name "Aqua (World) (v1.0) (Aftermarket) (Unl)" + description "Aqua (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Aqua (World) (v1.0) (Aftermarket) (Unl).gb" size 32768 crc 561aa835 sha1 311728bfcc1c4f51842f9da5022187e749e35045 ) +) + +game ( + name "Art School Pocket (World) (En) (Aftermarket) (Unl)" + description "Art School Pocket (World) (En) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (En) (Aftermarket) (Unl).gb" size 1048576 crc b4eab528 sha1 c482cfc6ec40b1f33c4ba48ecdc45fef4730b653 ) +) + +game ( + name "Art School Pocket (World) (Es) (Aftermarket) (Unl)" + description "Art School Pocket (World) (Es) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (Es) (Aftermarket) (Unl).gb" size 1048576 crc 240067df sha1 c8a75895c87b11f9493f629c19c54d0c607505bd ) +) + +game ( + name "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" + description "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 49a5b74d sha1 73ecffaee185eb2caf1db385d04b863676c777fb ) +) + +game ( + name "Art School Pocket (World) (De) (Aftermarket) (Unl)" + description "Art School Pocket (World) (De) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (De) (Aftermarket) (Unl).gb" size 1048576 crc 82b73e5b sha1 7772e2b9d5e722e54d19fc6283ccb1fa5d19b641 ) +) + +game ( + name "Asteroids Chasers (World) (Aftermarket) (Unl)" + description "Asteroids Chasers (World) (Aftermarket) (Unl)" + rom ( name "Asteroids Chasers (World) (Aftermarket) (Unl).gb" size 131072 crc 58d8b1b8 sha1 f93a4e6788eaf0231a6ca269cca297f0d45ec830 flags verified ) +) + +game ( + name "Astro-Jump (World) (Aftermarket) (Unl)" + description "Astro-Jump (World) (Aftermarket) (Unl)" + rom ( name "Astro-Jump (World) (Aftermarket) (Unl).gb" size 262144 crc c35a3b39 sha1 1bcb4be684626ce061aad105701548fa3a77e254 ) +) + +game ( + name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc afc128f2 sha1 956be9371990b18e351f2e10848b2ea8bb70c2b7 ) +) + +game ( + name "Auto Zone (World) (Aftermarket) (Unl)" + description "Auto Zone (World) (Aftermarket) (Unl)" + rom ( name "Auto Zone (World) (Aftermarket) (Unl).gb" size 524288 crc cee73c14 sha1 3070ec215014633dac5dbbb487aade2e2993c049 ) +) + +game ( + name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" + description "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" + rom ( name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl).gb" size 32768 crc bf922249 sha1 187782720d4f7c0986a0d916b0c7efa2c488612e ) +) + +game ( + name "Birdie Bartender (World) (Aftermarket) (Unl)" + description "Birdie Bartender (World) (Aftermarket) (Unl)" + rom ( name "Birdie Bartender (World) (Aftermarket) (Unl).gb" size 262144 crc 0bf2a1c8 sha1 aa1325fc7160b84745b076de9b976a1b368da50e ) +) + +game ( + name "Black Castle (World) (Aftermarket) (Unl)" + description "Black Castle (World) (Aftermarket) (Unl)" + rom ( name "Black Castle (World) (Aftermarket) (Unl).gb" size 65536 crc 10f577c7 sha1 45d979be572bb820835d2ecd4e990cd1eadbf5a6 ) +) + +game ( + name "Blitz Bomber (World) (Aftermarket) (Unl)" + description "Blitz Bomber (World) (Aftermarket) (Unl)" + rom ( name "Blitz Bomber (World) (Aftermarket) (Unl).gb" size 262144 crc 5e9956de sha1 b72cbc6bfa6ceef940f49c9c82024071c6f82b90 ) +) + +game ( + name "Blockade (World) (Aftermarket) (Unl)" + description "Blockade (World) (Aftermarket) (Unl)" + rom ( name "Blockade (World) (Aftermarket) (Unl).gb" size 262144 crc b8cfab16 sha1 9e753048a0eb036ac17c08f5a64d860abd1aaaf5 ) +) + +game ( + name "Bork Paw Kisses (World) (Aftermarket) (Unl)" + description "Bork Paw Kisses (World) (Aftermarket) (Unl)" + rom ( name "Bork Paw Kisses (World) (Aftermarket) (Unl).gb" size 262144 crc c29f0d35 sha1 8f1efe6982d2b4ebc1fbeb3ade68dd9b9aabb7a6 ) +) + +game ( + name "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" + description "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" + rom ( name "Borruga - Neo Pinball (World) (Aftermarket) (Unl).gb" size 32768 crc 2bb55ca5 sha1 269f12091d5ab87362a2cb2cf5484f14bfcbd537 flags verified ) +) + +game ( + name "Bounce (World) (v1.1) (Aftermarket) (Unl)" + description "Bounce (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Bounce (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc 827f2bd5 sha1 e9abf64de3faeb48151003ac8bb77dea61e838b5 ) +) + +game ( + name "Bouncing Ball, The (World) (Aftermarket) (Unl)" + description "Bouncing Ball, The (World) (Aftermarket) (Unl)" + rom ( name "Bouncing Ball, The (World) (Aftermarket) (Unl).gb" size 65536 crc 42ddf53e sha1 5d331f2e66d7d3f4b4b0fcbaf6ab4b1a0147db3e ) +) + +game ( + name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" + description "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" + rom ( name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl).gb" size 262144 crc 98222a4a sha1 0bdb8ad04469a329c8cee2fb0c55da35f7752042 ) +) + +game ( + name "Breakout Lava-Lamp (World) (Aftermarket) (Unl)" + description "Breakout Lava-Lamp (World) (Aftermarket) (Unl)" + rom ( name "Breakout Lava-Lamp (World) (Aftermarket) (Unl).gb" size 32768 crc 7fbe9fb7 sha1 9de08cdb4cdab58c79e0f2bdaef8b8bb736b9c50 ) +) + +game ( + name "Brimstone (World) (Demo) (Aftermarket) (Unl)" + description "Brimstone (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Brimstone (World) (Demo) (Aftermarket) (Unl).gb" size 262144 crc f18f44a6 sha1 f193af733f6dfdf8d4403be1d9caa67d7e6f3c37 ) +) + +game ( + name "Bug Bites! (World) (Aftermarket) (Unl)" + description "Bug Bites! (World) (Aftermarket) (Unl)" + rom ( name "Bug Bites! (World) (Aftermarket) (Unl).gb" size 262144 crc bb473d7a sha1 8d601612ac262e4548d8b8f6ac19a04cb92ecfb7 ) +) + +game ( + name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" + description "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" + rom ( name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl).gb" size 1048576 crc d0ed199c sha1 a1cbaacdf32cb8fb9a9c59fcb624c729e0ca17bf ) +) + +game ( + name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 3c492b31 sha1 0861af0039dab4b4f5bce747c6fcd586eced401a ) +) + +game ( + name "Cat and His Boy, A (World) (En,Es) (Demo) (Aftermarket) (Unl)" + description "Cat and His Boy, A (World) (En,Es) (Demo) (Aftermarket) (Unl)" + rom ( name "Cat and His Boy, A (World) (En,Es) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 11043693 sha1 4db27714c7af6041d5af3cf550e78d7235394afa ) +) + +game ( + name "Cave Fighter (World) (Aftermarket) (Unl)" + description "Cave Fighter (World) (Aftermarket) (Unl)" + rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gb" size 262144 crc e8f91f6a sha1 290048717d0a8cabb3cc591161339550eb53c161 ) +) + +game ( + name "Cel Story (World) (Aftermarket) (Unl)" + description "Cel Story (World) (Aftermarket) (Unl)" + rom ( name "Cel Story (World) (Aftermarket) (Unl).gb" size 524288 crc 8a456b61 sha1 730627b2298806e4f7e02dceffaa0f0edfc316f0 ) +) + +game ( + name "Cel Story (World) (Demo) (Aftermarket) (Unl)" + description "Cel Story (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Cel Story (World) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 92a9b588 sha1 70ab2b72b26c1d1cacc13d377984b969ddf44965 ) +) + +game ( + name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" + description "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 3e20c1a8 sha1 f76645a2830fcc733b7392a52112df628f0b7a4a ) +) + +game ( + name "Cherry Rescue! (World) (Aftermarket) (Unl)" + description "Cherry Rescue! (World) (Aftermarket) (Unl)" + rom ( name "Cherry Rescue! (World) (Aftermarket) (Unl).gb" size 524288 crc ba65812a sha1 740dba1827c730cc5d8bf67495bcede3a5352643 ) +) + +game ( + name "Christmas Carols (World) (Aftermarket) (Unl)" + description "Christmas Carols (World) (Aftermarket) (Unl)" + rom ( name "Christmas Carols (World) (Aftermarket) (Unl).gb" size 262144 crc a00bb310 sha1 e19b0a698d8194467d57c00664f00f9898ee5368 ) +) + +game ( + name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 2165f2e4 sha1 f8e5020298183c3f47836da3890b6bb398e2ecab ) +) + +game ( + name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 6afee818 sha1 602709c8655febb42899881a8ef598fb4b3da0c9 ) +) + +game ( + name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl).gb" size 1048576 crc 225ce296 sha1 45aebfe4e7f5382a4b31c3db270b75d2c458d1b2 ) +) + +game ( + name "Ciao Nonna (World) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (Aftermarket) (Unl).gb" size 1048576 crc dd7576d6 sha1 0556eb6160fdca6e7959bba1a619b8e34d974375 ) +) + +game ( + name "Coat Man (World) (Aftermarket) (Unl)" + description "Coat Man (World) (Aftermarket) (Unl)" + rom ( name "Coat Man (World) (Aftermarket) (Unl).gb" size 262144 crc db882ef2 sha1 242f4b3e04fe00b514544c5ef14288d13b5faf2c ) +) + +game ( + name "Commando (World) (Aftermarket) (Unl)" + description "Commando (World) (Aftermarket) (Unl)" + rom ( name "Commando (World) (Aftermarket) (Unl).gb" size 262144 crc 48173941 sha1 c861858e9f2cf7470e739c26ae9f17d3834ce464 ) +) + +game ( + name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" + description "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" + rom ( name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl).gb" size 262144 crc fd304687 sha1 7df11ec2946099d49dd62928118b6d76703dc57c ) +) + +game ( + name "Coucou (World) (Aftermarket) (Unl)" + description "Coucou (World) (Aftermarket) (Unl)" + rom ( name "Coucou (World) (Aftermarket) (Unl).gb" size 32768 crc e6aabd72 sha1 5283268e3640e2924d00aea3b12b2d3930bef43c ) +) + +game ( + name "Counting Sheep (World) (Aftermarket) (Unl)" + description "Counting Sheep (World) (Aftermarket) (Unl)" + rom ( name "Counting Sheep (World) (Aftermarket) (Unl).GB" size 65536 crc 6e97c837 sha1 e7e251ad86fa00803837cf871de62d3f100c83ce ) +) + +game ( + name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gb" size 262144 crc 10838580 sha1 c740bc995adf2bb638bb125a36edc416558fd4c6 ) +) + +game ( + name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" + description "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" + rom ( name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl).gb" size 1048576 crc e3a78253 sha1 45c9c6a7a4ec985146a4a616a49dba45decc6d3e ) +) + +game ( + name "Cyberlice (World) (Proto) (Aftermarket) (Unl)" + description "Cyberlice (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Cyberlice (World) (Proto) (Aftermarket) (Unl).gb" size 131072 crc 7e443267 sha1 220219db1870c3c0a562319aab9f1316b2863689 ) +) + +game ( + name "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" + description "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Dangan GB (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 5359d6db sha1 10029774046dabec2d8c0533caf94091f6e19071 ) +) + +game ( + name "Dangan GB (World) (Aftermarket) (Unl)" + description "Dangan GB (World) (Aftermarket) (Unl)" + rom ( name "Dangan GB (World) (Aftermarket) (Unl).gb" size 262144 crc daa59c9c sha1 8375d845fcfe4c236cd68f3d56a290f8c7b76c06 ) +) + +game ( + name "Dash (World) (Aftermarket) (Unl)" + description "Dash (World) (Aftermarket) (Unl)" + rom ( name "Dash (World) (Aftermarket) (Unl).gb" size 262144 crc 73868683 sha1 c1ffe7c25a34d65ed166293bc7d2b48b65ca922b ) +) + +game ( + name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" + description "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" + rom ( name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl).gb" size 1048576 crc 7da95971 sha1 23cff594ef4b0bb21883b422940526c7fe81f1fd flags verified ) +) + +game ( + name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" + description "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" + rom ( name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl).gb" size 1048576 crc 9e2bf649 sha1 3feeba5c438880f70cdfdc4ea7e29f77e645e9be flags verified ) +) + +game ( + name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" + description "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" + rom ( name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl).gb" size 1048576 crc 818a7db7 sha1 43a93dc6f7bef002271e583edaeaf2e7162b8af4 ) +) + +game ( + name "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" + description "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Deep Forest (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 3ddf177d sha1 517302d20cb5140975e6cd1b3c495786b6390aaf ) +) + +game ( + name "DiaMaze (World) (Aftermarket) (Unl)" + description "DiaMaze (World) (Aftermarket) (Unl)" + rom ( name "DiaMaze (World) (Aftermarket) (Unl).gb" size 262144 crc 956fa901 sha1 f41b98ac4669920ffede1736ddbd9e1f62d4cb0d ) +) + +game ( + name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" + description "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" + rom ( name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc b230b782 sha1 f1796dcbfb6f0f5e01c60222c376cc1c46945806 ) +) + +game ( + name "Dino's Offline Adventure (World) (Aftermarket) (Unl)" + description "Dino's Offline Adventure (World) (Aftermarket) (Unl)" + rom ( name "Dino's Offline Adventure (World) (Aftermarket) (Unl).gb" size 32768 crc d6bd0e6a sha1 6d11c145606f8e7ab25b2b07c299e36c8b442d23 ) +) + +game ( + name "DMG Deals Damage (World) (Aftermarket) (Unl)" + description "DMG Deals Damage (World) (Aftermarket) (Unl)" + rom ( name "DMG Deals Damage (World) (Aftermarket) (Unl).gb" size 32768 crc 250e0cbd sha1 a15539199e4b6bd2a71d1ac0e7c61ae4f19a65e7 flags verified ) +) + +game ( + name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc f339fa82 sha1 bdbc082017bdf2e4caa84e7d00dad9707727e9d4 ) +) + +game ( + name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl).gb" size 1048576 crc cfb44d68 sha1 6dde71bbec8b807af5132d1ef2e99c6bb6af3a1c ) +) + +game ( + name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl).gb" size 1048576 crc 62e0c3a2 sha1 e1b516e472e0c681b4ad1c7f4aeda55c91e7f340 ) +) + +game ( + name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" + description "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl).gb" size 1048576 crc e393d4aa sha1 d45dfcab4a76b62ea1e10730d01f755e12137484 ) +) + +game ( + name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl).gb" size 1048576 crc 3890e0a4 sha1 6998e1bbf2ccb9db3d661ddac2d7edf7571d0af7 ) +) + +game ( + name "Dog's Muck Island (World) (Aftermarket) (Unl)" + description "Dog's Muck Island (World) (Aftermarket) (Unl)" + rom ( name "Dog's Muck Island (World) (Aftermarket) (Unl).gb" size 262144 crc 79a7a06c sha1 eb4cea3b9db770bf3b586578af1ad7427d88ee8e ) +) + +game ( + name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" + description "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 83247308 sha1 4579eaa45e2bf8f17f4dc99bdfb0b98270b871f5 ) +) + +game ( + name "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" + description "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Dragon Battle (World) (Demo) (Aftermarket) (Unl).gb" size 4194304 crc c1e1e52c sha1 c5ac56e266c421a1c5b82de46859a44f75d03359 ) +) + +game ( + name "Dragonborne (World) (Aftermarket) (Unl)" + description "Dragonborne (World) (Aftermarket) (Unl)" + rom ( name "Dragonborne (World) (Aftermarket) (Unl).gb" size 2097152 crc 0ae28712 sha1 e3cd09069ee59ed3f7915a79af0667de4ebd7d50 ) +) + +game ( + name "Dragonborne (World) (Demo) (Aftermarket) (Unl)" + description "Dragonborne (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Dragonborne (World) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc eda66890 sha1 3a5bcd9daa830842da60d8ebf35fa7036a259d76 ) +) + +game ( + name "Duck (World) (Aftermarket) (Unl)" + description "Duck (World) (Aftermarket) (Unl)" + rom ( name "Duck (World) (Aftermarket) (Unl).gb" size 32768 crc 583691fd sha1 f7eccfb9ade282423db6122882adcef6fbf3e955 ) +) + +game ( + name "Elden Ring GB (World) (Aftermarket) (Unl)" + description "Elden Ring GB (World) (Aftermarket) (Unl)" + rom ( name "Elden Ring GB (World) (Aftermarket) (Unl).gb" size 524288 crc e7a420f3 sha1 2e0bec6acf1a94ae3f2f6cf2040323862933d95a ) +) + +game ( + name "ever - Lucid Space Program (World) (Aftermarket) (Unl)" + description "ever - Lucid Space Program (World) (Aftermarket) (Unl)" + rom ( name "ever - Lucid Space Program (World) (Aftermarket) (Unl).gb" size 262144 crc a5006140 sha1 051a1b8739c820424fad5103b64e578dd9a5b841 ) +) + +game ( + name "F-Zero - Project (World) (Aftermarket) (Unl)" + description "F-Zero - Project (World) (Aftermarket) (Unl)" + rom ( name "F-Zero - Project (World) (Aftermarket) (Unl).gb" size 1048576 crc 4c707059 sha1 5b823ee17691d286a45f0667cddd59ccaaab5d8b ) +) + +game ( + name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" + description "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" + rom ( name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 4f04cdfc sha1 591980cb5e17104d826c2a915f53bfc8a21affca ) +) + +game ( + name "Farm, The (World) (Aftermarket) (Unl)" + description "Farm, The (World) (Aftermarket) (Unl)" + rom ( name "Farm, The (World) (Aftermarket) (Unl).gb" size 524288 crc fbc1b5e8 sha1 d0fe06920f7e771d76507f60881904370ffbc145 ) +) + +game ( + name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" + description "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" + rom ( name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc 6cfb4669 sha1 339fd673509a5ac8f25426af25b4ccc96e8d2880 ) +) + +game ( + name "Finders Keepers (World) (Aftermarket) (Unl)" + description "Finders Keepers (World) (Aftermarket) (Unl)" + rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gb" size 524288 crc 6a98ac61 sha1 e40dd804388df8c08d3890d79eeafd8542cc8805 ) +) + +game ( + name "FlappyBird GB (World) (Aftermarket) (Unl)" + description "FlappyBird GB (World) (Aftermarket) (Unl)" + rom ( name "FlappyBird GB (World) (Aftermarket) (Unl).gb" size 131072 crc 51aa9cc2 sha1 8f2b803fdd737c9885b96d11622008f706061e00 ) +) + +game ( + name "Fly O'Clock (World) (Aftermarket) (Unl)" + description "Fly O'Clock (World) (Aftermarket) (Unl)" + rom ( name "Fly O'Clock (World) (Aftermarket) (Unl).gb" size 32768 crc 93df7f55 sha1 83dc8498bdbabc14a8f81a715c9da19970c1f0b9 ) +) + +game ( + name "Footballer of the Year (World) (v1.1) (Aftermarket) (Unl)" + description "Footballer of the Year (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Footballer of the Year (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 6e6ce1bb sha1 44166b7e6e8411ae61f37c7a78e90acaae66bcc5 ) +) + +game ( + name "Footballer of the Year (World) (v1.0) (Aftermarket) (Unl)" + description "Footballer of the Year (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Footballer of the Year (World) (v1.0) (Aftermarket) (Unl).gb" size 1048576 crc 91faa9b1 sha1 b7542729c8665a1a2af47f58fc59cc90f66fd77d ) +) + +game ( + name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" + description "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" + rom ( name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl).gb" size 32768 crc 36e2ca02 sha1 fd985703b296dd0bf74225c72155ea9e51dd6853 ) +) + +game ( + name "G-Man (World) (Aftermarket) (Unl)" + description "G-Man (World) (Aftermarket) (Unl)" + rom ( name "G-Man (World) (Aftermarket) (Unl).gb" size 524288 crc 7296da69 sha1 fdc9933d46a063575c175453b1da8042fd28b135 ) +) + +game ( + name "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" + description "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" + rom ( name "G-ZERO (World) (v2.6) (Aftermarket) (Unl).gb" size 65536 crc 7dd0c878 sha1 929d25a612308614ac3ac2ee5a19a9cd4a9968d6 ) +) + +game ( + name "GameBoy WORDLE (World) (Aftermarket) (Unl)" + description "GameBoy WORDLE (World) (Aftermarket) (Unl)" + rom ( name "GameBoy WORDLE (World) (Aftermarket) (Unl).gb" size 32768 crc cc971c0f sha1 ba93939b93ab3f3aa5f7aa451d50d9b89220adbc ) +) + +game ( + name "Genesis (World) (Aftermarket) (Unl)" + description "Genesis (World) (Aftermarket) (Unl)" + rom ( name "Genesis (World) (Aftermarket) (Unl).gb" size 65536 crc 74b3ec78 sha1 ca43f82d73ba0b3e43ec17f6bc6761c09ca23626 ) +) + +game ( + name "Genesis II (World) (Demo) (Aftermarket) (Unl)" + description "Genesis II (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Genesis II (World) (Demo) (Aftermarket) (Unl).gb" size 262144 crc d7aec1cc sha1 9700ea1278850df004ded7553253cfdd354f4ada ) +) + +game ( + name "Ghost Town (World) (Aftermarket) (Unl)" + description "Ghost Town (World) (Aftermarket) (Unl)" + rom ( name "Ghost Town (World) (Aftermarket) (Unl).gb" size 262144 crc 2d27cdf2 sha1 af526273cdaa6423b92d0484fb27af56fe355a5d ) +) + +game ( + name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" + description "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 4b19366d sha1 77f3b561bf28a81f38dbedc351752e10ff4c23dc ) +) + +game ( + name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" + description "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" + rom ( name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 3f34ff66 sha1 a0bff49b6917186d27dc24773da0674a18a6212c ) +) + +game ( + name "Great Detention Getaway, The (World) (Aftermarket) (Unl)" + description "Great Detention Getaway, The (World) (Aftermarket) (Unl)" + rom ( name "Great Detention Getaway, The (World) (Aftermarket) (Unl).gb" size 131072 crc 13b72ee4 sha1 efc3208cb99f9fb213875acd7b9b6c2e633b696a ) +) + +game ( + name "Gun Law (World) (Aftermarket) (Unl)" + description "Gun Law (World) (Aftermarket) (Unl)" + rom ( name "Gun Law (World) (Aftermarket) (Unl).gb" size 262144 crc b0d53211 sha1 ef6e3d287e99bd61861a333165c92b306238a45f ) +) + +game ( + name "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" + description "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Gunman Clive (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc 11f5fded sha1 ec03763db2c0d754e2eb7e98384ed92fc8aeeb1d ) +) + +game ( + name "Gunship (World) (Aftermarket) (Unl)" + description "Gunship (World) (Aftermarket) (Unl)" + rom ( name "Gunship (World) (Aftermarket) (Unl).gb" size 131072 crc bd31eef8 sha1 a801977c3746799cfb4d8bdfd679e45cccd3b719 ) +) + +game ( + name "Harbour Attack (World) (Aftermarket) (Unl)" + description "Harbour Attack (World) (Aftermarket) (Unl)" + rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 4018ebf7 sha1 5bbbe727ebc6a489f1a498d067e4f05d0d69b60f ) +) + +game ( + name "Heart Knight (World) (Aftermarket) (Unl)" + description "Heart Knight (World) (Aftermarket) (Unl)" + rom ( name "Heart Knight (World) (Aftermarket) (Unl).gb" size 32768 crc c7ecac73 sha1 dedcab41f58c58834e3534e877c494669a0d8952 ) +) + +game ( + name "Hermano (World) (v1.1) (Aftermarket) (Unl)" + description "Hermano (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Hermano (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 74a0419b sha1 c42cfe91a1ec593a76291e031c47137bd794ffda ) +) + +game ( + name "Hugo (World) (Aftermarket) (Unl)" + description "Hugo (World) (Aftermarket) (Unl)" + rom ( name "Hugo (World) (Aftermarket) (Unl).gb" size 262144 crc 8cc87f60 sha1 53fac2774b29a32501788e1eac65db23bf5c7b8f ) +) + +game ( + name "If (World) (Aftermarket) (Unl)" + description "If (World) (Aftermarket) (Unl)" + rom ( name "If (World) (Aftermarket) (Unl).gb" size 1048576 crc be7e4454 sha1 c11d8dc9ce96133f679678b07822a82f985e16f9 ) +) + +game ( + name "Impossible Gameboy (World) (Aftermarket) (Unl)" + description "Impossible Gameboy (World) (Aftermarket) (Unl)" + rom ( name "Impossible Gameboy (World) (Aftermarket) (Unl).gb" size 131072 crc ab65b738 sha1 d31cedd6227b23cf3d8ef81c73f133ab0b57e4f4 ) +) + +game ( + name "Interblocked (World) (Aftermarket) (Unl)" + description "Interblocked (World) (Aftermarket) (Unl)" + rom ( name "Interblocked (World) (Aftermarket) (Unl).gb" size 262144 crc 5c208855 sha1 8e46486533a3de9ee87cc07bf8efaf818752a61a ) +) + +game ( + name "Into the Blue (World) (Aftermarket) (Unl)" + description "Into the Blue (World) (Aftermarket) (Unl)" + rom ( name "Into the Blue (World) (Aftermarket) (Unl).gb" size 131072 crc 7714e96e sha1 5ac7a349bb37c8767c9db264ed8ae7b7647fa8ea ) +) + +game ( + name "Island, The (World) (Demo) (Aftermarket) (Unl)" + description "Island, The (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Island, The (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc d6a43a64 sha1 38419c50713b4e403b80f1da151a3e9d0654d47c ) +) + +game ( + name "Jabberwocky (World) (Aftermarket) (Unl)" + description "Jabberwocky (World) (Aftermarket) (Unl)" + rom ( name "Jabberwocky (World) (Aftermarket) (Unl).gb" size 1048576 crc cfc51717 sha1 b4e447f2197688c740a45dce27879a62c742fb96 ) +) + +game ( + name "Jane in the Jungle (World) (Aftermarket) (Unl)" + description "Jane in the Jungle (World) (Aftermarket) (Unl)" + rom ( name "Jane in the Jungle (World) (Aftermarket) (Unl).gb" size 262144 crc c68e751a sha1 dfc65dcf700a26b273d705b7cfececbc44b80587 ) +) + +game ( + name "Jet Set Willy (World) (Aftermarket) (Unl)" + description "Jet Set Willy (World) (Aftermarket) (Unl)" + rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gb" size 262144 crc 1686d7ed sha1 0e594224506fd087e36c66bb66905d4c91b02461 ) +) + +game ( + name "Joe Blade 2 (World) (Aftermarket) (Unl)" + description "Joe Blade 2 (World) (Aftermarket) (Unl)" + rom ( name "Joe Blade 2 (World) (Aftermarket) (Unl).gb" size 524288 crc 09f75c70 sha1 f001dffcd16be670c36a98dd9136f6f9fbf5b85d ) +) + +game ( + name "Jumpy (World) (Aftermarket) (Unl)" + description "Jumpy (World) (Aftermarket) (Unl)" + rom ( name "Jumpy (World) (Aftermarket) (Unl).gb" size 262144 crc 70f9af24 sha1 29152d8874c2a048f71e0be86aa9ee2d77996fb6 ) +) + +game ( + name "Just Fishing (World) (Aftermarket) (Unl)" + description "Just Fishing (World) (Aftermarket) (Unl)" + rom ( name "Just Fishing (World) (Aftermarket) (Unl).gb" size 131072 crc c0f675fc sha1 3591b258afb94e0b4d9e095ecf702fc4de3061e3 ) +) + +game ( + name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" + description "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" + rom ( name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl).gb" size 1048576 crc 986bfd75 sha1 6d15b5bc33d7c7771ba62d56ae7f25fa081bc564 ) +) + +game ( + name "Kitten's Getaway (World) (Es) (Aftermarket) (Unl)" + description "Kitten's Getaway (World) (Es) (Aftermarket) (Unl)" + rom ( name "Kitten's Getaway (World) (Es) (Aftermarket) (Unl).gb" size 262144 crc e621c535 sha1 a9e71e4a27e633e1649a131150c5811483b441d6 ) +) + +game ( + name "Krezber (World) (Aftermarket) (Unl)" + description "Krezber (World) (Aftermarket) (Unl)" + rom ( name "Krezber (World) (Aftermarket) (Unl).gb" size 65536 crc 27bddf77 sha1 2f4cffafc411b6895bf365b0773c4fa5d2ef7be3 ) +) + +game ( + name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" + description "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" + rom ( name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 0610049a sha1 a6fbe1a524547bebabc5e6b3baff1dff8f13dbd0 ) +) + +game ( + name "Kudzu (World) (v1.1c) (Demo) (Aftermarket) (Unl)" + description "Kudzu (World) (v1.1c) (Demo) (Aftermarket) (Unl)" + rom ( name "Kudzu (World) (v1.1c) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 4462ff70 sha1 18a2a762d7b994865c845ac2aa0a0cf7655af74e flags verified ) +) + +game ( + name "Laser Squad Alter (World) (Aftermarket) (Unl)" + description "Laser Squad Alter (World) (Aftermarket) (Unl)" + rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gb" size 1048576 crc a39b3a5a sha1 1620e585e77a2457cffde82453bec0c7a04e07cf ) +) + +game ( + name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 2c430576 sha1 0e290b387a45b6ea85c6d49bf18bce3ce94951b7 ) +) + +game ( + name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 5cf1a6f9 sha1 9fac1324e863f719674219eb41e45f1f745c67a9 ) +) + +game ( + name "Lawn Mower Land (World) (Aftermarket) (Unl)" + description "Lawn Mower Land (World) (Aftermarket) (Unl)" + rom ( name "Lawn Mower Land (World) (Aftermarket) (Unl).gb" size 32768 crc 11c62e39 sha1 1d6aa817ebf2a7e5d22285b906540272b67169da ) +) + +game ( + name "Leak, The (World) (Aftermarket) (Unl)" + description "Leak, The (World) (Aftermarket) (Unl)" + rom ( name "Leak, The (World) (Aftermarket) (Unl).GB" size 65536 crc ba3cfeae sha1 98de2d8be75e6d9cb4e87afe14b1380c033de797 ) +) + +game ( + name "Life's Too Short (World) (Aftermarket) (Unl)" + description "Life's Too Short (World) (Aftermarket) (Unl)" + rom ( name "Life's Too Short (World) (Aftermarket) (Unl).gb" size 262144 crc 458174cc sha1 7b704cd999cbeeb9991d675e2b1e67a906fa766d ) +) + +game ( + name "Linea, La (World) (Aftermarket) (Unl)" + description "Linea, La (World) (Aftermarket) (Unl)" + rom ( name "Linea, La (World) (Aftermarket) (Unl).gb" size 262144 crc c8750c01 sha1 00348fec54b5d3ebb762484bdcc015881bb9e95b ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc 9c4f03fd sha1 288cb53b4782df4409ee683e9aa11b4dd2a3a53e ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc e5988949 sha1 08d033c7ef20fd4d24d1f07b3ebb177fb9b78673 ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc 59568248 sha1 6571db155f6f25eeeec86d28b105bf8fef156322 ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc a26345b8 sha1 641110cb187657fd15ea254440e1c74ab4a88856 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc d70f1d25 sha1 02e2fb6cbc5cff05ed775c9e1cd9acc07fa2e036 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc ae07c093 sha1 9f40b8719b3fdd2f7e6c59a4f616e9eb712d538d ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc 34671dc6 sha1 377d22d54e6e1fa4fcd4b4576d5886774f9f6c97 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc a8fb0d7a sha1 26803ba3413c7c52a8a58393f63472bc87ec3c6b ) +) + +game ( + name "Lost Knight (World) (Proto) (Aftermarket) (Unl)" + description "Lost Knight (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Lost Knight (World) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 5ddcc941 sha1 ca9003ead7ee153faf087a83c4bdef1d409c597b ) +) + +game ( + name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" + description "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" + rom ( name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl).gb" size 524288 crc 1a5106a2 sha1 f56c1b324b8c1e17da86e40c5e9a887ec19b0c80 ) +) + +game ( + name "Machine, The (World) (v1.0) (Aftermarket) (Unl)" + description "Machine, The (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (v1.0) (Aftermarket) (Unl).gb" size 2097152 crc b06036a9 sha1 50c5d1eb7c8946ac2d7e2c566b1ea4a9b0d58e90 ) +) + +game ( + name "Mad Monster (World) (Aftermarket) (Unl)" + description "Mad Monster (World) (Aftermarket) (Unl)" + rom ( name "Mad Monster (World) (Aftermarket) (Unl).gb" size 524288 crc c3fd371c sha1 9f4bea7ca7d26080110f54392314c60761236638 ) +) + +game ( + name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" + description "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" + rom ( name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 76fcbc30 sha1 7a759372bd013dcdb59c9131a2908085fc04d648 ) +) + +game ( + name "Magipanels (World) (Aftermarket) (Unl)" + description "Magipanels (World) (Aftermarket) (Unl)" + rom ( name "Magipanels (World) (Aftermarket) (Unl).gb" size 131072 crc 0b66561b sha1 c9513f6769098f2185f632f87386788f0f0b6ad8 ) +) + +game ( + name "Mai Nurse (World) (v1.01) (Aftermarket) (Unl)" + description "Mai Nurse (World) (v1.01) (Aftermarket) (Unl)" + rom ( name "Mai Nurse (World) (v1.01) (Aftermarket) (Unl).gb" size 131072 crc 20d562b2 sha1 2d3b1dac701b518f9e5109dbc5e7d2bc8420dec3 ) +) + +game ( + name "Make Way (World) (Aftermarket) (Unl)" + description "Make Way (World) (Aftermarket) (Unl)" + rom ( name "Make Way (World) (Aftermarket) (Unl).gb" size 1048576 crc edeee5a8 sha1 19fd02e9318ed81ec968a2fca31ea0c3d8d94a7b ) +) + +game ( + name "Marron Helps a Friend (World) (Aftermarket) (Unl)" + description "Marron Helps a Friend (World) (Aftermarket) (Unl)" + rom ( name "Marron Helps a Friend (World) (Aftermarket) (Unl).gb" size 1048576 crc 08a3a987 sha1 adcd56fa3eba93edd20be25ae5cb349070cd0323 flags verified ) +) + +game ( + name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" + description "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl).gb" size 262144 crc dccaeb60 sha1 1e4fc83bfe9c9063975a3862770e4afee3f947a4 ) +) + +game ( + name "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" + description "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" + rom ( name "Marzipan Beef Reverser (World) (Aftermarket) (Unl).gb" size 131072 crc 4c3e0d15 sha1 6cbfb0390ee555718b5b0c3a5437b7d3d4ee0008 ) +) + +game ( + name "Meteorite (World) (Aftermarket) (Unl)" + description "Meteorite (World) (Aftermarket) (Unl)" + rom ( name "Meteorite (World) (Aftermarket) (Unl).gb" size 262144 crc 50cf593d sha1 0e88a47faf3273f87c1ead7f789faeb06d5333f3 ) +) + +game ( + name "Mission Mars (World) (Aftermarket) (Unl)" + description "Mission Mars (World) (Aftermarket) (Unl)" + rom ( name "Mission Mars (World) (Aftermarket) (Unl).gb" size 262144 crc cb3a9ab8 sha1 31625a90b61d28ac782909ed8b00b3a48df7742e ) +) + +game ( + name "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" + description "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" + rom ( name "Mona and the Witch's Hat (World) (Aftermarket) (Unl).gb" size 65536 crc 32ed7f4a sha1 625d3664d99dee075021b03ea6ff074ae2e49204 ) +) + +game ( + name "Monty on the Run (World) (Aftermarket) (Unl)" + description "Monty on the Run (World) (Aftermarket) (Unl)" + rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gb" size 524288 crc e2ebb406 sha1 41ac5993fbff58be0712b554aae5e4367b68677b ) +) + +game ( + name "Muncher (World) (Aftermarket) (Unl)" + description "Muncher (World) (Aftermarket) (Unl)" + rom ( name "Muncher (World) (Aftermarket) (Unl).gb" size 262144 crc 444d3d5e sha1 c3e09aff66c7e395bf95a1864963fbe979d5cb9b ) +) + +game ( + name "My Husband is a WITCH (World) (v1.1) (Aftermarket) (Unl)" + description "My Husband is a WITCH (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "My Husband is a WITCH (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 68801328 sha1 3b45dc8b655b688832a6b217c5cbc93a7a9f70cd ) +) + +game ( + name "My World (World) (Aftermarket) (Unl)" + description "My World (World) (Aftermarket) (Unl)" + rom ( name "My World (World) (Aftermarket) (Unl).gb" size 131072 crc 530b2edd sha1 ae29a721e6d1894e2faf736384737da7676e4fbc ) +) + +game ( + name "Neko Can Dream (World) (En) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (En) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (En) (Aftermarket) (Unl).gb" size 2097152 crc 6e76ef25 sha1 55686fde78d17d00adfc831eca2c699274a82273 ) +) + +game ( + name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc a0ad7a18 sha1 5fb1a09e04cf1704b059468de8855dfa7e23043b ) +) + +game ( + name "Neko Can Dream (World) (En) (Demo) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (En) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc dc011d07 sha1 43312b149355d20944e8a366584c69e5cb3be868 ) +) + +game ( + name "Nocptern (World) (v1.0) (Demo) (Aftermarket) (Unl)" + description "Nocptern (World) (v1.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Nocptern (World) (v1.0) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 118da307 sha1 33174a7727f6a1cc7c94b598ed6e9a4c2d1d410c ) +) + +game ( + name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" + description "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl).gb" size 262144 crc d6166c62 sha1 fa2198c5308a15195adbda004f09646589860d11 ) +) + +game ( + name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc 42b47080 sha1 08484b0f98e72d6577d9b7cde8c49908012d1fc5 ) +) + +game ( + name "Oblique Strategies (World) (Aftermarket) (Unl)" + description "Oblique Strategies (World) (Aftermarket) (Unl)" + rom ( name "Oblique Strategies (World) (Aftermarket) (Unl).gb" size 524288 crc 30eca8d3 sha1 6a09aabf30e2ebab2e31ae845cd2e8796c84797f ) +) + +game ( + name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl).gb" size 524288 crc d3eba01d sha1 8cf234bbcb68ca2b676a4ccec89814b0cbce1c07 ) +) + +game ( + name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 71f34822 sha1 f24da97f44d280f27f8ebe3acdc33fea758d2255 ) +) + +game ( + name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 76baab68 sha1 cd76da35541535dd244ad60d10eb998f7692f07a ) +) + +game ( + name "Olympic Skier (World) (Aftermarket) (Unl)" + description "Olympic Skier (World) (Aftermarket) (Unl)" + rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gb" size 524288 crc 93174431 sha1 7bcdf10533f8fe053e22534c4962ed4b1a5cf2e2 ) +) + +game ( + name "Opossum a la Mode (World) (Aftermarket) (Unl)" + description "Opossum a la Mode (World) (Aftermarket) (Unl)" + rom ( name "Opossum a la Mode (World) (Aftermarket) (Unl).gb" size 262144 crc 810477a9 sha1 3b6fb1311313687afebc4fb51f1b4befb5f47e1e ) +) + +game ( + name "Out on a Limb (World) (Aftermarket) (Unl)" + description "Out on a Limb (World) (Aftermarket) (Unl)" + rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gb" size 262144 crc be197f87 sha1 2ddc2378539316cf7a10e2cf8b562f17e1cf7a6a ) +) + +game ( + name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" + description "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl).gb" size 524288 crc ce707b9a sha1 b5757b268a09d9085d469eda0676991f7361ad8c ) +) + +game ( + name "Parasol Islands (World) (Aftermarket) (Unl)" + description "Parasol Islands (World) (Aftermarket) (Unl)" + rom ( name "Parasol Islands (World) (Aftermarket) (Unl).gb" size 1048576 crc b1d79c80 sha1 381f76af67f77e575beae2f45aefd21f079709e6 ) +) + +game ( + name "Penguin Migrants (World) (v1.2) (Aftermarket) (Unl)" + description "Penguin Migrants (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Penguin Migrants (World) (v1.2) (Aftermarket) (Unl).gb" size 32768 crc 866ac302 sha1 fa94f4d06eae2c49bbf1a654a8f658783dc6c28c ) +) + +game ( + name "Penguin Migrants (World) (v1.1) (Aftermarket) (Unl)" + description "Penguin Migrants (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Penguin Migrants (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc 1bc5f8aa sha1 bf5601202eeca5b892ae4f3db7a4019cdb3bc99a ) +) + +game ( + name "Penguin Migrants (World) (v1.0) (Aftermarket) (Unl)" + description "Penguin Migrants (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Penguin Migrants (World) (v1.0) (Aftermarket) (Unl).gb" size 32768 crc f6f681fa sha1 57b9cc41fc6d1e7cecf8ba2a1613d1fd126d97ad ) +) + +game ( + name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" + description "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" + rom ( name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl).gb" size 262144 crc 9b4bacaa sha1 09b0691f6823c54f1515dd3b66f135ac45a7dbc3 ) +) + +game ( + name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" + description "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" + rom ( name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl).gb" size 262144 crc 1e8b2a29 sha1 a25dfc43408080ac116479fa55c9e7320e5cc82a ) +) + +game ( + name "Phobos Dere .GB (World) (Aftermarket) (Unl)" + description "Phobos Dere .GB (World) (Aftermarket) (Unl)" + rom ( name "Phobos Dere .GB (World) (Aftermarket) (Unl).gb" size 1048576 crc ae97f4f8 sha1 e541505078ee5e7e5c897b4621cc693ce71e35ba flags verified ) +) + +game ( + name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" + description "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" + rom ( name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 58362b86 sha1 b4cc3c3735bc134e34b97e08ed24c57aef5c5ccf flags verified ) +) + +game ( + name "Pineapple Kid (World) (Aftermarket) (Unl)" + description "Pineapple Kid (World) (Aftermarket) (Unl)" + rom ( name "Pineapple Kid (World) (Aftermarket) (Unl).gb" size 131072 crc 9541488b sha1 fd574b5d407f3654db3227900a8ed7eff4fe48ae ) +) + +game ( + name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" + description "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 9d9102d9 sha1 105e78f740d6bc517ef0079f867e9fdce8d012d2 ) +) + +game ( + name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" + description "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" + rom ( name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl).gb" size 1048576 crc f41cf2a7 sha1 c07378c774602060f1f93f18fbfd3f0d552fe2d2 ) +) + +game ( + name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" + description "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl).gb" size 524288 crc 60c84f2e sha1 c39ec5e6a9a0be0970b56e788c3f60e9821dbbd3 ) +) + +game ( + name "Pluto's Corner (World) (Aftermarket) (Unl)" + description "Pluto's Corner (World) (Aftermarket) (Unl)" + rom ( name "Pluto's Corner (World) (Aftermarket) (Unl).gb" size 65536 crc 21fc06b3 sha1 94e4a442205079d85d5ca37042eaec555f7f49db ) +) + +game ( + name "Pogo Pete (World) (Aftermarket) (Unl)" + description "Pogo Pete (World) (Aftermarket) (Unl)" + rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gb" size 262144 crc 185ce1d5 sha1 74021e84c1d095b2401302e26352e810dbc432d8 ) +) + +game ( + name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" + description "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc ead528f9 sha1 909d3421747d211a2dc70918d2c952db953e49b2 ) +) + +game ( + name "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" + description "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.0.3) (Aftermarket) (Unl).gb" size 65536 crc 6c57e55e sha1 143f31656a5007f65b19d6e32967698bb8f72a66 ) +) + +game ( + name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" + description "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 7aaa853a sha1 0868bffd52b2bdc5601ab6cf1e25f40924ca643d ) +) + +game ( + name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" + description "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 801f097b sha1 5da110a88799765707e027bcedec0875a637509b ) +) + +game ( + name "Pull of the Void (World) (Aftermarket) (Unl)" + description "Pull of the Void (World) (Aftermarket) (Unl)" + rom ( name "Pull of the Void (World) (Aftermarket) (Unl).gb" size 262144 crc 69bfac8c sha1 df10665c8e79c587103d3de686b0261807819caf ) +) + +game ( + name "Purple Turtles (World) (Aftermarket) (Unl)" + description "Purple Turtles (World) (Aftermarket) (Unl)" + rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gb" size 262144 crc f7041a97 sha1 d2d7eff063104c8f205c192a902a53092c0b5f4a ) +) + +game ( + name "Pushingo (World) (Aftermarket) (Unl)" + description "Pushingo (World) (Aftermarket) (Unl)" + rom ( name "Pushingo (World) (Aftermarket) (Unl).gb" size 262144 crc a8541ed0 sha1 1ac1e22b191a95fdfa00c34ccba7387c991c827b ) +) + +game ( + name "Pyro la Chronoflamme (World) (Fr) (Proto) (Aftermarket) (Unl)" + description "Pyro la Chronoflamme (World) (Fr) (Proto) (Aftermarket) (Unl)" + rom ( name "Pyro la Chronoflamme (World) (Fr) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 2abc6b14 sha1 a13e1f09e9d3921e544c3fc17daebbadc93921b7 ) +) + +game ( + name "Quick Draw (World) (Aftermarket) (Unl)" + description "Quick Draw (World) (Aftermarket) (Unl)" + rom ( name "Quick Draw (World) (Aftermarket) (Unl).gb" size 262144 crc 7704671f sha1 75f96ce54ed8739d58153780e9b573a65f1c5880 ) +) + +game ( + name "radioRealm (World) (Ja) (Aftermarket) (Unl)" + description "radioRealm (World) (Ja) (Aftermarket) (Unl)" + rom ( name "radioRealm (World) (Ja) (Aftermarket) (Unl).gb" size 131072 crc 71375a39 sha1 489c8835c36a08f1d76a0653bf6ede3bbf53043f ) +) + +game ( + name "Raffles (World) (Aftermarket) (Unl)" + description "Raffles (World) (Aftermarket) (Unl)" + rom ( name "Raffles (World) (Aftermarket) (Unl).gb" size 262144 crc 0b400a91 sha1 aadfe3fd0720696547b73b272354b592b96f98f7 ) +) + +game ( + name "Remute - Living Electronics (World) (Album) (Aftermarket) (Unl)" + description "Remute - Living Electronics (World) (Album) (Aftermarket) (Unl)" + rom ( name "Remute - Living Electronics (World) (Album) (Aftermarket) (Unl).gb" size 2097152 crc 1ced0a62 sha1 bc4bf12344d3b9d028a7013c84b94aea515be196 flags verified ) +) + +game ( + name "Retroid (World) (Aftermarket) (Unl)" + description "Retroid (World) (Aftermarket) (Unl)" + rom ( name "Retroid (World) (Aftermarket) (Unl).gb" size 262144 crc 9f759f25 sha1 4c7323d6a10852fe416c7bd581d6ffdd2d473bb5 ) +) + +game ( + name "Rewind Time (World) (Aftermarket) (Unl)" + description "Rewind Time (World) (Aftermarket) (Unl)" + rom ( name "Rewind Time (World) (Aftermarket) (Unl).gb" size 262144 crc d8ad184a sha1 903ef8074e58a52bc98dcb9e3f2c88b52fc1335b ) +) + +game ( + name "Rhythm Land (World) (Aftermarket) (Unl)" + description "Rhythm Land (World) (Aftermarket) (Unl)" + rom ( name "Rhythm Land (World) (Aftermarket) (Unl).gb" size 131072 crc 4312c7ff sha1 c79f26ce187edea18cf92be8340ec0a0c8beec87 ) +) + +game ( + name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" + description "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" + rom ( name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl).gb" size 131072 crc fbf98400 sha1 1b831806d32e1ec35bc94a84384c6989433a274d ) +) + +game ( + name "Rig Attack (World) (Aftermarket) (Unl)" + description "Rig Attack (World) (Aftermarket) (Unl)" + rom ( name "Rig Attack (World) (Aftermarket) (Unl).gb" size 262144 crc dea8749d sha1 6f0fbac6b6c2e8f2d8df0a0a0e2f0c947e37b39a ) +) + +game ( + name "Robby's Day Out (World) (Aftermarket) (Unl)" + description "Robby's Day Out (World) (Aftermarket) (Unl)" + rom ( name "Robby's Day Out (World) (Aftermarket) (Unl).gb" size 262144 crc c3c89cd9 sha1 9d38b69ab9a4ff7bf387c88f2afed410d450f2e0 ) +) + +game ( + name "Roommate Simulator (World) (Aftermarket) (Unl)" + description "Roommate Simulator (World) (Aftermarket) (Unl)" + rom ( name "Roommate Simulator (World) (Aftermarket) (Unl).gb" size 131072 crc 3c95b1aa sha1 d5c99106c3bd4d46aeb75f513fd4314c19c734b2 ) +) + +game ( + name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" + description "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" + rom ( name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 51d09337 sha1 9e935cca00cb4c3aad7b1dfce9fe59f5d913bdff ) +) + +game ( + name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" + description "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl).gb" size 2097152 crc 6669f0be sha1 25bcf936e8dadb10d288473989891e4f2ec6c605 ) +) + +game ( + name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" + description "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl).gb" size 2097152 crc 1c4b7eb0 sha1 5cd15f4629fdbcfd6f752d89be755d5ac02b9435 ) +) + +game ( + name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" + description "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 03f2dd1a sha1 78fe9c7cd6d0d7f1157c8c7716642d17c4b80303 ) +) + +game ( + name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" + description "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 1048576 crc 994a2edd sha1 0132f0311d8478d4f45b3b8e2728698570091d69 ) +) + +game ( + name "Severen (World) (Demo) (Aftermarket) (Unl)" + description "Severen (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Severen (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 642f2244 sha1 d9692aa569820db3f38458819cba21846a2e06f4 ) +) + +game ( + name "Shapeshifter, The (World) (Aftermarket) (Unl)" + description "Shapeshifter, The (World) (Aftermarket) (Unl)" + rom ( name "Shapeshifter, The (World) (Aftermarket) (Unl).gb" size 1048576 crc ef735794 sha1 179e69199f19b403b4c1a9675a3ee431ee570797 ) +) + +game ( + name "Shark Attack (World) (Aftermarket) (Unl)" + description "Shark Attack (World) (Aftermarket) (Unl)" + rom ( name "Shark Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 3032025a sha1 6cc65bb719af53128bb04c9ee7c6abbf4ff1c3cf ) +) + +game ( + name "Sheep It Up (World) (Digital) (Aftermarket) (Unl)" + description "Sheep It Up (World) (Digital) (Aftermarket) (Unl)" + rom ( name "Sheep It Up (World) (Digital) (Aftermarket) (Unl).gb" size 32768 crc fa6de2e4 sha1 9ad365ed7d4e07041c0147831a9bb1c496ea0bc8 ) +) + +game ( + name "Shock Lobster (World) (Aftermarket) (Unl)" + description "Shock Lobster (World) (Aftermarket) (Unl)" + rom ( name "Shock Lobster (World) (Aftermarket) (Unl).gb" size 32768 crc 7a0622e6 sha1 10c1816724cd6e332d2a5aeed4e546e7bd764ebf ) +) + +game ( + name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" + description "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl).gb" size 32768 crc 8f244e86 sha1 7b8c8a9ec4758c6880598b9d508bc5805293dd87 ) +) + +game ( + name "Shootris (World) (Aftermarket) (Unl)" + description "Shootris (World) (Aftermarket) (Unl)" + rom ( name "Shootris (World) (Aftermarket) (Unl).gb" size 262144 crc 50180f64 sha1 5d978e6fc4bd5d9717d022360122458e95fffc29 ) +) + +game ( + name "Sloth Story (World) (Aftermarket) (Unl)" + description "Sloth Story (World) (Aftermarket) (Unl)" + rom ( name "Sloth Story (World) (Aftermarket) (Unl).gb" size 262144 crc c873f232 sha1 369d2afec4ffb59d4f3a59ee684c5bfec0b34ff8 ) +) + +game ( + name "Slurpee Cycle (World) (Aftermarket) (Unl)" + description "Slurpee Cycle (World) (Aftermarket) (Unl)" + rom ( name "Slurpee Cycle (World) (Aftermarket) (Unl).gb" size 131072 crc 8985031a sha1 1addff376e2734513406eca69a9c6679965faba9 ) +) + +game ( + name "Smickeonn - The Game (World) (Aftermarket) (Unl)" + description "Smickeonn - The Game (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game (World) (Aftermarket) (Unl).gb" size 524288 crc 93041fca sha1 e0981231d10aa8ea64eeaec1ff90210adf42ae05 ) +) + +game ( + name "Smickeonn 2 - The Game (World) (Aftermarket) (Unl)" + description "Smickeonn 2 - The Game (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn 2 - The Game (World) (Aftermarket) (Unl).gb" size 1048576 crc cd99b998 sha1 ac6b35af80c98ca5822e540a725b64a8c6dd5069 ) +) + +game ( + name "Snail, The (World) (v1.3) (Aftermarket) (Unl)" + description "Snail, The (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Snail, The (World) (v1.3) (Aftermarket) (Unl).gb" size 262144 crc 422a7b44 sha1 776f7578d747f935ebccda93d6487ffa4dc4bce3 ) +) + +game ( + name "Snakebird (World) (Aftermarket) (Unl)" + description "Snakebird (World) (Aftermarket) (Unl)" + rom ( name "Snakebird (World) (Aftermarket) (Unl).gb" size 131072 crc 4627f98e sha1 99cc82279d65b86b4366bf61db9bf67a78e051dc ) +) + +game ( + name "Snaky Pocket (World) (Aftermarket) (Unl)" + description "Snaky Pocket (World) (Aftermarket) (Unl)" + rom ( name "Snaky Pocket (World) (Aftermarket) (Unl).gb" size 32768 crc 7209370d sha1 f5eab31a499f33b3ae1f7b5b006dcca1df3ac2b9 ) +) + +game ( + name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" + description "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 665ad70a sha1 c5b6eb610caa2213d8db7ab204bad44d60f7d63a ) +) + +game ( + name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" + description "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl).gb" size 262144 crc feed93e0 sha1 721d78d4ef167acfcc00baf909db4c94d522d681 ) +) + +game ( + name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" + description "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl).gb" size 262144 crc 6547e5c8 sha1 53a42f45b7ed368d7af9d41f2442fe463c26e545 ) +) + +game ( + name "Space Trouble (World) (Proto) (Aftermarket) (Unl)" + description "Space Trouble (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Space Trouble (World) (Proto) (Aftermarket) (Unl).gb" size 524288 crc f015931c sha1 ec7bc27387d4d2ac01127bc24e1adf45b6ebc936 ) +) + +game ( + name "Spiky Harold (World) (Aftermarket) (Unl)" + description "Spiky Harold (World) (Aftermarket) (Unl)" + rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gb" size 524288 crc 2ac1b945 sha1 b8f37a64524bde4c2b6e9a1938ed6e5c0a5aad7c ) +) + +game ( + name "Star Catcher (World) (Aftermarket) (Unl)" + description "Star Catcher (World) (Aftermarket) (Unl)" + rom ( name "Star Catcher (World) (Aftermarket) (Unl).gb" size 131072 crc a14dffef sha1 22a2693db5266238751ba3ae2b8ea634bfbe78aa ) +) + +game ( + name "Stardiver (World) (Aftermarket) (Unl)" + description "Stardiver (World) (Aftermarket) (Unl)" + rom ( name "Stardiver (World) (Aftermarket) (Unl).gb" size 1048576 crc 25ff97f7 sha1 d609b8de2c7a61b7281fec5c761e3504aa4d94e9 ) +) + +game ( + name "Stick Man Guy (World) (Aftermarket) (Unl)" + description "Stick Man Guy (World) (Aftermarket) (Unl)" + rom ( name "Stick Man Guy (World) (Aftermarket) (Unl).gb" size 262144 crc 3a61fefc sha1 2f7351579e09ef29e067a69dfa3556448626d68e ) +) + +game ( + name "Super Connard (World) (Fr) (Aftermarket) (Unl)" + description "Super Connard (World) (Fr) (Aftermarket) (Unl)" + rom ( name "Super Connard (World) (Fr) (Aftermarket) (Unl).gb" size 32768 crc 9aaf301a sha1 6f4bf6c8206cc95cf17bea6739aa942034c2a230 ) +) + +game ( + name "Super Connard (World) (Fr) (Digital) (Aftermarket) (Unl)" + description "Super Connard (World) (Fr) (Digital) (Aftermarket) (Unl)" + rom ( name "Super Connard (World) (Fr) (Digital) (Aftermarket) (Unl).gb" size 32768 crc 7ebd22cd sha1 24264376aeee13d7f9b9424553f7fa4ba4b3b116 ) +) + +game ( + name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" + description "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" + rom ( name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl).gb" size 262144 crc 51946e8d sha1 cac4917d56da02cf88ba68e0c5189a18c2c234ac ) +) + +game ( + name "Super Hard Bouncer (World) (v1.1) (Aftermarket) (Unl)" + description "Super Hard Bouncer (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Super Hard Bouncer (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc a653f726 sha1 09c242a4c0752f251388026df7ed4baab5a8c56f ) +) + +game ( + name "Super Hard Bouncer (World) (v1.0) (Aftermarket) (Unl)" + description "Super Hard Bouncer (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Super Hard Bouncer (World) (v1.0) (Aftermarket) (Unl).gb" size 32768 crc 6308019a sha1 549c2624767633d6898ab9623eadb9579ec2779b ) +) + +game ( + name "Sushi Gun (World) (Aftermarket) (Unl)" + description "Sushi Gun (World) (Aftermarket) (Unl)" + rom ( name "Sushi Gun (World) (Aftermarket) (Unl).gb" size 262144 crc a9d405d6 sha1 c075856939d4fe3cd250083b527b3e09be70052d ) +) + +game ( + name "Swaplatformer (World) (Aftermarket) (Unl)" + description "Swaplatformer (World) (Aftermarket) (Unl)" + rom ( name "Swaplatformer (World) (Aftermarket) (Unl).gb" size 1048576 crc babe7935 sha1 3df0c37862b7c391a0d091a55db0d305341529c2 ) +) + +game ( + name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" + description "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 5898c134 sha1 bd3468395deb0009b190d0b5d487962ae65adbee ) +) + +game ( + name "Tech and Blood (World) (Aftermarket) (Unl)" + description "Tech and Blood (World) (Aftermarket) (Unl)" + rom ( name "Tech and Blood (World) (Aftermarket) (Unl).gb" size 262144 crc 3da2a358 sha1 40a00fce49b16cb36793df30e5156e5bf3e47778 ) +) + +game ( + name "The Light, The Fire (World) (Aftermarket) (Unl)" + description "The Light, The Fire (World) (Aftermarket) (Unl)" + rom ( name "The Light, The Fire (World) (Aftermarket) (Unl).gb" size 524288 crc b6a19823 sha1 d98e03602699f8602689f006e1f55f0c549b3cb7 ) +) + +game ( + name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" + description "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" + rom ( name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl).gb" size 1048576 crc 173b549a sha1 e000fbecda9ea6bbbd0c0370cf8c3faaa54bf64e ) +) + +game ( + name "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" + description "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" + rom ( name "Thin Ice Rescue, The (World) (Aftermarket) (Unl).gb" size 32768 crc 3e0483d6 sha1 b789ced0fe26785e7bce765a9d6ee783f9d967d8 ) +) + +game ( + name "TimberMan (World) (Aftermarket) (Unl)" + description "TimberMan (World) (Aftermarket) (Unl)" + rom ( name "TimberMan (World) (Aftermarket) (Unl).gb" size 32768 crc e0b8459c sha1 e3f4b4c4816cc0dda2885519f1386385e6a5e817 ) +) + +game ( + name "Tobu Tobu Girl (World) (Aftermarket) (Unl)" + description "Tobu Tobu Girl (World) (Aftermarket) (Unl)" + rom ( name "Tobu Tobu Girl (World) (Aftermarket) (Unl).gb" size 262144 crc ed12be6c sha1 8a8f3c1f21f903ea5a7df8fc8b0a6aa5a602e150 ) +) + +game ( + name "Touch the Cat (World) (Aftermarket) (Unl)" + description "Touch the Cat (World) (Aftermarket) (Unl)" + rom ( name "Touch the Cat (World) (Aftermarket) (Unl).gb" size 131072 crc 351fd00a sha1 9dc7b51a44aec9055924596c161972f366caf067 ) +) + +game ( + name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl).gb" size 2097152 crc 15afd765 sha1 c12e603492f8bcfffd28dd4733c7bc445c507642 ) +) + +game ( + name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl).gb" size 2097152 crc e1bdf67f sha1 ba492778121622b5288d4188edc344aa41aa6803 ) +) + +game ( + name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl).gb" size 1048576 crc 42bb7dab sha1 70fded7ce1edc54de85b020460f779feb9bdbc01 ) +) + +game ( + name "Traumatarium - Penitent (World) (2024-01-12) (Proto) (Aftermarket) (Unl)" + description "Traumatarium - Penitent (World) (2024-01-12) (Proto) (Aftermarket) (Unl)" + rom ( name "Traumatarium - Penitent (World) (2024-01-12) (Proto) (Aftermarket) (Unl).gb" size 4194304 crc 805f8257 sha1 a28d68f59b7ab3a6c95d5efc35c22ab9d7a74d31 ) +) + +game ( + name "Traumatarium - Penitent (World) (Demo) (Aftermarket) (Unl)" + description "Traumatarium - Penitent (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Traumatarium - Penitent (World) (Demo) (Aftermarket) (Unl).gb" size 4194304 crc 7d368277 sha1 efc91ca2873ff8f1733036e298950033d3456927 ) +) + +game ( + name "Treasure Island (World) (Aftermarket) (Unl)" + description "Treasure Island (World) (Aftermarket) (Unl)" + rom ( name "Treasure Island (World) (Aftermarket) (Unl).gb" size 262144 crc cbdec393 sha1 adeaba2723d286d143e0987f51ce9c8ad2f5e839 ) +) + +game ( + name "Vampire Night Shift (World) (Aftermarket) (Unl)" + description "Vampire Night Shift (World) (Aftermarket) (Unl)" + rom ( name "Vampire Night Shift (World) (Aftermarket) (Unl).gb" size 262144 crc 88acbc1a sha1 ef617803c2cdb14cfe3b3b2111aa239a3744e29e ) +) + +game ( + name "Waifu Clicker (World) (Aftermarket) (Unl)" + description "Waifu Clicker (World) (Aftermarket) (Unl)" + rom ( name "Waifu Clicker (World) (Aftermarket) (Unl).gb" size 65536 crc 155f85dc sha1 bb571ed69c3a33e45ba33fbb03a066ba98ae0b20 ) +) + +game ( + name "What Friends Are For (World) (Aftermarket) (Unl)" + description "What Friends Are For (World) (Aftermarket) (Unl)" + rom ( name "What Friends Are For (World) (Aftermarket) (Unl).gb" size 262144 crc cbed3dd6 sha1 58538084a964f779c2f756fbe732656f3f7bef66 ) +) + +game ( + name "Windows93 Adventure (World) (Aftermarket) (Unl)" + description "Windows93 Adventure (World) (Aftermarket) (Unl)" + rom ( name "Windows93 Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc e1ad0b6f sha1 3ad7327f6f94976c3d12054cf6deb2666ba9fa66 ) +) + +game ( + name "Witchscape (World) (Proto) (Aftermarket) (Unl)" + description "Witchscape (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Witchscape (World) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 2b2fcea0 sha1 8440a578567aa40c646d01c990317f9d12c444e5 ) +) + +game ( + name "Wizard of Wor (World) (Aftermarket) (Unl)" + description "Wizard of Wor (World) (Aftermarket) (Unl)" + rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gb" size 524288 crc bfb1563e sha1 108eefa154412e3422dce4e63bf34f5826ec1baa ) +) + +game ( + name "Woolball's Backyard (World) (Aftermarket) (Unl)" + description "Woolball's Backyard (World) (Aftermarket) (Unl)" + rom ( name "Woolball's Backyard (World) (Aftermarket) (Unl).gb" size 65536 crc 69e26eb6 sha1 28795c4b829440549b3ac2afe3282d85a439f7d7 ) +) + +game ( + name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" + description "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc 4e463a1a sha1 5d84f53f38aa24f54a6f897ca69ffc5d978805af ) +) + +game ( + name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" + description "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc fbc50ee8 sha1 52c27e64fb37412c97a53d5dde52c3803fd1e4f7 ) +) + +game ( + name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" + description "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl).gb" size 524288 crc 8a667058 sha1 e765d6915f543a5a65e8be440b3f29eb674a5448 ) +) + +game ( + name "Yvonne Goes to Carbonic (World) (v4.2) (Aftermarket) (Unl)" + description "Yvonne Goes to Carbonic (World) (v4.2) (Aftermarket) (Unl)" + rom ( name "Yvonne Goes to Carbonic (World) (v4.2) (Aftermarket) (Unl).gb" size 262144 crc d46cd738 sha1 b5e8f7b572a47aa191462bb4f980813ad6634ae0 ) +) + +game ( + name "Zagan Warrior (World) (Aftermarket) (Unl)" + description "Zagan Warrior (World) (Aftermarket) (Unl)" + rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gb" size 262144 crc 97fe7a94 sha1 88f76297a4ccf0e3a5ba16ca15237c88346c134a ) +) + +game ( + name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" + description "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl).gb" size 524288 crc f86c2766 sha1 ee86a28cf271be43739e406135e4d8bd4edf7686 ) +) + +game ( + name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" + description "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" + rom ( name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl).gb" size 2097152 crc 0b10adaf sha1 12f9ba0a4673dd2f59ba38e636332333a199dea5 ) +) + clrmamepro ( name "Nintendo - Game Boy Color" description "Nintendo - Game Boy Color" - version 20240107-011427 - author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, bikerspade, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, gordonj, halftheisland, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, Psychofox11, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xprism, xuom2, zg" + version 20240810-021134 + author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, bikerspade, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, gordonj, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, Psychofox11, psykopat, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xprism, xuom2, zg" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -34466,18 +35912,6 @@ game ( rom ( name "1942 (USA, Europe).gbc" size 1048576 crc 87431672 sha1 d960e951b18d07e79d046313df49c18313664224 ) ) -game ( - name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 2edc4684 sha1 a00b40a3f31bd875f4a0376d22099c3822c9ef98 ) -) - -game ( - name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" - description "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc ff0a848b sha1 837cbb4cf3a92266833099fa06b95edfcdb1865f ) -) - game ( name "2001 Fatal Fury (Taiwan) (En) (Unl)" description "2001 Fatal Fury (Taiwan) (En) (Unl)" @@ -34562,12 +35996,6 @@ game ( rom ( name "2003 Shuma Baolong - Gedou Ban (Taiwan) (Unl).gbc" size 2097152 crc 1219eec6 sha1 4a722c10e3893e04c67a66d0aea401d6d220ec7e ) ) -game ( - name "2123 (World) (Aftermarket) (Unl)" - description "2123 (World) (Aftermarket) (Unl)" - rom ( name "2123 (World) (Aftermarket) (Unl).gbc" size 262144 crc 22836942 sha1 eb9a2aff6485962f1a7773b7138f3c4208fa36e4 ) -) - game ( name "23 in 1 (Taiwan) (Unl)" description "23 in 1 (Taiwan) (Unl)" @@ -34610,12 +36038,6 @@ game ( rom ( name "3D Pool Allstars (USA) (En,Fr,Es) (Proto).gbc" size 1048576 crc 245de3e2 sha1 f7289c3eed275286d0fb3dc7097098276b746786 ) ) -game ( - name "3D Quasars (World) (Aftermarket) (Unl)" - description "3D Quasars (World) (Aftermarket) (Unl)" - rom ( name "3D Quasars (World) (Aftermarket) (Unl).gbc" size 262144 crc 1fd94e67 sha1 3f32226538d8c7f0c866c4b73e9f828265f2bb5b ) -) - game ( name "4 in 1 + 8 in 1 (World) (4B-001, 4B-009, 8B-001, Sachen) (Unl)" description "4 in 1 + 8 in 1 (World) (4B-001, 4B-009, 8B-001, Sachen) (Unl)" @@ -34652,12 +36074,6 @@ game ( rom ( name "720 Degrees (USA, Europe) (GB Compatible).gbc" size 1048576 crc e633841f sha1 78c0117c8ee32cfa605ac34eedf707cc535b3987 flags verified ) ) -game ( - name "Aardvark (World) (Aftermarket) (Unl)" - description "Aardvark (World) (Aftermarket) (Unl)" - rom ( name "Aardvark (World) (Aftermarket) (Unl).gbc" size 262144 crc 270d45b9 sha1 34a8d00af6be9083409e6fccd0825c6f185d135d flags verified ) -) - game ( name "Absolute X (Europe) (Proto)" description "Absolute X (Europe) (Proto)" @@ -34682,54 +36098,12 @@ game ( rom ( name "Action Replay Xtreme - Special Edition for Pokemon Crystal (Europe) (Unl).gbc" size 131072 crc c288e400 sha1 0280b05885fe5aca8c1884a16bd01513b99f4dc2 flags verified ) ) -game ( - name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" - description "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 1b5b9e64 sha1 c5dad32be800c36814a0f9b940e99b5eada34150 ) -) - -game ( - name "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl)" - description "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9f81e7a0 sha1 895148bc0a3b6f9ec59bebae43413d1f4eafd21a ) -) - -game ( - name "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl)" - description "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a5d0d1ec sha1 bc6367f77c235640cea5a1230cee253c99f846e5 ) -) - game ( name "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" description "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" rom ( name "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc d0d3dfed sha1 7919c5e6aa8d040b1f7953345b376d999cf22b18 ) ) -game ( - name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" - description "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f689b91e sha1 e55e427819916bb02189efe3883fb1dab3d80d35 ) -) - -game ( - name "Agency (World) (Aftermarket) (Unl)" - description "Agency (World) (Aftermarket) (Unl)" - rom ( name "Agency (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0d1bb2f7 sha1 5266589244fab2e9ff047af9f72641cda91e1d90 ) -) - -game ( - name "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" - description "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Agent B (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31b6e3fa sha1 11b3ce59c4eb86cee05873eb473dbf262cf986bd ) -) - -game ( - name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae767ad7 sha1 1a332aac66b24381f16819d1145fd4a917f2e0f3 ) -) - game ( name "AirForce Delta (Japan)" description "AirForce Delta (Japan)" @@ -34779,15 +36153,9 @@ game ( ) game ( - name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" - description "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b4d50eed sha1 f4513fc525cbcfa4a2804b55ce20c809e01d1c87 ) -) - -game ( - name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" - description "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" - rom ( name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible).gbc" size 1048576 crc 952b94e5 sha1 50f99b0fc5c2f5edc2e76ba973cc42fb0a1a02c8 ) + name "All Star Tennis '99 (USA) (Proto) (1999-09-13) (GB Compatible)" + description "All Star Tennis '99 (USA) (Proto) (1999-09-13) (GB Compatible)" + rom ( name "All Star Tennis '99 (USA) (Proto) (1999-09-13) (GB Compatible).gbc" size 1048576 crc e1b17e76 sha1 239e79281faacf7df2abfb527e6e2adfb58b0bc3 ) ) game ( @@ -34802,6 +36170,12 @@ game ( rom ( name "All Star Tennis 2000 (Europe) (AZTX) (Proto) (GB Compatible).gbc" size 1048576 crc deff8dfb sha1 c9db40e3e348668fe6fc41d031263acbe9041a67 ) ) +game ( + name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" + description "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" + rom ( name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible).gbc" size 1048576 crc 952b94e5 sha1 50f99b0fc5c2f5edc2e76ba973cc42fb0a1a02c8 ) +) + game ( name "All-Star Baseball 2000 (USA, Europe)" description "All-Star Baseball 2000 (USA, Europe)" @@ -34814,12 +36188,6 @@ game ( rom ( name "All-Star Baseball 2001 (USA).gbc" size 1048576 crc bc562466 sha1 f702df64d368b763187a5b1263a60fb3e842962b ) ) -game ( - name "Alley Cat (World) (Aftermarket) (Unl)" - description "Alley Cat (World) (Aftermarket) (Unl)" - rom ( name "Alley Cat (World) (Aftermarket) (Unl).gbc" size 262144 crc edb3ac37 sha1 a9aa1ecad6b67a6e5096fb1c10e39899c00a96a0 ) -) - game ( name "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl) (Beta)" description "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl) (Beta)" @@ -34880,12 +36248,6 @@ game ( rom ( name "Animorphs (USA).gbc" size 1048576 crc b4f293cc sha1 b3e5b34d5e97c49720861fabb6a29d557029279c ) ) -game ( - name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - description "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc dfcd02ef sha1 041473b2381dd9e11b3cbda5858f9841324327af ) -) - game ( name "Anpfiff - Der RTL Fussball-Manager (Germany)" description "Anpfiff - Der RTL Fussball-Manager (Germany)" @@ -34901,7 +36263,7 @@ game ( game ( name "Antz (USA) (En,Fr,Es) (GB Compatible)" description "Antz (USA) (En,Fr,Es) (GB Compatible)" - rom ( name "Antz (USA) (En,Fr,Es) (GB Compatible).gbc" size 1048576 crc dc0be439 sha1 85684d5891e4ec0f9fdf61b644bdf0ffbf1ba219 ) + rom ( name "Antz (USA) (En,Fr,Es) (GB Compatible).gbc" size 1048576 crc dc0be439 sha1 85684d5891e4ec0f9fdf61b644bdf0ffbf1ba219 flags verified ) ) game ( @@ -34928,24 +36290,12 @@ game ( rom ( name "Antz World Sportz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 67c7f85c sha1 d8ddf04baad3beadedf85847964f986ba89bc5ee ) ) -game ( - name "Apollo Mission (World) (Aftermarket) (Unl)" - description "Apollo Mission (World) (Aftermarket) (Unl)" - rom ( name "Apollo Mission (World) (Aftermarket) (Unl).gbc" size 262144 crc bec9d9a2 sha1 b2bcc61bcf269c0f5c0ce2a6e0bb1c7015dc9ff9 ) -) - game ( name "Aqualife (Japan) (SGB Enhanced) (GB Compatible)" description "Aqualife (Japan) (SGB Enhanced) (GB Compatible)" rom ( name "Aqualife (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e243feb4 sha1 69eaf53eccdaf98cd7cc0d436209f511b558d761 ) ) -game ( - name "Arena 3000 (World) (Aftermarket) (Unl)" - description "Arena 3000 (World) (Aftermarket) (Unl)" - rom ( name "Arena 3000 (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c17c15c sha1 007d23f73f68de01c250ec3d07403679137851ff ) -) - game ( name "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" description "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" @@ -35018,18 +36368,6 @@ game ( rom ( name "Asteroids (USA, Europe) (GB Compatible).gbc" size 1048576 crc 89d5d936 sha1 026f031e1bb787a4390e7873227dcb52a069a6e0 flags verified ) ) -game ( - name "Astro Plumber (World) (Aftermarket) (Unl)" - description "Astro Plumber (World) (Aftermarket) (Unl)" - rom ( name "Astro Plumber (World) (Aftermarket) (Unl).gbc" size 262144 crc d746db41 sha1 bf46ab2a3a1ffc3b712b9ae5cfa05441781ac9e4 ) -) - -game ( - name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" - description "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc e6a96130 sha1 2cd0ef086c4b89497d9497a17d871a6568a9e2d3 ) -) - game ( name "Atlantis - The Lost Empire (Europe) (En,Es,It)" description "Atlantis - The Lost Empire (Europe) (En,Es,It)" @@ -35048,12 +36386,6 @@ game ( rom ( name "Atlantis - The Lost Empire (USA, Europe).gbc" size 2097152 crc d594d24b sha1 ab5dd8efa36b33ce9aa090b3d990e8fc8828f7e2 ) ) -game ( - name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 0d60b100 sha1 9cc1a5140b96ad072d36151f5d99ff6eb699e605 ) -) - game ( name "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" description "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" @@ -35114,18 +36446,6 @@ game ( rom ( name "Austin Powers Episode IV (Europe) (En,Fr,De,Es,It) (Proto).gbc" size 2097152 crc f038cda7 sha1 937df6944709732d8d372ad5f629a665ffd12eac ) ) -game ( - name "Auto Zone (World) (Aftermarket) (Unl)" - description "Auto Zone (World) (Aftermarket) (Unl)" - rom ( name "Auto Zone (World) (Aftermarket) (Unl).gbc" size 524288 crc 2a86d386 sha1 83a37fb5c5d82e0ff06bb22b63761af996e4ad61 ) -) - -game ( - name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" - description "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc eac459fa sha1 68a5520be76c52a4936ad1756ea274667f2ac0e3 ) -) - game ( name "Aventures de Buzz l'Eclair, Les (France)" description "Aventures de Buzz l'Eclair, Les (France)" @@ -35186,12 +36506,6 @@ game ( rom ( name "Back to Earth 3D (Europe) (Demo).gbc" size 262144 crc d4255616 sha1 716722ed8756b656bba00cbff116f883e629cfd2 ) ) -game ( - name "Back to Nature (World) (Aftermarket) (Unl)" - description "Back to Nature (World) (Aftermarket) (Unl)" - rom ( name "Back to Nature (World) (Aftermarket) (Unl).gbc" size 262144 crc 861f9a63 sha1 3f4a6cd105d4c8af0312bef482c08784bbbfb0eb ) -) - game ( name "Backgammon (Europe) (En,Fr,De,Es) (GB Compatible)" description "Backgammon (Europe) (En,Fr,De,Es) (GB Compatible)" @@ -35258,12 +36572,6 @@ game ( rom ( name "Balloon Fight GB (Japan) (SGB Enhanced, GB Compatible) (NP).gbc" size 262144 crc d2af64ce sha1 dbaa1bf9061de0f052704d6a33892341a38f2152 ) ) -game ( - name "Bandits at Zero (World) (Aftermarket) (Unl)" - description "Bandits at Zero (World) (Aftermarket) (Unl)" - rom ( name "Bandits at Zero (World) (Aftermarket) (Unl).gbc" size 524288 crc c70f413e sha1 c885e109fbb53445db9618c6768c2259e6135921 ) -) - game ( name "Barbie - Aventura Submarina (Spain) (GB Compatible)" description "Barbie - Aventura Submarina (Spain) (GB Compatible)" @@ -35390,12 +36698,6 @@ game ( rom ( name "Battle Fishers (Japan).gbc" size 2097152 crc c99cf3c5 sha1 25d063b151c2d45a14d6952196490615b7e341c5 ) ) -game ( - name "Battle Star (World) (Aftermarket) (Unl)" - description "Battle Star (World) (Aftermarket) (Unl)" - rom ( name "Battle Star (World) (Aftermarket) (Unl).gbc" size 524288 crc b2fd062f sha1 ac4206129704e31386c9c0a1c961a148398f0ba3 ) -) - game ( name "Battleship (USA, Europe) (GB Compatible)" description "Battleship (USA, Europe) (GB Compatible)" @@ -35468,12 +36770,6 @@ game ( rom ( name "Benjamin Bluemchen - Ein verrueckter Tag im Zoo (Germany).gbc" size 2097152 crc 51972995 sha1 560fc8468ed559a72087f630eff015ffb8de22ca ) ) -game ( - name "Berks (World) (Aftermarket) (Unl)" - description "Berks (World) (Aftermarket) (Unl)" - rom ( name "Berks (World) (Aftermarket) (Unl).gbc" size 262144 crc 10ded9ab sha1 8b4c282cf973cdd9926a69ae1d8fcbaf79f8552b ) -) - game ( name "Beyblade - Fighting Tournament (Japan)" description "Beyblade - Fighting Tournament (Japan)" @@ -35492,12 +36788,6 @@ game ( rom ( name "Bibi und Tina - Fohlen Felix in Gefahr (Germany).gbc" size 1048576 crc 8874acd4 sha1 59843ced1e9cbcb02c6acbb8f533ec77b314882c flags verified ) ) -game ( - name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" - description "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 65536 crc b0401d96 sha1 ee5f2db597bb2fa06efe4a279a887b97bf23cac6 ) -) - game ( name "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" description "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" @@ -35552,18 +36842,6 @@ game ( rom ( name "Bionic Commando - Elite Forces (USA, Australia).gbc" size 2097152 crc a663cf31 sha1 33c28a2183f8b95cc2d8e0b6a0b005bfc230f1fc flags verified ) ) -game ( - name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" - description "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0d464785 sha1 790b9d231f6e66027e76264ef646c7a7cb9c878c ) -) - -game ( - name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - description "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 936443e2 sha1 b874c45d4866d5ef0c0d9837502ae42dd0ea3787 ) -) - game ( name "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" description "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" @@ -35576,12 +36854,6 @@ game ( rom ( name "Black Onyx, The (Japan).gbc" size 1048576 crc 582fe338 sha1 b0f009023a25e575b59e55dec07cda2826f48b65 ) ) -game ( - name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" - description "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 45c5f990 sha1 ec8c467e955d69b2084805f11a954e0d90855461 ) -) - game ( name "Blade (USA, Europe)" description "Blade (USA, Europe)" @@ -35594,18 +36866,6 @@ game ( rom ( name "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2f91e17c sha1 8b2e83d7f2b7d72d5cc1ac81c28c2173ad2fc9ba ) ) -game ( - name "Blaze (World) (Aftermarket) (Unl)" - description "Blaze (World) (Aftermarket) (Unl)" - rom ( name "Blaze (World) (Aftermarket) (Unl).gbc" size 262144 crc 7d2519c7 sha1 f9b1422a91cc1f3a55526ef8ba81b7a8297fc55e ) -) - -game ( - name "Blinky's Revenge (World) (Aftermarket) (Unl)" - description "Blinky's Revenge (World) (Aftermarket) (Unl)" - rom ( name "Blinky's Revenge (World) (Aftermarket) (Unl).gbc" size 262144 crc 2d2f9c2b sha1 1c39cc02396c74e7b0b282ead510e94c77ff7f1e ) -) - game ( name "Blue's Clues - Blue's Alphabet Book (USA) (Rev 1) (Proto)" description "Blue's Clues - Blue's Alphabet Book (USA) (Rev 1) (Proto)" @@ -35618,12 +36878,6 @@ game ( rom ( name "Blue's Clues - Blue's Alphabet Book (USA).gbc" size 1048576 crc 748d1345 sha1 f703b54746cb2ef08deba2518ce7b7a3836142aa ) ) -game ( - name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 440a2260 sha1 8472981264122ea588d991628c51020545779926 ) -) - game ( name "Boarder Zone (USA)" description "Boarder Zone (USA)" @@ -35660,12 +36914,6 @@ game ( rom ( name "Bob the Builder - Fix it Fun! (USA).gbc" size 1048576 crc 93fa37bd sha1 68bd9a1932d4e5333ab5b4dfe0d28f126e5d470f ) ) -game ( - name "Boing! (World) (Aftermarket) (Unl)" - description "Boing! (World) (Aftermarket) (Unl)" - rom ( name "Boing! (World) (Aftermarket) (Unl).gbc" size 2097152 crc 91961796 sha1 09fde4065941784bab4cf8f624a0398049ed4add ) -) - game ( name "Boku no Camp-jou (Japan)" description "Boku no Camp-jou (Japan)" @@ -35690,12 +36938,6 @@ game ( rom ( name "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan) (Rev 1).gbc" size 2097152 crc 75af0e84 sha1 acb2e549fb7d107d20507af88c36f40234f74958 flags verified ) ) -game ( - name "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" - description "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" - rom ( name "Bomb Runner 1-2 (World) (Aftermarket) (Unl).gbc" size 262144 crc d4c95ac0 sha1 3d020eb6e118b431899d79ce4a7bda9bc571c3a0 ) -) - game ( name "Bomberman Max - Ain Version (Japan)" description "Bomberman Max - Ain Version (Japan)" @@ -35762,18 +37004,6 @@ game ( rom ( name "Bomberman Selection (Korea) (Beta 1).gbc" size 1048576 crc 005ad4b7 sha1 206a19a48a35bcff18d5872b85ba4e8963827cb3 ) ) -game ( - name "Booty (World) (Aftermarket) (Unl)" - description "Booty (World) (Aftermarket) (Unl)" - rom ( name "Booty (World) (Aftermarket) (Unl).gbc" size 262144 crc ef6c39c8 sha1 3c487ddc03d935b583e186d1cc395966ef490412 ) -) - -game ( - name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" - description "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e92ce3d4 sha1 1ddf864188dfd741ccda0b0715e75e162d212605 ) -) - game ( name "Bouken! Dondoko Shima (Japan)" description "Bouken! Dondoko Shima (Japan)" @@ -35786,36 +37016,12 @@ game ( rom ( name "Bounced! (Europe) (Proto).gbc" size 1048576 crc 3948aee9 sha1 06d2d0eaea07d7a41834d4c9a5dfdbdda6889be9 ) ) -game ( - name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" - description "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ee1c2e1d sha1 b95dfdf10820671ab5f734ed7180cbf1967ca277 ) -) - game ( name "Brave Saga - Shinshou Astaria (Japan)" description "Brave Saga - Shinshou Astaria (Japan)" rom ( name "Brave Saga - Shinshou Astaria (Japan).gbc" size 2097152 crc 5d5d294a sha1 952b9e16a938b986a6216b8db6d62f71c4f853fa flags verified ) ) -game ( - name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" - description "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" - rom ( name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl).gbc" size 524288 crc 437a2973 sha1 9c219e2c489f5140314e89fbdc0bb387e1f1eed0 ) -) - -game ( - name "Bubble Trouble (World) (Aftermarket) (Unl)" - description "Bubble Trouble (World) (Aftermarket) (Unl)" - rom ( name "Bubble Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc 3374918b sha1 892388f81f7815ea3bca17632a6a9a33a6edafac ) -) - -game ( - name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" - description "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc e3f64fec sha1 51e302fd27d579c9a4e8109e6ea4af3275d475dd ) -) - game ( name "Buffy the Vampire Slayer (USA, Europe)" description "Buffy the Vampire Slayer (USA, Europe)" @@ -35900,12 +37106,6 @@ game ( rom ( name "Burger Paradise International (Japan).gbc" size 1048576 crc 9092b0eb sha1 71072a7f0165769649bce8c31c36f67bb0e02963 ) ) -game ( - name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" - description "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a5d6cd6a sha1 7464af8e6d9d0a4b11f510d22789a6830cd4c272 ) -) - game ( name "Bust-A-Move 4 (USA, Europe) (GB Compatible)" description "Bust-A-Move 4 (USA, Europe) (GB Compatible)" @@ -35942,18 +37142,6 @@ game ( rom ( name "Caise Gedou 29 in 1 Diannao Huamian Xuan Game (Taiwan) (Unl).gbc" size 2097152 crc 78c0e5bc sha1 358e628e680bc63227940ca6d76217d14fcd3409 flags verified ) ) -game ( - name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52da152b sha1 1bb4a376c03af67ca1e8426375fe1a644499d9ae ) -) - -game ( - name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" - description "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" - rom ( name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 1f2823cb sha1 8906832db7816be01ed37728f6e5a23e981e7e38 ) -) - game ( name "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" description "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" @@ -35972,6 +37160,12 @@ game ( rom ( name "Cannon Fodder (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 26f8e1a0 sha1 cc601984a2b52b44cf135e42bcac1bec44b7a6a3 ) ) +game ( + name "Capcom Fight 2003 (Hong Kong) (En) (Unl)" + description "Capcom Fight 2003 (Hong Kong) (En) (Unl)" + rom ( name "Capcom Fight 2003 (Hong Kong) (En) (Unl).gbc" size 2097152 crc 2f8ac081 sha1 3b7a16d1a5d91118960cfadcc41eecaa36097bac ) +) + game ( name "Capcom vs SNK - Millennium Fight 2001 (Taiwan) (En) (Unl)" description "Capcom vs SNK - Millennium Fight 2001 (Taiwan) (En) (Unl)" @@ -36020,12 +37214,6 @@ game ( rom ( name "Cardcaptor Sakura - Tomoeda Shougakkou Daiundoukai (Japan).gbc" size 2097152 crc f78f7998 sha1 1809154979b289750b572a61da1dc93b1b76360f ) ) -game ( - name "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" - description "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cargo (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a65d66f4 sha1 83c35ad553bde5ce3a6af418d7f8ad1fbe73b0f6 ) -) - game ( name "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl)" description "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl)" @@ -36098,12 +37286,6 @@ game ( rom ( name "Casper (USA).gbc" size 1048576 crc c775d653 sha1 82ac50380c3ed39fad13cc0bbe35e6457806a294 ) ) -game ( - name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" - description "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 280937cc sha1 9ec53942f0136076b6468671562764e1ab9dee3b ) -) - game ( name "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" description "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" @@ -36140,18 +37322,6 @@ game ( rom ( name "Catz (USA).gbc" size 1048576 crc 769a2c5a sha1 5c3c9a4d85a92779c7e8304f2c122296f62f9a9c ) ) -game ( - name "Cave Fighter (World) (Aftermarket) (Unl)" - description "Cave Fighter (World) (Aftermarket) (Unl)" - rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gbc" size 262144 crc 6f4641f0 sha1 05b441e3542452b1724017d20e2db602d0997773 ) -) - -game ( - name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" - description "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc defb3151 sha1 94770d13bd9b1b52224fe753f94ec580e1b4017c ) -) - game ( name "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" description "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" @@ -36230,12 +37400,6 @@ game ( rom ( name "Chase H.Q. - Secret Police (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 7c7fdefc sha1 030b45eb8929c1512826f288e4ba035e0083505c ) ) -game ( - name "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" - description "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" - rom ( name "Chase the Chuck Wagon (World) (Aftermarket) (Unl).gbc" size 262144 crc 3c3d653c sha1 27b462be532a37c15798eba0fd48154eff596753 ) -) - game ( name "Checkmate (Japan) (En,Ja) (GB Compatible)" description "Checkmate (Japan) (En,Ja) (GB Compatible)" @@ -36254,12 +37418,6 @@ game ( rom ( name "Chessmaster (USA, Europe) (GB Compatible).gbc" size 1048576 crc 1c13dbb0 sha1 84930fa75eccc34a8e9fb6a0387791d437d1a442 flags verified ) ) -game ( - name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 490a874a sha1 92567a6a58739a38e0d7b35d1327ccb999527fa0 ) -) - game ( name "Chi to Ase to Namida no Koukou Yakyuu (Japan)" description "Chi to Ase to Namida no Koukou Yakyuu (Japan)" @@ -36290,24 +37448,12 @@ game ( rom ( name "Chongwu Xiao Jingling - Jiejin Ta Zhi Wang (Taiwan) (Unl).gbc" size 1048576 crc 620e785d sha1 74da832c2eeb27a4260fe6f42514539473f48b11 ) ) -game ( - name "Chopper War (World) (Aftermarket) (Unl)" - description "Chopper War (World) (Aftermarket) (Unl)" - rom ( name "Chopper War (World) (Aftermarket) (Unl).gbc" size 524288 crc eb0f4f3e sha1 26970bb0753e792aaeb328e0f88d650acd413a9d ) -) - game ( name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible)" description "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible)" rom ( name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 65610ca4 sha1 8af215c632599aaab9bc4614194ac45802407bbc ) ) -game ( - name "Choro-Q (World) (Aftermarket) (Unl)" - description "Choro-Q (World) (Aftermarket) (Unl)" - rom ( name "Choro-Q (World) (Aftermarket) (Unl).gbc" size 262144 crc e40e99bd sha1 8534c4fe58aef32b8cfd4812fa1f2c1094e6b129 ) -) - game ( name "Chuanshuo (Taiwan) (Unl)" description "Chuanshuo (Taiwan) (Unl)" @@ -36326,18 +37472,6 @@ game ( rom ( name "Classic Bubble Bobble (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c1b22246 sha1 6e3739c0538467c220750f2e8d474433692bac09 ) ) -game ( - name "Climb It (World) (Aftermarket) (Unl)" - description "Climb It (World) (Aftermarket) (Unl)" - rom ( name "Climb It (World) (Aftermarket) (Unl).gbc" size 262144 crc e7210290 sha1 19f3b825eada3eda3135350bd0ddca6a20a5281f ) -) - -game ( - name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" - description "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c4b00adb sha1 07e4254c7f74b9d4caa6a1231558b2430dff163a flags verified ) -) - game ( name "Colin McRae Rally (Europe)" description "Colin McRae Rally (Europe)" @@ -36362,24 +37496,12 @@ game ( rom ( name "Commander Keen (USA, Europe).gbc" size 1048576 crc 4af4cc9c sha1 a00b7bdaaedeb67ad7e7555139301c8b4c92edea flags verified ) ) -game ( - name "Commando (World) (Aftermarket) (Unl)" - description "Commando (World) (Aftermarket) (Unl)" - rom ( name "Commando (World) (Aftermarket) (Unl).gbc" size 262144 crc 5381b103 sha1 414bb6bdc1ed5647707d7d49f194c387d4098f00 ) -) - game ( name "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" description "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" rom ( name "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc a50be9a8 sha1 e9c3b1bb20ea74f363191ea9144009d1b13246bb flags verified ) ) -game ( - name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" - description "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c53ace00 sha1 02fdc52bc934b80aa41520d92cf0340753d8f668 ) -) - game ( name "Cool Bricks (Europe) (En,Fr,De,Es,It)" description "Cool Bricks (Europe) (En,Fr,De,Es,It)" @@ -36392,24 +37514,6 @@ game ( rom ( name "Cool Hand (Europe) (En,Fr,De) (GB Compatible).gbc" size 524288 crc e6c91fb8 sha1 d116a77c501d5e553d1490993f8c0a9a92c3ea0c ) ) -game ( - name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc fe1bdae6 sha1 00d86bbdbc228ff3ea0684984a261cadbed5fb0a ) -) - -game ( - name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" - description "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" - rom ( name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 1780b904 sha1 fcbe2c2389e6c51a38eb17eb80ffb2e51955c7f2 ) -) - -game ( - name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" - description "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" - rom ( name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc e983a31f sha1 1d811dd440572243f9e95527d970f3ffa91ddbdf ) -) - game ( name "Crazy Bikers (Europe)" description "Crazy Bikers (Europe)" @@ -36428,12 +37532,6 @@ game ( rom ( name "Crazy Climber (USA) (Proto 1) (2000-09-22).gbc" size 131072 crc 748fa8b4 sha1 eb0eaed85cf5a72e0461eebbad38227bd018a999 ) ) -game ( - name "Crazy Golf (World) (Aftermarket) (Unl)" - description "Crazy Golf (World) (Aftermarket) (Unl)" - rom ( name "Crazy Golf (World) (Aftermarket) (Unl).gbc" size 262144 crc f7fe3d01 sha1 b06f47a713b66efa9133be43653c7c4cb5ebc93c ) -) - game ( name "Croc (USA, Europe)" description "Croc (USA, Europe)" @@ -36443,7 +37541,7 @@ game ( game ( name "Croc 2 (USA, Europe)" description "Croc 2 (USA, Europe)" - rom ( name "Croc 2 (USA, Europe).gbc" size 1048576 crc c1d60129 sha1 fa29d6c4239405b12b320bb6e8a65ca2083a4b1c ) + rom ( name "Croc 2 (USA, Europe).gbc" size 1048576 crc c1d60129 sha1 fa29d6c4239405b12b320bb6e8a65ca2083a4b1c flags verified ) ) game ( @@ -36488,12 +37586,6 @@ game ( rom ( name "Cubix - Robots for Everyone - Race 'n Robots (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 9f883b0f sha1 d62b85c664e0a42c84e56b939a201fe90d05a360 ) ) -game ( - name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gbc" size 262144 crc 30204c4e sha1 d6fb35f3bdd44429f88c10551692e1adf14356ab ) -) - game ( name "CyberTiger (USA, Europe)" description "CyberTiger (USA, Europe)" @@ -36572,36 +37664,6 @@ game ( rom ( name "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e2071293 sha1 2d961353e7242babce49dda8d017a459f4ef7609 ) ) -game ( - name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl).gbc" size 262144 crc 502385c4 sha1 3a310be21d5cc077da6eb8e3afa99ccff2eda84e ) -) - -game ( - name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc a504b906 sha1 4634631f2c0b4a618aeefc114e5b8e4ba9c7ee04 ) -) - -game ( - name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl).gbc" size 262144 crc a9714871 sha1 7d5b22d1c528603007e340f9d3562c1e53f10796 ) -) - -game ( - name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl).gbc" size 262144 crc 26d3fe7a sha1 36c9649d4e99fdcaa4cf590963d0c49a3cf8084e ) -) - -game ( - name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" - description "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc d34b719a sha1 446ca937d3e54ce33a49d1fff4692b3b906b539e ) -) - game ( name "Dance Dance Revolution GB (Japan)" description "Dance Dance Revolution GB (Japan)" @@ -36632,12 +37694,6 @@ game ( rom ( name "Dancing Furby (Japan) (GB Compatible).gbc" size 1048576 crc 3263f692 sha1 f3f7e37d64eef74d65456bae490e0a0b25897ac0 ) ) -game ( - name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" - description "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc df19aa9f sha1 412f18ba08f2f2a2afbf3bfb5281e360d7aba31d ) -) - game ( name "Data-Navi Pro Yakyuu (Japan)" description "Data-Navi Pro Yakyuu (Japan)" @@ -36671,25 +37727,7 @@ game ( game ( name "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl)" description "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc c25ee35a sha1 be0703ee2667ddc53cff9d6c7d22b30d272c0738 ) -) - -game ( - name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" - description "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc bb64f51c sha1 1611ddfdb9af72f20ddeca4133d8eebd0f14e424 ) -) - -game ( - name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" - description "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" - rom ( name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl).gbc" size 262144 crc 57ca8f69 sha1 8992f14f02bd37e11cb05511c17fff3d253ccf25 ) -) - -game ( - name "Days Without (World) (Aftermarket) (Unl)" - description "Days Without (World) (Aftermarket) (Unl)" - rom ( name "Days Without (World) (Aftermarket) (Unl).gbc" size 262144 crc 437b4921 sha1 cb21c1bca18d750ecde91dc3adb6b599c2ad75fa ) + rom ( name "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc c25ee35a sha1 be0703ee2667ddc53cff9d6c7d22b30d272c0738 flags verified ) ) game ( @@ -36704,24 +37742,12 @@ game ( rom ( name "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 0fd34427 sha1 8598594285f0342b3d93c447b475fadd4722c6cb ) ) -game ( - name "Death Race 16 (World) (Aftermarket) (Unl)" - description "Death Race 16 (World) (Aftermarket) (Unl)" - rom ( name "Death Race 16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b9488ec sha1 56b8a2d7117b12ff5e709e6a258f9a0b3b0ebe24 ) -) - game ( name "Deer Hunter (USA)" description "Deer Hunter (USA)" rom ( name "Deer Hunter (USA).gbc" size 1048576 crc 40a715fb sha1 87a012e82f2361760ae337b30e9d41ef2245419a ) ) -game ( - name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" - description "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7cff943e sha1 065b5325d44cb0e40f7b7803d707b8c1ea9ea5b2 ) -) - game ( name "Deja Vu I & II (Japan)" description "Deja Vu I & II (Japan)" @@ -36785,13 +37811,7 @@ game ( game ( name "Dexter's Laboratory - Robot Rampage (USA, Europe)" description "Dexter's Laboratory - Robot Rampage (USA, Europe)" - rom ( name "Dexter's Laboratory - Robot Rampage (USA, Europe).gbc" size 1048576 crc d24d6601 sha1 db107af55df07fb8c771c712b05d6aebb175e3c5 ) -) - -game ( - name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" - description "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c6b965b9 sha1 ac43f43bdcfc0347f24a0a70de213a4b701d8155 ) + rom ( name "Dexter's Laboratory - Robot Rampage (USA, Europe).gbc" size 1048576 crc d24d6601 sha1 db107af55df07fb8c771c712b05d6aebb175e3c5 flags verified ) ) game ( @@ -36806,6 +37826,12 @@ game ( rom ( name "Digimon 02 4 (Taiwan) (En) (Unl).gbc" size 1048576 crc a90061e9 sha1 0c8280e5349dda05fdd27bb1eb68a1be2f3d5c04 ) ) +game ( + name "Digimon 02 5 (USA) (Unl)" + description "Digimon 02 5 (USA) (Unl)" + rom ( name "Digimon 02 5 (USA) (Unl).gbc" size 1048576 crc 0bcbe728 sha1 f868fecce3bdec242937b93549f4861a0f481065 ) +) + game ( name "Digimon 2 (Taiwan) (En) (Unl)" description "Digimon 2 (Taiwan) (En) (Unl)" @@ -36842,6 +37868,12 @@ game ( rom ( name "Digimon Pocket (Taiwan) (En) (Unl).gbc" size 524288 crc 6791b106 sha1 87750928d5f005e67e51e4d08a6d82351effc7b2 ) ) +game ( + name "Digimon Pocket (Taiwan) (Zh) (Unl)" + description "Digimon Pocket (Taiwan) (Zh) (Unl)" + rom ( name "Digimon Pocket (Taiwan) (Zh) (Unl).gbc" size 524288 crc 6d39574e sha1 9560dac8eb9d676aeb5f2d92fbb0228cb4ec27cc ) +) + game ( name "Digimon Saphire (USA) (Unl)" description "Digimon Saphire (USA) (Unl)" @@ -36890,18 +37922,6 @@ game ( rom ( name "Dinosaur'us (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc f4609fe3 sha1 d0caf4b5172651aee2bbe38efdae084ce3d7a7ff ) ) -game ( - name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" - description "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ef349515 sha1 06fe25086432c82f1e4b4c44473dd5b487a8af05 ) -) - -game ( - name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" - description "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7c0f52cc sha1 8bc16b70838f9245b7e37c6dbe57159b294fbf81 ) -) - game ( name "Diva Starz (Europe)" description "Diva Starz (Europe)" @@ -36926,12 +37946,6 @@ game ( rom ( name "Diva Starz - Mall Mania (USA).gbc" size 1048576 crc ebe0ecd6 sha1 1d0edb87404409f1e4c124503be4cc59165c01da ) ) -game ( - name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" - description "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f4ff5eb0 sha1 6b421505acc626a34bb9306a3d88e1964a4502f3 ) -) - game ( name "Dogz (Europe)" description "Dogz (Europe)" @@ -36962,24 +37976,6 @@ game ( rom ( name "Dokidoki Densetsu - Mahoujin Guruguru (Japan).gbc" size 4194304 crc 83e47a1a sha1 1b4627699b45af36a42e75c1a217b40fb5bec4ba ) ) -game ( - name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52cf7153 sha1 74e6246405dd52d4c5c2eabc417946550c637164 ) -) - -game ( - name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8ca9dbe0 sha1 cf6eaac37c4ae1b3cfc4ed8d2ce73a143635b525 ) -) - -game ( - name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 3d87efd8 sha1 83201c43e9fc89f4393678ade8c6107b4cfdb628 ) -) - game ( name "Donald Duck - Daisy o Sukue! (Japan)" description "Donald Duck - Daisy o Sukue! (Japan)" @@ -37088,12 +38084,6 @@ game ( rom ( name "Doraemon no Study Boy - Kuku Game (Japan).gbc" size 1048576 crc a8a353d8 sha1 9b5c8b89b6e69d3803fbd43b2fe5130ad6d2f50b ) ) -game ( - name "Dork's Dilemma (World) (Aftermarket) (Unl)" - description "Dork's Dilemma (World) (Aftermarket) (Unl)" - rom ( name "Dork's Dilemma (World) (Aftermarket) (Unl).gbc" size 524288 crc 77b8b43b sha1 bd525f97cc316fed3f6271ed0929414df4c0389c ) -) - game ( name "Doug - La Grande Aventure (France)" description "Doug - La Grande Aventure (France)" @@ -37118,12 +38108,6 @@ game ( rom ( name "Doug's Big Game (Europe).gbc" size 1048576 crc b6ffbcca sha1 e9c207bb9b03b5762afd53c8f5295703cc1474b1 ) ) -game ( - name "Downer (World) (GB Compatible) (Aftermarket) (Unl)" - description "Downer (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Downer (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7a1c9a9f sha1 70044dca1282f4445fe05305586ecc69f4e52304 ) -) - game ( name "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" description "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" @@ -37133,7 +38117,7 @@ game ( game ( name "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It)" description "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It)" - rom ( name "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2f7aef51 sha1 815f252f761e0fd3f29b7acf32b2360264aefab1 ) + rom ( name "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2f7aef51 sha1 815f252f761e0fd3f29b7acf32b2360264aefab1 flags verified ) ) game ( @@ -37145,13 +38129,7 @@ game ( game ( name "Dragon Ball - Final Bout (Taiwan) (Unl)" description "Dragon Ball - Final Bout (Taiwan) (Unl)" - rom ( name "Dragon Ball - Final Bout (Taiwan) (Unl).gbc" size 1048576 crc d9849157 sha1 51ebe1a27e8295340f996d2841c5cc6e2bc9f548 ) -) - -game ( - name "Dragon Ball Z - 2002 Fighting (Taiwan) (Zh) (Unl)" - description "Dragon Ball Z - 2002 Fighting (Taiwan) (Zh) (Unl)" - rom ( name "Dragon Ball Z - 2002 Fighting (Taiwan) (Zh) (Unl).gbc" size 2097152 crc 8fa35740 sha1 008a559635c9d351d9f68b3a1ac0c687521821cf ) + rom ( name "Dragon Ball - Final Bout (Taiwan) (Unl).gbc" size 1048576 crc 039079bd sha1 682b1be82eccb9044fc61af689c39d07fa325fec ) ) game ( @@ -37406,24 +38384,6 @@ game ( rom ( name "Dragon's Lair (USA, Europe) (En,Ja,Fr,De,Es,Zh).gbc" size 4194304 crc bf076ca5 sha1 15fb0865314e43a83910d52cca7307502aab29fc ) ) -game ( - name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 9f30b891 sha1 9974d28975a2d8e1e41ce8f32351c6eef144919d ) -) - -game ( - name "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" - description "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 96f9b7c0 sha1 2b74d076cabff92e5935d922e8f37202a723aaf0 flags verified ) -) - -game ( - name "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc cad7369d sha1 0058096f8fcbb2774f908811aaa0b1ee54111493 ) -) - game ( name "Driver (Europe) (En,Fr,De,Es,It)" description "Driver (Europe) (En,Fr,De,Es,It)" @@ -37484,12 +38444,6 @@ game ( rom ( name "Dukes of Hazzard, The - Racing for Home (USA).gbc" size 2097152 crc fb08dceb sha1 6a39dfbce8b86db84615cdb5fb24012cbbac7b36 ) ) -game ( - name "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible)" - description "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible)" - rom ( name "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 2bcb5f78 sha1 766ab65d9420f361d8d9a4754ea8c6b692e34c36 ) -) - game ( name "Dungeon Savior (Japan) (Rev 1) (Proto) (SGB Enhanced) (GB Compatible)" description "Dungeon Savior (Japan) (Rev 1) (Proto) (SGB Enhanced) (GB Compatible)" @@ -37497,15 +38451,9 @@ game ( ) game ( - name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7c41cef6 sha1 e2df238887da0b6cf79513c7799ad707740eae30 ) -) - -game ( - name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc abb154db sha1 f3b456d6318bee05150403efa5a933996e1d744a ) + name "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible)" + description "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 2bcb5f78 sha1 766ab65d9420f361d8d9a4754ea8c6b692e34c36 ) ) game ( @@ -37562,6 +38510,12 @@ game ( rom ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (USA).gbc" size 1048576 crc 32c87958 sha1 da71b581f7415b6535ac4af2e8fccd2040c54215 ) ) +game ( + name "e'Fighter HOT (Taiwan) (En) (Unl)" + description "e'Fighter HOT (Taiwan) (En) (Unl)" + rom ( name "e'Fighter HOT (Taiwan) (En) (Unl).gbc" size 1048576 crc 8fa2539d sha1 93a3716f8f41b89bee795af6e8f6fdddfcd8acf1 ) +) + game ( name "Earthworm Jim - Menace 2 the Galaxy (USA, Europe) (GB Compatible)" description "Earthworm Jim - Menace 2 the Galaxy (USA, Europe) (GB Compatible)" @@ -37574,6 +38528,12 @@ game ( rom ( name "ECW Hardcore Revolution (USA, Europe).gbc" size 1048576 crc 484eba10 sha1 c337d0480e84f5e2b7e28b13c3667b8cf92d9649 ) ) +game ( + name "Elang 2003 - Mark of the Wolfs (Taiwan) (En) (Unl)" + description "Elang 2003 - Mark of the Wolfs (Taiwan) (En) (Unl)" + rom ( name "Elang 2003 - Mark of the Wolfs (Taiwan) (En) (Unl).gbc" size 1048576 crc 50a1e9a9 sha1 4a3ac88b7be532d5fd5c4d9e500532e96441a966 ) +) + game ( name "Elang Chuanshuo - Shiji Zhi Zhan (Taiwan) (Unl)" description "Elang Chuanshuo - Shiji Zhi Zhan (Taiwan) (Unl)" @@ -37586,12 +38546,6 @@ game ( rom ( name "Elemental Fighter (USA) (Proto).gbc" size 262144 crc 03fc3d03 sha1 92cce7614474d3f9ed9e3fdbd2e2bb434e074565 ) ) -game ( - name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc bffec2e1 sha1 a25cc6ee07e524f9a7121786bd0e513a1c6c2a8d ) -) - game ( name "Elevator Action EX (Europe) (En,Fr,De,Es,It)" description "Elevator Action EX (Europe) (En,Fr,De,Es,It)" @@ -37646,12 +38600,6 @@ game ( rom ( name "Emperor's New Groove, The (USA).gbc" size 2097152 crc 6ebad539 sha1 ba663289bd5d9d09bc8b9ac2c1d38293dcba9c02 ) ) -game ( - name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9ca3cf6c sha1 d3f4d21bf543431672268b476802693b2da9b6b9 ) -) - game ( name "Equestriad 2001 (Europe) (Proto)" description "Equestriad 2001 (Europe) (Proto)" @@ -37706,24 +38654,6 @@ game ( rom ( name "Evel Knievel (USA) (GB Compatible).gbc" size 2097152 crc 51e951b5 sha1 24cac6ab0151b33d2b1fd06ee01931802fb98267 flags verified ) ) -game ( - name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" - description "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f222b03b sha1 c14f008cfc182f35fe670e14b57052ae4f8d1c60 ) -) - -game ( - name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" - description "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 050caa5e sha1 e4b61c220b046e2287272f9b1bef85ad2d835fe3 ) -) - -game ( - name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" - description "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" - rom ( name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 20fe84af sha1 18056b5b032955099c606651f26164de131e54a6 ) -) - game ( name "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt)" description "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt)" @@ -37838,54 +38768,18 @@ game ( rom ( name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c4d3628f sha1 d07b600cc9af8cadc2581a6ac19aadea79313d69 flags verified ) ) -game ( - name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc bdaf8f3f sha1 d1ed0fb4d926f4c337399ca342644f89cf00790a ) -) - -game ( - name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e61c1dc2 sha1 d7a88a68ec65d9cf3f9521fc9ad9d3f4b51bac5d ) -) - -game ( - name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 63c6c960 sha1 b62ec7a341ea9a0bfe8f0b014da971b73606a86e ) -) - -game ( - name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - description "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc de373eba sha1 dbf2228017515b407ed9f4a9b3bf01bc2a5f7b0f ) -) - -game ( - name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" - description "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc 701847f5 sha1 aba3fecd55c0cee7fbe49506b367b7e94b56b81c ) -) - -game ( - name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" - description "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" - rom ( name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc f87760b3 sha1 ea0dd170812d1bcc38de1cabe12a372cd2178c95 ) -) - -game ( - name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" - description "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" - rom ( name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate).gbc" size 524288 crc 7bec6553 sha1 bdcadc0f98d8c9061cbe83c53a047719280b6e09 ) -) - game ( name "Fellowship of the Rings (Taiwan) (En) (Unl)" description "Fellowship of the Rings (Taiwan) (En) (Unl)" rom ( name "Fellowship of the Rings (Taiwan) (En) (Unl).gbc" size 524288 crc 4bcc59dc sha1 837232bd2eeb50b276049d0908f8ed4dc7efbcfe ) ) +game ( + name "Fellowship of the Rings (China) (En) (Unl)" + description "Fellowship of the Rings (China) (En) (Unl)" + rom ( name "Fellowship of the Rings (China) (En) (Unl).gbc" size 524288 crc 759f07bd sha1 83fec0fb02fdeda160a0de610acdf7446e373022 ) +) + game ( name "Feng Kuang A Gei III - Chaoji Zhadan Ren (Taiwan) (Unl)" description "Feng Kuang A Gei III - Chaoji Zhadan Ren (Taiwan) (Unl)" @@ -37928,42 +38822,6 @@ game ( rom ( name "FIFA 2000 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e6bc2e8c sha1 c40dd26a6d600818eca960bade3afa374a19bc12 ) ) -game ( - name "Fillo - Crystal Version (World) (Aftermarket) (Unl)" - description "Fillo - Crystal Version (World) (Aftermarket) (Unl)" - rom ( name "Fillo - Crystal Version (World) (Aftermarket) (Unl).gbc" size 524288 crc 88bb855c sha1 2ffc4199d94f8b29b3f84b7bdb2694154a0bd285 ) -) - -game ( - name "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" - description "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Find Out (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5f8b660e sha1 3605a96f6713157a88e4d88989d2e2f11b9db42f ) -) - -game ( - name "Finders Keepers (World) (Aftermarket) (Unl)" - description "Finders Keepers (World) (Aftermarket) (Unl)" - rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gbc" size 524288 crc 4cfa0cfd sha1 db002f4a2500a9dc98a9ac7c263293d6e4a72cf1 ) -) - -game ( - name "Fire Ant (World) (Aftermarket) (Unl)" - description "Fire Ant (World) (Aftermarket) (Unl)" - rom ( name "Fire Ant (World) (Aftermarket) (Unl).gbc" size 262144 crc 154cc020 sha1 b58ed66838db34fc7f8475ccb670267119d623a5 ) -) - -game ( - name "Fireman Fred (World) (Aftermarket) (Unl)" - description "Fireman Fred (World) (Aftermarket) (Unl)" - rom ( name "Fireman Fred (World) (Aftermarket) (Unl).gbc" size 524288 crc 563d9ca7 sha1 e62a9c6b6a39f0cb662fdb07b72669355b706f57 ) -) - -game ( - name "Firemen (World) (Aftermarket) (Unl)" - description "Firemen (World) (Aftermarket) (Unl)" - rom ( name "Firemen (World) (Aftermarket) (Unl).gbc" size 262144 crc 7299401f sha1 84c68614334578f866cfa929df736377f04f5d04 ) -) - game ( name "Fish Files, The (Europe) (En,Fr,De,Es,It)" description "Fish Files, The (Europe) (En,Fr,De,Es,It)" @@ -37977,21 +38835,9 @@ game ( ) game ( - name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" - description "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc c8014615 sha1 7221f5e53f6027183301d06e258c6cb417007b8c ) -) - -game ( - name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - description "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 507f9ea2 sha1 28ad64e379dc60d6e1c2617e073f6361c0feb475 flags verified ) -) - -game ( - name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - description "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc fcc05ec4 sha1 64d31f34e189b3af08bf0c659a93f71dbf83ef71 ) + name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" + description "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" + rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc a5b09726 sha1 2f7fb1afedd6c9657715b45397dc5492e40dfe45 flags verified ) ) game ( @@ -38006,30 +38852,12 @@ game ( rom ( name "Flintstones, The - Burgertime in Bedrock (USA).gbc" size 1048576 crc 14d8cc5d sha1 065851358f6720d4926faa42b015da68cafa6c28 ) ) -game ( - name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" - description "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" - rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc a5b09726 sha1 2f7fb1afedd6c9657715b45397dc5492e40dfe45 flags verified ) -) - game ( name "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" rom ( name "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 08b9e4aa sha1 3d538b78ef5f1238f47531c069921056b00e33b3 ) ) -game ( - name "Flooder (World) (Aftermarket) (Unl)" - description "Flooder (World) (Aftermarket) (Unl)" - rom ( name "Flooder (World) (Aftermarket) (Unl).gbc" size 32768 crc 253dcbe0 sha1 8fdcd8b02604ac5259fb6aa80e5ba67a03c861fb ) -) - -game ( - name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" - description "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" - rom ( name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl).gbc" size 32768 crc cdda76f8 sha1 e5eec8efc032aa5bce1826f7b6b8790c61c96e06 ) -) - game ( name "Floracy (Europe) (Proto) (2000-10-10)" description "Floracy (Europe) (Proto) (2000-10-10)" @@ -38043,15 +38871,9 @@ game ( ) game ( - name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" - description "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fa2d92a1 sha1 24f02d116aafb7b55d6cfd6d263b7595986af843 ) -) - -game ( - name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4c21e563 sha1 f6f84f1a44d41fa7d26a9195ddf791fae53dfcdf ) + name "Formula One 2000 (USA)" + description "Formula One 2000 (USA)" + rom ( name "Formula One 2000 (USA).gbc" size 1048576 crc 703c057f sha1 7a38195842e536581fdcea42e4ebe50967581736 ) ) game ( @@ -38060,12 +38882,6 @@ game ( rom ( name "Formula One 2000 (Europe) (En,Fr,De,Es,It) (Proto).gbc" size 1048576 crc e689bf16 sha1 7aa7073b7b494522f7cfcd268aa066b7fe52c671 ) ) -game ( - name "Formula One 2000 (USA)" - description "Formula One 2000 (USA)" - rom ( name "Formula One 2000 (USA).gbc" size 1048576 crc 703c057f sha1 7a38195842e536581fdcea42e4ebe50967581736 ) -) - game ( name "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt)" description "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt)" @@ -38078,24 +38894,6 @@ game ( rom ( name "Freestyle Scooter (Europe).gbc" size 1048576 crc ee79117d sha1 cf6ae174584bbfb5ae30478841114443adc00245 ) ) -game ( - name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" - description "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7543586a sha1 397821751ac6464582f61566f3a7c731a46b24ba ) -) - -game ( - name "Friendly Fire (World) (Aftermarket) (Unl)" - description "Friendly Fire (World) (Aftermarket) (Unl)" - rom ( name "Friendly Fire (World) (Aftermarket) (Unl).gbc" size 262144 crc 5c6dca2b sha1 8f8085010e28aa8bdb312d086b0002b706742282 ) -) - -game ( - name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - description "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc d8be10d6 sha1 d09f4d2f799ac2e2731be0171625846d28d0f57e ) -) - game ( name "Frogger (USA) (Rev 2) (GB Compatible)" description "Frogger (USA) (Rev 2) (GB Compatible)" @@ -38132,12 +38930,6 @@ game ( rom ( name "Frogger 2 (USA) (Rev 1).gbc" size 1048576 crc e3227b7d sha1 0d5028ca6fcc10df46d11cd4b56e5add1dc5e63e ) ) -game ( - name "From Below Pocket (World) (Aftermarket) (Unl)" - description "From Below Pocket (World) (Aftermarket) (Unl)" - rom ( name "From Below Pocket (World) (Aftermarket) (Unl).gbc" size 131072 crc 35ad9b5a sha1 c0e072bfb88c84dc68b2eded1f9c088d75ffa5ed ) -) - game ( name "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (Beta 1) (SGB Enhanced) (GB Compatible)" description "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (Beta 1) (SGB Enhanced) (GB Compatible)" @@ -38180,12 +38972,6 @@ game ( rom ( name "Front Row (Japan).gbc" size 1048576 crc 6eea9243 sha1 64c8a9459d7c80e297774dab7775b5edf59432cc ) ) -game ( - name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" - description "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 85edfba4 sha1 8a95571a32c5a23bd6be4edf6429f630d7a1a15a ) -) - game ( name "Full Time Soccer (Europe) (Unl)" description "Full Time Soccer (Europe) (Unl)" @@ -38198,12 +38984,6 @@ game ( rom ( name "Full Time Soccer & Hang Time Basketball (Europe) (Unl).gbc" size 524288 crc 0634c196 sha1 aefb746984b3450b90bbfaa5de21a252685ddabb ) ) -game ( - name "Fury (World) (Aftermarket) (Unl)" - description "Fury (World) (Aftermarket) (Unl)" - rom ( name "Fury (World) (Aftermarket) (Unl).gbc" size 262144 crc 7217c41d sha1 ef532b587eb438f1a39a77086ac0b8bbae23a16d ) -) - game ( name "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (AFMJ)" description "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (AFMJ)" @@ -38216,18 +38996,6 @@ game ( rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (BFWJ).gbc" size 4194304 crc f3c20fbe sha1 d9c490af97c08ac7053bbb9f7ae06d3501035127 flags verified ) ) -game ( - name "G-Man (World) (Aftermarket) (Unl)" - description "G-Man (World) (Aftermarket) (Unl)" - rom ( name "G-Man (World) (Aftermarket) (Unl).gbc" size 524288 crc ff3beab1 sha1 cb9486ca9a6ad3903662963aa966145257ef92a6 ) -) - -game ( - name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc fd2e40f4 sha1 e442316132506ff223a9e5f33d874b71ec09d71a flags verified ) -) - game ( name "Gaiamaster Duel - Card Attackers (Japan)" description "Gaiamaster Duel - Card Attackers (Japan)" @@ -38276,12 +39044,6 @@ game ( rom ( name "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1ac625da sha1 64ccb3b41715080a9aa13970678aa9047fc7a9fd flags verified ) ) -game ( - name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f1948966 sha1 14849ab5831c71949ec3a1fe7657050057d2cf29 ) -) - game ( name "Game Boy Color (World) (Demo) (Kiosk)" description "Game Boy Color (World) (Demo) (Kiosk)" @@ -38336,18 +39098,6 @@ game ( rom ( name "Game Conveni 21 (Japan) (GB Compatible).gbc" size 1048576 crc 994314b3 sha1 6803617abc46db83dbec08d10e03b9f9297f260e ) ) -game ( - name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" - description "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 96721e5d sha1 90fad94433a5b0dbcf73f4a2d4ebb75d7ab065c4 ) -) - -game ( - name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a02d2ae2 sha1 7eb6865c5c265193763ec0bf751d26964e870120 ) -) - game ( name "Games Frenzy (Europe) (En,Fr,De)" description "Games Frenzy (Europe) (En,Fr,De)" @@ -38415,81 +39165,39 @@ game ( ) game ( - name "GB Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" - description "GB Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" - rom ( name "GB Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP).gbc" size 131072 crc ec823cc1 sha1 0781eaecb7fd25c068e396b5eb02c6231baf6ea3 ) + name "GB-Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" + description "GB-Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" + rom ( name "GB-Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP).gbc" size 131072 crc ec823cc1 sha1 0781eaecb7fd25c068e396b5eb02c6231baf6ea3 ) ) game ( - name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f20c0097 sha1 691af25434a09931a302ced52c757d28b9b06619 ) + name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt 2)" + description "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt 2)" + rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt 2).gbc" size 1048576 crc 7afae089 sha1 b33c9f5012cc1a1a8c7ac9d95a183fd28d9bf9f3 ) ) game ( - name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 164999eb sha1 197d3d194d4cb6cae9a358f7fb53d6de649e7c5f ) + name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt)" + description "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt)" + rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt).gbc" size 1048576 crc c0ac1b50 sha1 4dcef6fcfe009e17da0bb13e50e7410a3f586e23 ) ) game ( - name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 60b075d1 sha1 0a66254b2327b48657de64d6102ac05f1e8700e7 ) + name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl)" + description "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl)" + rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl).gbc" size 1048576 crc 1b1c6f68 sha1 fd06c62b42878e8094e610b180c1848c785f67e9 ) ) game ( - name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 1a169897 sha1 0636b968e8e24fe7c1910f61db6e94fa84824494 ) + name "Gedou Jian Shen KF (Taiwan) (En) (Unl)" + description "Gedou Jian Shen KF (Taiwan) (En) (Unl)" + rom ( name "Gedou Jian Shen KF (Taiwan) (En) (Unl).gbc" size 1048576 crc 190702b3 sha1 be03f86ef0c6df8c6741fe1298496670fcc682cf ) ) game ( - name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 593965ff sha1 75d566045a680aaed4d40b83b6418cbfab5b4422 ) -) - -game ( - name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc d81ab567 sha1 1dfd3c4508ffb6598662bcf1b16ec109a9282dd5 ) -) - -game ( - name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f795689c sha1 9a332127182e8155d1a3dc53e1382a6c9dde6aeb ) -) - -game ( - name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 660ed37b sha1 0792fbef010cac21c12cbcb8b3c85b3af30faec4 ) -) - -game ( - name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 6dc4faaa sha1 7617083f9b13b2f95bdf1b0b327ffb4f8ccbe3c9 ) -) - -game ( - name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 8780e125 sha1 7163bfbaa2cae2f9d41c472128f69a4fa5879180 ) -) - -game ( - name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt)" - description "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt)" - rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt).gbc" size 1048576 crc c0ac1b50 sha1 4dcef6fcfe009e17da0bb13e50e7410a3f586e23 ) -) - -game ( - name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl)" - description "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl)" - rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl).gbc" size 1048576 crc 1b1c6f68 sha1 fd06c62b42878e8094e610b180c1848c785f67e9 ) + name "Gedou Qi Long Qiu 2002 (Taiwan) (Zh) (Unl)" + description "Gedou Qi Long Qiu 2002 (Taiwan) (Zh) (Unl)" + rom ( name "Gedou Qi Long Qiu 2002 (Taiwan) (Zh) (Unl).gbc" size 2097152 crc 8fa35740 sha1 008a559635c9d351d9f68b3a1ac0c687521821cf ) ) game ( @@ -38552,30 +39260,6 @@ game ( rom ( name "Gex 3 - Deep Pocket Gecko (USA).gbc" size 2097152 crc 85a98c7d sha1 0da71536a3e92dd537c7067ec1014a262dbc3837 ) ) -game ( - name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" - description "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" - rom ( name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc 4aa9a9c2 sha1 ac697bc27a126c1389e6bef94a2c83404e8819f2 ) -) - -game ( - name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 32e2ea48 sha1 ee11d5397316b69eee5ae3023de08c3b919c93df ) -) - -game ( - name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" - description "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ea87ad5d sha1 433e25df1421e77cdc807296e1ed662d9e43d685 ) -) - -game ( - name "Ghost Town (World) (Aftermarket) (Unl)" - description "Ghost Town (World) (Aftermarket) (Unl)" - rom ( name "Ghost Town (World) (Aftermarket) (Unl).gbc" size 262144 crc 52efcc35 sha1 1a4a7846d6c87f0bd8b267aa6a8aa98e797fedf8 ) -) - game ( name "Ghosts'n Goblins (USA, Europe) (GB Compatible)" description "Ghosts'n Goblins (USA, Europe) (GB Compatible)" @@ -38630,12 +39314,6 @@ game ( rom ( name "Gobs of Games (USA) (En,Fr,De).gbc" size 1048576 crc 2e61c391 sha1 89695361ccbca372662f6634678a40ea676076a7 ) ) -game ( - name "Gods of the Universe (World) (Aftermarket) (Unl)" - description "Gods of the Universe (World) (Aftermarket) (Unl)" - rom ( name "Gods of the Universe (World) (Aftermarket) (Unl).gbc" size 262144 crc 27b87354 sha1 74eb8cd698097290b93fb08d9b19486d05411877 ) -) - game ( name "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" description "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" @@ -38720,12 +39398,6 @@ game ( rom ( name "Goraku Ou Tango! (Japan) (GB Compatible).gbc" size 1048576 crc 81fb43e1 sha1 1d49232763c1422a00cbb893d0f900c44a2ccf54 ) ) -game ( - name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" - description "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ab10cec6 sha1 9dcaa6824fab806683737bdf1c76609c68c451a5 ) -) - game ( name "Grand Casino (Japan) (Proto)" description "Grand Casino (Japan) (Proto)" @@ -38774,24 +39446,6 @@ game ( rom ( name "Granduel - Shinki Dungeon no Hihou (Japan) (Sample).gbc" size 2097152 crc 7122136d sha1 534fc9ae5800eb935460f145e1bbc57f77ab2555 ) ) -game ( - name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a5ad3c0b sha1 1cf0cf6d1da5c5337856ecc0a60d2e9fb3c98f58 ) -) - -game ( - name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" - description "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b29fc03f sha1 2f979202a4bf4f98f3026a7548a8b6c7008806bf ) -) - -game ( - name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" - description "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a0e998e1 sha1 ab656383e9aaaa2991aa344bdc8f21370f0eda36 ) -) - game ( name "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" description "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" @@ -38828,54 +39482,6 @@ game ( rom ( name "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta).gbc" size 1048576 crc c38d52e7 sha1 675623b58fa0d307355c77d7a4783af7927681e9 ) ) -game ( - name "Grimace's Birthday (World) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (Aftermarket) (Unl).gbc" size 1048576 crc 7f4386e9 sha1 d6358d100ea65d34d95588f800635b64927baf82 ) -) - -game ( - name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl).gbc" size 1048576 crc 7744f551 sha1 035b7417e03c4e264a90212f2a3811012f03c2a2 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl).gbc" size 1048576 crc 9dee42fe sha1 071fa179df96950c3c92b0abbe32092b1816ec40 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc 9baa5f46 sha1 d247c03119ac14f97fdeeaa6bf0defa98e35fa17 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc ab41a9ef sha1 d8e727745e285f5e467f5eccbfd30ee175bafc2e flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl).gbc" size 1048576 crc f8e8e1f3 sha1 a3fdfe3981e800fa7c73ff989bc06426f668c331 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl).gbc" size 1048576 crc a7b59d7b sha1 295fdc3218d1699dea6d5832d068b721fccf9bd4 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc f3879ef0 sha1 27d7ee2f31bf575185711217c3cc9e08cbc5928a flags verified ) -) - game ( name "Grinch (Japan)" description "Grinch (Japan)" @@ -38906,24 +39512,6 @@ game ( rom ( name "Guiwu Zhe 2 (Taiwan) (Unl).gbc" size 2097152 crc 955bc6ad sha1 5fe41ac064f4b4d4476ef4177a2f4d69fae1a933 ) ) -game ( - name "Gun Law (World) (Aftermarket) (Unl)" - description "Gun Law (World) (Aftermarket) (Unl)" - rom ( name "Gun Law (World) (Aftermarket) (Unl).gbc" size 262144 crc 3a0b6823 sha1 c49f7e0a5055f836528a7bc0cb6f45f221c76475 ) -) - -game ( - name "Gunslinger (World) (Aftermarket) (Unl)" - description "Gunslinger (World) (Aftermarket) (Unl)" - rom ( name "Gunslinger (World) (Aftermarket) (Unl).gbc" size 262144 crc 0dfd765f sha1 8410ef1558649f9badc71629827ba1500510d221 ) -) - -game ( - name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" - description "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" - rom ( name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl).gbc" size 524288 crc 2d9b59bf sha1 d89fe1cd97d1ef2c457aa90b1c00e7b473c57270 ) -) - game ( name "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" description "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" @@ -38942,12 +39530,6 @@ game ( rom ( name "Gute Zeiten Schlechte Zeiten Quiz (Germany) (GB Compatible).gbc" size 1048576 crc 5f13a2d4 sha1 611d8ab71bdeb6b0fd292118676e85e940d11bd4 ) ) -game ( - name "Guzzler (World) (Aftermarket) (Unl)" - description "Guzzler (World) (Aftermarket) (Unl)" - rom ( name "Guzzler (World) (Aftermarket) (Unl).gbc" size 524288 crc 3684abd0 sha1 e36cd02fe2b697901843c4cbf6d83da8a9b7b923 ) -) - game ( name "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" description "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" @@ -38978,12 +39560,6 @@ game ( rom ( name "Halloween Racer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 70f3b431 sha1 15bf27a7847817fbbb9cb7729b8046a6d70164c5 ) ) -game ( - name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" - description "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c7297c31 sha1 c38cc0e80a2e04693e3a86574c03f23f3e472c88 flags verified ) -) - game ( name "Hamster Club (Japan) (GB Compatible)" description "Hamster Club (Japan) (GB Compatible)" @@ -39098,12 +39674,6 @@ game ( rom ( name "Hang Time Basketball (Europe) (Unl).gbc" size 262144 crc 3207b7d9 sha1 340201c045c020be6de3504fdecbce1ff07a2139 ) ) -game ( - name "Harbour Attack (World) (Aftermarket) (Unl)" - description "Harbour Attack (World) (Aftermarket) (Unl)" - rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc 7455782e sha1 1d0b3779007ba8f34e11b189552955dbf5c75a28 ) -) - game ( name "Harley-Davidson Motor Cycles - Race Across America (USA)" description "Harley-Davidson Motor Cycles - Race Across America (USA)" @@ -39200,30 +39770,6 @@ game ( rom ( name "Harvest Moon GBC (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ab5738a1 sha1 d407b9c20c5381f46ec460858539a5b6f559e04f ) ) -game ( - name "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" - description "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Haunted (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 4b3670bd sha1 f245b8e21716a400769488b852f15d276f3549a6 ) -) - -game ( - name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" - description "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 287afc75 sha1 42ccc76883c041bc5c6c25a2e61ccc939c14811f ) -) - -game ( - name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6e484d6a sha1 7282ef5cc2354345c8832b4dde66a559de74f73f ) -) - -game ( - name "Heebie Jeebies (World) (Aftermarket) (Unl)" - description "Heebie Jeebies (World) (Aftermarket) (Unl)" - rom ( name "Heebie Jeebies (World) (Aftermarket) (Unl).gbc" size 262144 crc 73762d53 sha1 d427f18cb854e1387d93c19b88cb7193975e6472 ) -) - game ( name "Hejin Zhuangbei II (Taiwan) (Unl)" description "Hejin Zhuangbei II (Taiwan) (Unl)" @@ -39320,31 +39866,6 @@ game ( rom ( name "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 84084e5f sha1 bb00ff88af717b45e08ef421ac77e0546870b1f4 flags verified ) ) -game ( - name "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl)" - description "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6f430dda sha1 e0cfe038063b1cd601a5f1b5af047efc705a7aaa ) -) - -game ( - name "High Noon (World) (Aftermarket) (Unl)" - description "High Noon (World) (Aftermarket) (Unl)" - rom ( name "High Noon (World) (Aftermarket) (Unl).gbc" size 262144 crc 1d00e48d sha1 21d5e871ed009a674659344d3d768fb2389c0d04 ) -) - -game ( - name "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" - description "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" - rom ( name "Hime's Quest (World) (Digital) (Aftermarket) (Unl).gbc" size 2097152 crc de5c21c2 sha1 7b6672c46c23aaa282bd4fded0713c6dfae2eb66 ) -) - -game ( - name "Hime's Quest (World) (Cart) (Aftermarket) (Unl)" - description "Hime's Quest (World) (Cart) (Aftermarket) (Unl)" - rom ( name "Hime's Quest (World) (Cart) (Aftermarket) (Unl).gbc" size 2097152 crc 546f578a sha1 ff90ca3ec7fb5d02865ae3cfd807ad3541dd21fc ) - rom ( name "Hime's Quest (World) (Cart) (Aftermarket) (Unl) (Factory Save).sav" size 32768 crc d5ed60c7 sha1 8d6c2e9da87837ba16bbd07247a91a0c3050d2fe ) -) - game ( name "Hiryuu no Ken - Retsuden GB (Japan)" description "Hiryuu no Ken - Retsuden GB (Japan)" @@ -39405,12 +39926,6 @@ game ( rom ( name "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 8ed4bbba sha1 222487f14aaaa8f0bb536a09238e63ac95636208 ) ) -game ( - name "Host, The (World) (Aftermarket) (Unl)" - description "Host, The (World) (Aftermarket) (Unl)" - rom ( name "Host, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 5f783000 sha1 05cc1f1e52167c6985ebb0a3e67af1fc2fbff93c ) -) - game ( name "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" description "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" @@ -39429,12 +39944,6 @@ game ( rom ( name "Hoyle Casino (USA).gbc" size 1048576 crc 413473b0 sha1 827efa6d7b56e919b95ae52c451be2a40d870822 ) ) -game ( - name "Hugo (World) (Aftermarket) (Unl)" - description "Hugo (World) (Aftermarket) (Unl)" - rom ( name "Hugo (World) (Aftermarket) (Unl).gbc" size 524288 crc 6581c78a sha1 390d2665f34ceaa5e34cc9f8f7c26d9e7583a92b ) -) - game ( name "Hugo - Black Diamond Fever (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" description "Hugo - Black Diamond Fever (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" @@ -39507,12 +40016,6 @@ game ( rom ( name "Indiana Jones and the Infernal Machine (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 7fff1142 sha1 6d568438aa3b9b67c55aded582cec136b15c46d7 flags verified ) ) -game ( - name "Infall (World) (Aftermarket) (Unl)" - description "Infall (World) (Aftermarket) (Unl)" - rom ( name "Infall (World) (Aftermarket) (Unl).gbc" size 131072 crc d9d90319 sha1 aafaf33fa43c7f0fd65cc8af03a42df25361fc74 ) -) - game ( name "Infinity (USA) (Proto) (2001-03-22)" description "Infinity (USA) (Proto) (2001-03-22)" @@ -39537,12 +40040,6 @@ game ( rom ( name "Inspector Gadget - Operation Madkactus (USA).gbc" size 1048576 crc 1af0b489 sha1 b0fa81a35e605948df3b7f1fcb5893bab99d9d6a ) ) -game ( - name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fea1cdb9 sha1 ac10ca63f15ca78af9f7d0eabb85eef8733aef50 ) -) - game ( name "International Karate 2000 (Europe)" description "International Karate 2000 (Europe)" @@ -39597,12 +40094,6 @@ game ( rom ( name "International Track & Field - Summer Games (Europe).gbc" size 1048576 crc d826c75f sha1 53e158cb23fa79026345dae775d9f020218f8bb2 ) ) -game ( - name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d6c1c1ac sha1 d722e95155455cf146a97222ccbc2237bea86509 ) -) - game ( name "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" description "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" @@ -39669,12 +40160,6 @@ game ( rom ( name "Jay und die Spielzeugdiebe (Germany).gbc" size 1048576 crc 73f4f6da sha1 dd01d68bab2d3615f173e4c9c94da56248fab580 ) ) -game ( - name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" - description "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9e97ac30 sha1 c07237d0f9c13b36ac2fcc5324b6e81122b0e189 ) -) - game ( name "Jeff Gordon XS Racing (USA) (GB Compatible)" description "Jeff Gordon XS Racing (USA) (GB Compatible)" @@ -39699,12 +40184,6 @@ game ( rom ( name "Jet de Go! - Let's Go by Airliner (Japan).gbc" size 2097152 crc 20c4ccf6 sha1 97bf75afa0089ddb342ea7046b7cd113ba2c6fec ) ) -game ( - name "Jet Set Willy (World) (Aftermarket) (Unl)" - description "Jet Set Willy (World) (Aftermarket) (Unl)" - rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gbc" size 262144 crc 659295ee sha1 bcb5a0e4566572aeb6cddea0897903ba207dc54f ) -) - game ( name "Jibaku-kun - Rei no Itsuki no Kajitsu (Japan) (Proto)" description "Jibaku-kun - Rei no Itsuki no Kajitsu (Japan) (Proto)" @@ -39807,18 +40286,6 @@ game ( rom ( name "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 9fa5cdb5 sha1 a332817b9561dcab7d1f3dc0cf300e1656b253c3 ) ) -game ( - name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8884d532 sha1 a41195443613fb4414d8536b1f3494677f6f253d ) -) - -game ( - name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" - description "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 570a8043 sha1 1ccbf555412a417135acea0b7b185a7f795a89da ) -) - game ( name "Juedui Wuli (Taiwan) (Unl)" description "Juedui Wuli (Taiwan) (Unl)" @@ -40041,12 +40508,6 @@ game ( rom ( name "Ken Griffey Jr.'s Slugfest (USA).gbc" size 1048576 crc 1e64d19c sha1 2362bdd8c26f30adb871259ce2d909ac6d505e36 ) ) -game ( - name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6a5abba1 sha1 0b3deef7a27201e81b4d39bc0bd10ff7ec73e380 ) -) - game ( name "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced) (GB Compatible)" description "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced) (GB Compatible)" @@ -40065,12 +40526,6 @@ game ( rom ( name "Kikansha Thomas - Sodor-tou no Nakama-tachi (Japan).gbc" size 1048576 crc 223bb19c sha1 8abd4406ec19bfecd6d675285fa73ef2d5ea622e ) ) -game ( - name "Kikstart (World) (Aftermarket) (Unl)" - description "Kikstart (World) (Aftermarket) (Unl)" - rom ( name "Kikstart (World) (Aftermarket) (Unl).gbc" size 524288 crc 9a9f483b sha1 bc472506f73f0c1a3f0a610c0136b324b7635c7f ) -) - game ( name "Kindaichi Shounen no Jikenbo - 10 Nenme no Shoutaijou (Japan) (SGB Enhanced) (GB Compatible)" description "Kindaichi Shounen no Jikenbo - 10 Nenme no Shoutaijou (Japan) (SGB Enhanced) (GB Compatible)" @@ -40167,12 +40622,6 @@ game ( rom ( name "Klustar (Japan) (Proto 1) (1998-10-01) (GB Compatible).gbc" size 131072 crc f9c6e0a5 sha1 4990b427f1b85ceca9646b3edfa921ed160a55a9 ) ) -game ( - name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f19d5e86 sha1 0f0e01a143182a9784c80a882ac206d02d8679d7 ) -) - game ( name "Knockout Kings (USA, Europe)" description "Knockout Kings (USA, Europe)" @@ -40257,6 +40706,12 @@ game ( rom ( name "Koto Battle - Tengai no Moribito (Japan).gbc" size 2097152 crc 430eb1e1 sha1 ac30025352026b34a0d9ccede82862f6e04aaf00 ) ) +game ( + name "Koudai Guaishou - Da Jihe (Taiwan) (Ja) (Pirate)" + description "Koudai Guaishou - Da Jihe (Taiwan) (Ja) (Pirate)" + rom ( name "Koudai Guaishou - Da Jihe (Taiwan) (Ja) (Pirate).gbc" size 2097152 crc a96e26c4 sha1 69d345f0da430d0b1c5f4edd086f244ddcf49c78 ) +) + game ( name "Koudai Guaishou - Dongzuo Pian (Taiwan) (En) (Unl)" description "Koudai Guaishou - Dongzuo Pian (Taiwan) (En) (Unl)" @@ -40330,27 +40785,15 @@ game ( ) game ( - name "Laser Squad Alter (World) (Aftermarket) (Unl)" - description "Laser Squad Alter (World) (Aftermarket) (Unl)" - rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gbc" size 1048576 crc 32f24248 sha1 26f4efe636214e72ec724f8887ca79fbc8abad80 ) + name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" + description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" + rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta).gbc" size 1048576 crc f90a3dae sha1 772539821e4b703259b2e2ad535d74a03fa22760 ) ) game ( - name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4a58315b sha1 5a234e33f7429b48f4374b5989e6df4d20352b4c ) -) - -game ( - name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5c405584 sha1 3ee043ba17f46a6afbbba8ac05f35d093b817fbc ) -) - -game ( - name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9a134100 sha1 75b5188a5b8a720ff08894379147c7870ac8825d ) + name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" + description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" + rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto).gbc" size 1048576 crc cf8e2371 sha1 f7b19c1501d325dd8ee219ccae2eaca130a5a21b ) ) game ( @@ -40365,42 +40808,12 @@ game ( rom ( name "Laura (USA).gbc" size 1048576 crc e2bff286 sha1 3fe3eb99ee818c94e9a07e19640af6a2aad33903 ) ) -game ( - name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" - description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" - rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta).gbc" size 1048576 crc f90a3dae sha1 772539821e4b703259b2e2ad535d74a03fa22760 ) -) - -game ( - name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" - description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" - rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto).gbc" size 1048576 crc cf8e2371 sha1 f7b19c1501d325dd8ee219ccae2eaca130a5a21b ) -) - game ( name "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It)" description "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It)" rom ( name "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 1b49d07d sha1 cb4847cd63c8cc52f04bf4d86d54954be3d8fc1a ) ) -game ( - name "Leaper (World) (Aftermarket) (Unl)" - description "Leaper (World) (Aftermarket) (Unl)" - rom ( name "Leaper (World) (Aftermarket) (Unl).gbc" size 524288 crc ed8cd385 sha1 425db2916263121f4aee91a8cab6286e39364f87 ) -) - -game ( - name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 953e25d1 sha1 018c7cada41e693a02b9c596d307b0aa9207eef4 ) -) - -game ( - name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1096252a sha1 c22cc79b25a05afad66e769dc0365b7c25f1bb85 ) -) - game ( name "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" description "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" @@ -40434,7 +40847,7 @@ game ( game ( name "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced) (GB Compatible)" description "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced) (GB Compatible)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f48824fe sha1 9a679e30b03e119a21ae7daac65e73e0ef4e0894 ) + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f48824fe sha1 9a679e30b03e119a21ae7daac65e73e0ef4e0894 flags verified ) ) game ( @@ -40480,9 +40893,9 @@ game ( ) game ( - name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" - description "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc 8afd751e sha1 797925a26eb39656aea60e10c8e9dd986b515b53 ) + name "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc 8afd751e sha1 797925a26eb39656aea60e10c8e9dd986b515b53 ) ) game ( @@ -40641,24 +41054,6 @@ game ( rom ( name "Lemmings VS (Japan).gbc" size 4194304 crc 947d45ae sha1 2ebb428a53acbcbc215f37bb263e44d94f547473 ) ) -game ( - name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" - description "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a91a698f sha1 26f38b3908c086b3e349324da32bc37213975030 ) -) - -game ( - name "Liberator (World) (Aftermarket) (Unl)" - description "Liberator (World) (Aftermarket) (Unl)" - rom ( name "Liberator (World) (Aftermarket) (Unl).gbc" size 262144 crc ebe70d3d sha1 e3afce5a2357732ed15d7f3c0900f7b48113efdc ) -) - -game ( - name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" - description "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b8dd8409 sha1 281abb583ec0039e2c981c2e95f7a92002da081b ) -) - game ( name "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" description "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" @@ -40707,12 +41102,6 @@ game ( rom ( name "LNF Stars 2001 (France).gbc" size 1048576 crc f8bf3ee7 sha1 07a0e1c0ddde6371dbaf25fd016bdc77c0eca090 ) ) -game ( - name "Loco-coco (World) (Aftermarket) (Unl)" - description "Loco-coco (World) (Aftermarket) (Unl)" - rom ( name "Loco-coco (World) (Aftermarket) (Unl).gbc" size 262144 crc f6b9fe4e sha1 8a8972ff3e208280a746a2015a20f67248180a1c ) -) - game ( name "Lode Runner - Domudomu Dan no Yabou (Japan) (GB Compatible)" description "Lode Runner - Domudomu Dan no Yabou (Japan) (GB Compatible)" @@ -40953,24 +41342,18 @@ game ( rom ( name "Luke Yingxiong 2 - Zook Hero 2 (Taiwan) (Unl).gbc" size 524288 crc 59822b31 sha1 4bf85d9641e3b842a917474dcb49a8b7f282711b ) ) +game ( + name "Luke Yingxiong Chuan 3 (Taiwan) (Unl)" + description "Luke Yingxiong Chuan 3 (Taiwan) (Unl)" + rom ( name "Luke Yingxiong Chuan 3 (Taiwan) (Unl).gbc" size 4194304 crc bd0e7c73 sha1 a095388a2ba13f0f846bbf4ee86ef25e49327c67 ) +) + game ( name "Luke Yingxiong Z (Taiwan) (Unl)" description "Luke Yingxiong Z (Taiwan) (Unl)" rom ( name "Luke Yingxiong Z (Taiwan) (Unl).gbc" size 1048576 crc 8ced0c21 sha1 271097c99be5f60fbdb561875d006a622093fe70 ) ) -game ( - name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" - description "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" - rom ( name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl).gbc" size 262144 crc 9edd066c sha1 4d43a38e8b5df41309f5b6ec13e4829db739d980 ) -) - -game ( - name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" - description "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" - rom ( name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl).gbc" size 262144 crc de5d5c0b sha1 5f038ef3657d3fbfb3be6917b24c3f933363ad4c ) -) - game ( name "Luoke Yingxiong EXE5 (Taiwan) (Unl)" description "Luoke Yingxiong EXE5 (Taiwan) (Unl)" @@ -41001,18 +41384,6 @@ game ( rom ( name "M&M's Minis Madness (USA) (Sample).gbc" size 1048576 crc 83293b1b sha1 2a0d0b7aa3b96b05bc020da496f2ce08e8fac190 ) ) -game ( - name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f55a9d95 sha1 2b22fbd76e11e6e45053b1e6989de303e3033c9e ) -) - -game ( - name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5662865e sha1 a5ac99a4087bd5ea45417e5b4a7c9af10433911a ) -) - game ( name "Macross 7 - Ginga no Heart o Furuwasero!! (Japan)" description "Macross 7 - Ginga no Heart o Furuwasero!! (Japan)" @@ -41055,12 +41426,6 @@ game ( rom ( name "Magi-Nation - Keeper's Quest (USA) (Proto).gbc" size 1048576 crc 89de57b7 sha1 7c6b427810be2f0d7496ccb5eff2226d3ed1194e ) ) -game ( - name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" - description "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c276843d sha1 852697a2952d2e7375b73aba877ebc17aa4f4179 ) -) - game ( name "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" description "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" @@ -41070,7 +41435,7 @@ game ( game ( name "Magical Drop (Europe) (En,Fr,De)" description "Magical Drop (Europe) (En,Fr,De)" - rom ( name "Magical Drop (Europe) (En,Fr,De).gbc" size 1048576 crc ea9ee203 sha1 8ef276f9c6a64d7cec527bcba8d1b7223de0e01c ) + rom ( name "Magical Drop (Europe) (En,Fr,De).gbc" size 1048576 crc ea9ee203 sha1 8ef276f9c6a64d7cec527bcba8d1b7223de0e01c flags verified ) ) game ( @@ -41103,12 +41468,6 @@ game ( rom ( name "Magical Tetris Challenge (USA).gbc" size 1048576 crc f53cf66c sha1 7cdb0bf463ad87ec8a68a564c3f03dbc890edd7e ) ) -game ( - name "Magician's Curse, The (World) (Aftermarket) (Unl)" - description "Magician's Curse, The (World) (Aftermarket) (Unl)" - rom ( name "Magician's Curse, The (World) (Aftermarket) (Unl).gbc" size 524288 crc f2b1967e sha1 3b5f97f9a0b4d63a3795695b0bda6e969de8e051 ) -) - game ( name "Mahjong Joou (Japan) (SGB Enhanced) (GB Compatible)" description "Mahjong Joou (Japan) (SGB Enhanced) (GB Compatible)" @@ -41289,12 +41648,6 @@ game ( rom ( name "Maya the Bee & Her Friends (Europe) (En,Fr,De) (GB Compatible).gbc" size 1048576 crc 983b1d26 sha1 522d7f33fd39bd00f48208743fb2246ef0bd3ff1 ) ) -game ( - name "Mayhem (World) (Aftermarket) (Unl)" - description "Mayhem (World) (Aftermarket) (Unl)" - rom ( name "Mayhem (World) (Aftermarket) (Unl).gbc" size 262144 crc 4d739ad7 sha1 9f141728a74432820f47cc24d230dc56d6ac099b ) -) - game ( name "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan)" description "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan)" @@ -41427,28 +41780,10 @@ game ( rom ( name "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc cabdd802 sha1 0858a619d716b0191713734d506d9f113f0d1c62 ) ) -game ( - name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" - description "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f614bdff sha1 7e46c193f6566f620acf20ead3a1fca1d677c221 ) -) - -game ( - name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 949c6ab9 sha1 34269af4db6c37b92fdc7f7f914c282174603ba8 ) -) - -game ( - name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 50618f4b sha1 c8d74af4746313800df3a23c1ad01f931e0e2eca flags verified ) -) - game ( name "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible)" description "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible)" - rom ( name "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 65b8b343 sha1 7ceb1c82bdd185546c3dd5d2653788d74d811f7a ) + rom ( name "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 65b8b343 sha1 7ceb1c82bdd185546c3dd5d2653788d74d811f7a flags verified ) ) game ( @@ -41511,12 +41846,6 @@ game ( rom ( name "Metamode (Japan).gbc" size 2097152 crc a76eed5b sha1 1c1d74c810b90cf4d2ee32859eaea569a5b45c3f ) ) -game ( - name "Meteorite (World) (Aftermarket) (Unl)" - description "Meteorite (World) (Aftermarket) (Unl)" - rom ( name "Meteorite (World) (Aftermarket) (Unl).gbc" size 131072 crc fafbcebf sha1 25a81d916f1ed80a2bca2fe7a555433f06d025e3 ) -) - game ( name "Mia Hamm Soccer Shootout (USA)" description "Mia Hamm Soccer Shootout (USA)" @@ -41595,18 +41924,6 @@ game ( rom ( name "Microsoft Pinball Arcade (Europe).gbc" size 1048576 crc 4eb7db14 sha1 f2874f0f3023d96edbdb94e5c0dc181d8baa3efb flags verified ) ) -game ( - name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" - description "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f9a5ed4e sha1 8b3e18287d5adf3b5a711e28a896f843927f22a2 ) -) - -game ( - name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" - description "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 177f0b6e sha1 e5fdb741d870de25affdc841c07eaa3000da25f5 ) -) - game ( name "Midway Presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" description "Midway Presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" @@ -41655,12 +41972,6 @@ game ( rom ( name "Minnie & Friends - Yume no Kuni o Sagashite (Japan).gbc" size 2097152 crc d47ae577 sha1 146f336d16d165590d09f41f44ba52a81816a033 flags verified ) ) -game ( - name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 854f4297 sha1 a1a44ce8052f06349df3cbdf9a6d976609213d68 ) -) - game ( name "Missile Command (Europe)" description "Missile Command (Europe)" @@ -41670,7 +41981,7 @@ game ( game ( name "Missile Command (USA) (Rumble Version)" description "Missile Command (USA) (Rumble Version)" - rom ( name "Missile Command (USA) (Rumble Version).gbc" size 1048576 crc 47543c51 sha1 7bd68586df8754cbc81b2dcbb6e2b5de43f812e8 ) + rom ( name "Missile Command (USA) (Rumble Version).gbc" size 1048576 crc 47543c51 sha1 7bd68586df8754cbc81b2dcbb6e2b5de43f812e8 flags verified ) ) game ( @@ -41697,12 +42008,6 @@ game ( rom ( name "Mission Bravo (USA) (Proto).gbc" size 1048576 crc b8fc72b6 sha1 2833855bb2b9fde988f8efcac3e357ef9f0f4f50 ) ) -game ( - name "Mission Mars (World) (Aftermarket) (Unl)" - description "Mission Mars (World) (Aftermarket) (Unl)" - rom ( name "Mission Mars (World) (Aftermarket) (Unl).gbc" size 262144 crc f651fcf4 sha1 479c70dd9c63cdcad99ca44720a9e0e2582df119 ) -) - game ( name "Mizuki Shigeru no Shin Youkaiden (Japan)" description "Mizuki Shigeru no Shin Youkaiden (Japan)" @@ -41745,18 +42050,6 @@ game ( rom ( name "Momotarou Densetsu 1-2 (Japan).gbc" size 2097152 crc da7fb08f sha1 acffa3417c85be574aa28432e29e1d40f28a565b flags verified ) ) -game ( - name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - description "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 39480c79 sha1 4348a7903e538e5367f2a60718f43cbeeccf96df ) -) - -game ( - name "Monkey Magic (World) (Aftermarket) (Unl)" - description "Monkey Magic (World) (Aftermarket) (Unl)" - rom ( name "Monkey Magic (World) (Aftermarket) (Unl).gbc" size 262144 crc c9c68715 sha1 bf5dc5593334fe1114461065a2b7284d28b31462 ) -) - game ( name "Monkey Puncher (Europe) (SGB Enhanced) (GB Compatible)" description "Monkey Puncher (Europe) (SGB Enhanced) (GB Compatible)" @@ -41859,12 +42152,6 @@ game ( rom ( name "Montezuma's Return! (USA) (En,Es) (GB Compatible).gbc" size 524288 crc de04772f sha1 616bb04e0254ef2ba9e1ea629493efdcc37d807c ) ) -game ( - name "Monty on the Run (World) (Aftermarket) (Unl)" - description "Monty on the Run (World) (Aftermarket) (Unl)" - rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gbc" size 524288 crc fd1066ac sha1 8390175e6be4731d9afa91715d7f8dd11693bb69 ) -) - game ( name "Moomin no Daibouken (Japan) (Beta)" description "Moomin no Daibouken (Japan) (Beta)" @@ -41919,18 +42206,6 @@ game ( rom ( name "Motocross Maniacs 2 (USA).gbc" size 1048576 crc 17d27fa9 sha1 5a0e7a9a71a88ee79529531274eb3696cf0fa42c ) ) -game ( - name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - description "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 362a84ba sha1 b4b3afa2379a07acab6965ae8fcf6d2ba82d6d7e ) -) - -game ( - name "Mr. Angry (World) (Aftermarket) (Unl)" - description "Mr. Angry (World) (Aftermarket) (Unl)" - rom ( name "Mr. Angry (World) (Aftermarket) (Unl).gbc" size 524288 crc b85e63a5 sha1 127ad5315e2bce37614a1e9f8605798e68718926 ) -) - game ( name "Mr. Driller (Europe)" description "Mr. Driller (Europe)" @@ -41970,7 +42245,7 @@ game ( game ( name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible)" description "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible)" - rom ( name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc 103e212d sha1 a468f7ad011c1b42ea3144e65607694493e7e4a7 ) + rom ( name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc 103e212d sha1 a468f7ad011c1b42ea3144e65607694493e7e4a7 flags verified ) ) game ( @@ -42003,12 +42278,6 @@ game ( rom ( name "Muchang Wuyu GB 6 (Taiwan) (Unl).gbc" size 2097152 crc 416e6efa sha1 86b2de0fc2806f3d13145e2c0296389ec0897a6a ) ) -game ( - name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" - description "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 846afc79 sha1 dae84fbc60839da29878714cd845c3704b915323 ) -) - game ( name "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" description "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" @@ -42033,36 +42302,12 @@ game ( rom ( name "Mummy, The (USA).gbc" size 1048576 crc c6ba9f27 sha1 35b10f392d514bce858c8c64f9c489500466d0ff ) ) -game ( - name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" - description "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" - rom ( name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl).gbc" size 524288 crc ec4f9d49 sha1 357db81755f1f0eb732367dd4090c446eb226ddf ) -) - -game ( - name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" - description "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" - rom ( name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl).gbc" size 524288 crc 1ba7d27f sha1 d4c4be65ba469369cd90aaa733d0a8e8af6bcdc1 ) -) - game ( name "Muteki Ou Tri-Zenon (Japan)" description "Muteki Ou Tri-Zenon (Japan)" rom ( name "Muteki Ou Tri-Zenon (Japan).gbc" size 2097152 crc 0bab7a61 sha1 2a7f422bf9af9aff126e47ede8b5ceec0630eb08 ) ) -game ( - name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - description "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9bff7b15 sha1 1f3aac8a3725cd1d0968529afc1c2031372d8ed1 ) -) - -game ( - name "My Friendly Little Island (World) (Aftermarket) (Unl)" - description "My Friendly Little Island (World) (Aftermarket) (Unl)" - rom ( name "My Friendly Little Island (World) (Aftermarket) (Unl).gbc" size 1048576 crc f6bf0584 sha1 81d724ad696084283712145adfef15769648b045 ) -) - game ( name "Mythri (USA) (Proto 1) (2000-08-02)" description "Mythri (USA) (Proto 1) (2000-08-02)" @@ -42156,7 +42401,7 @@ game ( game ( name "NASCAR 2000 (USA, Europe)" description "NASCAR 2000 (USA, Europe)" - rom ( name "NASCAR 2000 (USA, Europe).gbc" size 1048576 crc 54d90a4c sha1 37d3ffb5ae9bcf4c1cab7cece0a19d6b0b45c3a2 ) + rom ( name "NASCAR 2000 (USA, Europe).gbc" size 1048576 crc 54d90a4c sha1 37d3ffb5ae9bcf4c1cab7cece0a19d6b0b45c3a2 flags verified ) ) game ( @@ -42225,6 +42470,24 @@ game ( rom ( name "NBA Jam 2001 (USA, Europe).gbc" size 1048576 crc 3aa75f1c sha1 b1f7230dcccaecb7ae9b2a0e786effac2fc24497 flags verified ) ) +game ( + name "NBA Jam 2001 (USA, Europe) (Beta) (2000-02-07)" + description "NBA Jam 2001 (USA, Europe) (Beta) (2000-02-07)" + rom ( name "NBA Jam 2001 (USA, Europe) (Beta) (2000-02-07).gbc" size 131072 crc 594ee678 sha1 5d8ae5937a374fe4e36fe5303e3ad3757ee9675c ) +) + +game ( + name "NBA Jam 2001 (USA, Europe) (Beta) (2000-05-05)" + description "NBA Jam 2001 (USA, Europe) (Beta) (2000-05-05)" + rom ( name "NBA Jam 2001 (USA, Europe) (Beta) (2000-05-05).gbc" size 1048576 crc 926b47d1 sha1 ddbb720be9dd573728f897abe77569d42dae7baf ) +) + +game ( + name "NBA Jam 2001 (USA, Europe) (Beta) (2000-09-26)" + description "NBA Jam 2001 (USA, Europe) (Beta) (2000-09-26)" + rom ( name "NBA Jam 2001 (USA, Europe) (Beta) (2000-09-26).gbc" size 1048576 crc 0d5506ae sha1 2859d6ad2af7ff3333ad0d3750a1fd4b3088d47d ) +) + game ( name "NBA Jam 99 (USA, Europe) (GB Compatible)" description "NBA Jam 99 (USA, Europe) (GB Compatible)" @@ -42249,24 +42512,6 @@ game ( rom ( name "NBA Show Time - NBA on NBC (USA) (Rev 1) (Proto).gbc" size 1048576 crc 8bc9be45 sha1 fd4bb16f306e309834e276ed768e8e2ed402e138 ) ) -game ( - name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" - description "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc eedefa0c sha1 e63c16fe987fe655408be66198366a0147ac607c ) -) - -game ( - name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 53cf930c sha1 bd3272ca7ead64da3f68f774661a560add433b94 ) -) - -game ( - name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" - description "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 705b150f sha1 6258cf6ad167c9ae86609a8e620face1674a7ea7 ) -) - game ( name "Net de Get - Minigame @ 100 (Japan)" description "Net de Get - Minigame @ 100 (Japan)" @@ -42318,7 +42563,7 @@ game ( game ( name "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible)" description "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible)" - rom ( name "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible).gbc" size 524288 crc 107d734b sha1 66b69cba0705f0670759f01cfd586a50c47c7c89 ) + rom ( name "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible).gbc" size 524288 crc 107d734b sha1 66b69cba0705f0670759f01cfd586a50c47c7c89 flags verified ) ) game ( @@ -42363,12 +42608,6 @@ game ( rom ( name "Ninja JaJaMaru - The Great World Adventure DX (USA, Europe) (Ninja JaJaMaru Retro Collection) (Switch).gbc" size 262144 crc b5af4ca5 sha1 73efaca14c998dd6790e08f2ce2b6f73e7909ce4 flags verified ) ) -game ( - name "Ninja Master (World) (Aftermarket) (Unl)" - description "Ninja Master (World) (Aftermarket) (Unl)" - rom ( name "Ninja Master (World) (Aftermarket) (Unl).gbc" size 262144 crc bc550b84 sha1 0def135723ac40e4981c88f8888afbd40a15bb40 ) -) - game ( name "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" description "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" @@ -42405,12 +42644,6 @@ game ( rom ( name "NSYNC - Get to the Show (USA).gbc" size 1048576 crc f770878b sha1 23b031d03a139c4d963099070b0b290f5f806a6d ) ) -game ( - name "Number Builder (World) (Aftermarket) (Unl)" - description "Number Builder (World) (Aftermarket) (Unl)" - rom ( name "Number Builder (World) (Aftermarket) (Unl).gbc" size 262144 crc b8609d43 sha1 92952b752f50af889db891acc9eed8436ac6b87e ) -) - game ( name "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" description "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" @@ -42423,66 +42656,6 @@ game ( rom ( name "Nv Wang Gedou 2000 (Taiwan) (Unl).gbc" size 2097152 crc e1668b49 sha1 37516139aa317a16440379c1dc00bdfc4c1e607a flags verified ) ) -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e983e8d1 sha1 fc2a58d49327c88c895ae6681bde57e1a2687974 flags verified ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc ef42955e sha1 485b4d672d9edda40f9191f5f5cc223046000e67 flags verified ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 581efe4d sha1 125bb0564ee17f8e55046a1c25e53ee9a4254303 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e26ddbbb sha1 853115369b8ca583d038d00c1dde59b6a74b73a2 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 1e8ac5b9 sha1 99c11bef7feb17a9e7212cf9b6593478f671bc32 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f5df28c2 sha1 7b511444e1eb86fffcf93599a78e0e2c44aecc8a ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl).gbc" size 2097152 crc 63bddc68 sha1 fab777e607bd8aba70eb65829143039dbe6ac08e ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 1f1af42a sha1 ddcdbfa716d716e1b7bb258caaaa7b76d041b5a9 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" - description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt).gbc" size 524288 crc 834a8021 sha1 d5af2bf38eda4c181993e992764788003509ebfd ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 42d9c38c sha1 ae719190cf2f433c359bc425775710f4aa67e860 ) -) - game ( name "NYR - New York Race (Europe) (En,Fr,De,Es,It,Pt)" description "NYR - New York Race (Europe) (En,Fr,De,Es,It,Pt)" @@ -42495,24 +42668,6 @@ game ( rom ( name "O'Leary Manager 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca).gbc" size 1048576 crc 3485761a sha1 724aa0f905d7a6e7b9b2b01a477f424ac95eadf9 ) ) -game ( - name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c055ef9 sha1 d4fa4e02753a9fe539f70d0927ba5bf9caa02d3c ) -) - -game ( - name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" - description "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7ed58128 sha1 e543c39f8e55b1788476b94028a54fc2fc9c7ea0 ) -) - -game ( - name "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible)" - description "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible)" - rom ( name "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 4b83b14f sha1 c9d4d1dd1c33a9fa9b54e9f2a7a5f6dd90069b91 flags verified ) -) - game ( name "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" description "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" @@ -42520,9 +42675,9 @@ game ( ) game ( - name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" - description "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9742276d sha1 cd8f18d6e5fabaa130a42e5618e29c5ff26f6a93 ) + name "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 4b83b14f sha1 c9d4d1dd1c33a9fa9b54e9f2a7a5f6dd90069b91 flags verified ) ) game ( @@ -42555,24 +42710,6 @@ game ( rom ( name "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan) (GB Compatible).gbc" size 2097152 crc ed7461d2 sha1 66d87a06d4d951e7695df73f53793a462509e4d0 ) ) -game ( - name "Olympic Skier (World) (Aftermarket) (Unl)" - description "Olympic Skier (World) (Aftermarket) (Unl)" - rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gbc" size 524288 crc 5e81cef7 sha1 a7a552a9eb984098a67e063c2eca907eec000fc1 ) -) - -game ( - name "One Day (World) (GB Compatible) (Aftermarket) (Unl)" - description "One Day (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "One Day (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fd52acc7 sha1 bdb5590b61791b89e9afa871d32648d7a66ce1f4 ) -) - -game ( - name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" - description "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 7348bb32 sha1 e63e06d602473206b21138f5322acf86b5b6b9b8 ) -) - game ( name "Original Moorhuhn Jagd, Die (Germany)" description "Original Moorhuhn Jagd, Die (Germany)" @@ -42609,12 +42746,6 @@ game ( rom ( name "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2a39a874 sha1 71797aa125b88614182ce3d0f8252d6ed8cfa08e ) ) -game ( - name "Out on a Limb (World) (Aftermarket) (Unl)" - description "Out on a Limb (World) (Aftermarket) (Unl)" - rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gbc" size 262144 crc a6671528 sha1 f21cb71adcea1029151930eb98c4e9b446e4cfee ) -) - game ( name "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced) (GB Compatible)" description "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced) (GB Compatible)" @@ -42651,42 +42782,12 @@ game ( rom ( name "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1e443d1b sha1 969d5352c15e3e5daa891edcda91bd48a8380308 ) ) -game ( - name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c6e83f41 sha1 44b117d94a80617a77abbdcc76d9d69b66efe56b ) -) - -game ( - name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - description "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 69483f81 sha1 4d162c9637a20cfc7c92e6ea7a61fad0ed22137a ) -) - -game ( - name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" - description "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" - rom ( name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 262144 crc 0db301c2 sha1 58ec8f209ed6e33adfb253014ea69ae1ee53c145 ) -) - -game ( - name "Pact, The (World) (Aftermarket) (Unl)" - description "Pact, The (World) (Aftermarket) (Unl)" - rom ( name "Pact, The (World) (Aftermarket) (Unl).gbc" size 262144 crc 304df19a sha1 97af064f9063cd353e55ac0e1f6d1ca8b4a6d2b9 ) -) - game ( name "Painter (Europe) (Unl)" description "Painter (Europe) (Unl)" rom ( name "Painter (Europe) (Unl).gbc" size 262144 crc f4801f21 sha1 78db482d1d12b4556b6a5b995ce37a2435236a06 ) ) -game ( - name "Panik!16 (World) (Aftermarket) (Unl)" - description "Panik!16 (World) (Aftermarket) (Unl)" - rom ( name "Panik!16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b31122d sha1 98d74fd64e4f7e835f1101b05816b8938a34a416 ) -) - game ( name "Paperboy (USA, Europe)" description "Paperboy (USA, Europe)" @@ -42729,12 +42830,6 @@ game ( rom ( name "Peugeot - Orbital Diagnostic System (Unknown) (Alt) (Unl) [b].gbc" size 32768 crc 424912fe sha1 bd5735021e4593ec07082e6197e683496d0ecf0b flags baddump ) ) -game ( - name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" - description "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 154cb547 sha1 3b217c595e6a5b115dc7130123a321049cf01d22 ) -) - game ( name "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" description "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" @@ -42759,24 +42854,6 @@ game ( rom ( name "Piecrust (World) (Unl).gbc" size 32768 crc f39c8119 sha1 b01cad9652bf1c65151dd8d2bd21251a9cf44d43 ) ) -game ( - name "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 3c2bafdc sha1 d38f3f5e491dbaed84e88099987712449db9b33d ) -) - -game ( - name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 189aa999 sha1 2cf46a36502eaf22ac9572fe1136d369fcbe9e46 ) -) - -game ( - name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" - description "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1601d6fa sha1 87b4edf0398f0154d7556e3cd96f97b19e699a40 ) -) - game ( name "Pitfall - Beyond the Jungle (USA, Europe) (GB Compatible)" description "Pitfall - Beyond the Jungle (USA, Europe) (GB Compatible)" @@ -42807,12 +42884,6 @@ game ( rom ( name "Player Manager 2001 (Europe) (En,Fr).gbc" size 1048576 crc 375c35e0 sha1 6e21a85257361be76914f418409124c5bc315429 ) ) -game ( - name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 29415ff7 sha1 89b3fd633e8cef3b8523b1ef2a0072db2d7416d7 ) -) - game ( name "Pocket Billiards - Funk the 9 Ball (Japan)" description "Pocket Billiards - Funk the 9 Ball (Japan)" @@ -43053,12 +43124,6 @@ game ( rom ( name "Pocket Soccer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 2097152 crc e8f5824f sha1 4d06ea937a02a8f458186a9382994b09a97481a4 ) ) -game ( - name "Pogo Pete (World) (Aftermarket) (Unl)" - description "Pogo Pete (World) (Aftermarket) (Unl)" - rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gbc" size 262144 crc 3001ed1b sha1 f9dab150843c2b8f300d36b1dd53dd1a22b481a3 ) -) - game ( name "Pokemon - Crystal Version (Australia)" description "Pokemon - Crystal Version (Australia)" @@ -43113,6 +43178,18 @@ game ( rom ( name "Pokemon - Kristall-Edition (Germany).gbc" size 2097152 crc 616d85de sha1 accb584293ba056152f1fd908439b019017ff2fe ) ) +game ( + name "Pokemon - La Version Esmeralda - Special Pikachu Edition (Spain) (Pirate)" + description "Pokemon - La Version Esmeralda - Special Pikachu Edition (Spain) (Pirate)" + rom ( name "Pokemon - La Version Esmeralda - Special Pikachu Edition (Spain) (Pirate).gbc" size 524288 crc 0d009399 sha1 9e953c1acccd3527a555cf4ba25da38adf99755c ) +) + +game ( + name "Pokemon - Mewtwo Strikes Back (Taiwan) (Zh) (Unl)" + description "Pokemon - Mewtwo Strikes Back (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon - Mewtwo Strikes Back (Taiwan) (Zh) (Unl).gbc" size 524288 crc 2930fa45 sha1 382a257199720d970f58e94cd4102acb809dec07 ) +) + game ( name "Pokemon - Mewtwo Strikes Back (Taiwan) (En) (Unl)" description "Pokemon - Mewtwo Strikes Back (Taiwan) (En) (Unl)" @@ -43146,19 +43223,19 @@ game ( game ( name "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible)" description "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible)" - rom ( name "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc e0c216ea sha1 a4a7e8079b7a53e4d9ef43382bbb1090b9d45d1a ) + rom ( name "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc e0c216ea sha1 a4a7e8079b7a53e4d9ef43382bbb1090b9d45d1a flags verified ) ) game ( name "Pokemon - Version Cristal (France)" description "Pokemon - Version Cristal (France)" - rom ( name "Pokemon - Version Cristal (France).gbc" size 2097152 crc 878b2aa7 sha1 c055992b16b7399c687647725cdd1f4f13a2f75c ) + rom ( name "Pokemon - Version Cristal (France).gbc" size 2097152 crc 878b2aa7 sha1 c055992b16b7399c687647725cdd1f4f13a2f75c flags verified ) ) game ( name "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible)" description "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible)" - rom ( name "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 37a70702 sha1 c147c0d8c2b71b7628a7233436f5c052b5b17081 ) + rom ( name "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 37a70702 sha1 c147c0d8c2b71b7628a7233436f5c052b5b17081 flags verified ) ) game ( @@ -43209,6 +43286,12 @@ game ( rom ( name "Pokemon Diamond (Taiwan) (En) (Unl).gbc" size 524288 crc 1b5bef4b sha1 433e7991b706baedf59af8b91bc142ba2f72112f ) ) +game ( + name "Pokemon Diamond (Taiwan) (Zh) (Unl)" + description "Pokemon Diamond (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon Diamond (Taiwan) (Zh) (Unl).gbc" size 524288 crc 7309551a sha1 3fb38a7f49e13f5bfce0cd1983d9006b30f68930 ) +) + game ( name "Pokemon Gold (Taiwan) (En) (Unl)" description "Pokemon Gold (Taiwan) (En) (Unl)" @@ -43227,6 +43310,12 @@ game ( rom ( name "Pokemon Jade (Taiwan) (En) (Pirate).gbc" size 2097152 crc aa07f269 sha1 994a205d7c0b55f45715a65b23ec31258e43652f ) ) +game ( + name "Pokemon Jade (Taiwan) (Zh) (Unl)" + description "Pokemon Jade (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon Jade (Taiwan) (Zh) (Unl).gbc" size 524288 crc b9ffd78c sha1 c46c3a9e221da8d41a9eb1a84765368d975dfaa1 ) +) + game ( name "Pokemon Jade Version - Special Pikachu Edition (USA) (Pirate)" description "Pokemon Jade Version - Special Pikachu Edition (USA) (Pirate)" @@ -43275,6 +43364,36 @@ game ( rom ( name "Pokemon Puzzle Challenge (USA, Australia).gbc" size 2097152 crc d06bba96 sha1 bbf952412250ae511b3b862566e424ce6a672f99 flags verified ) ) +game ( + name "Pokemon Ruby (Taiwan) (Unl)" + description "Pokemon Ruby (Taiwan) (Unl)" + rom ( name "Pokemon Ruby (Taiwan) (Unl).gbc" size 524288 crc 7a2fc378 sha1 1f9e62faa85e9058bec16be8b6c14223bb3ac15b ) +) + +game ( + name "Pokemon Sapphire (Taiwan) (En) (Unl)" + description "Pokemon Sapphire (Taiwan) (En) (Unl)" + rom ( name "Pokemon Sapphire (Taiwan) (En) (Unl).gbc" size 524288 crc 8077dd95 sha1 2e3a28e02d5bfe259d9367d1205daa52912a1f8f ) +) + +game ( + name "Pokemon Sapphire (Taiwan) (Zh) (Unl)" + description "Pokemon Sapphire (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon Sapphire (Taiwan) (Zh) (Unl).gbc" size 524288 crc f3c1c00c sha1 75639d4dbe72d044002f768d5dbbd08caf003fdc ) +) + +game ( + name "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 942d0b7f sha1 dffc15f3063a4c2df84c6361406b41aec1696d3e flags verified ) +) + +game ( + name "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 3f1d7e58 sha1 c54b81e638b0c45d3569f9f5f0345df9e95ce975 ) +) + game ( name "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced) (GB Compatible)" description "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced) (GB Compatible)" @@ -43293,18 +43412,6 @@ game ( rom ( name "Pokemon Trading Card Game (USA, Australia) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 81069d53 sha1 0f8670a583255cff3e5b7ca71b5d7454d928fc48 flags verified ) ) -game ( - name "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible)" - description "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible)" - rom ( name "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 942d0b7f sha1 dffc15f3063a4c2df84c6361406b41aec1696d3e flags verified ) -) - -game ( - name "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible)" - description "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible)" - rom ( name "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 3f1d7e58 sha1 c54b81e638b0c45d3569f9f5f0345df9e95ce975 ) -) - game ( name "Pokemon Vision Jade (Taiwan) (De) (Unl)" description "Pokemon Vision Jade (Taiwan) (De) (Unl)" @@ -43312,15 +43419,9 @@ game ( ) game ( - name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" - description "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" - rom ( name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 42298fd8 sha1 90c535bf70e2ca7b91af67b8f08865f423c3034f ) -) - -game ( - name "Pokettohiro! (World) (Demo) (Aftermarket) (Unl)" - description "Pokettohiro! (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Pokettohiro! (World) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc b9e724ef sha1 28a01fd6ea95a146008435c5bc27b51b607bb86b ) + name "Polaris SnoCross (USA) (Beta) (Rumble Version)" + description "Polaris SnoCross (USA) (Beta) (Rumble Version)" + rom ( name "Polaris SnoCross (USA) (Beta) (Rumble Version).gbc" size 1048576 crc 673623c4 sha1 4176ef1f9fd37156a4cac37a2d146ed2deeb5a7b ) ) game ( @@ -43329,12 +43430,6 @@ game ( rom ( name "Polaris SnoCross (USA) (Rumble Version).gbc" size 1048576 crc dd8b189e sha1 e893808fe227a1608c0604382d6a0340ec704c3b flags verified ) ) -game ( - name "Polaris SnoCross (USA) (Beta) (Rumble Version)" - description "Polaris SnoCross (USA) (Beta) (Rumble Version)" - rom ( name "Polaris SnoCross (USA) (Beta) (Rumble Version).gbc" size 1048576 crc 673623c4 sha1 4176ef1f9fd37156a4cac37a2d146ed2deeb5a7b ) -) - game ( name "Pong - The Next Level (USA, Europe)" description "Pong - The Next Level (USA, Europe)" @@ -43389,54 +43484,6 @@ game ( rom ( name "Portal Runner (USA).gbc" size 1048576 crc 913ac306 sha1 a8347366f15c0e454fa253bad5b4053d2a9613aa ) ) -game ( - name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 50393a65 sha1 2c2c6ed8be7a13bf279e435c5984f175c8affcad ) -) - -game ( - name "Postie (World) (GB Compatible) (Aftermarket) (Unl)" - description "Postie (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Postie (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ff6bbc83 sha1 3ff236972d1e344eb50e696db3cc090f2b5d28b1 ) -) - -game ( - name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6da19041 sha1 eb581935ad9223d723fdbc8339c03436df051947 ) -) - -game ( - name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" - description "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d0d8386d sha1 fbddf81a1663388ff0efeeb9051e68e0c323c839 ) -) - -game ( - name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" - description "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f0191467 sha1 3876f1aa896759f427ad2dc88a48788817e60c06 flags verified ) -) - -game ( - name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" - description "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e8f68acc sha1 156d315b7a2a035d5cd429fb8c7e051e67e83c93 flags verified ) -) - -game ( - name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 592b6097 sha1 874d5e4ffc7d36259bef6ec6a86a1de8289b8d54 ) -) - -game ( - name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b01c4ff1 sha1 898dbf10550af7e39b8f7a0818a78083ae40f4fe ) -) - game ( name "Power Pro Kun Pocket (Japan) (SGB Enhanced) (GB Compatible)" description "Power Pro Kun Pocket (Japan) (SGB Enhanced) (GB Compatible)" @@ -43599,18 +43646,6 @@ game ( rom ( name "Prince of Persia (Japan) (Proto).gbc" size 1048576 crc d7dbbe1e sha1 6fd97e1f75570e7568b3dc4ab28834813afb4484 ) ) -game ( - name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" - description "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a86cada1 sha1 b02096c489c0f36582061d6eb62beb17e8294b61 ) -) - -game ( - name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" - description "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e171f327 sha1 b03df48f48529ac1be79699d6f34f324adcfb436 ) -) - game ( name "Pro Darts (USA)" description "Pro Darts (USA)" @@ -43665,12 +43700,6 @@ game ( rom ( name "Project S-11 (USA).gbc" size 524288 crc 20cee2e8 sha1 cbedd34a0c6a2f4e58d05f0bb6d54f7cbcda815c ) ) -game ( - name "Proof of Destruction (World) (Aftermarket) (Unl)" - description "Proof of Destruction (World) (Aftermarket) (Unl)" - rom ( name "Proof of Destruction (World) (Aftermarket) (Unl).gbc" size 262144 crc fa528f88 sha1 5062f16346c31cae1b13e469cb610ce84d4eecb2 ) -) - game ( name "Puchi Carat (USA) (Proto 2) (SGB Enhanced) (GB Compatible)" description "Puchi Carat (USA) (Proto 2) (SGB Enhanced) (GB Compatible)" @@ -43707,12 +43736,6 @@ game ( rom ( name "Pumuckls Abenteuer im Geisterschloss (Germany).gbc" size 1048576 crc 87fcec24 sha1 0fe14ef81b11c854f080e804c5d3cb14601b2794 ) ) -game ( - name "Purple Turtles (World) (Aftermarket) (Unl)" - description "Purple Turtles (World) (Aftermarket) (Unl)" - rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gbc" size 262144 crc 471277df sha1 a73cb69d1fb42f45f3649c4d1b4775e98fe35b78 ) -) - game ( name "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced) (GB Compatible)" description "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced) (GB Compatible)" @@ -43803,12 +43826,6 @@ game ( rom ( name "Quan Ba Tianxia (Taiwan) (Unl).gbc" size 4194304 crc 2c922ed6 sha1 c19eb98a9745d2c2ce9e4dba3f17ae0b3dee0f49 ) ) -game ( - name "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" - description "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Quartet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 46743216 sha1 bf866b438a602af386f8fad02727b4084edf6047 ) -) - game ( name "Quest - Brian's Journey (USA) (GB Compatible)" description "Quest - Brian's Journey (USA) (GB Compatible)" @@ -43821,12 +43838,6 @@ game ( rom ( name "Quest - Fantasy Challenge (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 98285775 sha1 86812b2cd4304dc7ee2dd3faf16737b0414aaffb ) ) -game ( - name "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9ac546d5 sha1 25b3a21135bfc7587c096b10f4a20d8b3095d721 ) -) - game ( name "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced) (GB Compatible)" description "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced) (GB Compatible)" @@ -43881,12 +43892,6 @@ game ( rom ( name "Radikal Bikers (Europe) (En,Fr,De,Es) (Proto).gbc" size 2097152 crc 81e25d37 sha1 f16aa29669b15153a63ad92388768e38aa18fbf8 ) ) -game ( - name "Raffles (World) (Aftermarket) (Unl)" - description "Raffles (World) (Aftermarket) (Unl)" - rom ( name "Raffles (World) (Aftermarket) (Unl).gbc" size 262144 crc e41d6472 sha1 4b5eb518ff52c235c674e0695fdde2b8b01f58fa ) -) - game ( name "Rainbow Islands (Europe) (En,Fr,De,Es,It)" description "Rainbow Islands (Europe) (En,Fr,De,Es,It)" @@ -43935,12 +43940,6 @@ game ( rom ( name "Rats! (USA) (En,Es) (GB Compatible).gbc" size 524288 crc 17635ad1 sha1 5e423dfab8221b69a641d2e535ebfe1e3759a2e4 ) ) -game ( - name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" - description "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 09196a32 sha1 8218ad22b29fb32c66430a17a97775dd30b2f34b flags verified ) -) - game ( name "Rayman (Europe) (En,Fr,De,Es,It,Nl)" description "Rayman (Europe) (En,Fr,De,Es,It,Nl)" @@ -44025,24 +44024,6 @@ game ( rom ( name "Remen Gaoxiao - Shuma Guaishou III (Taiwan) (Unl).gbc" size 524288 crc 9f64fb1c sha1 b8d6910c8b5c1cab044c61679bbbc4f213648f56 ) ) -game ( - name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc e92034d8 sha1 14b9614cea9be7d5c6e12aece692582ba2ca2b75 flags verified ) -) - -game ( - name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 3a1b1d83 sha1 4dda0cce6907de94eeae3f11a40238c3f5155ca7 ) -) - -game ( - name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc f8c7f180 sha1 07674d42f5d4efaec14750ae56d8f28c4b54c020 flags verified ) -) - game ( name "Rescue Heroes - Fire Frenzy (USA)" description "Rescue Heroes - Fire Frenzy (USA)" @@ -44085,18 +44066,6 @@ game ( rom ( name "Resident Evil Gaiden (USA).gbc" size 2097152 crc f8c5021b sha1 a302cddc085d65ca778153e2a591bd648ce963c9 ) ) -game ( - name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" - description "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 8bd98942 sha1 3a5dbafa829e57089de8cfc93c806f7ee023ff1b ) -) - -game ( - name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c761189c sha1 f7f18d83218b66b9d1cd7267d6d4acfd4eded6c7 ) -) - game ( name "Return of the Ninja (Europe)" description "Return of the Ninja (Europe)" @@ -44109,6 +44078,12 @@ game ( rom ( name "Return of the Ninja (USA).gbc" size 1048576 crc a07da702 sha1 e33352f0ac19d28983ebed0758d022861473ec0e ) ) +game ( + name "Return of the Ninja (World) (Limited Run Games)" + description "Return of the Ninja (World) (Limited Run Games)" + rom ( name "Return of the Ninja (World) (Limited Run Games).gbc" size 1048576 crc df445c4a sha1 d73049119fbc163183fdb95e9b299ca4d1d4e8e3 ) +) + game ( name "Revelations - The Demon Slayer (USA) (SGB Enhanced) (GB Compatible)" description "Revelations - The Demon Slayer (USA) (SGB Enhanced) (GB Compatible)" @@ -44121,24 +44096,12 @@ game ( rom ( name "Rhino Rumble (USA, Europe).gbc" size 1048576 crc 73160e05 sha1 2caf47c20d8632e47c4426dd3564e76415139973 flags verified ) ) -game ( - name "Rig Attack (World) (Aftermarket) (Unl)" - description "Rig Attack (World) (Aftermarket) (Unl)" - rom ( name "Rig Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc d013d775 sha1 90bfd921c986abff4555b761cedc90ec36c43fff ) -) - game ( name "Rip-Tide Racer (Europe) (En,Fr,De,Es,It) (GB Compatible)" description "Rip-Tide Racer (Europe) (En,Fr,De,Es,It) (GB Compatible)" rom ( name "Rip-Tide Racer (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc ab8c3a31 sha1 3354d6e79b8094bbaa4ef48eb8bd2b0774c46e1a ) ) -game ( - name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" - description "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae3f980b sha1 67f63517eacfea22922d07be0efc5fc8f8b8a1d2 ) -) - game ( name "Road Champs - BXS Stunt Biking (USA, Europe)" description "Road Champs - BXS Stunt Biking (USA, Europe)" @@ -44160,7 +44123,7 @@ game ( game ( name "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible)" description "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible)" - rom ( name "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 38b022be sha1 ede737e99108be29daf94fee8e10f5dd770731bb ) + rom ( name "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 38b022be sha1 ede737e99108be29daf94fee8e10f5dd770731bb flags verified ) ) game ( @@ -44175,18 +44138,6 @@ game ( rom ( name "Robin Hood (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc d4f84329 sha1 fe0c42e949bc41f070b22dd24e643aa42b007667 ) ) -game ( - name "Robin to the Rescue (World) (Aftermarket) (Unl)" - description "Robin to the Rescue (World) (Aftermarket) (Unl)" - rom ( name "Robin to the Rescue (World) (Aftermarket) (Unl).gbc" size 262144 crc 9cd52c18 sha1 ef3bea9ed0de41e311b5f15fccbb0f451848d56c ) -) - -game ( - name "Robo Knight (World) (Aftermarket) (Unl)" - description "Robo Knight (World) (Aftermarket) (Unl)" - rom ( name "Robo Knight (World) (Aftermarket) (Unl).gbc" size 524288 crc 8d4507f0 sha1 6012f9a3ae6201e363f46a75e0100552ecb91335 ) -) - game ( name "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" description "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" @@ -44253,12 +44204,6 @@ game ( rom ( name "Rocket Power - La Glisse de l'Extreme (France).gbc" size 1048576 crc c9a7aa7b sha1 b6b9b7b2fb2ff11d41c6531fe21bfd5aa89f7ab4 ) ) -game ( - name "Rockman (World) (Aftermarket) (Unl)" - description "Rockman (World) (Aftermarket) (Unl)" - rom ( name "Rockman (World) (Aftermarket) (Unl).gbc" size 262144 crc 490b5676 sha1 6f78200acb6698e268e26c1912d64a002cbd3d89 ) -) - game ( name "Rockman 3 (Taiwan) (Unl)" description "Rockman 3 (Taiwan) (Unl)" @@ -44272,9 +44217,9 @@ game ( ) game ( - name "Rockman DX8 (Taiwan) (En) (Unl)" - description "Rockman DX8 (Taiwan) (En) (Unl)" - rom ( name "Rockman DX8 (Taiwan) (En) (Unl).gbc" size 1048576 crc 4c6c9eaf sha1 1274bb7d5570f4f1101dff1d13d9b5665deaa3da ) + name "Rockman DX8 (China) (En) (Unl)" + description "Rockman DX8 (China) (En) (Unl)" + rom ( name "Rockman DX8 (China) (En) (Unl).gbc" size 1048576 crc 4c6c9eaf sha1 1274bb7d5570f4f1101dff1d13d9b5665deaa3da ) ) game ( @@ -44379,30 +44324,6 @@ game ( rom ( name "RPG Tsukuru GB (Japan) (Rev 1) (Possible Proto) (NP).gbc" size 2097152 crc 57f82031 sha1 f4c36b3cbb13d3cbaaa81e97b0636c4515ce501e ) ) -game ( - name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a46baa15 sha1 87dd5a6ccb5db59dae09f1953062420977ad2d92 ) -) - -game ( - name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5602ca84 sha1 49d692796a6d0f3dcfc988648b446c0934f0e794 ) -) - -game ( - name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b2547aa6 sha1 981a464d6e1c9e5ac59549845b41dae4817ed3b8 ) -) - -game ( - name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c18f82cb sha1 bd8cd5822dcc61f7eb0cf2584c9a5b5a94bde14a ) -) - game ( name "Rugrats - Time Travelers (USA, Europe) (GB Compatible)" description "Rugrats - Time Travelers (USA, Europe) (GB Compatible)" @@ -44457,28 +44378,10 @@ game ( rom ( name "Runelords (USA) (Proto).gbc" size 4194304 crc 392af730 sha1 2bdcf8208cd0530c75195fd23f2f7839a3480bff ) ) -game ( - name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" - description "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" - rom ( name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 2097152 crc 96b1ceec sha1 771135edfbc64f7332a9cbd0d72af7a9d0d71f82 ) -) - -game ( - name "RunieStory (World) (Aftermarket) (Unl)" - description "RunieStory (World) (Aftermarket) (Unl)" - rom ( name "RunieStory (World) (Aftermarket) (Unl).gbc" size 2097152 crc 2249b449 sha1 0f6a391d7e05f66092a98e411069fab8e3f24221 ) -) - -game ( - name "Runner (World) (Aftermarket) (Unl)" - description "Runner (World) (Aftermarket) (Unl)" - rom ( name "Runner (World) (Aftermarket) (Unl).gbc" size 262144 crc 4cd8ccb2 sha1 da735d415ed463a953bac45f4793342bd9be2e96 ) -) - game ( name "Saban's Power Rangers - Lightspeed Rescue (USA, Europe)" description "Saban's Power Rangers - Lightspeed Rescue (USA, Europe)" - rom ( name "Saban's Power Rangers - Lightspeed Rescue (USA, Europe).gbc" size 1048576 crc 99869172 sha1 e7d0f2f21cdcda49516f682092d0b2017e82d379 ) + rom ( name "Saban's Power Rangers - Lightspeed Rescue (USA, Europe).gbc" size 1048576 crc 99869172 sha1 e7d0f2f21cdcda49516f682092d0b2017e82d379 flags verified ) ) game ( @@ -44523,18 +44426,6 @@ game ( rom ( name "Sakura Taisen GB 2 - Thunderbolt Sakusen (Japan).gbc" size 4194304 crc 47636a2c sha1 13092603ea1d54264bc48f02c2796947badb462c ) ) -game ( - name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" - description "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 4e4af60b sha1 ab8d49a99d02eb5c97d75f62dfb3720eec2b5abd ) -) - -game ( - name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" - description "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 40dc168d sha1 af25acc86f0eef4ce72199383b96fcb4c9f0115e ) -) - game ( name "Samurai Kid (Japan)" description "Samurai Kid (Japan)" @@ -44565,10 +44456,16 @@ game ( rom ( name "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e787b44c sha1 ec6089ff2cfcb17faf6a8ea9a4171869b3c7289b ) ) +game ( + name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl) (Alt)" + description "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl) (Alt)" + rom ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl) (Alt).gbc" size 1048576 crc 728255e5 sha1 d9a978c6b4745d964128eb0eced022337849467c ) +) + game ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl)" description "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl)" - rom ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl).gbc" size 1048576 crc 728255e5 sha1 d9a978c6b4745d964128eb0eced022337849467c ) + rom ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl).gbc" size 1048576 crc 48d2607f sha1 8ee81543442932b87349eef3a9287a923cec827c ) ) game ( @@ -44607,12 +44504,6 @@ game ( rom ( name "Santa Claus Junior (Europe).gbc" size 1048576 crc a744df64 sha1 ab74474cd63a2c74bf9617907270d26b5d183b89 ) ) -game ( - name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" - description "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc db928e22 sha1 e175d35e6112c347ecd1e0a379e98f430823ba94 ) -) - game ( name "Saru Puncher (Japan) (SGB Enhanced) (GB Compatible)" description "Saru Puncher (Japan) (SGB Enhanced) (GB Compatible)" @@ -44823,6 +44714,12 @@ game ( rom ( name "Shantae (USA) (Beta).gbc" size 4194304 crc 3b4d6c50 sha1 141dc57955e84d51f0099c0709a0626d43ab8fa7 ) ) +game ( + name "Shantae (World) (Limited Run Games)" + description "Shantae (World) (Limited Run Games)" + rom ( name "Shantae (World) (Limited Run Games).gbc" size 4194304 crc 96d2774e sha1 71bc428f2746df2a2c6238e14f594d3e5c8da131 ) +) + game ( name "Shantae (World) (Switch)" description "Shantae (World) (Switch)" @@ -44847,12 +44744,6 @@ game ( rom ( name "Shaoling Legend - Hero, the Saver (Taiwan) (En) (Unl).gbc" size 2097152 crc a321ff7d sha1 b1194edd0962c50cf909262004a102f01f556723 ) ) -game ( - name "Shark Attack (World) (Aftermarket) (Unl)" - description "Shark Attack (World) (Aftermarket) (Unl)" - rom ( name "Shark Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc cf80a2ba sha1 291f453a185f836fcafbd7e41945a409638980c0 ) -) - game ( name "Shaun Palmer's Pro Snowboarder (USA, Australia)" description "Shaun Palmer's Pro Snowboarder (USA, Australia)" @@ -44890,9 +44781,21 @@ game ( ) game ( - name "Shi Mian Maifu - Fengyun Pian (Taiwan) (Unl)" - description "Shi Mian Maifu - Fengyun Pian (Taiwan) (Unl)" - rom ( name "Shi Mian Maifu - Fengyun Pian (Taiwan) (Unl).gbc" size 1048576 crc a5f686c3 sha1 68798ac090df9f5fb1ea9c409adf3dc639bc9842 ) + name "Shi Mian Maifu - Fengyun Pian (China) (Unl)" + description "Shi Mian Maifu - Fengyun Pian (China) (Unl)" + rom ( name "Shi Mian Maifu - Fengyun Pian (China) (Unl).gbc" size 1048576 crc a5f686c3 sha1 68798ac090df9f5fb1ea9c409adf3dc639bc9842 ) +) + +game ( + name "Shi Mian Maifu - Tianlong Pian (China) (Unl)" + description "Shi Mian Maifu - Tianlong Pian (China) (Unl)" + rom ( name "Shi Mian Maifu - Tianlong Pian (China) (Unl).gbc" size 1048576 crc 605cd86e sha1 b457bafb6b55a82920743d52284918ac74f35852 ) +) + +game ( + name "Shi Mian Maifu - Yingxiong Pian (China) (Unl)" + description "Shi Mian Maifu - Yingxiong Pian (China) (Unl)" + rom ( name "Shi Mian Maifu - Yingxiong Pian (China) (Unl).gbc" size 1048576 crc 2382b3d7 sha1 72077d32c2ab84b6bb1e4ad59bc8c88dbcf1da77 ) ) game ( @@ -45070,9 +44973,9 @@ game ( ) game ( - name "Shuma Baolong 02 5 (China) (Unl)" - description "Shuma Baolong 02 5 (China) (Unl)" - rom ( name "Shuma Baolong 02 5 (China) (Unl).gbc" size 1048576 crc 5ba9f8b5 sha1 c441fcbdb343e0c3c76803aa55ceb728158a8948 ) + name "Shuma Baolong 02 5 (Taiwan) (Unl)" + description "Shuma Baolong 02 5 (Taiwan) (Unl)" + rom ( name "Shuma Baolong 02 5 (Taiwan) (Unl).gbc" size 1048576 crc 5ba9f8b5 sha1 c441fcbdb343e0c3c76803aa55ceb728158a8948 ) ) game ( @@ -45105,72 +45008,12 @@ game ( rom ( name "Shutokou Racing, The (Japan) (SGB Enhanced) (GB Compatible).gbc" size 131072 crc 36e781cd sha1 0f29818190ea9ce8c242b648ba64d50cc5408e5a ) ) -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 599132ec sha1 762087df0e5820f1e50da2a22f9ee3b8d16c3e49 ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5370b1bf sha1 966e2d79ab4930039c3d6c43fdbb8cdc068ba347 ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 16f34bcc sha1 c34e744b9120e3a1b2b054d3708e4ab594726c5a ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 31ce3f27 sha1 c33d685d5ea5cd6cd954af3bc9ee92719b9578b1 ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc d54b53cb sha1 08948befa0227b795d00fe60e9eede6a1f56597b ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 314be6b5 sha1 37978f85ae92e7d9a53611659513fd360f57a5b1 ) -) - -game ( - name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" - description "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc 7ebcdd4e sha1 b99f43719155cafbc3dbd7df0ade281c3c7ba171 ) -) - game ( name "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe)" description "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe)" rom ( name "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe).gbc" size 1048576 crc ebaf4888 sha1 a5be079336e48552e53706f0380f35829d91b3c0 ) ) -game ( - name "Skelby (World) (Aftermarket) (Unl)" - description "Skelby (World) (Aftermarket) (Unl)" - rom ( name "Skelby (World) (Aftermarket) (Unl).gbc" size 524288 crc 6ec6c18c sha1 887555aa7e2e61b68a21020237b7d508bb71aded ) -) - -game ( - name "Skycon (World) (Aftermarket) (Unl)" - description "Skycon (World) (Aftermarket) (Unl)" - rom ( name "Skycon (World) (Aftermarket) (Unl).gbc" size 524288 crc 195dbc30 sha1 df29ece6c5f5b14840663495230135dd79c5163a ) -) - -game ( - name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" - description "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c906c5af sha1 0e0d472b282e3ea590e0f126baf633ef0d9298fa ) -) - game ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" description "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" @@ -45183,18 +45026,6 @@ game ( rom ( name "Smurfs Nightmare, The (USA).gbc" size 1048576 crc b50cafe4 sha1 1d0d3512f32176b7035f9c2a77d4636b1d08b349 ) ) -game ( - name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1aecd096 sha1 8ce256d963a55badf71fd45047c173a74d76a92c ) -) - -game ( - name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6cf39388 sha1 9cf5a1d3e8119303a1f4b04b8f4d8b683aee699e ) -) - game ( name "Snobow Champion (Japan)" description "Snobow Champion (Japan)" @@ -45225,12 +45056,6 @@ game ( rom ( name "Snoopy Tennis (Europe) (En,Fr,De,Es,It,Nl) (Beta).gbc" size 1048576 crc 49db04a6 sha1 03adc2731945bc86588fffedfee2050a00679ce6 ) ) -game ( - name "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" - description "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Snooze (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b246095f sha1 b7fdcc006c9c06dd391ee26d44b278d9d3793f6d ) -) - game ( name "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)" description "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)" @@ -45255,12 +45080,6 @@ game ( rom ( name "Soccer Manager (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 237ecef9 sha1 353eb6aaf40a78ebf1bca9298726d068a5986efa ) ) -game ( - name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" - description "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 9e864f1c sha1 ce5dc23c04ff18dfac2367e53d241e81c4bbc3a3 ) -) - game ( name "Solomon (Japan)" description "Solomon (Japan)" @@ -45381,12 +45200,6 @@ game ( rom ( name "Spawn (USA).gbc" size 2097152 crc 72fcb0ad sha1 4f816eec1b5dc79928ade9f3a3c687b8aa5b2f87 ) ) -game ( - name "Spectipede (World) (Aftermarket) (Unl)" - description "Spectipede (World) (Aftermarket) (Unl)" - rom ( name "Spectipede (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c33f76e sha1 834a450d9ceb78b9d89d551300d4d0ea08cd8a6a ) -) - game ( name "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" description "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" @@ -45420,7 +45233,7 @@ game ( game ( name "Spider-Man 2 - The Sinister Six (USA, Europe)" description "Spider-Man 2 - The Sinister Six (USA, Europe)" - rom ( name "Spider-Man 2 - The Sinister Six (USA, Europe).gbc" size 1048576 crc a7faaccf sha1 22c63fa198df68edb9cbe22e35cbd307174c9eb9 ) + rom ( name "Spider-Man 2 - The Sinister Six (USA, Europe).gbc" size 1048576 crc a7faaccf sha1 22c63fa198df68edb9cbe22e35cbd307174c9eb9 flags verified ) ) game ( @@ -45429,12 +45242,6 @@ game ( rom ( name "Spider-Man 3 - Movie Version (USA) (Unl).gbc" size 2097152 crc 2c0d43a9 sha1 8a6b6a1300db59b86ddf87599cfc8edd2e52e2b0 ) ) -game ( - name "Spiky Harold (World) (Aftermarket) (Unl)" - description "Spiky Harold (World) (Aftermarket) (Unl)" - rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gbc" size 262144 crc 7e9eda35 sha1 486d294b8cf226876581d543e3a08018321bc402 ) -) - game ( name "Spirou - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da)" description "Spirou - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da)" @@ -45495,12 +45302,6 @@ game ( rom ( name "Star Heritage (Europe) (Proto) (Password Version).gbc" size 1048576 crc b39b4532 sha1 6eb2c27e2eedb22b4055ded87fce0621d460fe5b ) ) -game ( - name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" - description "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 29320841 sha1 890fda255106ea64bac4973e2e9f4b31bb925d35 ) -) - game ( name "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" description "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" @@ -45537,36 +45338,12 @@ game ( rom ( name "Star Wars Episode I - Racer (USA, Europe) (Rumble Version).gbc" size 2097152 crc 0ebc5758 sha1 c0613d654a4382f0c50fd4d389d3a6aeef4d5207 flags verified ) ) -game ( - name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" - description "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 82658661 sha1 dd45b0e3f346ce33668d49092b29a44597686061 ) -) - -game ( - name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" - description "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ce90a95b sha1 75457c5affd0c126f2c916e857950b5cde46a95e ) -) - -game ( - name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" - description "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b3a04b44 sha1 b16f21b46dfe4e6ce0368e3c5a3fae397274ebbf ) -) - game ( name "Startled 911 (Taiwan) (En) (Unl)" description "Startled 911 (Taiwan) (En) (Unl)" rom ( name "Startled 911 (Taiwan) (En) (Unl).gbc" size 2097152 crc 7273a4f4 sha1 14154ba420826a406890079d7cc0b420a042e34f ) ) -game ( - name "Stellar Wars (World) (Aftermarket) (Unl)" - description "Stellar Wars (World) (Aftermarket) (Unl)" - rom ( name "Stellar Wars (World) (Aftermarket) (Unl).gbc" size 262144 crc e0b96256 sha1 ba2d10a2a5f3f073aea11e26ae5c53c9cf7866f8 ) -) - game ( name "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" description "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" @@ -45615,18 +45392,6 @@ game ( rom ( name "Stuart Little - The Journey Home (USA, Europe).gbc" size 1048576 crc eb273887 sha1 d3c31e41709c54af328787036db1b98997f508ea ) ) -game ( - name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" - description "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2dc3fdae sha1 a551d904c4af661bd4b6e88063cb5541900117b0 ) -) - -game ( - name "Suicide Run (World) (Aftermarket) (Unl)" - description "Suicide Run (World) (Aftermarket) (Unl)" - rom ( name "Suicide Run (World) (Aftermarket) (Unl).gbc" size 262144 crc d29ab1aa sha1 df373f58e51155e32fb81825a9082150f6d263c8 ) -) - game ( name "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" description "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" @@ -45675,18 +45440,18 @@ game ( rom ( name "Super Breakout! (USA) (GB Compatible).gbc" size 1048576 crc 52f51cb5 sha1 8c795b6d8ebc3a796821a6b2879f3e5cebf9215c ) ) -game ( - name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" - description "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c47330e2 sha1 6151286e93b2e2fb92f583371e650e36ab91aaf7 ) -) - game ( name "Super Chinese Fighter EX (Japan)" description "Super Chinese Fighter EX (Japan)" rom ( name "Super Chinese Fighter EX (Japan).gbc" size 1048576 crc dcdaa333 sha1 0296d0a60933c798b21399195789d10eb319872f ) ) +game ( + name "Super Color 26-in-1 (Taiwan) (Unl)" + description "Super Color 26-in-1 (Taiwan) (Unl)" + rom ( name "Super Color 26-in-1 (Taiwan) (Unl).gbc" size 4194304 crc 71e9a5d9 sha1 0f8657e4583389a23d61d8d0bd7fe322bcaabf6b ) +) + game ( name "Super Doll Licca-chan - Kisekae Daisakusen (Japan)" description "Super Doll Licca-chan - Kisekae Daisakusen (Japan)" @@ -45729,42 +45494,6 @@ game ( rom ( name "Super Gals! Kotobuki Ran 2 - Miracle Getting (Japan).gbc" size 4194304 crc e77fa0f2 sha1 a724c6dd33b84ae9120d041fc49d66692c798dd0 ) ) -game ( - name "Super Gran (World) (Aftermarket) (Unl)" - description "Super Gran (World) (Aftermarket) (Unl)" - rom ( name "Super Gran (World) (Aftermarket) (Unl).gbc" size 262144 crc 98ee2e8a sha1 5afe9c7ab1b9d86048a570e7a37a0c244cb84e43 ) -) - -game ( - name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" - description "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a38d702f sha1 301f93da4e5b0cd8dc3f1bf3e66e38176b8a909b ) -) - -game ( - name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" - description "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" - rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl).gbc" size 524288 crc 8e1f6bb0 sha1 27522a35211b0f015fa9550c2520f1da1c346886 ) -) - -game ( - name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" - description "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" - rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl).gbc" size 524288 crc f9731ee2 sha1 23855b95d04a6c7c6d2ce7977bb31dbe6c0e68a0 ) -) - -game ( - name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" - description "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" - rom ( name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl).gbc" size 524288 crc 87956ddf sha1 b23320d5d3fde2a55b301f7bea324833c31c32d5 ) -) - -game ( - name "Super JetPak DX (World) (GB Compatible) (Aftermarket)" - description "Super JetPak DX (World) (GB Compatible) (Aftermarket)" - rom ( name "Super JetPak DX (World) (GB Compatible) (Aftermarket).gbc" size 131072 crc 22def6f9 sha1 e7438db01fbbdeea2404dbf3d093370421ec4e1c flags verified ) -) - game ( name "Super Mario Bros. Deluxe (Japan) (NP)" description "Super Mario Bros. Deluxe (Japan) (NP)" @@ -45951,18 +45680,6 @@ game ( rom ( name "SWiV (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 44d30b7a sha1 7e037008eabf01fa647cdfb0d5c88766a6f77423 ) ) -game ( - name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" - description "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 64921bb1 sha1 b36ec89e0299c19767cc5c6467fa3664abbc3017 ) -) - -game ( - name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - description "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b2b5dc4b sha1 aaa66863b2e68865359d1c0db2047bab6f64f9ee ) -) - game ( name "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced) (GB Compatible)" description "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced) (GB Compatible)" @@ -46029,6 +45746,12 @@ game ( rom ( name "Taikong Zhanshi DX3 - Zuizhong Huanxiang (Taiwan) (Unl).gbc" size 2097152 crc ddf36a27 sha1 0a62b484c5730a3a1f8b32cc2ed97af128d2130c ) ) +game ( + name "Taikong Zhanshi X - Fantasy War (Taiwan) (Unl)" + description "Taikong Zhanshi X - Fantasy War (Taiwan) (Unl)" + rom ( name "Taikong Zhanshi X - Fantasy War (Taiwan) (Unl).gbc" size 1048576 crc 09fedecc sha1 c4fd2de9cf8d75de069abadf165252dac5712691 ) +) + game ( name "Taisen Tsume Shougi (Japan) (NP) (GB Compatible)" description "Taisen Tsume Shougi (Japan) (NP) (GB Compatible)" @@ -46047,36 +45770,18 @@ game ( rom ( name "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6a0c272d sha1 d6d90667ebf295016f01b4604ab03ab5b1876d00 ) ) -game ( - name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" - description "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a685f89a sha1 15a709d4300464b03ede4d774ce69cfb699c0fcf ) -) - game ( name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible)" description "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible)" rom ( name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 725cf31c sha1 ef322f4160ceebd8da67758ebd73225190af6d23 flags verified ) ) -game ( - name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" - description "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" - rom ( name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl).gbc" size 262144 crc 257d9201 sha1 d78e0b03a3915531e780057c4ad7ed2b3f849825 ) -) - game ( name "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced) (GB Compatible)" description "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced) (GB Compatible)" rom ( name "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc ce8ae58c sha1 f752e96602274a29006425a06086d8ab45e1075c ) ) -game ( - name "Tank Attack (World) (Aftermarket) (Unl)" - description "Tank Attack (World) (Aftermarket) (Unl)" - rom ( name "Tank Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc c77dc518 sha1 4751a6999f4dbe7e66b997372588f6bd15e4d9d0 ) -) - game ( name "Tarzan (France)" description "Tarzan (France)" @@ -46131,18 +45836,6 @@ game ( rom ( name "Taxi 3 (France).gbc" size 1048576 crc 2838996f sha1 e43817c673d47b7587f542dcc9f74190c63629ff ) ) -game ( - name "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" - description "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" - rom ( name "Tazz (World) (2022-10-13) (Aftermarket) (Unl).gbc" size 262144 crc 1d97b754 sha1 39226ed715ae8d94f9187c3e5e8a849eac92ca26 ) -) - -game ( - name "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" - description "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" - rom ( name "Tazz (World) (2022-10-17) (Aftermarket) (Unl).gbc" size 262144 crc 6fb0ba23 sha1 543118e54b166ea2b8b5979f8468cc2f5662161f ) -) - game ( name "Tech Deck Skateboarding (USA, Europe)" description "Tech Deck Skateboarding (USA, Europe)" @@ -46299,18 +45992,6 @@ game ( rom ( name "Tintin au Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 6832f38a sha1 eef17d4a827efab90c03083edb0bee534cd64188 ) ) -game ( - name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" - description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc af13e718 sha1 307e51664db2101755b6c617f3d81ee58676c485 ) -) - -game ( - name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0518f5aa sha1 85e5cd0cf7a6cc4a5946c93fa8665235a686e554 ) -) - game ( name "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It)" description "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It)" @@ -46335,12 +46016,6 @@ game ( rom ( name "Tiny Toon Adventures - Dizzy's Candy Quest (USA) (Proto).gbc" size 1048576 crc 23bb87a5 sha1 4eb0359a278173ae6c12e9452a7a2a9573a58c77 ) ) -game ( - name "Tir Na Nog (World) (Aftermarket) (Unl)" - description "Tir Na Nog (World) (Aftermarket) (Unl)" - rom ( name "Tir Na Nog (World) (Aftermarket) (Unl).gbc" size 1048576 crc 44524c90 sha1 ac712228460e9d4268f90ec4cf9ac2137fa667c4 ) -) - game ( name "Titi - Le Tour du Monde en 80 Chats (France)" description "Titi - Le Tour du Monde en 80 Chats (France)" @@ -46365,12 +46040,6 @@ game ( rom ( name "TNN Outdoors Fishing Champ (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 00a14d18 sha1 acfe7c9edd20f7d6b155deebc9428703edf28978 ) ) -game ( - name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - description "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 16650a8b sha1 fe6eef70d48dda741f7ad3b6cc5e753e8cd13239 ) -) - game ( name "TOCA Touring Car Championship (USA, Europe)" description "TOCA Touring Car Championship (USA, Europe)" @@ -46479,12 +46148,6 @@ game ( rom ( name "Tomb Raider 2 (Taiwan) (Unl).gbc" size 4194304 crc 717a5d19 sha1 5b9325b6e322a806677c6ea37a0054381609b99e ) ) -game ( - name "Tomte Trouble (World) (Aftermarket) (Unl)" - description "Tomte Trouble (World) (Aftermarket) (Unl)" - rom ( name "Tomte Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc a43d6b82 sha1 99730fe00703d655b1c806f49c9e3c2fb3dec58e flags verified ) -) - game ( name "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" description "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" @@ -46518,7 +46181,7 @@ game ( game ( name "Tonka Raceway (USA) (Rumble Version)" description "Tonka Raceway (USA) (Rumble Version)" - rom ( name "Tonka Raceway (USA) (Rumble Version).gbc" size 1048576 crc a5af4b28 sha1 6a86b7172c53a8e67f3d72f953116991640f6e71 ) + rom ( name "Tonka Raceway (USA) (Rumble Version).gbc" size 1048576 crc a5af4b28 sha1 6a86b7172c53a8e67f3d72f953116991640f6e71 flags verified ) ) game ( @@ -46653,12 +46316,6 @@ game ( rom ( name "Tottoko Hamutarou 2 - Hamu-chan Zu Daishuugou Dechu (Japan).gbc" size 2097152 crc f1fbcf84 sha1 adb1d5242a62d41c6e435b31082685ea4eec651a flags verified ) ) -game ( - name "Tower of Evil (World) (Aftermarket) (Unl)" - description "Tower of Evil (World) (Aftermarket) (Unl)" - rom ( name "Tower of Evil (World) (Aftermarket) (Unl).gbc" size 524288 crc aeb6e36f sha1 e9a6a007e935afb522c67d355e0354b0fb9af3c6 ) -) - game ( name "Towers - Lord Baniff's Deceit (USA, Europe)" description "Towers - Lord Baniff's Deceit (USA, Europe)" @@ -46713,18 +46370,6 @@ game ( rom ( name "Trade & Battle Card Hero (Japan) (Rev 1) (3DS Virtual Console) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc d98a877d sha1 c6c1e0365166b53d25a1f84bc380948a9661df30 ) ) -game ( - name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b0a32d51 sha1 4c0d639722d1cd8393e008d174b8f7266d089ead ) -) - -game ( - name "Treasure Island Color (World) (Aftermarket) (Unl)" - description "Treasure Island Color (World) (Aftermarket) (Unl)" - rom ( name "Treasure Island Color (World) (Aftermarket) (Unl).gbc" size 262144 crc 4ab0eb5a sha1 3ebddd4e1f5b3a87726ef34a5b7d36de8c722f36 ) -) - game ( name "Trick Boarder (Europe)" description "Trick Boarder (Europe)" @@ -46743,6 +46388,12 @@ game ( rom ( name "Trickboarder GP (Japan).gbc" size 1048576 crc 31740097 sha1 263d8612ecdf651115df6f896737b8c498c970c0 ) ) +game ( + name "Trip World DX (World) (Limited Run Games)" + description "Trip World DX (World) (Limited Run Games)" + rom ( name "Trip World DX (World) (Limited Run Games).gbc" size 524288 crc af17b3eb sha1 6871dd15e2081432ab4c7727f88491f7bbd95099 flags verified ) +) + game ( name "Triple Play 2001 (USA, Europe)" description "Triple Play 2001 (USA, Europe)" @@ -46755,12 +46406,6 @@ game ( rom ( name "Trouballs (USA).gbc" size 524288 crc 260eed04 sha1 dc4d0f608354e7cc32df7501dbacf8c50d70e728 ) ) -game ( - name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" - description "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4b9143ad sha1 0e51e398d44aaad74a7c622f7818b56a3b34db56 ) -) - game ( name "True Color 25 in 1 (Taiwan) (Unl)" description "True Color 25 in 1 (Taiwan) (Unl)" @@ -46815,24 +46460,12 @@ game ( rom ( name "Turok 3 - Shadow of Oblivion (USA, Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6d48765e sha1 4b240f6b8e3648f2cbafa2fd6ee4e5b508950122 flags verified ) ) -game ( - name "Tutti Frutti (World) (Aftermarket) (Unl)" - description "Tutti Frutti (World) (Aftermarket) (Unl)" - rom ( name "Tutti Frutti (World) (Aftermarket) (Unl).gbc" size 262144 crc ca377ca6 sha1 53d97b93b9d190de40ed2d81e18b4cbe44f99a23 ) -) - game ( name "Tutty (Europe) (Demo)" description "Tutty (Europe) (Demo)" rom ( name "Tutty (Europe) (Demo).gbc" size 131072 crc c4655f0a sha1 51883c4cc1469987483f993e3904da22690faeb9 ) ) -game ( - name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 01239312 sha1 4f21c3539ef40a7630581fe50533371e0d1a1ba9 ) -) - game ( name "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" description "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" @@ -46869,36 +46502,12 @@ game ( rom ( name "Tweety's High-Flying Adventure (USA).gbc" size 1048576 crc 4e226396 sha1 9702aeea4a92625d2c19aa7f606b589cb7531613 ) ) -game ( - name "Tycoon Tex (World) (Aftermarket) (Unl)" - description "Tycoon Tex (World) (Aftermarket) (Unl)" - rom ( name "Tycoon Tex (World) (Aftermarket) (Unl).gbc" size 262144 crc fa8436ba sha1 d37bcd93d647ac7efb761c539785a4ef570cdcc8 ) -) - -game ( - name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" - description "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" - rom ( name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl).gbc" size 2097152 crc 8067298a sha1 e44280161ca9d482fae08de844ccc9754abf68b0 ) -) - -game ( - name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" - description "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" - rom ( name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0ce45101 sha1 f61677146ef67b026c636742f0109b8c478d0942 ) -) - game ( name "Tyrannosaurus Tex (USA) (Proto)" description "Tyrannosaurus Tex (USA) (Proto)" rom ( name "Tyrannosaurus Tex (USA) (Proto).gbc" size 2097152 crc 1bd4e588 sha1 e2fcc7fcc643f9d7fc61acce6c5ed1f8abc13fa0 ) ) -game ( - name "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" - description "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" - rom ( name "Tyrannosaurus Tex (World) (Aftermarket) (Unl).gbc" size 2097152 crc e90504c1 sha1 7e41e92f92ff06101e48dee758420f1bd3959013 ) -) - game ( name "Tyrian 2000 (USA) (Proto) (GB Compatible)" description "Tyrian 2000 (USA) (Proto) (GB Compatible)" @@ -46953,24 +46562,6 @@ game ( rom ( name "Ultimate Surfing (USA).gbc" size 1048576 crc e84df1f0 sha1 264c19ab212d938839306f7e8230d5caee3cf3e7 ) ) -game ( - name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 29bb9238 sha1 39fbfb220e9be0120090f770249049b3f3583f64 ) -) - -game ( - name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 977b54f4 sha1 016dde406896d827dcad682d40b52d0e9eeefa88 ) -) - -game ( - name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" - description "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 36e4ff4c sha1 b5c9b5f07e31729678637d883b2564c1448b0e57 ) -) - game ( name "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" description "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" @@ -46983,12 +46574,6 @@ game ( rom ( name "Uno (USA) (GB Compatible).gbc" size 1048576 crc f026d509 sha1 20868148461618d1195570775b183a065781ce35 ) ) -game ( - name "UXB (World) (Aftermarket) (Unl)" - description "UXB (World) (Aftermarket) (Unl)" - rom ( name "UXB (World) (Aftermarket) (Unl).gbc" size 262144 crc dd42be4c sha1 6ef7abb689b1c75f613ed253644fbb0f377b7a95 ) -) - game ( name "V-Rally - Championship Edition (Europe) (En,Fr,De,Es)" description "V-Rally - Championship Edition (Europe) (En,Fr,De,Es)" @@ -47007,12 +46592,6 @@ game ( rom ( name "V-Rally - Edition 99 (USA) (En,Fr,Es).gbc" size 1048576 crc da300c6c sha1 638266c9d2d16486c2ed00510176112071b05e2c ) ) -game ( - name "Varmit (World) (Aftermarket) (Unl)" - description "Varmit (World) (Aftermarket) (Unl)" - rom ( name "Varmit (World) (Aftermarket) (Unl).gbc" size 2097152 crc e4827006 sha1 b61876c714c47f62a77304b79f6e34b8d0e7f8a2 ) -) - game ( name "Vegas Games (Europe) (En,Fr,De)" description "Vegas Games (Europe) (En,Fr,De)" @@ -47055,24 +46634,12 @@ game ( rom ( name "Visiteurs, Les (France) (GB Compatible).gbc" size 1048576 crc d843f898 sha1 307b5d80fd7def049d446bf3406ec8d57dfee93d ) ) -game ( - name "VOX (World) (Aftermarket) (Unl)" - description "VOX (World) (Aftermarket) (Unl)" - rom ( name "VOX (World) (Aftermarket) (Unl).gbc" size 262144 crc 346561fb sha1 54a03c77653a19eb1b0d8a6ac82f498f83f35ef2 ) -) - game ( name "VR Sports - Powerboat Racing (USA) (Proto)" description "VR Sports - Powerboat Racing (USA) (Proto)" rom ( name "VR Sports - Powerboat Racing (USA) (Proto).gbc" size 1048576 crc cff671f1 sha1 1c77f032cdd373bfa108ea82c463f8f9f6874c71 ) ) -game ( - name "Wacky Painter (World) (Aftermarket) (Unl)" - description "Wacky Painter (World) (Aftermarket) (Unl)" - rom ( name "Wacky Painter (World) (Aftermarket) (Unl).gbc" size 262144 crc 09daa18d sha1 5425dc675101d63bea03b1c8f46f86fe200ad392 ) -) - game ( name "Wacky Races (Europe) (En,Fr,De,Es,It,Nl)" description "Wacky Races (Europe) (En,Fr,De,Es,It,Nl)" @@ -47139,24 +46706,6 @@ game ( rom ( name "Warlocked (USA).gbc" size 2097152 crc cfa0df0f sha1 2f9c05f74476368bd6dbba7d675e7870cf8ca27c flags verified ) ) -game ( - name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1bfe1bf9 sha1 fae12dbbb75ae024e96a7ee21ad4077fdb5ed9a1 ) -) - -game ( - name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a381c914 sha1 adf37c5d2f706743b2a4946378df49ed19212039 ) -) - -game ( - name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 5519c167 sha1 04a53af6a77b884af91f8047d70fc0331bf23913 ) -) - game ( name "Warriors of Might and Magic (USA) (En,Fr,De)" description "Warriors of Might and Magic (USA) (En,Fr,De)" @@ -47199,30 +46748,6 @@ game ( rom ( name "Watashi no Restaurant (Japan) (Beta 3).gbc" size 1048576 crc a0ed2859 sha1 343bf8ebb6fa3ce89501f7c4c219fb7e864c38a3 ) ) -game ( - name "Water Grandprix (World) (Aftermarket) (Unl)" - description "Water Grandprix (World) (Aftermarket) (Unl)" - rom ( name "Water Grandprix (World) (Aftermarket) (Unl).gbc" size 262144 crc 82f54e7e sha1 4029e003870b2afb78a3644e24397d80fc5a3210 ) -) - -game ( - name "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" - description "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Waternet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc ef202121 sha1 a11f931b18ba42f48a91e817b7117fa0e3e79518 ) -) - -game ( - name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - description "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 75591760 sha1 e04b01ada17e6924503029cd09a107b7f5d06f17 ) -) - -game ( - name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - description "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc f8402dc5 sha1 6feb4178589e87c6267683078201f0630cca23d6 ) -) - game ( name "WCW Mayhem (USA, Europe)" description "WCW Mayhem (USA, Europe)" @@ -47271,24 +46796,6 @@ game ( rom ( name "Wetrix GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6215c5b3 sha1 92944052b6e4448abf0103f085998662e0140825 ) ) -game ( - name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 776fc18e sha1 5c4a227c0b2f53e4a349e482c5ba87cb83404f8e ) -) - -game ( - name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" - description "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c3d5cbf sha1 a235c0915ac2b826eeb5884d0eccd321236fdb0c ) -) - -game ( - name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" - description "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl).GBC" size 65536 crc 28114b89 sha1 05b90f0a7e92d42b3008c749d5edeab2a2eae973 ) -) - game ( name "Who Wants to Be a Millionaire - 2nd Edition (USA)" description "Who Wants to Be a Millionaire - 2nd Edition (USA)" @@ -47301,18 +46808,6 @@ game ( rom ( name "Wild Thornberrys, The - Rambler (USA).gbc" size 1048576 crc 0e1465cb sha1 0e806f0e6c1a41e764683850a3c15a80ac7fc9a5 ) ) -game ( - name "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 04e04980 sha1 574cf911d6d8f73699203cd6db42ceec777f7f93 ) -) - -game ( - name "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl)" - description "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 7328cfb6 sha1 039874148f27ffe533de4ef086f29e724a3217a9 ) -) - game ( name "Wings of Fury (Europe) (En,Fr,De) (GB Compatible)" description "Wings of Fury (Europe) (En,Fr,De) (GB Compatible)" @@ -47334,13 +46829,7 @@ game ( game ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (USA)" description "Winnie the Pooh - Adventures in the 100 Acre Wood (USA)" - rom ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (USA).gbc" size 2097152 crc 066a2196 sha1 5ff68bc5ec735d090b24aab79a787f77f26afb08 ) -) - -game ( - name "Wizard of Wor (World) (Aftermarket) (Unl)" - description "Wizard of Wor (World) (Aftermarket) (Unl)" - rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gbc" size 524288 crc 492a9529 sha1 a391646d259a39e7026574145e0a2bacf5f6937b ) + rom ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (USA).gbc" size 2097152 crc 066a2196 sha1 5ff68bc5ec735d090b24aab79a787f77f26afb08 flags verified ) ) game ( @@ -47409,12 +46898,6 @@ game ( rom ( name "Woody Woodpecker Racing (USA).gbc" size 1048576 crc 0424cf43 sha1 be98d0a54aedcf59cddc111c72db66105aea1375 ) ) -game ( - name "World Cup (World) (Aftermarket) (Unl)" - description "World Cup (World) (Aftermarket) (Unl)" - rom ( name "World Cup (World) (Aftermarket) (Unl).gbc" size 262144 crc 56b3ab5f sha1 075890510b3ef205ca50ebbbcf7c0a0c56032cb9 ) -) - game ( name "World Soccer GB 2 (Japan) (SGB Enhanced) (GB Compatible)" description "World Soccer GB 2 (Japan) (SGB Enhanced) (GB Compatible)" @@ -47445,10 +46928,16 @@ game ( rom ( name "Worms Armageddon (Europe) (Beta).gbc" size 1048576 crc 66fda365 sha1 b0b14b13ec7cffb04efbf0dcdd93a2eea679ea0c ) ) +game ( + name "Worms Armageddon (World) (Limited Run Games)" + description "Worms Armageddon (World) (Limited Run Games)" + rom ( name "Worms Armageddon (World) (Limited Run Games).gbc" size 1048576 crc 626dfadb sha1 5fce1d1b6a7cfa994808d473602f569537dc0231 ) +) + game ( name "WWF Attitude (USA, Europe)" description "WWF Attitude (USA, Europe)" - rom ( name "WWF Attitude (USA, Europe).gbc" size 1048576 crc d5fdf68a sha1 d5c37eabe3311666123b22f44a973c06d96bfce0 ) + rom ( name "WWF Attitude (USA, Europe).gbc" size 1048576 crc d5fdf68a sha1 d5c37eabe3311666123b22f44a973c06d96bfce0 flags verified ) ) game ( @@ -47589,6 +47078,12 @@ game ( rom ( name "Xtreme Sports (World) (Switch).gbc" size 4194304 crc c0437e08 sha1 5da3ad1c5354f29a74c571c2b598da96213afbe1 flags verified ) ) +game ( + name "Xtreme Sports (World) (Limited Run Games)" + description "Xtreme Sports (World) (Limited Run Games)" + rom ( name "Xtreme Sports (World) (Limited Run Games).gbc" size 4194304 crc b8a3ecdd sha1 7ec1e0e88f4827c421dc91cff03ad7932bd652f5 ) +) + game ( name "Xtreme Wheels (Europe)" description "Xtreme Wheels (Europe)" @@ -47607,12 +47102,6 @@ game ( rom ( name "Xtreme Wheels (Japan) (Possible Proto) (NP).gbc" size 1048576 crc 30132ab8 sha1 a9f67640d20771e64b1474144fcca9beebdde85d ) ) -game ( - name "Xzap (World) (Aftermarket) (Unl)" - description "Xzap (World) (Aftermarket) (Unl)" - rom ( name "Xzap (World) (Aftermarket) (Unl).gbc" size 262144 crc 68ceec9c sha1 35ae73d3ec93c95fdad9a358ccc34bcfc12445b1 ) -) - game ( name "Yakouchuu GB (Japan)" description "Yakouchuu GB (Japan)" @@ -47625,24 +47114,6 @@ game ( rom ( name "Yars' Revenge (USA, Europe) (GB Compatible).gbc" size 1048576 crc d6a26444 sha1 45fb176d539ae4a65af1f6340a9bd398dd7956d2 ) ) -game ( - name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" - description "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b304833d sha1 c2be46b8230bfcf509d031902c9bf144de97ef58 ) -) - -game ( - name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc f15351c8 sha1 a78ff2eef780287bbdc37df122cfc1c504526662 ) -) - -game ( - name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b70c1c7f sha1 ce25cdf6a6264586423e76e34dc42779d39a1cb1 ) -) - game ( name "Yin Ban Zhongwen RPG Zhanlve + Dongzuo + Yizhi 12 in 1 (Taiwan) (Unl)" description "Yin Ban Zhongwen RPG Zhanlve + Dongzuo + Yizhi 12 in 1 (Taiwan) (Unl)" @@ -47793,22 +47264,10 @@ game ( rom ( name "Yuenan Zhanyi X - Shenru Dihou (Taiwan) (Unl).gbc" size 2097152 crc 602951a6 sha1 6703e9f68b989c976e93bd2eb63f884ceaff63f1 ) ) -game ( - name "Zagan Warrior (World) (Aftermarket) (Unl)" - description "Zagan Warrior (World) (Aftermarket) (Unl)" - rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gbc" size 262144 crc e770f71a sha1 99d9267946e7bf26942a8276863ba50ef0b8f90e ) -) - -game ( - name "Zap'em (World) (Aftermarket) (Unl)" - description "Zap'em (World) (Aftermarket) (Unl)" - rom ( name "Zap'em (World) (Aftermarket) (Unl).gbc" size 262144 crc 66f17c5e sha1 63d44c8c2492dc32bcf632feb2d994e9af25fc97 ) -) - game ( name "Zebco Fishing! (USA) (Rumble Version)" description "Zebco Fishing! (USA) (Rumble Version)" - rom ( name "Zebco Fishing! (USA) (Rumble Version).gbc" size 1048576 crc 3cc6b1f9 sha1 9b6c536b403c62af102e3800658c9dec258be249 ) + rom ( name "Zebco Fishing! (USA) (Rumble Version).gbc" size 1048576 crc 3cc6b1f9 sha1 9b6c536b403c62af102e3800658c9dec258be249 flags verified ) ) game ( @@ -47961,12 +47420,6 @@ game ( rom ( name "Zen-Nihon Shounen Soccer Taikai - Mezase Nihon Ichi! (Japan).gbc" size 2097152 crc efad8b34 sha1 bffe5fdb803f0872d1c0de9d152eb626c5b36147 ) ) -game ( - name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" - description "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" - rom ( name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc db0951d3 sha1 7b74c658f24894659cfda1fc3c7775fd9f7b6013 ) -) - game ( name "Zhen Sanguo Wushuang 2 - Shin Sangokumusou (Taiwan) (Unl)" description "Zhen Sanguo Wushuang 2 - Shin Sangokumusou (Taiwan) (Unl)" @@ -47979,12 +47432,24 @@ game ( rom ( name "Zhihuan Wang - Shoubu Qu (Taiwan) (Zh) (Unl).gbc" size 2097152 crc 8160b3f5 sha1 97d7e0d05205b02c6cb69e68978a3f0fd2e3fde0 ) ) +game ( + name "Zhihuan Wang 2 (China) (Zh) (Unl)" + description "Zhihuan Wang 2 (China) (Zh) (Unl)" + rom ( name "Zhihuan Wang 2 (China) (Zh) (Unl).gbc" size 524288 crc e6748d1f sha1 108c318a859b39e88d15b2e3dc4d26002286305f ) +) + game ( name "Zhizhu Xia III - Dianying Ban (Taiwan) (Unl)" description "Zhizhu Xia III - Dianying Ban (Taiwan) (Unl)" rom ( name "Zhizhu Xia III - Dianying Ban (Taiwan) (Unl).gbc" size 2097152 crc d311efcc sha1 9eb0c468d5f898ef7b4d6ff74d7ff497b8c7818d ) ) +game ( + name "Zhong Zhuang Ji Bing (China) (Pirate)" + description "Zhong Zhuang Ji Bing (China) (Pirate)" + rom ( name "Zhong Zhuang Ji Bing (China) (Pirate).gbc" size 2097152 crc ad626c50 sha1 c3b3d8d43495ded5e4aff1b9416fe4d43b8e7453 ) +) + game ( name "Zidane - Football Generation (Europe) (En,Fr,De,Es,It)" description "Zidane - Football Generation (Europe) (En,Fr,De,Es,It)" @@ -48003,12 +47468,6 @@ game ( rom ( name "Zoboomafoo - Playtime in Zobooland (USA).gbc" size 1048576 crc 38d91885 sha1 a85a113bc266325f807f110daaf30feeea4b2738 ) ) -game ( - name "Zodiac (World) (Aftermarket) (Unl)" - description "Zodiac (World) (Aftermarket) (Unl)" - rom ( name "Zodiac (World) (Aftermarket) (Unl).gbc" size 262144 crc c4d86c05 sha1 73bd9e6e3bede8de489680ba84129e8fd17abbc0 ) -) - game ( name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced) (GB Compatible)" description "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced) (GB Compatible)" @@ -48033,6 +47492,3200 @@ game ( rom ( name "Zok Zok Heroes (Japan).gbc" size 2097152 crc c09f9e1b sha1 91ab908fddebd926e7db8d61295a40955b2adc39 ) ) +game ( + name "Zook Z (USA) (Unl)" + description "Zook Z (USA) (Unl)" + rom ( name "Zook Z (USA) (Unl).gbc" size 1048576 crc a7b09e70 sha1 243cc40cfc6bcbd3b6106870773a72edff079904 ) +) + +clrmamepro ( + name "Nintendo - Game Boy Color (Aftermarket)" + description "Nintendo - Game Boy Color (Aftermarket)" + version 20240810-021134 + author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, bikerspade, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, gordonj, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, Psychofox11, psykopat, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xprism, xuom2, zg" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 2edc4684 sha1 a00b40a3f31bd875f4a0376d22099c3822c9ef98 ) +) + +game ( + name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc ff0a848b sha1 837cbb4cf3a92266833099fa06b95edfcdb1865f ) +) + +game ( + name "2123 (World) (Aftermarket) (Unl)" + description "2123 (World) (Aftermarket) (Unl)" + rom ( name "2123 (World) (Aftermarket) (Unl).gbc" size 262144 crc 22836942 sha1 eb9a2aff6485962f1a7773b7138f3c4208fa36e4 ) +) + +game ( + name "3D Quasars (World) (Aftermarket) (Unl)" + description "3D Quasars (World) (Aftermarket) (Unl)" + rom ( name "3D Quasars (World) (Aftermarket) (Unl).gbc" size 262144 crc 1fd94e67 sha1 3f32226538d8c7f0c866c4b73e9f828265f2bb5b ) +) + +game ( + name "5 Minutes until Goodbye (World) (GB Compatible) (Aftermarket) (Unl)" + description "5 Minutes until Goodbye (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "5 Minutes until Goodbye (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 48f0b5f2 sha1 fcb0161c637cd3d0f1ae66d032917f94aea11047 ) +) + +game ( + name "60 Minutes til Rot (World) (v1.6b) (GB Compatible) (Aftermarket) (Unl)" + description "60 Minutes til Rot (World) (v1.6b) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "60 Minutes til Rot (World) (v1.6b) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9a10228a sha1 43ee50322e45c533fe67972db9a9d56f91a6a99b ) +) + +game ( + name "Aardvark (World) (Aftermarket) (Unl)" + description "Aardvark (World) (Aftermarket) (Unl)" + rom ( name "Aardvark (World) (Aftermarket) (Unl).gbc" size 262144 crc 270d45b9 sha1 34a8d00af6be9083409e6fccd0825c6f185d135d flags verified ) +) + +game ( + name "Ack Ack Attack (World) (Aftermarket) (Unl)" + description "Ack Ack Attack (World) (Aftermarket) (Unl)" + rom ( name "Ack Ack Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc c5bedd2e sha1 2a5c7cfb58ccb233a4e688f007ff1436c6c9a208 ) +) + +game ( + name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 1b5b9e64 sha1 c5dad32be800c36814a0f9b940e99b5eada34150 ) +) + +game ( + name "Adventure (World) (Aftermarket) (Unl)" + description "Adventure (World) (Aftermarket) (Unl)" + rom ( name "Adventure (World) (Aftermarket) (Unl).gbc" size 262144 crc c23d33c9 sha1 d579a1753d7875413f9e0022285b5741665e4abc ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (En) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (En) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (En) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9f81e7a0 sha1 895148bc0a3b6f9ec59bebae43413d1f4eafd21a ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a5d0d1ec sha1 bc6367f77c235640cea5a1230cee253c99f846e5 ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (Ja) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (Ja) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (Ja) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 3c9b424f sha1 7bd924752dca6fd772f6df9360117bd4b006ad88 ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (Es) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (Es) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (Es) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 2f758976 sha1 2aa834c26a06771d53ce35bb0b5b1b9c87e9e2ce ) +) + +game ( + name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" + description "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f689b91e sha1 e55e427819916bb02189efe3883fb1dab3d80d35 ) +) + +game ( + name "Agency (World) (Aftermarket) (Unl)" + description "Agency (World) (Aftermarket) (Unl)" + rom ( name "Agency (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0d1bb2f7 sha1 5266589244fab2e9ff047af9f72641cda91e1d90 ) +) + +game ( + name "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" + description "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Agent B (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31b6e3fa sha1 11b3ce59c4eb86cee05873eb473dbf262cf986bd ) +) + +game ( + name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae767ad7 sha1 1a332aac66b24381f16819d1145fd4a917f2e0f3 ) +) + +game ( + name "Airwolf 16 (World) (Aftermarket) (Unl)" + description "Airwolf 16 (World) (Aftermarket) (Unl)" + rom ( name "Airwolf 16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 6ecfd234 sha1 968355e655492a9aa5c36faacac9d34b289132bd ) +) + +game ( + name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" + description "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b4d50eed sha1 f4513fc525cbcfa4a2804b55ce20c809e01d1c87 ) +) + +game ( + name "Alley Cat (World) (Aftermarket) (Unl)" + description "Alley Cat (World) (Aftermarket) (Unl)" + rom ( name "Alley Cat (World) (Aftermarket) (Unl).gbc" size 262144 crc edb3ac37 sha1 a9aa1ecad6b67a6e5096fb1c10e39899c00a96a0 ) +) + +game ( + name "Android Nim (World) (Aftermarket) (Unl)" + description "Android Nim (World) (Aftermarket) (Unl)" + rom ( name "Android Nim (World) (Aftermarket) (Unl).gbc" size 262144 crc bd1e0cd7 sha1 efe551c498f6fdb3089a5b453b043fb61246e777 ) +) + +game ( + name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + description "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc dfcd02ef sha1 041473b2381dd9e11b3cbda5858f9841324327af ) +) + +game ( + name "Apollo Mission (World) (Aftermarket) (Unl)" + description "Apollo Mission (World) (Aftermarket) (Unl)" + rom ( name "Apollo Mission (World) (Aftermarket) (Unl).gbc" size 262144 crc bec9d9a2 sha1 b2bcc61bcf269c0f5c0ce2a6e0bb1c7015dc9ff9 ) +) + +game ( + name "Arena 3000 (World) (Aftermarket) (Unl)" + description "Arena 3000 (World) (Aftermarket) (Unl)" + rom ( name "Arena 3000 (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c17c15c sha1 007d23f73f68de01c250ec3d07403679137851ff ) +) + +game ( + name "Astral Possession (World) (GB Compatible) (Aftermarket) (Unl)" + description "Astral Possession (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Astral Possession (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 788043b5 sha1 0d5e4098b62e93c68108cfd5b767d45241ec6963 ) +) + +game ( + name "Astro Plumber (World) (Aftermarket) (Unl)" + description "Astro Plumber (World) (Aftermarket) (Unl)" + rom ( name "Astro Plumber (World) (Aftermarket) (Unl).gbc" size 262144 crc d746db41 sha1 bf46ab2a3a1ffc3b712b9ae5cfa05441781ac9e4 ) +) + +game ( + name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" + description "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc e6a96130 sha1 2cd0ef086c4b89497d9497a17d871a6568a9e2d3 ) +) + +game ( + name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 0d60b100 sha1 9cc1a5140b96ad072d36151f5d99ff6eb699e605 ) +) + +game ( + name "Auto Zone (World) (Aftermarket) (Unl)" + description "Auto Zone (World) (Aftermarket) (Unl)" + rom ( name "Auto Zone (World) (Aftermarket) (Unl).gbc" size 524288 crc 2a86d386 sha1 83a37fb5c5d82e0ff06bb22b63761af996e4ad61 ) +) + +game ( + name "Autobahn (World) (Aftermarket) (Unl)" + description "Autobahn (World) (Aftermarket) (Unl)" + rom ( name "Autobahn (World) (Aftermarket) (Unl).gbc" size 262144 crc d2fee5f1 sha1 6de35bd07f46720372ede9b5175399f2055e593d ) +) + +game ( + name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" + description "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc eac459fa sha1 68a5520be76c52a4936ad1756ea274667f2ac0e3 ) +) + +game ( + name "Back to Nature (World) (Aftermarket) (Unl)" + description "Back to Nature (World) (Aftermarket) (Unl)" + rom ( name "Back to Nature (World) (Aftermarket) (Unl).gbc" size 262144 crc 861f9a63 sha1 3f4a6cd105d4c8af0312bef482c08784bbbfb0eb ) +) + +game ( + name "Bandits at Zero (World) (Aftermarket) (Unl)" + description "Bandits at Zero (World) (Aftermarket) (Unl)" + rom ( name "Bandits at Zero (World) (Aftermarket) (Unl).gbc" size 524288 crc c70f413e sha1 c885e109fbb53445db9618c6768c2259e6135921 ) +) + +game ( + name "Basketbrawl (World) (Aftermarket) (Unl)" + description "Basketbrawl (World) (Aftermarket) (Unl)" + rom ( name "Basketbrawl (World) (Aftermarket) (Unl).gbc" size 1048576 crc 51efcd7b sha1 3c626d9fec2eb252a50c5022be46525103560fde ) +) + +game ( + name "Basketbrawl - Deluxe Edition (World) (Aftermarket) (Unl)" + description "Basketbrawl - Deluxe Edition (World) (Aftermarket) (Unl)" + rom ( name "Basketbrawl - Deluxe Edition (World) (Aftermarket) (Unl).gbc" size 1048576 crc 3da834f2 sha1 a627c03f958bc13b11e1832b6ab53fe298167ebc ) +) + +game ( + name "Battle Star (World) (Aftermarket) (Unl)" + description "Battle Star (World) (Aftermarket) (Unl)" + rom ( name "Battle Star (World) (Aftermarket) (Unl).gbc" size 524288 crc b2fd062f sha1 ac4206129704e31386c9c0a1c961a148398f0ba3 ) +) + +game ( + name "Berks (World) (Aftermarket) (Unl)" + description "Berks (World) (Aftermarket) (Unl)" + rom ( name "Berks (World) (Aftermarket) (Unl).gbc" size 262144 crc 10ded9ab sha1 8b4c282cf973cdd9926a69ae1d8fcbaf79f8552b ) +) + +game ( + name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 65536 crc b0401d96 sha1 ee5f2db597bb2fa06efe4a279a887b97bf23cac6 ) +) + +game ( + name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0d464785 sha1 790b9d231f6e66027e76264ef646c7a7cb9c878c ) +) + +game ( + name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + description "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 936443e2 sha1 b874c45d4866d5ef0c0d9837502ae42dd0ea3787 ) +) + +game ( + name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" + description "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 45c5f990 sha1 ec8c467e955d69b2084805f11a954e0d90855461 ) +) + +game ( + name "Blaze (World) (Aftermarket) (Unl)" + description "Blaze (World) (Aftermarket) (Unl)" + rom ( name "Blaze (World) (Aftermarket) (Unl).gbc" size 262144 crc 7d2519c7 sha1 f9b1422a91cc1f3a55526ef8ba81b7a8297fc55e ) +) + +game ( + name "Blinky's Revenge (World) (Aftermarket) (Unl)" + description "Blinky's Revenge (World) (Aftermarket) (Unl)" + rom ( name "Blinky's Revenge (World) (Aftermarket) (Unl).gbc" size 262144 crc 2d2f9c2b sha1 1c39cc02396c74e7b0b282ead510e94c77ff7f1e ) +) + +game ( + name "Block Droppin' (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Block Droppin' (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Block Droppin' (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 7e8ec278 sha1 6e8577c68402888a3244f153909a959f701eca0e ) +) + +game ( + name "Block Droppin' (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Block Droppin' (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Block Droppin' (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 5a0f9578 sha1 37743ac843330cfc8350e67238fdd395174ca1d4 ) +) + +game ( + name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 440a2260 sha1 8472981264122ea588d991628c51020545779926 ) +) + +game ( + name "Boing! (World) (Aftermarket) (Unl)" + description "Boing! (World) (Aftermarket) (Unl)" + rom ( name "Boing! (World) (Aftermarket) (Unl).gbc" size 2097152 crc 91961796 sha1 09fde4065941784bab4cf8f624a0398049ed4add ) +) + +game ( + name "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" + description "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" + rom ( name "Bomb Runner 1-2 (World) (Aftermarket) (Unl).gbc" size 262144 crc d4c95ac0 sha1 3d020eb6e118b431899d79ce4a7bda9bc571c3a0 ) +) + +game ( + name "Booga-Boo (World) (Aftermarket) (Unl)" + description "Booga-Boo (World) (Aftermarket) (Unl)" + rom ( name "Booga-Boo (World) (Aftermarket) (Unl).gbc" size 262144 crc 7fa7fe54 sha1 00323df5a855f1499810dfe959a58d105daf6871 ) +) + +game ( + name "Booty (World) (Aftermarket) (Unl)" + description "Booty (World) (Aftermarket) (Unl)" + rom ( name "Booty (World) (Aftermarket) (Unl).gbc" size 262144 crc ef6c39c8 sha1 3c487ddc03d935b583e186d1cc395966ef490412 ) +) + +game ( + name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e92ce3d4 sha1 1ddf864188dfd741ccda0b0715e75e162d212605 ) +) + +game ( + name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" + description "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ee1c2e1d sha1 b95dfdf10820671ab5f734ed7180cbf1967ca277 ) +) + +game ( + name "Boxing Master (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Boxing Master (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Boxing Master (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc d1fc5295 sha1 cd336de23457b30cf7a5bf6ae62e8c606507a5a5 ) +) + +game ( + name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" + description "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" + rom ( name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl).gbc" size 524288 crc 437a2973 sha1 9c219e2c489f5140314e89fbdc0bb387e1f1eed0 ) +) + +game ( + name "Bubble Frog (World) (GB Compatible) (Aftermarket) (Unl)" + description "Bubble Frog (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bubble Frog (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 0fd51f93 sha1 e4894fd9392a9e1c42d432bc73681ca5bccfe9a8 ) +) + +game ( + name "Bubble Trouble (World) (Aftermarket) (Unl)" + description "Bubble Trouble (World) (Aftermarket) (Unl)" + rom ( name "Bubble Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc 3374918b sha1 892388f81f7815ea3bca17632a6a9a33a6edafac ) +) + +game ( + name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc e3f64fec sha1 51e302fd27d579c9a4e8109e6ea4af3275d475dd ) +) + +game ( + name "Bug Byte (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Bug Byte (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bug Byte (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc ee41d61b sha1 68f5712ca543c9f02b731e6dc8ec042fc790f839 ) +) + +game ( + name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" + description "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a5d6cd6a sha1 7464af8e6d9d0a4b11f510d22789a6830cd4c272 ) +) + +game ( + name "Bygone Choices (World) (GB Compatible) (Aftermarket) (Unl)" + description "Bygone Choices (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bygone Choices (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc dbaec8ec sha1 699b752e8a4a21b7f814f59e35260e0b82fc6795 ) +) + +game ( + name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52da152b sha1 1bb4a376c03af67ca1e8426375fe1a644499d9ae ) +) + +game ( + name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" + description "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" + rom ( name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 1f2823cb sha1 8906832db7816be01ed37728f6e5a23e981e7e38 ) +) + +game ( + name "Canoe Slalom (World) (Aftermarket) (Unl)" + description "Canoe Slalom (World) (Aftermarket) (Unl)" + rom ( name "Canoe Slalom (World) (Aftermarket) (Unl).gbc" size 262144 crc 38ce9e68 sha1 9fc025682ea0f19f975aa492dd51c5710d8b04a7 ) +) + +game ( + name "Cappimon (World) (v1.1) (Demo) (Aftermarket) (Unl)" + description "Cappimon (World) (v1.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Cappimon (World) (v1.1) (Demo) (Aftermarket) (Unl).gbc" size 262144 crc ee6da010 sha1 a9d24cc03a6892035eaa448fea9c54ba16569b2d ) +) + +game ( + name "Cappimon (World) (v1.0) (Demo) (Aftermarket) (Unl)" + description "Cappimon (World) (v1.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Cappimon (World) (v1.0) (Demo) (Aftermarket) (Unl).gbc" size 262144 crc 46201a19 sha1 c641e81c551158a2cf3a43403ddb384a7d76bab4 ) +) + +game ( + name "Capybara Quest (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Capybara Quest (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Capybara Quest (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b4719bab sha1 5e952ffe5136fd818d8663047f195f20dad9c3f6 ) +) + +game ( + name "Capybara Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Capybara Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Capybara Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 10854c85 sha1 7c4cdccc471ccf925a9ccf258c3e862681c3d1e9 ) +) + +game ( + name "Capybara Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Capybara Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Capybara Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 0795de60 sha1 7bed040a4bd916d04a9b251d14c89c9c1361cf09 ) +) + +game ( + name "Capybara Village (World) (v1.1) (Proto) (Aftermarket) (Unl)" + description "Capybara Village (World) (v1.1) (Proto) (Aftermarket) (Unl)" + rom ( name "Capybara Village (World) (v1.1) (Proto) (Aftermarket) (Unl).gbc" size 524288 crc b761bac5 sha1 9c299efb05516075a67516875ecfe47a32d04ef0 ) +) + +game ( + name "Capybara Village (World) (v1.0) (Proto) (Cozy Spring Jam) (Aftermarket) (Unl)" + description "Capybara Village (World) (v1.0) (Proto) (Cozy Spring Jam) (Aftermarket) (Unl)" + rom ( name "Capybara Village (World) (v1.0) (Proto) (Cozy Spring Jam) (Aftermarket) (Unl).gbc" size 524288 crc 44deeab3 sha1 057ade8edd41efbfb168ad709e95222c7c0118fa ) +) + +game ( + name "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cargo (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a65d66f4 sha1 83c35ad553bde5ce3a6af418d7f8ad1fbe73b0f6 ) +) + +game ( + name "Castlevania - Demon Castle (World) (Aftermarket) (Unl)" + description "Castlevania - Demon Castle (World) (Aftermarket) (Unl)" + rom ( name "Castlevania - Demon Castle (World) (Aftermarket) (Unl).gbc" size 4194304 crc af20c186 sha1 8b593ebcb4c30f7709ca97ec977e8680df9b5fb7 ) +) + +game ( + name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 280937cc sha1 9ec53942f0136076b6468671562764e1ab9dee3b ) +) + +game ( + name "Cat Jumper (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cat Jumper (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cat Jumper (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc cde77e9d sha1 1acc8a49751cd45a84e53a435ddeed0357b87894 ) +) + +game ( + name "Cave Fighter (World) (Aftermarket) (Unl)" + description "Cave Fighter (World) (Aftermarket) (Unl)" + rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gbc" size 262144 crc 6f4641f0 sha1 05b441e3542452b1724017d20e2db602d0997773 ) +) + +game ( + name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc defb3151 sha1 94770d13bd9b1b52224fe753f94ec580e1b4017c ) +) + +game ( + name "Cavelon (World) (Aftermarket) (Unl)" + description "Cavelon (World) (Aftermarket) (Unl)" + rom ( name "Cavelon (World) (Aftermarket) (Unl).gbc" size 262144 crc 9fdd01f6 sha1 ff40729d06a6ce91446347b4bd69deaa6ba7d8b4 ) +) + +game ( + name "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" + description "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" + rom ( name "Chase the Chuck Wagon (World) (Aftermarket) (Unl).gbc" size 262144 crc 3c3d653c sha1 27b462be532a37c15798eba0fd48154eff596753 ) +) + +game ( + name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 490a874a sha1 92567a6a58739a38e0d7b35d1327ccb999527fa0 ) +) + +game ( + name "Chopper War (World) (Aftermarket) (Unl)" + description "Chopper War (World) (Aftermarket) (Unl)" + rom ( name "Chopper War (World) (Aftermarket) (Unl).gbc" size 524288 crc eb0f4f3e sha1 26970bb0753e792aaeb328e0f88d650acd413a9d ) +) + +game ( + name "Choro-Q (World) (Aftermarket) (Unl)" + description "Choro-Q (World) (Aftermarket) (Unl)" + rom ( name "Choro-Q (World) (Aftermarket) (Unl).gbc" size 262144 crc e40e99bd sha1 8534c4fe58aef32b8cfd4812fa1f2c1094e6b129 ) +) + +game ( + name "Chromanoids (World) (v1.1) (Aftermarket) (Unl)" + description "Chromanoids (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Chromanoids (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc 05d5d28f sha1 2885e9bfeca429a261f0871e31fdd3c5e682bd33 ) +) + +game ( + name "Chromanoids (World) (v1.0) (Aftermarket) (Unl)" + description "Chromanoids (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Chromanoids (World) (v1.0) (Aftermarket) (Unl).gbc" size 262144 crc 50c4585f sha1 2d1dc090806463a6ff8c2fc17c32061a9e731d6f ) +) + +game ( + name "Chrome and Blood (World) (v1.02) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Chrome and Blood (World) (v1.02) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chrome and Blood (World) (v1.02) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5c3f27d7 sha1 cda9b333b019dbe460f2a5cebe71c0cae258d7cd ) +) + +game ( + name "Chrome and Blood (World) (v1.00) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Chrome and Blood (World) (v1.00) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chrome and Blood (World) (v1.00) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 15cb5c58 sha1 a0d441f71caed08a52a41813d74031f13fd49d49 ) +) + +game ( + name "Chumbles Bumbles (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Chumbles Bumbles (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chumbles Bumbles (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0ff2779c sha1 976790e64ce929a48a756cd1df46f325a7819f31 ) +) + +game ( + name "Church of Pastor Chuck (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Church of Pastor Chuck (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Church of Pastor Chuck (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b9ca1669 sha1 d86af4b9288df8dc175a4c5647bc010328aab257 ) +) + +game ( + name "Climb It (World) (Aftermarket) (Unl)" + description "Climb It (World) (Aftermarket) (Unl)" + rom ( name "Climb It (World) (Aftermarket) (Unl).gbc" size 262144 crc e7210290 sha1 19f3b825eada3eda3135350bd0ddca6a20a5281f ) +) + +game ( + name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c4b00adb sha1 07e4254c7f74b9d4caa6a1231558b2430dff163a flags verified ) +) + +game ( + name "Closet Monsters (World) (GB Compatible) (Aftermarket) (Unl)" + description "Closet Monsters (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Closet Monsters (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 57b5d189 sha1 42e8694bb746df0b61662238d81369b15e26e6de ) +) + +game ( + name "Cold Nights (World) (Aftermarket) (Unl)" + description "Cold Nights (World) (Aftermarket) (Unl)" + rom ( name "Cold Nights (World) (Aftermarket) (Unl).gbc" size 524288 crc cdca8a46 sha1 5a2222da34e7cf9166502f9a6bea13a713744e89 ) +) + +game ( + name "Commando (World) (Aftermarket) (Unl)" + description "Commando (World) (Aftermarket) (Unl)" + rom ( name "Commando (World) (Aftermarket) (Unl).gbc" size 262144 crc 5381b103 sha1 414bb6bdc1ed5647707d7d49f194c387d4098f00 ) +) + +game ( + name "Cookie Monster Munch (World) (Aftermarket) (Unl)" + description "Cookie Monster Munch (World) (Aftermarket) (Unl)" + rom ( name "Cookie Monster Munch (World) (Aftermarket) (Unl).gbc" size 262144 crc 420db35c sha1 0584d434503040f3922595250c9b311f62483e70 ) +) + +game ( + name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" + description "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c53ace00 sha1 02fdc52bc934b80aa41520d92cf0340753d8f668 ) +) + +game ( + name "Cops and Robbers (World) (Aftermarket) (Unl)" + description "Cops and Robbers (World) (Aftermarket) (Unl)" + rom ( name "Cops and Robbers (World) (Aftermarket) (Unl).gbc" size 262144 crc 3c185eca sha1 8f8bbd15c0ab85345f3a3ae7e737e596311c19a1 ) +) + +game ( + name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc fe1bdae6 sha1 00d86bbdbc228ff3ea0684984a261cadbed5fb0a ) +) + +game ( + name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 1780b904 sha1 fcbe2c2389e6c51a38eb17eb80ffb2e51955c7f2 ) +) + +game ( + name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc e983a31f sha1 1d811dd440572243f9e95527d970f3ffa91ddbdf ) +) + +game ( + name "Cosmo Knight ZiON (World) (En,Es) (v2.38) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En,Es) (v2.38) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En,Es) (v2.38) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 936752aa sha1 68e31afa8bc49f8b5e7ba9d978896539669cf3d1 ) +) + +game ( + name "Crazy Golf (World) (Aftermarket) (Unl)" + description "Crazy Golf (World) (Aftermarket) (Unl)" + rom ( name "Crazy Golf (World) (Aftermarket) (Unl).gbc" size 262144 crc f7fe3d01 sha1 b06f47a713b66efa9133be43653c7c4cb5ebc93c ) +) + +game ( + name "Crest RPG (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Crest RPG (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Crest RPG (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c28f1ec5 sha1 2dd0b6a18e265653d382414de009ec8f154880da ) +) + +game ( + name "Cult of Blood, The (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + description "Cult of Blood, The (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cult of Blood, The (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5064aa20 sha1 2700521c7ff492fb015cc8dd453672a5989b80a7 ) +) + +game ( + name "Cult of Blood, The (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + description "Cult of Blood, The (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cult of Blood, The (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 9015c454 sha1 60b41b89cc9bce22ea06595ee332c3c1549db935 ) +) + +game ( + name "Cuthbert Enters the Tombs of Doom (World) (Aftermarket) (Unl)" + description "Cuthbert Enters the Tombs of Doom (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert Enters the Tombs of Doom (World) (Aftermarket) (Unl).gbc" size 524288 crc 149a2951 sha1 2e7d760cd0836599bbc4222c66dddb4643183f07 ) +) + +game ( + name "Cuthbert in Space (World) (Aftermarket) (Unl)" + description "Cuthbert in Space (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert in Space (World) (Aftermarket) (Unl).gbc" size 262144 crc c64000f3 sha1 6818167c491863cb19c2308c177203e38e0338d9 ) +) + +game ( + name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gbc" size 262144 crc 30204c4e sha1 d6fb35f3bdd44429f88c10551692e1adf14356ab ) +) + +game ( + name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl).gbc" size 262144 crc 502385c4 sha1 3a310be21d5cc077da6eb8e3afa99ccff2eda84e ) +) + +game ( + name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc a504b906 sha1 4634631f2c0b4a618aeefc114e5b8e4ba9c7ee04 ) +) + +game ( + name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl).gbc" size 262144 crc a9714871 sha1 7d5b22d1c528603007e340f9d3562c1e53f10796 ) +) + +game ( + name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl).gbc" size 262144 crc 26d3fe7a sha1 36c9649d4e99fdcaa4cf590963d0c49a3cf8084e ) +) + +game ( + name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" + description "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc d34b719a sha1 446ca937d3e54ce33a49d1fff4692b3b906b539e ) +) + +game ( + name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc df19aa9f sha1 412f18ba08f2f2a2afbf3bfb5281e360d7aba31d ) +) + +game ( + name "Darklite (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Darklite (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Darklite (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 98a264a8 sha1 4cbd2cc8779698deb61f39ca255c6f45db7bd3b9 ) +) + +game ( + name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc bb64f51c sha1 1611ddfdb9af72f20ddeca4133d8eebd0f14e424 ) +) + +game ( + name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" + description "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" + rom ( name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl).gbc" size 262144 crc 57ca8f69 sha1 8992f14f02bd37e11cb05511c17fff3d253ccf25 ) +) + +game ( + name "Days Without (World) (Aftermarket) (Unl)" + description "Days Without (World) (Aftermarket) (Unl)" + rom ( name "Days Without (World) (Aftermarket) (Unl).gbc" size 262144 crc 437b4921 sha1 cb21c1bca18d750ecde91dc3adb6b599c2ad75fa ) +) + +game ( + name "Death Race 16 (World) (Aftermarket) (Unl)" + description "Death Race 16 (World) (Aftermarket) (Unl)" + rom ( name "Death Race 16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b9488ec sha1 56b8a2d7117b12ff5e709e6a258f9a0b3b0ebe24 ) +) + +game ( + name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7cff943e sha1 065b5325d44cb0e40f7b7803d707b8c1ea9ea5b2 ) +) + +game ( + name "Descent (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Descent (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Descent (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7d3ce321 sha1 1a42289186a7722a8ccdbd35bcd704f832dc3c04 ) +) + +game ( + name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c6b965b9 sha1 ac43f43bdcfc0347f24a0a70de213a4b701d8155 ) +) + +game ( + name "Dicee! (World) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + description "Dicee! (World) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dicee! (World) (v1.4) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b7f0a85f sha1 6911854fe18000b0fe6015863240d0664d914547 ) +) + +game ( + name "Dicee! (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Dicee! (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dicee! (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 08b37ad8 sha1 27e7a34d44640162a4aec02e28b93d295d78180b ) +) + +game ( + name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" + description "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ef349515 sha1 06fe25086432c82f1e4b4c44473dd5b487a8af05 ) +) + +game ( + name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" + description "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7c0f52cc sha1 8bc16b70838f9245b7e37c6dbe57159b294fbf81 ) +) + +game ( + name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" + description "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f4ff5eb0 sha1 6b421505acc626a34bb9306a3d88e1964a4502f3 ) +) + +game ( + name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52cf7153 sha1 74e6246405dd52d4c5c2eabc417946550c637164 ) +) + +game ( + name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8ca9dbe0 sha1 cf6eaac37c4ae1b3cfc4ed8d2ce73a143635b525 ) +) + +game ( + name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 3d87efd8 sha1 83201c43e9fc89f4393678ade8c6107b4cfdb628 ) +) + +game ( + name "Dork's Dilemma (World) (Aftermarket) (Unl)" + description "Dork's Dilemma (World) (Aftermarket) (Unl)" + rom ( name "Dork's Dilemma (World) (Aftermarket) (Unl).gbc" size 524288 crc 77b8b43b sha1 bd525f97cc316fed3f6271ed0929414df4c0389c ) +) + +game ( + name "Downer (World) (GB Compatible) (Aftermarket) (Unl)" + description "Downer (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Downer (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7a1c9a9f sha1 70044dca1282f4445fe05305586ecc69f4e52304 ) +) + +game ( + name "Dracula - Dark Reign (World) (Demo) (Aftermarket) (Unl)" + description "Dracula - Dark Reign (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Dracula - Dark Reign (World) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc 4cfb1db2 sha1 6052c794b2c30a0538f57af0ab5253c626c860c5 ) +) + +game ( + name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 9f30b891 sha1 9974d28975a2d8e1e41ce8f32351c6eef144919d ) +) + +game ( + name "Dragonmaster (World) (Aftermarket) (Unl)" + description "Dragonmaster (World) (Aftermarket) (Unl)" + rom ( name "Dragonmaster (World) (Aftermarket) (Unl).gbc" size 262144 crc 4aaf9f58 sha1 6400de1108f1c3e5fca15de47f62299bfc66a938 ) +) + +game ( + name "Dragonyhm (World) (v1.0.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonyhm (World) (v1.0.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonyhm (World) (v1.0.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 96f9b7c0 sha1 2b74d076cabff92e5935d922e8f37202a723aaf0 flags verified ) +) + +game ( + name "Dragonyhm (World) (v1.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonyhm (World) (v1.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonyhm (World) (v1.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc cad7369d sha1 0058096f8fcbb2774f908811aaa0b1ee54111493 ) +) + +game ( + name "Dungeon Crystal (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dungeon Crystal (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dungeon Crystal (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 028a6e47 sha1 3fb673067aee3c50b65f0f8316bfff46a76c19bb ) +) + +game ( + name "Dungeon Crystal (World) (v1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dungeon Crystal (World) (v1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dungeon Crystal (World) (v1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0eaeeca3 sha1 0b452000a244cd9757c4bb158d997785a13b0d1e ) +) + +game ( + name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7c41cef6 sha1 e2df238887da0b6cf79513c7799ad707740eae30 ) +) + +game ( + name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc abb154db sha1 f3b456d6318bee05150403efa5a933996e1d744a ) +) + +game ( + name "Egbert (World) (Aftermarket) (Unl)" + description "Egbert (World) (Aftermarket) (Unl)" + rom ( name "Egbert (World) (Aftermarket) (Unl).gbc" size 262144 crc a0e904fc sha1 ead756b54b2c1462708b4509ac35503f04e482cf ) +) + +game ( + name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc bffec2e1 sha1 a25cc6ee07e524f9a7121786bd0e513a1c6c2a8d ) +) + +game ( + name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9ca3cf6c sha1 d3f4d21bf543431672268b476802693b2da9b6b9 ) +) + +game ( + name "Escape from Vostok (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Escape from Vostok (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Escape from Vostok (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5d19bbcb sha1 6bb0ddd2b05d0ae6c7d2538f68f4b587901c29fd ) +) + +game ( + name "Everlasting Summer (World) (Proto) (Aftermarket) (Unl)" + description "Everlasting Summer (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Everlasting Summer (World) (Proto) (Aftermarket) (Unl).gbc" size 262144 crc e45f6923 sha1 a4d7b12c71faf37a6703ded4d8a39844cf4f0395 ) +) + +game ( + name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + description "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f222b03b sha1 c14f008cfc182f35fe670e14b57052ae4f8d1c60 ) +) + +game ( + name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" + description "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 050caa5e sha1 e4b61c220b046e2287272f9b1bef85ad2d835fe3 ) +) + +game ( + name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" + description "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" + rom ( name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 20fe84af sha1 18056b5b032955099c606651f26164de131e54a6 ) +) + +game ( + name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc bdaf8f3f sha1 d1ed0fb4d926f4c337399ca342644f89cf00790a ) +) + +game ( + name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e61c1dc2 sha1 d7a88a68ec65d9cf3f9521fc9ad9d3f4b51bac5d flags verified ) +) + +game ( + name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 63c6c960 sha1 b62ec7a341ea9a0bfe8f0b014da971b73606a86e ) +) + +game ( + name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc de373eba sha1 dbf2228017515b407ed9f4a9b3bf01bc2a5f7b0f ) +) + +game ( + name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" + description "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc 701847f5 sha1 aba3fecd55c0cee7fbe49506b367b7e94b56b81c ) +) + +game ( + name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" + description "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc f87760b3 sha1 ea0dd170812d1bcc38de1cabe12a372cd2178c95 ) +) + +game ( + name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" + description "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" + rom ( name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate).gbc" size 524288 crc 7bec6553 sha1 bdcadc0f98d8c9061cbe83c53a047719280b6e09 ) +) + +game ( + name "Fighter on the Path of Glory (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + description "Fighter on the Path of Glory (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fighter on the Path of Glory (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 38f208f3 sha1 a4034a72dfacfe33fc924ab689f9a9303656c43d ) +) + +game ( + name "Fillo - Crystal Version (World) (Aftermarket) (Unl)" + description "Fillo - Crystal Version (World) (Aftermarket) (Unl)" + rom ( name "Fillo - Crystal Version (World) (Aftermarket) (Unl).gbc" size 524288 crc 88bb855c sha1 2ffc4199d94f8b29b3f84b7bdb2694154a0bd285 ) +) + +game ( + name "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" + description "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Find Out (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5f8b660e sha1 3605a96f6713157a88e4d88989d2e2f11b9db42f ) +) + +game ( + name "Finders Keepers (World) (Aftermarket) (Unl)" + description "Finders Keepers (World) (Aftermarket) (Unl)" + rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gbc" size 524288 crc 4cfa0cfd sha1 db002f4a2500a9dc98a9ac7c263293d6e4a72cf1 ) +) + +game ( + name "Fire Ant (World) (Aftermarket) (Unl)" + description "Fire Ant (World) (Aftermarket) (Unl)" + rom ( name "Fire Ant (World) (Aftermarket) (Unl).gbc" size 262144 crc 154cc020 sha1 b58ed66838db34fc7f8475ccb670267119d623a5 ) +) + +game ( + name "Fireman Fred (World) (Aftermarket) (Unl)" + description "Fireman Fred (World) (Aftermarket) (Unl)" + rom ( name "Fireman Fred (World) (Aftermarket) (Unl).gbc" size 524288 crc 563d9ca7 sha1 e62a9c6b6a39f0cb662fdb07b72669355b706f57 ) +) + +game ( + name "Firemen (World) (Aftermarket) (Unl)" + description "Firemen (World) (Aftermarket) (Unl)" + rom ( name "Firemen (World) (Aftermarket) (Unl).gbc" size 262144 crc 7299401f sha1 84c68614334578f866cfa929df736377f04f5d04 ) +) + +game ( + name "Fishing for Asteroids (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Fishing for Asteroids (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fishing for Asteroids (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc aae310ed sha1 b874c82fe582ee34b93cd4f6dcfc16e6fe991efe ) +) + +game ( + name "Fishing for Asteroids (World) (v1.0) (Mini Jam 153) (GB Compatible) (Aftermarket) (Unl)" + description "Fishing for Asteroids (World) (v1.0) (Mini Jam 153) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fishing for Asteroids (World) (v1.0) (Mini Jam 153) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc efbefb4b sha1 966f3f17b7acf5a60212d300c62fd5a4e50047ae ) +) + +game ( + name "Fishnet Burn (World) (Demo) (Aftermarket) (Unl)" + description "Fishnet Burn (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Fishnet Burn (World) (Demo) (Aftermarket) (Unl).gbc" size 262144 crc a317673d sha1 3b28ba3bbcb2c387976e98a47650426131823c56 ) +) + +game ( + name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" + description "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc c8014615 sha1 7221f5e53f6027183301d06e258c6cb417007b8c ) +) + +game ( + name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + description "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 507f9ea2 sha1 28ad64e379dc60d6e1c2617e073f6361c0feb475 flags verified ) +) + +game ( + name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + description "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc fcc05ec4 sha1 64d31f34e189b3af08bf0c659a93f71dbf83ef71 ) +) + +game ( + name "Flooder (World) (Aftermarket) (Unl)" + description "Flooder (World) (Aftermarket) (Unl)" + rom ( name "Flooder (World) (Aftermarket) (Unl).gbc" size 32768 crc 253dcbe0 sha1 8fdcd8b02604ac5259fb6aa80e5ba67a03c861fb ) +) + +game ( + name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" + description "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" + rom ( name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl).gbc" size 32768 crc cdda76f8 sha1 e5eec8efc032aa5bce1826f7b6b8790c61c96e06 ) +) + +game ( + name "Foal's Creek (World) (v1.06) (GB Compatible) (Aftermarket) (Unl)" + description "Foal's Creek (World) (v1.06) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Foal's Creek (World) (v1.06) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 40027de8 sha1 6d4152d0db5c7fdc2d3271ffc9195494e637c85a ) +) + +game ( + name "Foal's Creek (World) (v1.05) (GB Compatible) (Aftermarket) (Unl)" + description "Foal's Creek (World) (v1.05) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Foal's Creek (World) (v1.05) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c0db789e sha1 025e83abce412435c41e77dc7ecc606af96f874b ) +) + +game ( + name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" + description "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fa2d92a1 sha1 24f02d116aafb7b55d6cfd6d263b7595986af843 ) +) + +game ( + name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4c21e563 sha1 f6f84f1a44d41fa7d26a9195ddf791fae53dfcdf ) +) + +game ( + name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" + description "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7543586a sha1 397821751ac6464582f61566f3a7c731a46b24ba ) +) + +game ( + name "Friendly Fire (World) (Aftermarket) (Unl)" + description "Friendly Fire (World) (Aftermarket) (Unl)" + rom ( name "Friendly Fire (World) (Aftermarket) (Unl).gbc" size 262144 crc 5c6dca2b sha1 8f8085010e28aa8bdb312d086b0002b706742282 ) +) + +game ( + name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc d8be10d6 sha1 d09f4d2f799ac2e2731be0171625846d28d0f57e ) +) + +game ( + name "From Below Pocket (World) (Aftermarket) (Unl)" + description "From Below Pocket (World) (Aftermarket) (Unl)" + rom ( name "From Below Pocket (World) (Aftermarket) (Unl).gbc" size 131072 crc 35ad9b5a sha1 c0e072bfb88c84dc68b2eded1f9c088d75ffa5ed ) +) + +game ( + name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" + description "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 85edfba4 sha1 8a95571a32c5a23bd6be4edf6429f630d7a1a15a ) +) + +game ( + name "Fury (World) (Aftermarket) (Unl)" + description "Fury (World) (Aftermarket) (Unl)" + rom ( name "Fury (World) (Aftermarket) (Unl).gbc" size 262144 crc 7217c41d sha1 ef532b587eb438f1a39a77086ac0b8bbae23a16d ) +) + +game ( + name "G-Man (World) (Aftermarket) (Unl)" + description "G-Man (World) (Aftermarket) (Unl)" + rom ( name "G-Man (World) (Aftermarket) (Unl).gbc" size 524288 crc ff3beab1 sha1 cb9486ca9a6ad3903662963aa966145257ef92a6 ) +) + +game ( + name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc fd2e40f4 sha1 e442316132506ff223a9e5f33d874b71ec09d71a flags verified ) +) + +game ( + name "Game Boy Camera Gallery - Mystery Show (World) (v1.4) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "Game Boy Camera Gallery - Mystery Show (World) (v1.4) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Game Boy Camera Gallery - Mystery Show (World) (v1.4) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc aba1f99a sha1 8278abbe74202537bdc42f2e00875a12e77c9115 ) +) + +game ( + name "Game Boy Camera Gallery - Mystery Show (World) (v1.2) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "Game Boy Camera Gallery - Mystery Show (World) (v1.2) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Game Boy Camera Gallery - Mystery Show (World) (v1.2) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b3629b4a sha1 649678adc47eeb1386a90084ddb2fbf99b08ca4c ) +) + +game ( + name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f1948966 sha1 14849ab5831c71949ec3a1fe7657050057d2cf29 ) +) + +game ( + name "Game with The Cerulean Blob, The (World) (Demo) (Aftermarket) (Unl)" + description "Game with The Cerulean Blob, The (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Game with The Cerulean Blob, The (World) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc be05262e sha1 9fff6703a876d19027f8d8c590d1223d0e931420 ) +) + +game ( + name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 96721e5d sha1 90fad94433a5b0dbcf73f4a2d4ebb75d7ab065c4 ) +) + +game ( + name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a02d2ae2 sha1 7eb6865c5c265193763ec0bf751d26964e870120 ) +) + +game ( + name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f20c0097 sha1 691af25434a09931a302ced52c757d28b9b06619 ) +) + +game ( + name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 164999eb sha1 197d3d194d4cb6cae9a358f7fb53d6de649e7c5f ) +) + +game ( + name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 60b075d1 sha1 0a66254b2327b48657de64d6102ac05f1e8700e7 ) +) + +game ( + name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 1a169897 sha1 0636b968e8e24fe7c1910f61db6e94fa84824494 ) +) + +game ( + name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 593965ff sha1 75d566045a680aaed4d40b83b6418cbfab5b4422 ) +) + +game ( + name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc d81ab567 sha1 1dfd3c4508ffb6598662bcf1b16ec109a9282dd5 ) +) + +game ( + name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f795689c sha1 9a332127182e8155d1a3dc53e1382a6c9dde6aeb ) +) + +game ( + name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 660ed37b sha1 0792fbef010cac21c12cbcb8b3c85b3af30faec4 ) +) + +game ( + name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 6dc4faaa sha1 7617083f9b13b2f95bdf1b0b327ffb4f8ccbe3c9 ) +) + +game ( + name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 8780e125 sha1 7163bfbaa2cae2f9d41c472128f69a4fa5879180 ) +) + +game ( + name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc 4aa9a9c2 sha1 ac697bc27a126c1389e6bef94a2c83404e8819f2 ) +) + +game ( + name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 32e2ea48 sha1 ee11d5397316b69eee5ae3023de08c3b919c93df ) +) + +game ( + name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ea87ad5d sha1 433e25df1421e77cdc807296e1ed662d9e43d685 ) +) + +game ( + name "Ghost Town (World) (Aftermarket) (Unl)" + description "Ghost Town (World) (Aftermarket) (Unl)" + rom ( name "Ghost Town (World) (Aftermarket) (Unl).gbc" size 262144 crc 52efcc35 sha1 1a4a7846d6c87f0bd8b267aa6a8aa98e797fedf8 ) +) + +game ( + name "Gods of the Universe (World) (Aftermarket) (Unl)" + description "Gods of the Universe (World) (Aftermarket) (Unl)" + rom ( name "Gods of the Universe (World) (Aftermarket) (Unl).gbc" size 262144 crc 27b87354 sha1 74eb8cd698097290b93fb08d9b19486d05411877 ) +) + +game ( + name "Gopher (World) (Aftermarket) (Unl)" + description "Gopher (World) (Aftermarket) (Unl)" + rom ( name "Gopher (World) (Aftermarket) (Unl).gbc" size 262144 crc 22802c30 sha1 e629199b6bd492bd5efa77c0d4d467e053d44877 ) +) + +game ( + name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ab10cec6 sha1 9dcaa6824fab806683737bdf1c76609c68c451a5 ) +) + +game ( + name "GPC Rally (World) (v1.1) (Aftermarket) (Unl)" + description "GPC Rally (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "GPC Rally (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc 2ed2487c sha1 a711bbb2d7dc2b0c377ecd7b20f4862330961b51 ) +) + +game ( + name "GPC Rally (World) (v1.0) (Aftermarket) (Unl)" + description "GPC Rally (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "GPC Rally (World) (v1.0) (Aftermarket) (Unl).gbc" size 262144 crc 3b15bdb8 sha1 b6500b0250d8358644e41e26ed8fb92c5b24535d ) +) + +game ( + name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a5ad3c0b sha1 1cf0cf6d1da5c5337856ecc0a60d2e9fb3c98f58 ) +) + +game ( + name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" + description "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b29fc03f sha1 2f979202a4bf4f98f3026a7548a8b6c7008806bf ) +) + +game ( + name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a0e998e1 sha1 ab656383e9aaaa2991aa344bdc8f21370f0eda36 ) +) + +game ( + name "Gridtrap (World) (Aftermarket) (Unl)" + description "Gridtrap (World) (Aftermarket) (Unl)" + rom ( name "Gridtrap (World) (Aftermarket) (Unl).gbc" size 262144 crc 5a5453f6 sha1 b43d05eddcd1ab2d5934dd2a722f145a3084c4ad ) +) + +game ( + name "Grimace's Birthday (World) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (Aftermarket) (Unl).gbc" size 1048576 crc 7f4386e9 sha1 d6358d100ea65d34d95588f800635b64927baf82 ) +) + +game ( + name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl).gbc" size 1048576 crc 7744f551 sha1 035b7417e03c4e264a90212f2a3811012f03c2a2 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl).gbc" size 1048576 crc 9dee42fe sha1 071fa179df96950c3c92b0abbe32092b1816ec40 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc 9baa5f46 sha1 d247c03119ac14f97fdeeaa6bf0defa98e35fa17 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc ab41a9ef sha1 d8e727745e285f5e467f5eccbfd30ee175bafc2e flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl).gbc" size 1048576 crc f8e8e1f3 sha1 a3fdfe3981e800fa7c73ff989bc06426f668c331 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl).gbc" size 1048576 crc a7b59d7b sha1 295fdc3218d1699dea6d5832d068b721fccf9bd4 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc f3879ef0 sha1 27d7ee2f31bf575185711217c3cc9e08cbc5928a flags verified ) +) + +game ( + name "Gun Law (World) (Aftermarket) (Unl)" + description "Gun Law (World) (Aftermarket) (Unl)" + rom ( name "Gun Law (World) (Aftermarket) (Unl).gbc" size 262144 crc 3a0b6823 sha1 c49f7e0a5055f836528a7bc0cb6f45f221c76475 ) +) + +game ( + name "Gunslinger (World) (Aftermarket) (Unl)" + description "Gunslinger (World) (Aftermarket) (Unl)" + rom ( name "Gunslinger (World) (Aftermarket) (Unl).gbc" size 262144 crc 0dfd765f sha1 8410ef1558649f9badc71629827ba1500510d221 ) +) + +game ( + name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" + description "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" + rom ( name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl).gbc" size 524288 crc 2d9b59bf sha1 d89fe1cd97d1ef2c457aa90b1c00e7b473c57270 ) +) + +game ( + name "Guzzler (World) (Aftermarket) (Unl)" + description "Guzzler (World) (Aftermarket) (Unl)" + rom ( name "Guzzler (World) (Aftermarket) (Unl).gbc" size 524288 crc 3684abd0 sha1 e36cd02fe2b697901843c4cbf6d83da8a9b7b923 ) +) + +game ( + name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" + description "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c7297c31 sha1 c38cc0e80a2e04693e3a86574c03f23f3e472c88 flags verified ) +) + +game ( + name "Harbour Attack (World) (Aftermarket) (Unl)" + description "Harbour Attack (World) (Aftermarket) (Unl)" + rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc 7455782e sha1 1d0b3779007ba8f34e11b189552955dbf5c75a28 ) +) + +game ( + name "Hat Boy (World) (GB Compatible) (Aftermarket) (Unl)" + description "Hat Boy (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hat Boy (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 81d24d61 sha1 7265cad6c8e253d3cf6d1f0dcb218316f10ca091 ) +) + +game ( + name "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" + description "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Haunted (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 4b3670bd sha1 f245b8e21716a400769488b852f15d276f3549a6 ) +) + +game ( + name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" + description "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 287afc75 sha1 42ccc76883c041bc5c6c25a2e61ccc939c14811f ) +) + +game ( + name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6e484d6a sha1 7282ef5cc2354345c8832b4dde66a559de74f73f ) +) + +game ( + name "Heebie Jeebies (World) (Aftermarket) (Unl)" + description "Heebie Jeebies (World) (Aftermarket) (Unl)" + rom ( name "Heebie Jeebies (World) (Aftermarket) (Unl).gbc" size 262144 crc 73762d53 sha1 d427f18cb854e1387d93c19b88cb7193975e6472 ) +) + +game ( + name "Hidden Gems (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + description "Hidden Gems (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hidden Gems (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6f430dda sha1 e0cfe038063b1cd601a5f1b5af047efc705a7aaa ) +) + +game ( + name "Hidden Gems (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Hidden Gems (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hidden Gems (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7296d7e0 sha1 ae0fd7bcda2a3d7c1c342157ecb801ba8e380b5f ) +) + +game ( + name "High Noon (World) (Aftermarket) (Unl)" + description "High Noon (World) (Aftermarket) (Unl)" + rom ( name "High Noon (World) (Aftermarket) (Unl).gbc" size 262144 crc 1d00e48d sha1 21d5e871ed009a674659344d3d768fb2389c0d04 ) +) + +game ( + name "Hightail (World) (Demo 4F) (Aftermarket) (Unl)" + description "Hightail (World) (Demo 4F) (Aftermarket) (Unl)" + rom ( name "Hightail (World) (Demo 4F) (Aftermarket) (Unl).gbc" size 524288 crc f199c768 sha1 c794f30bedc69aa4d3567ab8f06f4ad651d5be24 ) +) + +game ( + name "Hightail (World) (Demo 4A) (Aftermarket) (Unl)" + description "Hightail (World) (Demo 4A) (Aftermarket) (Unl)" + rom ( name "Hightail (World) (Demo 4A) (Aftermarket) (Unl).gbc" size 262144 crc 8f01efcb sha1 bbf1f2af7594862f94b72f2f5a7be54040aa8569 ) +) + +game ( + name "Hime's Quest (World) (Aftermarket) (Unl)" + description "Hime's Quest (World) (Aftermarket) (Unl)" + rom ( name "Hime's Quest (World) (Aftermarket) (Unl).gbc" size 2097152 crc 546f578a sha1 ff90ca3ec7fb5d02865ae3cfd807ad3541dd21fc ) +) + +game ( + name "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" + description "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" + rom ( name "Hime's Quest (World) (Digital) (Aftermarket) (Unl).gbc" size 2097152 crc de5c21c2 sha1 7b6672c46c23aaa282bd4fded0713c6dfae2eb66 ) +) + +game ( + name "Hopp It (World) (Aftermarket) (Unl)" + description "Hopp It (World) (Aftermarket) (Unl)" + rom ( name "Hopp It (World) (Aftermarket) (Unl).gbc" size 262144 crc 675fbae3 sha1 cc10828f99675068eb79310b629f1365540b2979 ) +) + +game ( + name "Host, The (World) (Aftermarket) (Unl)" + description "Host, The (World) (Aftermarket) (Unl)" + rom ( name "Host, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 5f783000 sha1 05cc1f1e52167c6985ebb0a3e67af1fc2fbff93c ) +) + +game ( + name "Hugo (World) (Aftermarket) (Unl)" + description "Hugo (World) (Aftermarket) (Unl)" + rom ( name "Hugo (World) (Aftermarket) (Unl).gbc" size 524288 crc 6581c78a sha1 390d2665f34ceaa5e34cc9f8f7c26d9e7583a92b ) +) + +game ( + name "Hunt the Gwumbus (World) (v2.1) (Aftermarket) (Unl)" + description "Hunt the Gwumbus (World) (v2.1) (Aftermarket) (Unl)" + rom ( name "Hunt the Gwumbus (World) (v2.1) (Aftermarket) (Unl).gbc" size 524288 crc 956f1e5d sha1 66769e2feb53ad70503849f271146c6f830bc2fe ) +) + +game ( + name "Hunter in the Lost Forest (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "Hunter in the Lost Forest (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hunter in the Lost Forest (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc feac2611 sha1 1b10f2ec15d25584da2f2c123ecc97df7f7a0af0 ) +) + +game ( + name "Hunter in the Lost Forest (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + description "Hunter in the Lost Forest (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hunter in the Lost Forest (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ee633b7b sha1 6fc0ab0c6dffc8925ceb538ffc78cc70cd4ac0e4 ) +) + +game ( + name "Infall (World) (Aftermarket) (Unl)" + description "Infall (World) (Aftermarket) (Unl)" + rom ( name "Infall (World) (Aftermarket) (Unl).gbc" size 131072 crc d9d90319 sha1 aafaf33fa43c7f0fd65cc8af03a42df25361fc74 ) +) + +game ( + name "Inscryption (World) (v0.5) (Aftermarket) (Unl)" + description "Inscryption (World) (v0.5) (Aftermarket) (Unl)" + rom ( name "Inscryption (World) (v0.5) (Aftermarket) (Unl).gbc" size 524288 crc ae0a1c16 sha1 480ce539500d814fd3822fed7525c21027ac361b ) +) + +game ( + name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fea1cdb9 sha1 ac10ca63f15ca78af9f7d0eabb85eef8733aef50 ) +) + +game ( + name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d6c1c1ac sha1 d722e95155455cf146a97222ccbc2237bea86509 ) +) + +game ( + name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" + description "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9e97ac30 sha1 c07237d0f9c13b36ac2fcc5324b6e81122b0e189 ) +) + +game ( + name "Jet Set Willy (World) (Aftermarket) (Unl)" + description "Jet Set Willy (World) (Aftermarket) (Unl)" + rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gbc" size 262144 crc 659295ee sha1 bcb5a0e4566572aeb6cddea0897903ba207dc54f ) +) + +game ( + name "Jet Set Willy II - The Final Frontier (World) (Aftermarket) (Unl)" + description "Jet Set Willy II - The Final Frontier (World) (Aftermarket) (Unl)" + rom ( name "Jet Set Willy II - The Final Frontier (World) (Aftermarket) (Unl).gbc" size 524288 crc 8a4c58fa sha1 2e5b5a943b9f449bccb968b52ebc3dc8a4b3cb83 ) +) + +game ( + name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8884d532 sha1 a41195443613fb4414d8536b1f3494677f6f253d ) +) + +game ( + name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" + description "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 570a8043 sha1 1ccbf555412a417135acea0b7b185a7f795a89da ) +) + +game ( + name "Junior Maths 2 (World) (Aftermarket) (Unl)" + description "Junior Maths 2 (World) (Aftermarket) (Unl)" + rom ( name "Junior Maths 2 (World) (Aftermarket) (Unl).gbc" size 262144 crc 72c67d63 sha1 648273123a1bb64cd7fda7f611bb9cf53a5b0214 ) +) + +game ( + name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6a5abba1 sha1 0b3deef7a27201e81b4d39bc0bd10ff7ec73e380 ) +) + +game ( + name "Kikstart (World) (Aftermarket) (Unl)" + description "Kikstart (World) (Aftermarket) (Unl)" + rom ( name "Kikstart (World) (Aftermarket) (Unl).gbc" size 524288 crc 9a9f483b sha1 bc472506f73f0c1a3f0a610c0136b324b7635c7f ) +) + +game ( + name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f19d5e86 sha1 0f0e01a143182a9784c80a882ac206d02d8679d7 ) +) + +game ( + name "KnockOut (World) (Aftermarket) (Unl)" + description "KnockOut (World) (Aftermarket) (Unl)" + rom ( name "KnockOut (World) (Aftermarket) (Unl).gbc" size 131072 crc a060e59f sha1 164e078fce73674e3a5ad1cfd9e881813ce7a210 ) +) + +game ( + name "Larion's Tinker Toys (World) (Proto 2) (Aftermarket) (Unl)" + description "Larion's Tinker Toys (World) (Proto 2) (Aftermarket) (Unl)" + rom ( name "Larion's Tinker Toys (World) (Proto 2) (Aftermarket) (Unl).gbc" size 262144 crc fe421365 sha1 545551a382899d3689e2a501ccaccf500b9291df ) +) + +game ( + name "Larion's Tinker Toys (World) (Proto 1) (Aftermarket) (Unl)" + description "Larion's Tinker Toys (World) (Proto 1) (Aftermarket) (Unl)" + rom ( name "Larion's Tinker Toys (World) (Proto 1) (Aftermarket) (Unl).gbc" size 262144 crc 317d6e20 sha1 1867920232b32cf95eedfd47d9935e2d482c567d ) +) + +game ( + name "Laser Squad Alter (World) (Aftermarket) (Unl)" + description "Laser Squad Alter (World) (Aftermarket) (Unl)" + rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gbc" size 1048576 crc 32f24248 sha1 26f4efe636214e72ec724f8887ca79fbc8abad80 ) +) + +game ( + name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4a58315b sha1 5a234e33f7429b48f4374b5989e6df4d20352b4c ) +) + +game ( + name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5c405584 sha1 3ee043ba17f46a6afbbba8ac05f35d093b817fbc ) +) + +game ( + name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9a134100 sha1 75b5188a5b8a720ff08894379147c7870ac8825d ) +) + +game ( + name "Leaper (World) (Aftermarket) (Unl)" + description "Leaper (World) (Aftermarket) (Unl)" + rom ( name "Leaper (World) (Aftermarket) (Unl).gbc" size 524288 crc ed8cd385 sha1 425db2916263121f4aee91a8cab6286e39364f87 ) +) + +game ( + name "Lee Carvallo's Putting Challenge II (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Lee Carvallo's Putting Challenge II (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lee Carvallo's Putting Challenge II (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e8f402e2 sha1 16633011144af9519037672f67f42c9a9459bb65 ) +) + +game ( + name "Lee Carvallo's Putting Challenge II (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Lee Carvallo's Putting Challenge II (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lee Carvallo's Putting Challenge II (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 67f5a155 sha1 9f25aaf58f440cc62992b3268d239399fb5b377b ) +) + +game ( + name "Lee Carvallo's Putting Challenge II (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Lee Carvallo's Putting Challenge II (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lee Carvallo's Putting Challenge II (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 915b7710 sha1 10d60a8d381b547e622e84859ee6ae7f19995818 ) +) + +game ( + name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 953e25d1 sha1 018c7cada41e693a02b9c596d307b0aa9207eef4 ) +) + +game ( + name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1096252a sha1 c22cc79b25a05afad66e769dc0365b7c25f1bb85 ) +) + +game ( + name "Legend of Carrot (World) (Aftermarket) (Unl)" + description "Legend of Carrot (World) (Aftermarket) (Unl)" + rom ( name "Legend of Carrot (World) (Aftermarket) (Unl).gbc" size 131072 crc 965a02af sha1 fa404e1b2b4544b4969c14ec41f81e87304234c8 ) +) + +game ( + name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" + description "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a91a698f sha1 26f38b3908c086b3e349324da32bc37213975030 ) +) + +game ( + name "Liberator (World) (Aftermarket) (Unl)" + description "Liberator (World) (Aftermarket) (Unl)" + rom ( name "Liberator (World) (Aftermarket) (Unl).gbc" size 262144 crc ebe70d3d sha1 e3afce5a2357732ed15d7f3c0900f7b48113efdc ) +) + +game ( + name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" + description "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b8dd8409 sha1 281abb583ec0039e2c981c2e95f7a92002da081b ) +) + +game ( + name "Loco-coco (World) (Aftermarket) (Unl)" + description "Loco-coco (World) (Aftermarket) (Unl)" + rom ( name "Loco-coco (World) (Aftermarket) (Unl).gbc" size 262144 crc f6b9fe4e sha1 8a8972ff3e208280a746a2015a20f67248180a1c ) +) + +game ( + name "Love is Dead (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Love is Dead (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Love is Dead (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc dd537a3b sha1 f3e44fea9faed10c0aebaf11dd2f7821076a7315 ) +) + +game ( + name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" + description "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" + rom ( name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl).gbc" size 262144 crc 9edd066c sha1 4d43a38e8b5df41309f5b6ec13e4829db739d980 ) +) + +game ( + name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" + description "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" + rom ( name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl).gbc" size 262144 crc de5d5c0b sha1 5f038ef3657d3fbfb3be6917b24c3f933363ad4c ) +) + +game ( + name "Lunatic Tower (World) (Aftermarket) (Unl)" + description "Lunatic Tower (World) (Aftermarket) (Unl)" + rom ( name "Lunatic Tower (World) (Aftermarket) (Unl).gbc" size 524288 crc 6edacbb3 sha1 ee706a5f6272bda950a5d80ffc071453a9880fb6 ) +) + +game ( + name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f55a9d95 sha1 2b22fbd76e11e6e45053b1e6989de303e3033c9e ) +) + +game ( + name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5662865e sha1 a5ac99a4087bd5ea45417e5b4a7c9af10433911a ) +) + +game ( + name "Mage and the Grimoire of Beast (World) (En) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Mage and the Grimoire of Beast (World) (En) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mage and the Grimoire of Beast (World) (En) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4197bfd5 sha1 83f15e10963a2991636a382168aa035c7f340b3c ) +) + +game ( + name "Mage and the Grimoire of Beast (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Mage and the Grimoire of Beast (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mage and the Grimoire of Beast (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6d8126b4 sha1 89d7df077818f000fef3c59429a6deb1a423aa03 ) +) + +game ( + name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" + description "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c276843d sha1 852697a2952d2e7375b73aba877ebc17aa4f4179 ) +) + +game ( + name "Magician's Curse, The (World) (Aftermarket) (Unl)" + description "Magician's Curse, The (World) (Aftermarket) (Unl)" + rom ( name "Magician's Curse, The (World) (Aftermarket) (Unl).gbc" size 524288 crc f2b1967e sha1 3b5f97f9a0b4d63a3795695b0bda6e969de8e051 ) +) + +game ( + name "Mayhem (World) (Aftermarket) (Unl)" + description "Mayhem (World) (Aftermarket) (Unl)" + rom ( name "Mayhem (World) (Aftermarket) (Unl).gbc" size 262144 crc 4d739ad7 sha1 9f141728a74432820f47cc24d230dc56d6ac099b ) +) + +game ( + name "Meiji Jingu (World) (Aftermarket) (Unl)" + description "Meiji Jingu (World) (Aftermarket) (Unl)" + rom ( name "Meiji Jingu (World) (Aftermarket) (Unl).gbc" size 262144 crc 56905954 sha1 9656d278857f6cfa08b8820409b665306c3d18aa ) +) + +game ( + name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f614bdff sha1 7e46c193f6566f620acf20ead3a1fca1d677c221 ) +) + +game ( + name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 949c6ab9 sha1 34269af4db6c37b92fdc7f7f914c282174603ba8 ) +) + +game ( + name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 50618f4b sha1 c8d74af4746313800df3a23c1ad01f931e0e2eca flags verified ) +) + +game ( + name "Meteorite (World) (Aftermarket) (Unl)" + description "Meteorite (World) (Aftermarket) (Unl)" + rom ( name "Meteorite (World) (Aftermarket) (Unl).gbc" size 131072 crc fafbcebf sha1 25a81d916f1ed80a2bca2fe7a555433f06d025e3 ) +) + +game ( + name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" + description "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f9a5ed4e sha1 8b3e18287d5adf3b5a711e28a896f843927f22a2 ) +) + +game ( + name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" + description "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 177f0b6e sha1 e5fdb741d870de25affdc841c07eaa3000da25f5 ) +) + +game ( + name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 854f4297 sha1 a1a44ce8052f06349df3cbdf9a6d976609213d68 ) +) + +game ( + name "Mission Mars (World) (Aftermarket) (Unl)" + description "Mission Mars (World) (Aftermarket) (Unl)" + rom ( name "Mission Mars (World) (Aftermarket) (Unl).gbc" size 262144 crc f651fcf4 sha1 479c70dd9c63cdcad99ca44720a9e0e2582df119 ) +) + +game ( + name "Mob Creche Parallel Game (World) (En,Ja) (Aftermarket) (Unl)" + description "Mob Creche Parallel Game (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Mob Creche Parallel Game (World) (En,Ja) (Aftermarket) (Unl).gbc" size 262144 crc e138c5a5 sha1 9446639471efe21304c0c09c9540010941ae3f9f ) +) + +game ( + name "Mommy (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mommy (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mommy (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 5d644d24 sha1 3bc152e2899d54d6c400e2e0a114e0aa67a56a69 ) +) + +game ( + name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 39480c79 sha1 4348a7903e538e5367f2a60718f43cbeeccf96df ) +) + +game ( + name "Monkey Magic (World) (Aftermarket) (Unl)" + description "Monkey Magic (World) (Aftermarket) (Unl)" + rom ( name "Monkey Magic (World) (Aftermarket) (Unl).gbc" size 262144 crc c9c68715 sha1 bf5dc5593334fe1114461065a2b7284d28b31462 ) +) + +game ( + name "Monty on the Run (World) (Aftermarket) (Unl)" + description "Monty on the Run (World) (Aftermarket) (Unl)" + rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gbc" size 524288 crc fd1066ac sha1 8390175e6be4731d9afa91715d7f8dd11693bb69 ) +) + +game ( + name "Mount Vesuvius (World) (Aftermarket) (Unl)" + description "Mount Vesuvius (World) (Aftermarket) (Unl)" + rom ( name "Mount Vesuvius (World) (Aftermarket) (Unl).gbc" size 262144 crc 1292ecfb sha1 dd71a1a7282a8a68c70d705d8eab8b2bd73132e3 ) +) + +game ( + name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + description "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 362a84ba sha1 b4b3afa2379a07acab6965ae8fcf6d2ba82d6d7e ) +) + +game ( + name "Mr. Angry (World) (Aftermarket) (Unl)" + description "Mr. Angry (World) (Aftermarket) (Unl)" + rom ( name "Mr. Angry (World) (Aftermarket) (Unl).gbc" size 524288 crc b85e63a5 sha1 127ad5315e2bce37614a1e9f8605798e68718926 ) +) + +game ( + name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 846afc79 sha1 dae84fbc60839da29878714cd845c3704b915323 ) +) + +game ( + name "Munch It (World) (Aftermarket) (Unl)" + description "Munch It (World) (Aftermarket) (Unl)" + rom ( name "Munch It (World) (Aftermarket) (Unl).gbc" size 262144 crc 3d7ce6c7 sha1 55b390866d0922685bd1f42e8ee7310f021fa0dc ) +) + +game ( + name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" + description "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" + rom ( name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl).gbc" size 524288 crc ec4f9d49 sha1 357db81755f1f0eb732367dd4090c446eb226ddf ) +) + +game ( + name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" + description "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" + rom ( name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl).gbc" size 524288 crc 1ba7d27f sha1 d4c4be65ba469369cd90aaa733d0a8e8af6bcdc1 ) +) + +game ( + name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9bff7b15 sha1 1f3aac8a3725cd1d0968529afc1c2031372d8ed1 ) +) + +game ( + name "My Friendly Little Island (World) (Aftermarket) (Unl)" + description "My Friendly Little Island (World) (Aftermarket) (Unl)" + rom ( name "My Friendly Little Island (World) (Aftermarket) (Unl).gbc" size 1048576 crc f6bf0584 sha1 81d724ad696084283712145adfef15769648b045 ) +) + +game ( + name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc eedefa0c sha1 e63c16fe987fe655408be66198366a0147ac607c ) +) + +game ( + name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 53cf930c sha1 bd3272ca7ead64da3f68f774661a560add433b94 ) +) + +game ( + name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" + description "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 705b150f sha1 6258cf6ad167c9ae86609a8e620face1674a7ea7 ) +) + +game ( + name "Neonsomnia (World) (v0.1) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Neonsomnia (World) (v0.1) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neonsomnia (World) (v0.1) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 394ce9cb sha1 3d24808bf0bb1a06212a48309d8affe5d26eeeba ) +) + +game ( + name "Nightmare Hamlet (World) (Aftermarket) (Unl)" + description "Nightmare Hamlet (World) (Aftermarket) (Unl)" + rom ( name "Nightmare Hamlet (World) (Aftermarket) (Unl).gbc" size 131072 crc 574bf5b6 sha1 05d043816bb4eb9cc57b369ab5f966b610ba5c2f ) +) + +game ( + name "Ninja Master (World) (Aftermarket) (Unl)" + description "Ninja Master (World) (Aftermarket) (Unl)" + rom ( name "Ninja Master (World) (Aftermarket) (Unl).gbc" size 262144 crc bc550b84 sha1 0def135723ac40e4981c88f8888afbd40a15bb40 ) +) + +game ( + name "Number Builder (World) (Aftermarket) (Unl)" + description "Number Builder (World) (Aftermarket) (Unl)" + rom ( name "Number Builder (World) (Aftermarket) (Unl).gbc" size 262144 crc b8609d43 sha1 92952b752f50af889db891acc9eed8436ac6b87e ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e983e8d1 sha1 fc2a58d49327c88c895ae6681bde57e1a2687974 flags verified ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc ef42955e sha1 485b4d672d9edda40f9191f5f5cc223046000e67 flags verified ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 581efe4d sha1 125bb0564ee17f8e55046a1c25e53ee9a4254303 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e26ddbbb sha1 853115369b8ca583d038d00c1dde59b6a74b73a2 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 1e8ac5b9 sha1 99c11bef7feb17a9e7212cf9b6593478f671bc32 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f5df28c2 sha1 7b511444e1eb86fffcf93599a78e0e2c44aecc8a ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl).gbc" size 2097152 crc 63bddc68 sha1 fab777e607bd8aba70eb65829143039dbe6ac08e ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 1f1af42a sha1 ddcdbfa716d716e1b7bb258caaaa7b76d041b5a9 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" + description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt).gbc" size 524288 crc 834a8021 sha1 d5af2bf38eda4c181993e992764788003509ebfd ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 42d9c38c sha1 ae719190cf2f433c359bc425775710f4aa67e860 ) +) + +game ( + name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c055ef9 sha1 d4fa4e02753a9fe539f70d0927ba5bf9caa02d3c ) +) + +game ( + name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" + description "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7ed58128 sha1 e543c39f8e55b1788476b94028a54fc2fc9c7ea0 ) +) + +game ( + name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" + description "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9742276d sha1 cd8f18d6e5fabaa130a42e5618e29c5ff26f6a93 ) +) + +game ( + name "Olympic Skier (World) (Aftermarket) (Unl)" + description "Olympic Skier (World) (Aftermarket) (Unl)" + rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gbc" size 524288 crc 5e81cef7 sha1 a7a552a9eb984098a67e063c2eca907eec000fc1 ) +) + +game ( + name "One Day (World) (GB Compatible) (Aftermarket) (Unl)" + description "One Day (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "One Day (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fd52acc7 sha1 bdb5590b61791b89e9afa871d32648d7a66ce1f4 ) +) + +game ( + name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" + description "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 7348bb32 sha1 e63e06d602473206b21138f5322acf86b5b6b9b8 ) +) + +game ( + name "Out on a Limb (World) (Aftermarket) (Unl)" + description "Out on a Limb (World) (Aftermarket) (Unl)" + rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gbc" size 262144 crc a6671528 sha1 f21cb71adcea1029151930eb98c4e9b446e4cfee ) +) + +game ( + name "Outta Time (World) (Aftermarket) (Unl)" + description "Outta Time (World) (Aftermarket) (Unl)" + rom ( name "Outta Time (World) (Aftermarket) (Unl).gbc" size 262144 crc 18522ba7 sha1 e9ef4c1d24e42ba7920bf8e7d72f804f058b93c6 ) +) + +game ( + name "Outward (World) (Aftermarket) (Unl)" + description "Outward (World) (Aftermarket) (Unl)" + rom ( name "Outward (World) (Aftermarket) (Unl).gbc" size 131072 crc c554bf64 sha1 6cfb29fed8ce82384d9051424a4b55673c182c8f ) +) + +game ( + name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c6e83f41 sha1 44b117d94a80617a77abbdcc76d9d69b66efe56b ) +) + +game ( + name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 69483f81 sha1 4d162c9637a20cfc7c92e6ea7a61fad0ed22137a ) +) + +game ( + name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" + description "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" + rom ( name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 262144 crc 0db301c2 sha1 58ec8f209ed6e33adfb253014ea69ae1ee53c145 ) +) + +game ( + name "Pact, The (World) (Aftermarket) (Unl)" + description "Pact, The (World) (Aftermarket) (Unl)" + rom ( name "Pact, The (World) (Aftermarket) (Unl).gbc" size 262144 crc 304df19a sha1 97af064f9063cd353e55ac0e1f6d1ca8b4a6d2b9 ) +) + +game ( + name "Paku Paku GB (World) (GB Compatible) (Aftermarket) (Unl)" + description "Paku Paku GB (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Paku Paku GB (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 62b5a15f sha1 2b85528aef01cb5caab4cff898c2bc66e211b3bf ) +) + +game ( + name "Pancho (World) (Aftermarket) (Unl)" + description "Pancho (World) (Aftermarket) (Unl)" + rom ( name "Pancho (World) (Aftermarket) (Unl).gbc" size 524288 crc d32d46c5 sha1 2f46974e6d92f5deb277818d95426a4507b3701d ) +) + +game ( + name "Panik!16 (World) (Aftermarket) (Unl)" + description "Panik!16 (World) (Aftermarket) (Unl)" + rom ( name "Panik!16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b31122d sha1 98d74fd64e4f7e835f1101b05816b8938a34a416 ) +) + +game ( + name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" + description "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 154cb547 sha1 3b217c595e6a5b115dc7130123a321049cf01d22 ) +) + +game ( + name "Pilgrim's Peril (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + description "Pilgrim's Peril (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pilgrim's Peril (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 3c2bafdc sha1 d38f3f5e491dbaed84e88099987712449db9b33d ) +) + +game ( + name "Pilgrim's Peril (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + description "Pilgrim's Peril (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pilgrim's Peril (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc cdded15b sha1 2b85eb77ab2dcea4f645abcc1a66dbce54a6ebaa ) +) + +game ( + name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 189aa999 sha1 2cf46a36502eaf22ac9572fe1136d369fcbe9e46 ) +) + +game ( + name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" + description "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1601d6fa sha1 87b4edf0398f0154d7556e3cd96f97b19e699a40 ) +) + +game ( + name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 29415ff7 sha1 89b3fd633e8cef3b8523b1ef2a0072db2d7416d7 ) +) + +game ( + name "Pogo Pete (World) (Aftermarket) (Unl)" + description "Pogo Pete (World) (Aftermarket) (Unl)" + rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gbc" size 262144 crc 3001ed1b sha1 f9dab150843c2b8f300d36b1dd53dd1a22b481a3 ) +) + +game ( + name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 42298fd8 sha1 90c535bf70e2ca7b91af67b8f08865f423c3034f ) +) + +game ( + name "Pokettohiro! (World) (v1.0) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (v1.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (v1.0) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc b9e724ef sha1 28a01fd6ea95a146008435c5bc27b51b607bb86b ) +) + +game ( + name "Pokettohiro! (World) (v3.0) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (v3.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (v3.0) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc b9b4e3c0 sha1 a8ba9c09ef0889640e41d79838bcd98b7bc4e5d4 ) +) + +game ( + name "Pomape Castle (World) (GB Compatible) (Aftermarket) (Unl)" + description "Pomape Castle (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pomape Castle (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9350c71d sha1 a0f449e270b72de56bfea151b5ac271c0c7e3c93 ) +) + +game ( + name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 50393a65 sha1 2c2c6ed8be7a13bf279e435c5984f175c8affcad ) +) + +game ( + name "Postie (World) (GB Compatible) (Aftermarket) (Unl)" + description "Postie (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Postie (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ff6bbc83 sha1 3ff236972d1e344eb50e696db3cc090f2b5d28b1 ) +) + +game ( + name "Postman Pat's Trail Game (World) (Aftermarket) (Unl)" + description "Postman Pat's Trail Game (World) (Aftermarket) (Unl)" + rom ( name "Postman Pat's Trail Game (World) (Aftermarket) (Unl).gbc" size 262144 crc ad31b512 sha1 135977fe71677e3c49450e2c6ff63105d10dfaac ) +) + +game ( + name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6da19041 sha1 eb581935ad9223d723fdbc8339c03436df051947 ) +) + +game ( + name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" + description "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d0d8386d sha1 fbddf81a1663388ff0efeeb9051e68e0c323c839 ) +) + +game ( + name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f0191467 sha1 3876f1aa896759f427ad2dc88a48788817e60c06 flags verified ) +) + +game ( + name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e8f68acc sha1 156d315b7a2a035d5cd429fb8c7e051e67e83c93 flags verified ) +) + +game ( + name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 592b6097 sha1 874d5e4ffc7d36259bef6ec6a86a1de8289b8d54 ) +) + +game ( + name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b01c4ff1 sha1 898dbf10550af7e39b8f7a0818a78083ae40f4fe ) +) + +game ( + name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" + description "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a86cada1 sha1 b02096c489c0f36582061d6eb62beb17e8294b61 ) +) + +game ( + name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" + description "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e171f327 sha1 b03df48f48529ac1be79699d6f34f324adcfb436 ) +) + +game ( + name "Proof of Destruction (World) (Aftermarket) (Unl)" + description "Proof of Destruction (World) (Aftermarket) (Unl)" + rom ( name "Proof of Destruction (World) (Aftermarket) (Unl).gbc" size 262144 crc fa528f88 sha1 5062f16346c31cae1b13e469cb610ce84d4eecb2 ) +) + +game ( + name "Purple Turtles (World) (Aftermarket) (Unl)" + description "Purple Turtles (World) (Aftermarket) (Unl)" + rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gbc" size 262144 crc 471277df sha1 a73cb69d1fb42f45f3649c4d1b4775e98fe35b78 ) +) + +game ( + name "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" + description "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quartet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 46743216 sha1 bf866b438a602af386f8fad02727b4084edf6047 ) +) + +game ( + name "Quest Arrest (World) (v1.1) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "Quest Arrest (World) (v1.1) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quest Arrest (World) (v1.1) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9ac546d5 sha1 25b3a21135bfc7587c096b10f4a20d8b3095d721 ) +) + +game ( + name "Quest of the MX-129 Wizard (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Quest of the MX-129 Wizard (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quest of the MX-129 Wizard (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 776ab9fd sha1 65d98bae58e5e4f723b1ec838ad4e1f2036c4468 ) +) + +game ( + name "Raffles (World) (Aftermarket) (Unl)" + description "Raffles (World) (Aftermarket) (Unl)" + rom ( name "Raffles (World) (Aftermarket) (Unl).gbc" size 262144 crc e41d6472 sha1 4b5eb518ff52c235c674e0695fdde2b8b01f58fa ) +) + +game ( + name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" + description "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 09196a32 sha1 8218ad22b29fb32c66430a17a97775dd30b2f34b flags verified ) +) + +game ( + name "Remi's Pizzaria (World) (GB Compatible) (Aftermarket) (Unl)" + description "Remi's Pizzaria (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Remi's Pizzaria (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f7a4fcfb sha1 fdc8c8a1bab2dfcfe3e43175e830382fe63d5c7d ) +) + +game ( + name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc e92034d8 sha1 14b9614cea9be7d5c6e12aece692582ba2ca2b75 flags verified ) +) + +game ( + name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 3a1b1d83 sha1 4dda0cce6907de94eeae3f11a40238c3f5155ca7 ) +) + +game ( + name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc f8c7f180 sha1 07674d42f5d4efaec14750ae56d8f28c4b54c020 flags verified ) +) + +game ( + name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" + description "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 8bd98942 sha1 3a5dbafa829e57089de8cfc93c806f7ee023ff1b ) +) + +game ( + name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c761189c sha1 f7f18d83218b66b9d1cd7267d6d4acfd4eded6c7 ) +) + +game ( + name "Rig Attack (World) (Aftermarket) (Unl)" + description "Rig Attack (World) (Aftermarket) (Unl)" + rom ( name "Rig Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc d013d775 sha1 90bfd921c986abff4555b761cedc90ec36c43fff ) +) + +game ( + name "Ripjack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Ripjack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ripjack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 218b54ec sha1 624cb4afcabd03f4f2f4bea95f9998a6a04ae42b ) +) + +game ( + name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" + description "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae3f980b sha1 67f63517eacfea22922d07be0efc5fc8f8b8a1d2 ) +) + +game ( + name "Robin to the Rescue (World) (Aftermarket) (Unl)" + description "Robin to the Rescue (World) (Aftermarket) (Unl)" + rom ( name "Robin to the Rescue (World) (Aftermarket) (Unl).gbc" size 262144 crc 9cd52c18 sha1 ef3bea9ed0de41e311b5f15fccbb0f451848d56c ) +) + +game ( + name "Robo Knight (World) (Aftermarket) (Unl)" + description "Robo Knight (World) (Aftermarket) (Unl)" + rom ( name "Robo Knight (World) (Aftermarket) (Unl).gbc" size 524288 crc 8d4507f0 sha1 6012f9a3ae6201e363f46a75e0100552ecb91335 ) +) + +game ( + name "Rockets Vs Cars (World) (GB Compatible) (Aftermarket) (Unl)" + description "Rockets Vs Cars (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Rockets Vs Cars (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc eaae6f3e sha1 446e688f42e886c51c74719b93a326ae5b56920d ) +) + +game ( + name "Rockman (World) (Aftermarket) (Unl)" + description "Rockman (World) (Aftermarket) (Unl)" + rom ( name "Rockman (World) (Aftermarket) (Unl).gbc" size 262144 crc 490b5676 sha1 6f78200acb6698e268e26c1912d64a002cbd3d89 ) +) + +game ( + name "Rootin' Tootin' Cowboy Wizard Lizards (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Rootin' Tootin' Cowboy Wizard Lizards (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Rootin' Tootin' Cowboy Wizard Lizards (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1fcdc59e sha1 e741ac0918ce14df473600d34836f744c2507fa0 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a46baa15 sha1 87dd5a6ccb5db59dae09f1953062420977ad2d92 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5602ca84 sha1 49d692796a6d0f3dcfc988648b446c0934f0e794 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b2547aa6 sha1 981a464d6e1c9e5ac59549845b41dae4817ed3b8 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c18f82cb sha1 bd8cd5822dcc61f7eb0cf2584c9a5b5a94bde14a ) +) + +game ( + name "Ruin Run (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Ruin Run (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruin Run (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ddbfb0ce sha1 fb4730afe4e10529015513cc1dec8889c00cb373 ) +) + +game ( + name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" + description "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 2097152 crc 96b1ceec sha1 771135edfbc64f7332a9cbd0d72af7a9d0d71f82 ) +) + +game ( + name "RunieStory (World) (Aftermarket) (Unl)" + description "RunieStory (World) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (Aftermarket) (Unl).gbc" size 2097152 crc 2249b449 sha1 0f6a391d7e05f66092a98e411069fab8e3f24221 ) +) + +game ( + name "RunieStory (World) (v1.1) (Aftermarket) (Unl)" + description "RunieStory (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (v1.1) (Aftermarket) (Unl).gbc" size 2097152 crc dd81f722 sha1 f2ad05b15a4ed1611b0d5b52525d16a5f00867bc ) +) + +game ( + name "RunieStory (World) (Aftermarket) (Unl) (Alt)" + description "RunieStory (World) (Aftermarket) (Unl) (Alt)" + rom ( name "RunieStory (World) (Aftermarket) (Unl) (Alt).gbc" size 2097152 crc 367c802d sha1 b9ec81a8c71ea13b553b478535071715a2ab07d9 ) +) + +game ( + name "Runner (World) (Aftermarket) (Unl)" + description "Runner (World) (Aftermarket) (Unl)" + rom ( name "Runner (World) (Aftermarket) (Unl).gbc" size 262144 crc 4cd8ccb2 sha1 da735d415ed463a953bac45f4793342bd9be2e96 ) +) + +game ( + name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" + description "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 4e4af60b sha1 ab8d49a99d02eb5c97d75f62dfb3720eec2b5abd ) +) + +game ( + name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" + description "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 40dc168d sha1 af25acc86f0eef4ce72199383b96fcb4c9f0115e ) +) + +game ( + name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" + description "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc db928e22 sha1 e175d35e6112c347ecd1e0a379e98f430823ba94 ) +) + +game ( + name "Sergio Kidd (World) (En,Es) (v2.013) (Aftermarket) (Unl)" + description "Sergio Kidd (World) (En,Es) (v2.013) (Aftermarket) (Unl)" + rom ( name "Sergio Kidd (World) (En,Es) (v2.013) (Aftermarket) (Unl).gbc" size 1048576 crc e23bc705 sha1 986708b9cb96c56e3592030d45dc5433d3aa63c5 ) +) + +game ( + name "Sergio Kidd (World) (En,Es) (v1.995) (Aftermarket) (Unl)" + description "Sergio Kidd (World) (En,Es) (v1.995) (Aftermarket) (Unl)" + rom ( name "Sergio Kidd (World) (En,Es) (v1.995) (Aftermarket) (Unl).gbc" size 1048576 crc 1d871322 sha1 e57357be09657bc42e5ccee937edcf1653468402 ) +) + +game ( + name "Shark Attack (World) (Aftermarket) (Unl)" + description "Shark Attack (World) (Aftermarket) (Unl)" + rom ( name "Shark Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc cf80a2ba sha1 291f453a185f836fcafbd7e41945a409638980c0 ) +) + +game ( + name "Shoot It (World) (Aftermarket) (Unl)" + description "Shoot It (World) (Aftermarket) (Unl)" + rom ( name "Shoot It (World) (Aftermarket) (Unl).gbc" size 262144 crc 54afa0ff sha1 f3c574e274d1531e3f53511da0d57751e989a665 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 599132ec sha1 762087df0e5820f1e50da2a22f9ee3b8d16c3e49 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5370b1bf sha1 966e2d79ab4930039c3d6c43fdbb8cdc068ba347 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 16f34bcc sha1 c34e744b9120e3a1b2b054d3708e4ab594726c5a ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 31ce3f27 sha1 c33d685d5ea5cd6cd954af3bc9ee92719b9578b1 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc d54b53cb sha1 08948befa0227b795d00fe60e9eede6a1f56597b ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 314be6b5 sha1 37978f85ae92e7d9a53611659513fd360f57a5b1 ) +) + +game ( + name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" + description "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc 7ebcdd4e sha1 b99f43719155cafbc3dbd7df0ade281c3c7ba171 ) +) + +game ( + name "Sir Knight (World) (Aftermarket) (Unl)" + description "Sir Knight (World) (Aftermarket) (Unl)" + rom ( name "Sir Knight (World) (Aftermarket) (Unl).gbc" size 262144 crc 8c31c136 sha1 d8be26e0688301a76def8f5fbc246a9c9005862e ) +) + +game ( + name "Skelby (World) (Aftermarket) (Unl)" + description "Skelby (World) (Aftermarket) (Unl)" + rom ( name "Skelby (World) (Aftermarket) (Unl).gbc" size 524288 crc 6ec6c18c sha1 887555aa7e2e61b68a21020237b7d508bb71aded ) +) + +game ( + name "Skull Nightmare (World) (Aftermarket) (Unl)" + description "Skull Nightmare (World) (Aftermarket) (Unl)" + rom ( name "Skull Nightmare (World) (Aftermarket) (Unl).gbc" size 131072 crc c36941d3 sha1 49f03694965f79688aef724308c83988e71fd374 ) +) + +game ( + name "Skycon (World) (Aftermarket) (Unl)" + description "Skycon (World) (Aftermarket) (Unl)" + rom ( name "Skycon (World) (Aftermarket) (Unl).gbc" size 524288 crc 195dbc30 sha1 df29ece6c5f5b14840663495230135dd79c5163a ) +) + +game ( + name "Slime Dungeon (World) (GB Compatible) (Aftermarket) (Unl)" + description "Slime Dungeon (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Slime Dungeon (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 3967fb31 sha1 926e584b8952aba86761b430daedc5b91177e408 ) +) + +game ( + name "Slime's Adventure (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Slime's Adventure (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Slime's Adventure (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 61b14549 sha1 87b84c85bb32a1d0874053cdf749f8391a275324 ) +) + +game ( + name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" + description "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c906c5af sha1 0e0d472b282e3ea590e0f126baf633ef0d9298fa ) +) + +game ( + name "Smickeonn - The Game 2 - Virtual Boy Edition (World) (Aftermarket) (Unl)" + description "Smickeonn - The Game 2 - Virtual Boy Edition (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game 2 - Virtual Boy Edition (World) (Aftermarket) (Unl).gbc" size 1048576 crc 71ed0db8 sha1 e7b39b17e3e8e7ac1cf2e0b179e2c14874533835 ) +) + +game ( + name "Smickeonn - The Game Boy Adventure (World) (Aftermarket) (Unl)" + description "Smickeonn - The Game Boy Adventure (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game Boy Adventure (World) (Aftermarket) (Unl).gbc" size 1048576 crc 96efbfb9 sha1 3900ab947af4c582cd34cec7f2977219115d65e4 ) +) + +game ( + name "Smickeonn - The Game Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Smickeonn - The Game Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 02bb005e sha1 0c1bf424968530a70ecbe382d002fc6bd629962c ) +) + +game ( + name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1aecd096 sha1 8ce256d963a55badf71fd45047c173a74d76a92c ) +) + +game ( + name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6cf39388 sha1 9cf5a1d3e8119303a1f4b04b8f4d8b683aee699e ) +) + +game ( + name "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" + description "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snooze (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b246095f sha1 b7fdcc006c9c06dd391ee26d44b278d9d3793f6d ) +) + +game ( + name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" + description "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 9e864f1c sha1 ce5dc23c04ff18dfac2367e53d241e81c4bbc3a3 ) +) + +game ( + name "Space Fleet (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Space Fleet (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Space Fleet (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc d9244730 sha1 6987a43315abca95b85d84c278a6b1ae5dea185a ) +) + +game ( + name "Space War (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Space War (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Space War (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c54f07e1 sha1 de6107573654309805bbb0ac86a748311ae70d4e ) +) + +game ( + name "Spectipede (World) (Aftermarket) (Unl)" + description "Spectipede (World) (Aftermarket) (Unl)" + rom ( name "Spectipede (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c33f76e sha1 834a450d9ceb78b9d89d551300d4d0ea08cd8a6a ) +) + +game ( + name "Spiky Harold (World) (Aftermarket) (Unl)" + description "Spiky Harold (World) (Aftermarket) (Unl)" + rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gbc" size 262144 crc 7e9eda35 sha1 486d294b8cf226876581d543e3a08018321bc402 ) +) + +game ( + name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" + description "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 29320841 sha1 890fda255106ea64bac4973e2e9f4b31bb925d35 ) +) + +game ( + name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" + description "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 82658661 sha1 dd45b0e3f346ce33668d49092b29a44597686061 ) +) + +game ( + name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" + description "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ce90a95b sha1 75457c5affd0c126f2c916e857950b5cde46a95e ) +) + +game ( + name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" + description "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b3a04b44 sha1 b16f21b46dfe4e6ce0368e3c5a3fae397274ebbf ) +) + +game ( + name "Starseed (World) (GB Compatible) (Aftermarket) (Unl)" + description "Starseed (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Starseed (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e21ff9e0 sha1 3479e222263814374a557870034bc215aea3408d ) +) + +game ( + name "Starseed 2 (World) (GB Compatible) (Aftermarket) (Unl)" + description "Starseed 2 (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Starseed 2 (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc dd4528d2 sha1 43a02f79fd5da23cfeccc13aa5970265f428dddc ) +) + +game ( + name "Stellar Wars (World) (Aftermarket) (Unl)" + description "Stellar Wars (World) (Aftermarket) (Unl)" + rom ( name "Stellar Wars (World) (Aftermarket) (Unl).gbc" size 262144 crc e0b96256 sha1 ba2d10a2a5f3f073aea11e26ae5c53c9cf7866f8 ) +) + +game ( + name "Stratacombo (World) (v1.2) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Stratacombo (World) (v1.2) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stratacombo (World) (v1.2) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 43c70a69 sha1 9931a9e3a0e4a0edcd336acfb433713991a50ad2 ) +) + +game ( + name "Stratacombo (World) (v1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Stratacombo (World) (v1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stratacombo (World) (v1.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 06575da1 sha1 3c621c921d7995acb88754634328de8ec32b444b ) +) + +game ( + name "Stratagem Hero (World) (GB Compatible) (Aftermarket) (Unl)" + description "Stratagem Hero (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stratagem Hero (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ff118db9 sha1 f89ff66e8e593729ed9605b0107ed6d12d9b858d ) +) + +game ( + name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" + description "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2dc3fdae sha1 a551d904c4af661bd4b6e88063cb5541900117b0 ) +) + +game ( + name "Suicide Run (World) (Aftermarket) (Unl)" + description "Suicide Run (World) (Aftermarket) (Unl)" + rom ( name "Suicide Run (World) (Aftermarket) (Unl).gbc" size 262144 crc d29ab1aa sha1 df373f58e51155e32fb81825a9082150f6d263c8 ) +) + +game ( + name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c47330e2 sha1 6151286e93b2e2fb92f583371e650e36ab91aaf7 ) +) + +game ( + name "Super Gran (World) (Aftermarket) (Unl)" + description "Super Gran (World) (Aftermarket) (Unl)" + rom ( name "Super Gran (World) (Aftermarket) (Unl).gbc" size 262144 crc 98ee2e8a sha1 5afe9c7ab1b9d86048a570e7a37a0c244cb84e43 ) +) + +game ( + name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a38d702f sha1 301f93da4e5b0cd8dc3f1bf3e66e38176b8a909b ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl).gbc" size 524288 crc 8e1f6bb0 sha1 27522a35211b0f015fa9550c2520f1da1c346886 ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl).gbc" size 524288 crc f9731ee2 sha1 23855b95d04a6c7c6d2ce7977bb31dbe6c0e68a0 ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl).gbc" size 524288 crc 87956ddf sha1 b23320d5d3fde2a55b301f7bea324833c31c32d5 ) +) + +game ( + name "Super JetPak DX (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super JetPak DX (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super JetPak DX (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 22def6f9 sha1 e7438db01fbbdeea2404dbf3d093370421ec4e1c flags verified ) +) + +game ( + name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" + description "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 64921bb1 sha1 b36ec89e0299c19767cc5c6467fa3664abbc3017 ) +) + +game ( + name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + description "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b2b5dc4b sha1 aaa66863b2e68865359d1c0db2047bab6f64f9ee ) +) + +game ( + name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Swordsman on the Eternal Journey (World) (En,Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f2762fb0 sha1 b4d33ac2e410a55d27edb2abe6fc2268ca18ae26 ) +) + +game ( + name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + description "Swordsman on the Eternal Journey (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc bc3a78de sha1 54f9f0caa96edac7d336d85548e099a4e5110bdd ) +) + +game ( + name "Swordsman on the Eternal Journey (World) (It) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Swordsman on the Eternal Journey (World) (It) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordsman on the Eternal Journey (World) (It) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 4a733a47 sha1 a45a31e6491a5d8a9288dc64823d7266060681b3 ) +) + +game ( + name "Take Your Medicine (World) (En,Pt) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Take Your Medicine (World) (En,Pt) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Take Your Medicine (World) (En,Pt) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31a6b0ff sha1 baa07cfb71e42487eb57490c5b6cdec72e6893f7 ) +) + +game ( + name "Take Your Medicine (World) (En,Pt) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Take Your Medicine (World) (En,Pt) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Take Your Medicine (World) (En,Pt) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 255f67de sha1 8c973fafc9576e57a7714bda6425d30cdf7edd2c ) +) + +game ( + name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" + description "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a685f89a sha1 15a709d4300464b03ede4d774ce69cfb699c0fcf ) +) + +game ( + name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" + description "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" + rom ( name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl).gbc" size 262144 crc 257d9201 sha1 d78e0b03a3915531e780057c4ad7ed2b3f849825 ) +) + +game ( + name "Tank Attack (World) (Aftermarket) (Unl)" + description "Tank Attack (World) (Aftermarket) (Unl)" + rom ( name "Tank Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc c77dc518 sha1 4751a6999f4dbe7e66b997372588f6bd15e4d9d0 ) +) + +game ( + name "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" + description "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" + rom ( name "Tazz (World) (2022-10-13) (Aftermarket) (Unl).gbc" size 262144 crc 1d97b754 sha1 39226ed715ae8d94f9187c3e5e8a849eac92ca26 ) +) + +game ( + name "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" + description "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" + rom ( name "Tazz (World) (2022-10-17) (Aftermarket) (Unl).gbc" size 262144 crc 6fb0ba23 sha1 543118e54b166ea2b8b5979f8468cc2f5662161f ) +) + +game ( + name "Tiledentity (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Tiledentity (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiledentity (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 678383d3 sha1 a97c2b31ce138e81e0bfabee89aa58426d41e0a9 ) +) + +game ( + name "Tiledentity (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Tiledentity (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiledentity (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a9a24479 sha1 59b1d66807141ca42809189544e1104bd8d0454b ) +) + +game ( + name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc af13e718 sha1 307e51664db2101755b6c617f3d81ee58676c485 ) +) + +game ( + name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0518f5aa sha1 85e5cd0cf7a6cc4a5946c93fa8665235a686e554 ) +) + +game ( + name "Tir Na Nog (World) (Aftermarket) (Unl)" + description "Tir Na Nog (World) (Aftermarket) (Unl)" + rom ( name "Tir Na Nog (World) (Aftermarket) (Unl).gbc" size 1048576 crc 44524c90 sha1 ac712228460e9d4268f90ec4cf9ac2137fa667c4 ) +) + +game ( + name "To The Stars (World) (GB Compatible) (Aftermarket) (Unl)" + description "To The Stars (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "To The Stars (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2e1ca159 sha1 fb8269ff0377ac755b95e8e1ed935ad00d4476ee ) +) + +game ( + name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 16650a8b sha1 fe6eef70d48dda741f7ad3b6cc5e753e8cd13239 ) +) + +game ( + name "Tomte Trouble (World) (Aftermarket) (Unl)" + description "Tomte Trouble (World) (Aftermarket) (Unl)" + rom ( name "Tomte Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc a43d6b82 sha1 99730fe00703d655b1c806f49c9e3c2fb3dec58e flags verified ) +) + +game ( + name "Tools of Nexaura (World) (v0.4) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + description "Tools of Nexaura (World) (v0.4) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tools of Nexaura (World) (v0.4) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 50707e43 sha1 4a50327514554f075178f4d6342a4497d3122f31 ) +) + +game ( + name "Tower of Evil (World) (Aftermarket) (Unl)" + description "Tower of Evil (World) (Aftermarket) (Unl)" + rom ( name "Tower of Evil (World) (Aftermarket) (Unl).gbc" size 524288 crc aeb6e36f sha1 e9a6a007e935afb522c67d355e0354b0fb9af3c6 ) +) + +game ( + name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b0a32d51 sha1 4c0d639722d1cd8393e008d174b8f7266d089ead ) +) + +game ( + name "Treasure Island Color (World) (Aftermarket) (Unl)" + description "Treasure Island Color (World) (Aftermarket) (Unl)" + rom ( name "Treasure Island Color (World) (Aftermarket) (Unl).gbc" size 262144 crc 4ab0eb5a sha1 3ebddd4e1f5b3a87726ef34a5b7d36de8c722f36 ) +) + +game ( + name "Tristam Island (World) (v1.6) (GB Compatible) (Aftermarket) (Unl)" + description "Tristam Island (World) (v1.6) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tristam Island (World) (v1.6) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f6449829 sha1 5f1a11c4de8635fd5247ebb7f26273a40048567e flags verified ) +) + +game ( + name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4b9143ad sha1 0e51e398d44aaad74a7c622f7818b56a3b34db56 ) +) + +game ( + name "Tutti Frutti (World) (Aftermarket) (Unl)" + description "Tutti Frutti (World) (Aftermarket) (Unl)" + rom ( name "Tutti Frutti (World) (Aftermarket) (Unl).gbc" size 262144 crc ca377ca6 sha1 53d97b93b9d190de40ed2d81e18b4cbe44f99a23 ) +) + +game ( + name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 01239312 sha1 4f21c3539ef40a7630581fe50533371e0d1a1ba9 ) +) + +game ( + name "Tycoon Tex (World) (Aftermarket) (Unl)" + description "Tycoon Tex (World) (Aftermarket) (Unl)" + rom ( name "Tycoon Tex (World) (Aftermarket) (Unl).gbc" size 262144 crc fa8436ba sha1 d37bcd93d647ac7efb761c539785a4ef570cdcc8 ) +) + +game ( + name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" + description "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" + rom ( name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl).gbc" size 2097152 crc 8067298a sha1 e44280161ca9d482fae08de844ccc9754abf68b0 ) +) + +game ( + name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" + description "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" + rom ( name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0ce45101 sha1 f61677146ef67b026c636742f0109b8c478d0942 ) +) + +game ( + name "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" + description "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" + rom ( name "Tyrannosaurus Tex (World) (Aftermarket) (Unl).gbc" size 2097152 crc e90504c1 sha1 7e41e92f92ff06101e48dee758420f1bd3959013 ) +) + +game ( + name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 29bb9238 sha1 39fbfb220e9be0120090f770249049b3f3583f64 ) +) + +game ( + name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 977b54f4 sha1 016dde406896d827dcad682d40b52d0e9eeefa88 ) +) + +game ( + name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" + description "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 36e4ff4c sha1 b5c9b5f07e31729678637d883b2564c1448b0e57 ) +) + +game ( + name "Usurper Ghoul (World) (v1.9) (GB Compatible) (Aftermarket) (Unl)" + description "Usurper Ghoul (World) (v1.9) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Usurper Ghoul (World) (v1.9) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fc94dbf3 sha1 5be7317929c81780f478f745111f8f45798da866 ) +) + +game ( + name "UXB (World) (Aftermarket) (Unl)" + description "UXB (World) (Aftermarket) (Unl)" + rom ( name "UXB (World) (Aftermarket) (Unl).gbc" size 262144 crc dd42be4c sha1 6ef7abb689b1c75f613ed253644fbb0f377b7a95 ) +) + +game ( + name "Varmit (World) (Aftermarket) (Unl)" + description "Varmit (World) (Aftermarket) (Unl)" + rom ( name "Varmit (World) (Aftermarket) (Unl).gbc" size 2097152 crc e4827006 sha1 b61876c714c47f62a77304b79f6e34b8d0e7f8a2 ) +) + +game ( + name "Vixen (World) (Aftermarket) (Unl)" + description "Vixen (World) (Aftermarket) (Unl)" + rom ( name "Vixen (World) (Aftermarket) (Unl).gbc" size 524288 crc 0c347734 sha1 90f251f8f481f157de5b3efe3c8e3356ed1314b4 ) +) + +game ( + name "VOX (World) (Aftermarket) (Unl)" + description "VOX (World) (Aftermarket) (Unl)" + rom ( name "VOX (World) (Aftermarket) (Unl).gbc" size 262144 crc 346561fb sha1 54a03c77653a19eb1b0d8a6ac82f498f83f35ef2 ) +) + +game ( + name "Wacky Painter (World) (Aftermarket) (Unl)" + description "Wacky Painter (World) (Aftermarket) (Unl)" + rom ( name "Wacky Painter (World) (Aftermarket) (Unl).gbc" size 262144 crc 09daa18d sha1 5425dc675101d63bea03b1c8f46f86fe200ad392 ) +) + +game ( + name "Walaki (World) (Hu) (Aftermarket) (Unl)" + description "Walaki (World) (Hu) (Aftermarket) (Unl)" + rom ( name "Walaki (World) (Hu) (Aftermarket) (Unl).gbc" size 262144 crc 254875ac sha1 388d6c339b8d62db18e540f59a2930af4088ca7e ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1bfe1bf9 sha1 fae12dbbb75ae024e96a7ee21ad4077fdb5ed9a1 ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a381c914 sha1 adf37c5d2f706743b2a4946378df49ed19212039 ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 5519c167 sha1 04a53af6a77b884af91f8047d70fc0331bf23913 ) +) + +game ( + name "Water Grandprix (World) (Aftermarket) (Unl)" + description "Water Grandprix (World) (Aftermarket) (Unl)" + rom ( name "Water Grandprix (World) (Aftermarket) (Unl).gbc" size 262144 crc 82f54e7e sha1 4029e003870b2afb78a3644e24397d80fc5a3210 ) +) + +game ( + name "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" + description "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Waternet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc ef202121 sha1 a11f931b18ba42f48a91e817b7117fa0e3e79518 ) +) + +game ( + name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + description "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 75591760 sha1 e04b01ada17e6924503029cd09a107b7f5d06f17 ) +) + +game ( + name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + description "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc f8402dc5 sha1 6feb4178589e87c6267683078201f0630cca23d6 ) +) + +game ( + name "Wayfarer Boo - Pushing Through (World) (v1.1) (Aftermarket) (Unl)" + description "Wayfarer Boo - Pushing Through (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Wayfarer Boo - Pushing Through (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc 903d1b1a sha1 12b8a0bdadd503f6114fcf28a43652d5d69749f4 ) +) + +game ( + name "Wayfarer Boo - Pushing Through (World) (v1.0) (Aftermarket) (Unl)" + description "Wayfarer Boo - Pushing Through (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Wayfarer Boo - Pushing Through (World) (v1.0) (Aftermarket) (Unl).gbc" size 262144 crc b5d0ab10 sha1 7451a93a3a2f17b5187883ad2b59c4dda99a2ac7 ) +) + +game ( + name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 776fc18e sha1 5c4a227c0b2f53e4a349e482c5ba87cb83404f8e ) +) + +game ( + name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" + description "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c3d5cbf sha1 a235c0915ac2b826eeb5884d0eccd321236fdb0c ) +) + +game ( + name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" + description "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl).GBC" size 65536 crc 28114b89 sha1 05b90f0a7e92d42b3008c749d5edeab2a2eae973 ) +) + +game ( + name "Who Dares Wins II (World) (Aftermarket) (Unl)" + description "Who Dares Wins II (World) (Aftermarket) (Unl)" + rom ( name "Who Dares Wins II (World) (Aftermarket) (Unl).gbc" size 262144 crc d12ea4bd sha1 cd91248bc0efd4fd3f182eda4559b1d6b720e3d9 ) +) + +game ( + name "Wicked Plague (World) (v0.1.2) (Proto) (Aftermarket) (Unl)" + description "Wicked Plague (World) (v0.1.2) (Proto) (Aftermarket) (Unl)" + rom ( name "Wicked Plague (World) (v0.1.2) (Proto) (Aftermarket) (Unl).gbc" size 524288 crc 80e43cec sha1 dee4f074029352efb3e6683e0c31c9350bdb8199 ) +) + +game ( + name "Wicked Plague (World) (v0.1.1) (Proto) (Aftermarket) (Unl)" + description "Wicked Plague (World) (v0.1.1) (Proto) (Aftermarket) (Unl)" + rom ( name "Wicked Plague (World) (v0.1.1) (Proto) (Aftermarket) (Unl).gbc" size 524288 crc 4029708f sha1 2279270c9a0d28934c5b5efda9c047ab27ffccb8 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (Beta 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 04e04980 sha1 574cf911d6d8f73699203cd6db42ceec777f7f93 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (EGS) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (EGS) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (EGS) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 7328cfb6 sha1 039874148f27ffe533de4ef086f29e724a3217a9 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (Beta 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 6bc9de3d sha1 12d55dad39a9663083f9ad176563576a5cc44069 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (Kitmaker) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (Kitmaker) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (Kitmaker) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5179988b sha1 20e8daa159ceddace966afd3cd19eae71bb3bf6f ) +) + +game ( + name "Witches and Butchers (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + description "Witches and Butchers (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Witches and Butchers (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 321aecca sha1 90541cd5b08f6030b5b2fe4f1e0ac7c0b616e01e ) +) + +game ( + name "Witches and Butchers (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + description "Witches and Butchers (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Witches and Butchers (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9b53a90f sha1 77210d3c0825d913f4aebf09a10897a84ca23881 ) +) + +game ( + name "Wizard of Wor (World) (Aftermarket) (Unl)" + description "Wizard of Wor (World) (Aftermarket) (Unl)" + rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gbc" size 524288 crc 492a9529 sha1 a391646d259a39e7026574145e0a2bacf5f6937b ) +) + +game ( + name "Wolf Pack (World) (Aftermarket) (Unl)" + description "Wolf Pack (World) (Aftermarket) (Unl)" + rom ( name "Wolf Pack (World) (Aftermarket) (Unl).gbc" size 262144 crc ae35b80b sha1 56b20f0ab63a1459c1271e4cd062e8f92f7d10a4 ) +) + +game ( + name "World Cup (World) (Aftermarket) (Unl)" + description "World Cup (World) (Aftermarket) (Unl)" + rom ( name "World Cup (World) (Aftermarket) (Unl).gbc" size 262144 crc 56b3ab5f sha1 075890510b3ef205ca50ebbbcf7c0a0c56032cb9 ) +) + +game ( + name "Wrestling Thunder City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Wrestling Thunder City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wrestling Thunder City (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 4fc94f1c sha1 3c5e6ec96c1110ef9c21a8d92cc24c0c721fddd3 ) +) + +game ( + name "Xzap (World) (Aftermarket) (Unl)" + description "Xzap (World) (Aftermarket) (Unl)" + rom ( name "Xzap (World) (Aftermarket) (Unl).gbc" size 262144 crc 68ceec9c sha1 35ae73d3ec93c95fdad9a358ccc34bcfc12445b1 ) +) + +game ( + name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b304833d sha1 c2be46b8230bfcf509d031902c9bf144de97ef58 ) +) + +game ( + name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc f15351c8 sha1 a78ff2eef780287bbdc37df122cfc1c504526662 ) +) + +game ( + name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b70c1c7f sha1 ce25cdf6a6264586423e76e34dc42779d39a1cb1 ) +) + +game ( + name "YiYa - The Digital Pet Game (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "YiYa - The Digital Pet Game (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "YiYa - The Digital Pet Game (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b2c84c00 sha1 8bf1843102bc5a8577a8d0b44a16e46ade14bd16 ) +) + +game ( + name "YiYa - The Digital Pet Game DX (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "YiYa - The Digital Pet Game DX (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "YiYa - The Digital Pet Game DX (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 21e80905 sha1 b372eb9d049c962392868d7abfcb7b7e4ab2d40f ) +) + +game ( + name "Yurivania - Uhaul of the Night (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + description "Yurivania - Uhaul of the Night (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Yurivania - Uhaul of the Night (World) (v1.5) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c5447011 sha1 8197ed0ac5591893b7d04ed3f02529f120daab7e ) +) + +game ( + name "Yurivania 0 - Soul Night Prelude (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Yurivania 0 - Soul Night Prelude (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Yurivania 0 - Soul Night Prelude (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 8cdf4b90 sha1 9df6bf7c2babc47cc9e461d16a7ab1a24d898003 ) +) + +game ( + name "Yurivania II - Josette's Quest (World) (v1.3) (Aftermarket) (Unl)" + description "Yurivania II - Josette's Quest (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Yurivania II - Josette's Quest (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc b80d7525 sha1 05c7256bf9f12f60f453a0627d813904c8713378 ) +) + +game ( + name "Yurivania II - Josette's Quest (World) (v1.2) (Aftermarket) (Unl)" + description "Yurivania II - Josette's Quest (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Yurivania II - Josette's Quest (World) (v1.2) (Aftermarket) (Unl).gbc" size 1048576 crc c3a76413 sha1 6b6dac77795148d7eba6f7c8fa1c65a6d1e404c3 ) +) + +game ( + name "Yurivania III - Circle of the Polycule (World) (v1.4) (Aftermarket) (Unl)" + description "Yurivania III - Circle of the Polycule (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Yurivania III - Circle of the Polycule (World) (v1.4) (Aftermarket) (Unl).gbc" size 2097152 crc 439b087f sha1 91178b5ba17e891060badf0c7681e6a76052de97 ) +) + +game ( + name "Zagan Warrior (World) (Aftermarket) (Unl)" + description "Zagan Warrior (World) (Aftermarket) (Unl)" + rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gbc" size 262144 crc e770f71a sha1 99d9267946e7bf26942a8276863ba50ef0b8f90e ) +) + +game ( + name "Zap'em (World) (Aftermarket) (Unl)" + description "Zap'em (World) (Aftermarket) (Unl)" + rom ( name "Zap'em (World) (Aftermarket) (Unl).gbc" size 262144 crc 66f17c5e sha1 63d44c8c2492dc32bcf632feb2d994e9af25fc97 ) +) + +game ( + name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" + description "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" + rom ( name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc db0951d3 sha1 7b74c658f24894659cfda1fc3c7775fd9f7b6013 ) +) + +game ( + name "Zippy The Pinecone (World) (GB Compatible) (Aftermarket) (Unl)" + description "Zippy The Pinecone (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Zippy The Pinecone (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc d1854d92 sha1 ba5f1a020f39ecd29669fc38ca4b23dd4f3dc061 ) +) + +game ( + name "Zippy The Pinecone (World) (v2.7) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Zippy The Pinecone (World) (v2.7) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Zippy The Pinecone (World) (v2.7) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fc555c4d sha1 ad3e95a917c4572c150b4b7cc49d17f1b20a0408 ) +) + +game ( + name "Zodiac (World) (Aftermarket) (Unl)" + description "Zodiac (World) (Aftermarket) (Unl)" + rom ( name "Zodiac (World) (Aftermarket) (Unl).gbc" size 262144 crc c4d86c05 sha1 73bd9e6e3bede8de489680ba84129e8fd17abbc0 ) +) + game ( name "Zone Control (World) (Aftermarket) (Unl)" description "Zone Control (World) (Aftermarket) (Unl)" @@ -48040,8 +50693,8 @@ game ( ) game ( - name "Zook Z (USA) (Unl)" - description "Zook Z (USA) (Unl)" - rom ( name "Zook Z (USA) (Unl).gbc" size 1048576 crc a7b09e70 sha1 243cc40cfc6bcbd3b6106870773a72edff079904 ) + name "Zork + Harris (World) (v0.0.1.0) (Proto) (Aftermarket) (Unl)" + description "Zork + Harris (World) (v0.0.1.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Zork + Harris (World) (v0.0.1.0) (Proto) (Aftermarket) (Unl).gbc" size 262144 crc 38282614 sha1 2507cfd5414c45b8a2f9839552d6115730da6bf8 ) ) From 8ab2681bca4052b9c53fb8d255e42d28a9095821 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 10 Aug 2024 21:23:00 -0700 Subject: [PATCH 242/336] Core: Expose more ROM information from the API --- CHANGES | 1 + include/mgba/core/core.h | 3 +- include/mgba/core/interface.h | 8 +++++ include/mgba/internal/gb/gb.h | 3 +- include/mgba/internal/gba/gba.h | 3 +- src/core/library.c | 7 +++-- src/core/scripting.c | 12 ++++---- src/gb/core.c | 11 ++----- src/gb/gb.c | 37 +++++++++-------------- src/gba/core.c | 11 ++----- src/gba/gba.c | 33 ++++++++++---------- src/platform/qt/BattleChipView.cpp | 13 ++++---- src/platform/qt/CoreController.cpp | 6 ++-- src/platform/qt/GBAOverride.cpp | 6 ++-- src/platform/qt/ROMInfo.cpp | 14 ++++----- src/platform/qt/ROMInfo.ui | 48 +++++++++++++++++++++++++----- src/platform/qt/ReportView.cpp | 15 +++++----- src/platform/test/perf-main.c | 7 ++--- 18 files changed, 129 insertions(+), 109 deletions(-) diff --git a/CHANGES b/CHANGES index 9af2528d9..c2617c316 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,7 @@ Misc: - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Qt: Pass logging context through to video proxy thread (fixes mgba.io/i/3095) + - Qt: Show maker code and game version in ROM info - Scripting: Add `callbacks:oneshot` for single-call callbacks - Switch: Add bilinear filtering option (closes mgba.io/i/3111) - Vita: Add imc0 and xmc0 mount point support diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 97f256c82..18295ed13 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -119,8 +119,7 @@ struct mCore { int32_t (*frameCycles)(const struct mCore*); int32_t (*frequency)(const struct mCore*); - void (*getGameTitle)(const struct mCore*, char* title); - void (*getGameCode)(const struct mCore*, char* title); + void (*getGameInfo)(const struct mCore*, struct mGameInfo* info); void (*setPeripheral)(struct mCore*, int type, void*); void* (*getPeripheral)(struct mCore*, int type); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 3e6261e9c..2f4e299dd 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -22,6 +22,14 @@ enum mCoreFeature { mCORE_FEATURE_OPENGL = 1, }; +struct mGameInfo { + char title[17]; + char system[4]; + char code[5]; + char maker[3]; + uint8_t version; +}; + struct mCoreCallbacks { void* context; void (*videoFrameStarted)(void* context); diff --git a/include/mgba/internal/gb/gb.h b/include/mgba/internal/gb/gb.h index 08068ec58..64579d3c1 100644 --- a/include/mgba/internal/gb/gb.h +++ b/include/mgba/internal/gb/gb.h @@ -190,8 +190,7 @@ void GBSavedataUnmask(struct GB* gb); struct Patch; void GBApplyPatch(struct GB* gb, struct Patch* patch); -void GBGetGameTitle(const struct GB* gba, char* out); -void GBGetGameCode(const struct GB* gba, char* out); +void GBGetGameInfo(const struct GB* gba, struct mGameInfo* info); void GBTestKeypadIRQ(struct GB* gb); diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index cc340d760..ea9d69961 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -182,8 +182,7 @@ void GBAUnloadMB(struct GBA* gba); bool GBALoadNull(struct GBA* gba); -void GBAGetGameCode(const struct GBA* gba, char* out); -void GBAGetGameTitle(const struct GBA* gba, char* out); +void GBAGetGameInfo(const struct GBA* gba, struct mGameInfo* info); void GBATestKeypadIRQ(struct GBA* gba); diff --git a/src/core/library.c b/src/core/library.c index 44148f7f5..1c92a0cbc 100644 --- a/src/core/library.c +++ b/src/core/library.c @@ -6,6 +6,7 @@ #include #include +#include #include #ifdef USE_SQLITE3 @@ -291,8 +292,10 @@ bool _mLibraryAddEntry(struct mLibrary* library, const char* filename, const cha core->init(core); core->loadROM(core, vf); - core->getGameTitle(core, entry.internalTitle); - core->getGameCode(core, entry.internalCode); + struct mGameInfo info; + core->getGameInfo(core, &info); + snprintf(entry.internalCode, sizeof(entry.internalCode), "%s-%s", info.system, info.code); + strlcpy(entry.internalTitle, info.title, sizeof(entry.internalTitle)); core->checksum(core, &entry.crc32, mCHECKSUM_CRC32); entry.platform = core->platform(core); entry.title = NULL; diff --git a/src/core/scripting.c b/src/core/scripting.c index ea0af459d..064027d45 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -332,15 +332,15 @@ mSCRIPT_DEFINE_STRUCT(mScriptMemoryDomain) mSCRIPT_DEFINE_END; static struct mScriptValue* _mScriptCoreGetGameTitle(const struct mCore* core) { - char title[32] = {0}; - core->getGameTitle(core, title); - return mScriptStringCreateFromASCII(title); + struct mGameInfo info; + core->getGameInfo(core, &info); + return mScriptStringCreateFromASCII(info.title); } static struct mScriptValue* _mScriptCoreGetGameCode(const struct mCore* core) { - char code[16] = {0}; - core->getGameCode(core, code); - return mScriptStringCreateFromASCII(code); + struct mGameInfo info; + core->getGameInfo(core, &info); + return mScriptStringCreateFromASCII(info.code); } static struct mScriptValue* _mScriptCoreChecksum(const struct mCore* core, int t) { diff --git a/src/gb/core.c b/src/gb/core.c index 4e8351fc6..ed8dda1e5 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -781,12 +781,8 @@ static int32_t _GBCoreFrequency(const struct mCore* core) { return DMG_SM83_FREQUENCY; } -static void _GBCoreGetGameTitle(const struct mCore* core, char* title) { - GBGetGameTitle(core->board, title); -} - -static void _GBCoreGetGameCode(const struct mCore* core, char* title) { - GBGetGameCode(core->board, title); +static void _GBCoreGetGameInfo(const struct mCore* core, struct mGameInfo* info) { + GBGetGameInfo(core->board, info); } static void _GBCoreSetPeripheral(struct mCore* core, int type, void* periph) { @@ -1332,8 +1328,7 @@ struct mCore* GBCoreCreate(void) { core->frameCounter = _GBCoreFrameCounter; core->frameCycles = _GBCoreFrameCycles; core->frequency = _GBCoreFrequency; - core->getGameTitle = _GBCoreGetGameTitle; - core->getGameCode = _GBCoreGetGameCode; + core->getGameInfo = _GBCoreGetGameInfo; core->setPeripheral = _GBCoreSetPeripheral; core->getPeripheral = _GBCoreGetPeripheral; core->busRead8 = _GBCoreBusRead8; diff --git a/src/gb/gb.c b/src/gb/gb.c index c6198ed58..ea0a4d7df 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -16,6 +16,7 @@ #include #include #include +#include #include const uint32_t CGB_SM83_FREQUENCY = 0x800000; @@ -1116,38 +1117,28 @@ bool GBIsROM(struct VFile* vf) { return false; } -void GBGetGameTitle(const struct GB* gb, char* out) { +void GBGetGameInfo(const struct GB* gb, struct mGameInfo* info) { + memset(info, 0, sizeof(*info)); const struct GBCartridge* cart = NULL; if (gb->memory.rom) { cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; } - if (!cart) { - return; - } - if (cart->oldLicensee != 0x33) { - memcpy(out, cart->titleLong, 16); - } else { - memcpy(out, cart->titleShort, 11); - } -} -void GBGetGameCode(const struct GB* gb, char* out) { - memset(out, 0, 8); - const struct GBCartridge* cart = NULL; - if (gb->memory.rom) { - cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; - } - if (!cart) { - return; - } if (cart->cgb == 0xC0) { - memcpy(out, "CGB-????", 8); + strlcpy(info->system, "CGB", sizeof(info->system)); } else { - memcpy(out, "DMG-????", 8); + strlcpy(info->system, "DMG", sizeof(info->system)); } - if (cart->oldLicensee == 0x33) { - memcpy(&out[4], cart->maker, 4); + + if (cart->oldLicensee != 0x33) { + memcpy(info->title, cart->titleLong, 16); + snprintf(info->maker, sizeof(info->maker), "%02X", cart->oldLicensee); + } else { + memcpy(info->title, cart->titleShort, 11); + memcpy(info->code, cart->maker, 4); + memcpy(info->maker, &cart->licensee, 2); } + info->version = cart->version; } void GBFrameStarted(struct GB* gb) { diff --git a/src/gba/core.c b/src/gba/core.c index 1f39afea6..b39a5f401 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -870,12 +870,8 @@ static int32_t _GBACoreFrequency(const struct mCore* core) { return GBA_ARM7TDMI_FREQUENCY; } -static void _GBACoreGetGameTitle(const struct mCore* core, char* title) { - GBAGetGameTitle(core->board, title); -} - -static void _GBACoreGetGameCode(const struct mCore* core, char* title) { - GBAGetGameCode(core->board, title); +static void _GBACoreGetGameInfo(const struct mCore* core, struct mGameInfo* info) { + GBAGetGameInfo(core->board, info); } static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { @@ -1550,8 +1546,7 @@ struct mCore* GBACoreCreate(void) { core->frameCounter = _GBACoreFrameCounter; core->frameCycles = _GBACoreFrameCycles; core->frequency = _GBACoreFrequency; - core->getGameTitle = _GBACoreGetGameTitle; - core->getGameCode = _GBACoreGetGameCode; + core->getGameInfo = _GBACoreGetGameInfo; core->setPeripheral = _GBACoreSetPeripheral; core->getPeripheral = _GBACoreGetPeripheral; core->busRead8 = _GBACoreBusRead8; diff --git a/src/gba/gba.c b/src/gba/gba.c index 2d10f5cc9..f9c4dad5d 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #ifdef USE_ELF @@ -849,26 +850,24 @@ bool GBAIsBIOS(struct VFile* vf) { return true; } -void GBAGetGameCode(const struct GBA* gba, char* out) { - memset(out, 0, 8); - if (!gba->memory.rom) { - return; - } - - memcpy(out, "AGB-", 4); - memcpy(&out[4], &((struct GBACartridge*) gba->memory.rom)->id, 4); -} - -void GBAGetGameTitle(const struct GBA* gba, char* out) { +void GBAGetGameInfo(const struct GBA* gba, struct mGameInfo* info) { + memset(info, 0, sizeof(*info)); + strlcpy(info->system, "AGB", sizeof(info->system)); + struct GBACartridge* cart = NULL; if (gba->memory.rom) { - memcpy(out, &((struct GBACartridge*) gba->memory.rom)->title, 12); - return; + cart = (struct GBACartridge*) gba->memory.rom; + } else if (gba->isPristine && gba->memory.wram) { + cart = (struct GBACartridge*) gba->memory.wram; } - if (gba->isPristine && gba->memory.wram) { - memcpy(out, &((struct GBACartridge*) gba->memory.wram)->title, 12); - return; + + if (cart) { + memcpy(info->title, &cart->title, 12); + memcpy(info->code, &cart->id, 4); + memcpy(info->maker, &cart->maker, 2); + info->version = cart->version; + } else { + strlcpy(info->title, "(BIOS)", 12); } - strncpy(out, "(BIOS)", 12); } void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) { diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index d72f78c41..f7d6eb4c7 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -30,12 +30,11 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo m_ui.setupUi(this); m_ui.chipList->setModel(&m_model); - char title[9]; CoreController::Interrupter interrupter(m_controller); mCore* core = m_controller->thread()->core; - title[8] = '\0'; - core->getGameCode(core, title); - QString qtitle(title); + mGameInfo info; + core->getGameInfo(core, &info); + QString qtitle(info.title); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) int size = QFontMetrics(QFont()).height() / ((int) ceil(devicePixelRatioF()) * 12); @@ -101,11 +100,11 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo m_controller->attachBattleChipGate(); setFlavor(4); - if (qtitle.startsWith("AGB-B4B") || qtitle.startsWith("AGB-B4W") || qtitle.startsWith("AGB-BR4") || qtitle.startsWith("AGB-BZ3")) { + if (qtitle.startsWith("B4B") || qtitle.startsWith("B4W") || qtitle.startsWith("BR4") || qtitle.startsWith("BZ3")) { m_ui.gateBattleChip->setChecked(true); - } else if (qtitle.startsWith("AGB-BRB") || qtitle.startsWith("AGB-BRK")) { + } else if (qtitle.startsWith("BRB") || qtitle.startsWith("BRK")) { m_ui.gateProgress->setChecked(true); - } else if (qtitle.startsWith("AGB-BR5") || qtitle.startsWith("AGB-BR6")) { + } else if (qtitle.startsWith("BR5") || qtitle.startsWith("BR6")) { m_ui.gateBeastLink->setChecked(true); } diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 02cd4db4c..519ce45fb 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -1318,9 +1318,9 @@ void CoreController::updateROMInfo() { mCore* core = m_threadContext.core; core->checksum(core, &m_crc32, mCHECKSUM_CRC32); - char gameTitle[17] = { '\0' }; - core->getGameTitle(core, gameTitle); - m_internalTitle = QLatin1String(gameTitle); + mGameInfo info; + core->getGameInfo(core, &info); + m_internalTitle = QLatin1String(info.title); #ifdef USE_SQLITE3 if (db && m_crc32 && NoIntroDBLookupGameByCRC(db, m_crc32, &game)) { diff --git a/src/platform/qt/GBAOverride.cpp b/src/platform/qt/GBAOverride.cpp index 57fb2048e..dbf627268 100644 --- a/src/platform/qt/GBAOverride.cpp +++ b/src/platform/qt/GBAOverride.cpp @@ -14,9 +14,9 @@ void GBAOverride::identify(const struct mCore* core) { if (core->platform(core) != mPLATFORM_GBA) { return; } - char gameId[8]; - core->getGameCode(core, gameId); - memcpy(override.id, &gameId[4], 4); + mGameInfo info; + core->getGameInfo(core, &info); + memcpy(override.id, info.code, 4); } void GBAOverride::save(struct Configuration* config) const { diff --git a/src/platform/qt/ROMInfo.cpp b/src/platform/qt/ROMInfo.cpp index 473918f26..9f2537439 100644 --- a/src/platform/qt/ROMInfo.cpp +++ b/src/platform/qt/ROMInfo.cpp @@ -27,16 +27,16 @@ ROMInfo::ROMInfo(std::shared_ptr controller, QWidget* parent) CoreController::Interrupter interrupter(controller); mCore* core = controller->thread()->core; - char title[17] = {}; - core->getGameTitle(core, title); - m_ui.title->setText(QLatin1String(title)); - title[8] = '\0'; - core->getGameCode(core, title); - if (title[0]) { - m_ui.id->setText(QLatin1String(title)); + mGameInfo info; + core->getGameInfo(core, &info); + m_ui.title->setText(QLatin1String(info.title)); + if (info.code[0]) { + m_ui.id->setText(QLatin1String(info.code)); } else { m_ui.id->setText(tr("(unknown)")); } + m_ui.maker->setText(QLatin1String(info.maker)); + m_ui.version->setText(QString::number(info.version)); core->checksum(core, &crc32, mCHECKSUM_CRC32); diff --git a/src/platform/qt/ROMInfo.ui b/src/platform/qt/ROMInfo.ui index 727cff032..655d4810f 100644 --- a/src/platform/qt/ROMInfo.ui +++ b/src/platform/qt/ROMInfo.ui @@ -6,8 +6,8 @@ 0 0 - 236 - 146 + 178 + 198 @@ -75,13 +75,47 @@ + + + Maker Code: + + + + + + + {MAKER} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Revision: + + + + + + + {VERSION} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + File size: - + {SIZE} @@ -91,14 +125,14 @@ - + CRC32: - + {CRC} @@ -108,14 +142,14 @@ - + Save file: - + {SAVEFILE} diff --git a/src/platform/qt/ReportView.cpp b/src/platform/qt/ReportView.cpp index 04944ef5c..9843cae76 100644 --- a/src/platform/qt/ReportView.cpp +++ b/src/platform/qt/ReportView.cpp @@ -497,17 +497,16 @@ void ReportView::addROMInfo(QStringList& report, CoreController* controller) { report << QString("Currently paused: %1").arg(yesNo[controller->isPaused()]); mCore* core = controller->thread()->core; - char title[17] = {}; - core->getGameTitle(core, title); - report << QString("Internal title: %1").arg(QLatin1String(title)); - - title[8] = '\0'; - core->getGameCode(core, title); - if (title[0]) { - report << QString("Game code: %1").arg(QLatin1String(title)); + struct mGameInfo info; + core->getGameInfo(core, &info); + report << QString("Internal title: %1").arg(QLatin1String(info.title)); + if (info.code[0]) { + report << QString("Game code: %1").arg(QLatin1String(info.code)); } else { report << QString("Invalid game code"); } + report << QString("Game maker: %1").arg(QLatin1String(info.maker)); + report << QString("Game version: %1").arg(info.version); uint32_t crc32 = 0; core->checksum(core, &crc32, mCHECKSUM_CRC32); diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index 38d50b30c..26a3715eb 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -196,8 +196,6 @@ bool _mPerfRunCore(const char* fname, const struct mArguments* args, const struc } // TODO: Put back debugger - char gameCode[9] = { 0 }; - core->init(core); if (!perfOpts->noVideo) { core->setVideoBuffer(core, _outputBuffer, 256); @@ -226,7 +224,8 @@ bool _mPerfRunCore(const char* fname, const struct mArguments* args, const struc mCoreLoadStateNamed(core, _savestate, 0); } - core->getGameCode(core, gameCode); + struct mGameInfo info; + core->getGameInfo(core, &info); int frames = perfOpts->frames; if (!frames) { @@ -255,7 +254,7 @@ bool _mPerfRunCore(const char* fname, const struct mArguments* args, const struc } else { rendererName = "software"; } - snprintf(buffer, sizeof(buffer), "%s,%i,%" PRIu64 ",%s\n", gameCode, frames, duration, rendererName); + snprintf(buffer, sizeof(buffer), "%s-%s,%i,%" PRIu64 ",%s\n", info.system, info.code, frames, duration, rendererName); printf("%s", buffer); if (_socket != INVALID_SOCKET) { SocketSend(_socket, buffer, strlen(buffer)); From b12858e97498c2ee4719db5672c0e4843c98c421 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 11 Aug 2024 20:04:35 -0700 Subject: [PATCH 243/336] GBA: Fix getting game info for multiboot ROMs --- CHANGES | 1 + src/gba/gba.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index c2617c316..0adab6673 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Other fixes: - GB: Fix uninitialized save data when loading undersized temporary saves - GB, GBA Core: Fix memory leak if reloading debug symbols - GB Serialize: Prevent loading invalid states where LY >= 144 in modes other than 1 + - GBA: Fix getting game info for multiboot ROMs - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf diff --git a/src/gba/gba.c b/src/gba/gba.c index f9c4dad5d..ce7e3478e 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -408,10 +408,14 @@ bool GBALoadMB(struct GBA* gba, struct VFile* vf) { gba->mbVf = vf; vf->seek(vf, 0, SEEK_SET); memset(gba->memory.wram, 0, GBA_SIZE_EWRAM); - vf->read(vf, gba->memory.wram, GBA_SIZE_EWRAM); + off_t read = vf->read(vf, gba->memory.wram, GBA_SIZE_EWRAM); + if (read < 0) { + return false; + } if (gba->cpu && gba->memory.activeRegion == GBA_REGION_IWRAM) { gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); } + gba->romCrc32 = doCrc32(gba->memory.wram, read); return true; } @@ -856,7 +860,7 @@ void GBAGetGameInfo(const struct GBA* gba, struct mGameInfo* info) { struct GBACartridge* cart = NULL; if (gba->memory.rom) { cart = (struct GBACartridge*) gba->memory.rom; - } else if (gba->isPristine && gba->memory.wram) { + } else if (gba->mbVf && gba->memory.wram) { cart = (struct GBACartridge*) gba->memory.wram; } From 17cf2e6237f11c802f3d7baa051c44cd7c63ea2c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 11 Aug 2024 23:22:13 -0700 Subject: [PATCH 244/336] No-Intro: Index database on MD5 and SHA1 too --- src/feature/sqlite3/no-intro.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/feature/sqlite3/no-intro.c b/src/feature/sqlite3/no-intro.c index 649364de6..f79f98a9d 100644 --- a/src/feature/sqlite3/no-intro.c +++ b/src/feature/sqlite3/no-intro.c @@ -47,7 +47,9 @@ struct NoIntroDB* NoIntroDBLoad(const char* path) { "flags INTEGER DEFAULT 0," "gid INTEGER NOT NULL REFERENCES games(gid) ON DELETE CASCADE" ");\n" - "CREATE INDEX IF NOT EXISTS crc32 ON roms (crc32);"; + "CREATE INDEX IF NOT EXISTS crc32 ON roms (crc32);\n" + "CREATE INDEX IF NOT EXISTS md5 ON roms (md5);\n" + "CREATE INDEX IF NOT EXISTS sha1 ON roms (sha1);\n"; if (sqlite3_exec(db->db, createTables, NULL, NULL, NULL)) { goto error; } From dfab80127764acfb3b6e1895a5a2ca890d084fcf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 12 Aug 2024 16:08:36 -0700 Subject: [PATCH 245/336] No-Intro: Prevent database from being downgraded --- src/feature/sqlite3/no-intro.c | 35 +++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/feature/sqlite3/no-intro.c b/src/feature/sqlite3/no-intro.c index f79f98a9d..463a2fe5e 100644 --- a/src/feature/sqlite3/no-intro.c +++ b/src/feature/sqlite3/no-intro.c @@ -72,6 +72,7 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { sqlite3_stmt* gamedbTable = NULL; sqlite3_stmt* gamedbDrop = NULL; + sqlite3_stmt* gamedbSelect = NULL; sqlite3_stmt* gameTable = NULL; sqlite3_stmt* romTable = NULL; char* fieldName = NULL; @@ -91,6 +92,11 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { return false; } + static const char selectGamedb[] = "SELECT * FROM gamedb WHERE name = ? AND version >= ?;"; + if (sqlite3_prepare_v2(db->db, selectGamedb, -1, &gamedbSelect, NULL)) { + return false; + } + static const char insertGame[] = "INSERT INTO games (dbid, name) VALUES (?, ?);"; if (sqlite3_prepare_v2(db->db, insertGame, -1, &gameTable, NULL)) { return false; @@ -161,18 +167,24 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { break; case ')': if (currentDb < 0 && dbType && dbVersion) { - sqlite3_clear_bindings(gamedbDrop); - sqlite3_reset(gamedbDrop); - sqlite3_bind_text(gamedbDrop, 1, dbType, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(gamedbDrop, 2, dbVersion, -1, SQLITE_TRANSIENT); - sqlite3_step(gamedbDrop); + sqlite3_clear_bindings(gamedbSelect); + sqlite3_reset(gamedbSelect); + sqlite3_bind_text(gamedbSelect, 1, dbType, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(gamedbSelect, 2, dbVersion, -1, SQLITE_TRANSIENT); + if (sqlite3_step(gamedbSelect) != SQLITE_ROW) { + sqlite3_clear_bindings(gamedbDrop); + sqlite3_reset(gamedbDrop); + sqlite3_bind_text(gamedbDrop, 1, dbType, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(gamedbDrop, 2, dbVersion, -1, SQLITE_TRANSIENT); + sqlite3_step(gamedbDrop); - sqlite3_clear_bindings(gamedbTable); - sqlite3_reset(gamedbTable); - sqlite3_bind_text(gamedbTable, 1, dbType, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(gamedbTable, 2, dbVersion, -1, SQLITE_TRANSIENT); - if (sqlite3_step(gamedbTable) == SQLITE_DONE) { - currentDb = sqlite3_last_insert_rowid(db->db); + sqlite3_clear_bindings(gamedbTable); + sqlite3_reset(gamedbTable); + sqlite3_bind_text(gamedbTable, 1, dbType, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(gamedbTable, 2, dbVersion, -1, SQLITE_TRANSIENT); + if (sqlite3_step(gamedbTable) == SQLITE_DONE) { + currentDb = sqlite3_last_insert_rowid(db->db); + } } free((void*) dbType); free((void*) dbVersion); @@ -272,6 +284,7 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { sqlite3_finalize(gamedbTable); sqlite3_finalize(gamedbDrop); + sqlite3_finalize(gamedbSelect); sqlite3_finalize(gameTable); sqlite3_finalize(romTable); From cd22c140f07c273026b403f74f98a4716b973bd0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 13 Aug 2024 00:16:42 -0700 Subject: [PATCH 246/336] GB: Fix potential null pointer deref --- src/gb/gb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index ea0a4d7df..282fc45c1 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -1119,11 +1119,11 @@ bool GBIsROM(struct VFile* vf) { void GBGetGameInfo(const struct GB* gb, struct mGameInfo* info) { memset(info, 0, sizeof(*info)); - const struct GBCartridge* cart = NULL; - if (gb->memory.rom) { - cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; + if (!gb->memory.rom) { + return; } + const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; if (cart->cgb == 0xC0) { strlcpy(info->system, "CGB", sizeof(info->system)); } else { From e91da0f423f2ac0ac7641fdda622569b256c0e99 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 13 Aug 2024 18:38:07 -0700 Subject: [PATCH 247/336] Scripting: Expose currentCycle in debugger builds The global time is only maintained in debugger builds for performance reasons. While it can be reconstructed on GBA, this is not the case on GB, so limit it to debugger builds only. --- src/core/scripting.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/scripting.c b/src/core/scripting.c index 064027d45..a00d5cbdc 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -938,6 +938,10 @@ static bool _mScriptCoreAdapterClearBreakpoint(struct mScriptCoreAdapter* adapte } return true; } + +uint64_t _mScriptCoreAdapterCurrentCycle(struct mScriptCoreAdapter* adapter) { + return mTimingGlobalTime(adapter->core->timing); +} #endif static void _mScriptCoreAdapterDeinit(struct mScriptCoreAdapter* adapter) { @@ -1085,6 +1089,7 @@ mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write16, _mScriptCoreAdap mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write32, _mScriptCoreAdapterWrite32, 2, U32, address, U32, value); #ifdef ENABLE_DEBUGGERS +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U64, currentCycle, _mScriptCoreAdapterCurrentCycle, 0); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setBreakpoint, _mScriptCoreAdapterSetBreakpoint, 3, WRAPPER, callback, U32, address, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setWatchpoint, _mScriptCoreAdapterSetWatchpoint, 4, WRAPPER, callback, U32, address, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setRangeWatchpoint, _mScriptCoreAdapterSetRangeWatchpoint, 5, WRAPPER, callback, U32, minAddress, U32, maxAddress, S32, type, S32, segment); @@ -1150,6 +1155,8 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write16) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write32) #ifdef ENABLE_DEBUGGERS + mSCRIPT_DEFINE_DOCSTRING("Get the current execution cycle") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, currentCycle) mSCRIPT_DEFINE_DOCSTRING("Set a breakpoint at a given address") mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setBreakpoint) mSCRIPT_DEFINE_DOCSTRING("Clear a breakpoint or watchpoint for a given id returned by a previous call") From eaee4228bad46a23f2f6805437d239d2b41e5373 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 16 Aug 2024 02:32:44 -0700 Subject: [PATCH 248/336] GBA Video: Improve emulation of window start/end conditions (fixes #1945) --- CHANGES | 1 + .../internal/gba/renderers/video-software.h | 2 + src/gba/renderers/video-software.c | 82 ++++++++++--------- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index 0adab6673..3aef9e246 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Emulation fixes: - GBA Serialize: Fix some minor save state edge cases - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) + - GBA Video: Improve emulation of window start/end conditions (fixes mgba.io/i/1945) Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index 969ffed64..d03c52374 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -118,6 +118,7 @@ struct GBAVideoSoftwareRenderer { struct WindowControl control; int16_t offsetX; int16_t offsetY; + bool on; } winN[2]; struct WindowControl winout; @@ -142,6 +143,7 @@ struct GBAVideoSoftwareRenderer { struct ScanlineCache { uint16_t io[GBA_REG(SOUND1CNT_LO)]; int32_t scale[2][2]; + bool windowOn[2]; } cache[GBA_VIDEO_VERTICAL_PIXELS]; int nextY; diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 6c78c08e0..7eba88ba3 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -35,14 +35,15 @@ static void GBAVideoSoftwareRendererWriteBGY_LO(struct GBAVideoSoftwareBackgroun static void GBAVideoSoftwareRendererWriteBGY_HI(struct GBAVideoSoftwareBackground* bg, uint16_t value); static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value); -static void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* renderer, int y); +static void GBAVideoSoftwareRendererStepWindow(struct GBAVideoSoftwareRenderer* renderer, int y); +static void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* renderer); static void GBAVideoSoftwareRendererPostprocessBuffer(struct GBAVideoSoftwareRenderer* renderer); static int GBAVideoSoftwareRendererPreprocessSpriteLayer(struct GBAVideoSoftwareRenderer* renderer, int y); static void _updatePalettes(struct GBAVideoSoftwareRenderer* renderer); static void _updateFlags(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg); -static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win, int y); +static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win); static void _breakWindowInner(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win); void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { @@ -343,28 +344,10 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender case GBA_REG_WIN0V: softwareRenderer->winN[0].v.end = value; softwareRenderer->winN[0].v.start = value >> 8; - if (softwareRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[0].v.start > softwareRenderer->winN[0].v.end) { - softwareRenderer->winN[0].v.start = 0; - } - if (softwareRenderer->winN[0].v.end > GBA_VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[0].v.end = GBA_VIDEO_VERTICAL_PIXELS; - if (softwareRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[0].v.start = GBA_VIDEO_VERTICAL_PIXELS; - } - } break; case GBA_REG_WIN1V: softwareRenderer->winN[1].v.end = value; softwareRenderer->winN[1].v.start = value >> 8; - if (softwareRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[1].v.start > softwareRenderer->winN[1].v.end) { - softwareRenderer->winN[1].v.start = 0; - } - if (softwareRenderer->winN[1].v.end > GBA_VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[1].v.end = GBA_VIDEO_VERTICAL_PIXELS; - if (softwareRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[1].v.start = GBA_VIDEO_VERTICAL_PIXELS; - } - } break; case GBA_REG_WININ: value &= 0x3F3F; @@ -432,17 +415,7 @@ static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* render memset(softwareRenderer->scanlineDirty, 0xFFFFFFFF, sizeof(softwareRenderer->scanlineDirty)); } -static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win, int y) { - if (win->v.end >= win->v.start) { - if (y >= win->v.end + win->offsetY) { - return; - } - if (y < win->v.start + win->offsetY) { - return; - } - } else if (y >= win->v.end + win->offsetY && y < win->v.start + win->offsetY) { - return; - } +static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win) { if (win->h.end > GBA_VIDEO_HORIZONTAL_PIXELS || win->h.end < win->h.start) { struct WindowN splits[2] = { *win, *win }; splits[0].h.start = 0; @@ -585,6 +558,14 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render softwareRenderer->cache[y].scale[1][0] = softwareRenderer->bg[3].sx; softwareRenderer->cache[y].scale[1][1] = softwareRenderer->bg[3].sy; + GBAVideoSoftwareRendererStepWindow(softwareRenderer, y); + if (softwareRenderer->cache[y].windowOn[0] != softwareRenderer->winN[0].on || + softwareRenderer->cache[y].windowOn[1] != softwareRenderer->winN[1].on) { + dirty = true; + } + softwareRenderer->cache[y].windowOn[0] = softwareRenderer->winN[0].on; + softwareRenderer->cache[y].windowOn[1] = softwareRenderer->winN[1].on; + if (!dirty) { if (GBARegisterDISPCNTGetMode(softwareRenderer->dispcnt) != 0) { if (softwareRenderer->bg[2].enabled == ENABLED_MAX) { @@ -610,7 +591,7 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render return; } - GBAVideoSoftwareRendererPreprocessBuffer(softwareRenderer, y); + GBAVideoSoftwareRendererPreprocessBuffer(softwareRenderer); softwareRenderer->spriteCyclesRemaining = GBARegisterDISPCNTIsHblankIntervalFree(softwareRenderer->dispcnt) ? OBJ_HBLANK_FREE_LENGTH : OBJ_LENGTH; int spriteLayers = GBAVideoSoftwareRendererPreprocessSpriteLayer(softwareRenderer, y); @@ -747,6 +728,20 @@ static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* rendere if (softwareRenderer->bg[3].enabled > 0) { softwareRenderer->bg[3].enabled = ENABLED_MAX; } + + int i; + for (i = 0; i < 2; ++i) { + struct WindowN* win = &softwareRenderer->winN[i]; + if (win->v.end >= GBA_VIDEO_VERTICAL_PIXELS && win->v.end < VIDEO_VERTICAL_TOTAL_PIXELS) { + win->on = false; + } + + if (win->v.start >= GBA_VIDEO_VERTICAL_PIXELS && + win->v.start < VIDEO_VERTICAL_TOTAL_PIXELS && + win->v.start > win->v.end) { + win->on = true; + } + } } static void GBAVideoSoftwareRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { @@ -855,7 +850,20 @@ static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* } } -void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* softwareRenderer, int y) { +void GBAVideoSoftwareRendererStepWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, int y) { + int i; + for (i = 0; i < 2; ++i) { + struct WindowN* win = &softwareRenderer->winN[i]; + if (y == win->v.start + win->offsetY) { + win->on = true; + } + if (y == win->v.end + win->offsetY) { + win->on = false; + } + } +} + +void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* softwareRenderer) { int x; for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; x += 4) { softwareRenderer->spriteLayer[x] = FLAG_UNWRITTEN; @@ -868,11 +876,11 @@ void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* s softwareRenderer->nWindows = 1; if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { softwareRenderer->windows[0].control = softwareRenderer->winout; - if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[1]) { - _breakWindow(softwareRenderer, &softwareRenderer->winN[1], y); + if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[1] && softwareRenderer->winN[1].on) { + _breakWindow(softwareRenderer, &softwareRenderer->winN[1]); } - if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[0]) { - _breakWindow(softwareRenderer, &softwareRenderer->winN[0], y); + if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[0] && softwareRenderer->winN[0].on) { + _breakWindow(softwareRenderer, &softwareRenderer->winN[0]); } } else { softwareRenderer->windows[0].control.packed = 0xFF; From ecfdff23382c16d6772d6be89f69afafcb3491b2 Mon Sep 17 00:00:00 2001 From: anthonydo8196 Date: Mon, 19 Aug 2024 20:58:47 -0500 Subject: [PATCH 249/336] Add load most recent script menu option (#3266) --- .gitignore | Bin 323 -> 454 bytes src/platform/qt/scripting/ScriptingView.cpp | 15 ++++++++++++++- src/platform/qt/scripting/ScriptingView.h | 2 ++ src/platform/qt/scripting/ScriptingView.ui | 6 ++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fedbc461f4689076caf4b0cd451a299043c4fcdf..e9e3b3956726efab97169a7e106d812bb3e0b72f 100644 GIT binary patch literal 454 zcmZWl!EVDK4D~ru{sF1CN+tV-RoYIIs!cmr1l-0gfe4eVz3kg((qudAfS=#9{V;6Q zD+Wwt)rmZEU2XNqn6{F97s6jdf#GiJs;)Nbc_idur#z`vMEY8x|HzV2S%TbH%-}9qN3`3x9bmIoCcgX9{Q57mi`6f6DHMgp7HW zZR`gbItunCxK(bnE!K}+ZFG{^UM@UR;B36tGpno4aLC$WK|8aW-Huo@~+JTMIZY7SbdWk}K= Oq=O{a;>WXFnfw82-g}Jz literal 323 zcmYLF!EVDK488j+ka~+$vTsize)|l`v;%(jv;BCmGq0Gi zkT)la$k5rDv2@TqH0A50ak_heoq3)q1{0{Dmt06^`=L@B>^tb~!vB+hdQK(6JselectionModel(), &QItemSelectionModel::currentChanged, this, &ScriptingView::selectBuffer); connect(m_ui.load, &QAction::triggered, this, &ScriptingView::load); + connect(m_ui.loadMostRecent, &QAction::triggered, this, &ScriptingView::loadMostRecent); connect(m_ui.reset, &QAction::triggered, controller, &ScriptingController::reset); m_mruFiles = m_config->getMRU(ConfigController::MRU::Script); @@ -66,6 +67,10 @@ void ScriptingView::load() { } } +void ScriptingView::loadMostRecent() { + m_controller->loadFile(m_mruFiles.at(0)); +} + void ScriptingView::controllerReset() { selectBuffer(QModelIndex()); } @@ -105,7 +110,15 @@ void ScriptingView::updateMRU() { m_ui.mru->clear(); for (const auto& fname : m_mruFiles) { m_ui.mru->addAction(fname, [this, fname]() { - m_controller->loadFile(fname); + if (m_controller->loadFile(fname)) { + appendMRU(fname); + } }); } + checkEmptyMRU(); } + + +void ScriptingView::checkEmptyMRU() { + m_ui.loadMostRecent->setEnabled(!m_mruFiles.isEmpty()); +} \ No newline at end of file diff --git a/src/platform/qt/scripting/ScriptingView.h b/src/platform/qt/scripting/ScriptingView.h index 1f90a3f19..a62bd2314 100644 --- a/src/platform/qt/scripting/ScriptingView.h +++ b/src/platform/qt/scripting/ScriptingView.h @@ -22,6 +22,7 @@ public: private slots: void submitRepl(); void load(); + void loadMostRecent(); void controllerReset(); void selectBuffer(const QModelIndex& current, const QModelIndex& = QModelIndex()); @@ -31,6 +32,7 @@ private: void appendMRU(const QString&); void updateMRU(); + void checkEmptyMRU(); Ui::ScriptingView m_ui; diff --git a/src/platform/qt/scripting/ScriptingView.ui b/src/platform/qt/scripting/ScriptingView.ui index 8b97449b0..4d55a8707 100644 --- a/src/platform/qt/scripting/ScriptingView.ui +++ b/src/platform/qt/scripting/ScriptingView.ui @@ -98,6 +98,7 @@ + @@ -108,6 +109,11 @@ Load script... + + + + &Load most recent + From 84dd69ff86aaaccf85b33f83a26f18203a4a0b4f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 25 Aug 2024 02:32:04 -0700 Subject: [PATCH 250/336] Util: Add UIntList predefined vector --- include/mgba-util/vector.h | 1 + src/util/vector.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/mgba-util/vector.h b/include/mgba-util/vector.h index 8c0f11e45..c837379e2 100644 --- a/include/mgba-util/vector.h +++ b/include/mgba-util/vector.h @@ -112,6 +112,7 @@ CXX_GUARD_START } \ DECLARE_VECTOR(IntList, int); +DECLARE_VECTOR(UIntList, unsigned); DECLARE_VECTOR(SInt8List, int8_t); DECLARE_VECTOR(SInt16List, int16_t); DECLARE_VECTOR(SInt32List, int32_t); diff --git a/src/util/vector.c b/src/util/vector.c index 28750a1b4..f84838a16 100644 --- a/src/util/vector.c +++ b/src/util/vector.c @@ -6,6 +6,7 @@ #include DEFINE_VECTOR(IntList, int); +DEFINE_VECTOR(UIntList, unsigned); DEFINE_VECTOR(SInt8List, int8_t); DEFINE_VECTOR(SInt16List, int16_t); DEFINE_VECTOR(SInt32List, int32_t); From c06a376b2e2f5f9023a6edec1ec20df3ab532c1d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 31 Aug 2024 05:14:54 -0700 Subject: [PATCH 251/336] Core: Switch video log state load/store to use mCore*State functions --- src/feature/video-logger.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index 978700864..adcbea276 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -511,9 +511,13 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) { #endif if (core) { - context->initialStateSize = core->stateSize(core); + struct VFile* vf = VFileMemChunk(NULL, core->stateSize(core)); + mCoreSaveStateNamed(core, vf, 0); + context->initialStateSize = vf->size(vf); context->initialState = anonymousMemoryMap(context->initialStateSize); - core->saveState(core, context->initialState); + vf->seek(vf, 0, SEEK_SET); + vf->write(vf, context->initialState, context->initialStateSize); + vf->close(vf); core->startVideoLog(core, context); } @@ -763,15 +767,15 @@ void mVideoLogContextDestroy(struct mCore* core, struct mVideoLogContext* contex void mVideoLogContextRewind(struct mVideoLogContext* context, struct mCore* core) { _readHeader(context); if (core) { - size_t size = core->stateSize(core); - if (size <= context->initialStateSize) { - core->loadState(core, context->initialState); + struct VFile* vf; + if (context->initialStateSize < core->stateSize(core)) { + vf = VFileMemChunk(NULL, core->stateSize(core)); + vf->write(vf, context->initialState, context->initialStateSize); } else { - void* extendedState = anonymousMemoryMap(size); - memcpy(extendedState, context->initialState, context->initialStateSize); - core->loadState(core, extendedState); - mappedMemoryFree(extendedState, size); + vf = VFileFromConstMemory(context->initialState, context->initialStateSize); } + mCoreLoadStateNamed(core, vf, 0); + vf->close(vf); } off_t pointer = context->backing->seek(context->backing, 0, SEEK_CUR); From 3a6657bd88ec04744896e4704a5c40baf1067b75 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 00:55:29 -0700 Subject: [PATCH 252/336] Core: Add stubs for loading/saving subsystem extra state --- include/mgba/core/core.h | 2 ++ include/mgba/core/serialize.h | 2 ++ src/core/serialize.c | 3 +++ src/gb/core.c | 14 ++++++++++++++ src/gba/core.c | 14 ++++++++++++++ 5 files changed, 35 insertions(+) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 18295ed13..04bca4689 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -109,6 +109,8 @@ struct mCore { size_t (*stateSize)(struct mCore*); bool (*loadState)(struct mCore*, const void* state); bool (*saveState)(struct mCore*, void* state); + bool (*loadExtraState)(struct mCore*, const struct mStateExtdata*); + bool (*saveExtraState)(struct mCore*, struct mStateExtdata*); void (*setKeys)(struct mCore*, uint32_t keys); void (*addKeys)(struct mCore*, uint32_t keys); diff --git a/include/mgba/core/serialize.h b/include/mgba/core/serialize.h index ee9de69a1..e7b114271 100644 --- a/include/mgba/core/serialize.h +++ b/include/mgba/core/serialize.h @@ -17,6 +17,8 @@ enum mStateExtdataTag { EXTDATA_CHEATS = 3, EXTDATA_RTC = 4, EXTDATA_SCREENSHOT_DIMENSIONS = 5, + EXTDATA_SUBSYSTEM_START = 0x40, + EXTDATA_SUBSYSTEM_MAX = 0x7F, EXTDATA_META_TIME = 0x101, EXTDATA_META_CREATOR = 0x102, EXTDATA_MAX diff --git a/src/core/serialize.c b/src/core/serialize.c index b721cdafa..e42457470 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -371,6 +371,7 @@ bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags) { mStateExtdataInit(&extdata); size_t stateSize = core->stateSize(core); + core->saveExtraState(core, &extdata); if (flags & SAVESTATE_METADATA) { uint64_t* creationUsec = malloc(sizeof(*creationUsec)); if (creationUsec) { @@ -528,6 +529,8 @@ bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags) { bool success = core->loadState(core, state); mappedMemoryFree(state, core->stateSize(core)); + core->loadExtraState(core, &extdata); + unsigned width, height; core->currentVideoSize(core, &width, &height); diff --git a/src/gb/core.c b/src/gb/core.c index ed8dda1e5..17a474ed1 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -743,6 +743,18 @@ static bool _GBCoreSaveState(struct mCore* core, void* state) { return true; } +static bool _GBCoreLoadExtraState(struct mCore* core, const struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + +static bool _GBCoreSaveExtraState(struct mCore* core, struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + static void _GBCoreSetKeys(struct mCore* core, uint32_t keys) { struct GBCore* gbcore = (struct GBCore*) core; gbcore->keys = keys; @@ -1321,6 +1333,8 @@ struct mCore* GBCoreCreate(void) { core->stateSize = _GBCoreStateSize; core->loadState = _GBCoreLoadState; core->saveState = _GBCoreSaveState; + core->loadExtraState = _GBCoreLoadExtraState; + core->saveExtraState = _GBCoreSaveExtraState; core->setKeys = _GBCoreSetKeys; core->addKeys = _GBCoreAddKeys; core->clearKeys = _GBCoreClearKeys; diff --git a/src/gba/core.c b/src/gba/core.c index b39a5f401..904d85c20 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -832,6 +832,18 @@ static bool _GBACoreSaveState(struct mCore* core, void* state) { return true; } +static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + +static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + static void _GBACoreSetKeys(struct mCore* core, uint32_t keys) { struct GBA* gba = core->board; gba->keysActive = keys; @@ -1539,6 +1551,8 @@ struct mCore* GBACoreCreate(void) { core->stateSize = _GBACoreStateSize; core->loadState = _GBACoreLoadState; core->saveState = _GBACoreSaveState; + core->loadExtraState = _GBACoreLoadExtraState; + core->saveExtraState = _GBACoreSaveExtraState; core->setKeys = _GBACoreSetKeys; core->addKeys = _GBACoreAddKeys; core->clearKeys = _GBACoreClearKeys; From 59b561b8c01d988d267c2ffc371733b899a81a78 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 01:28:05 -0700 Subject: [PATCH 253/336] Core: mStateExtdataGet const correctness --- include/mgba/core/serialize.h | 2 +- src/core/serialize.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mgba/core/serialize.h b/include/mgba/core/serialize.h index e7b114271..177a7871a 100644 --- a/include/mgba/core/serialize.h +++ b/include/mgba/core/serialize.h @@ -44,7 +44,7 @@ struct mStateExtdata { void mStateExtdataInit(struct mStateExtdata*); void mStateExtdataDeinit(struct mStateExtdata*); void mStateExtdataPut(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); -bool mStateExtdataGet(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); +bool mStateExtdataGet(const struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); struct VFile; bool mStateExtdataSerialize(struct mStateExtdata* extdata, struct VFile* vf); diff --git a/src/core/serialize.c b/src/core/serialize.c index e42457470..203ed809a 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -57,7 +57,7 @@ void mStateExtdataPut(struct mStateExtdata* extdata, enum mStateExtdataTag tag, extdata->data[tag] = *item; } -bool mStateExtdataGet(struct mStateExtdata* extdata, enum mStateExtdataTag tag, struct mStateExtdataItem* item) { +bool mStateExtdataGet(const struct mStateExtdata* extdata, enum mStateExtdataTag tag, struct mStateExtdataItem* item) { if (tag == EXTDATA_NONE || tag >= EXTDATA_MAX) { return false; } From da553d191f005e7a921dc1067b973e3d516b7d81 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 01:36:07 -0700 Subject: [PATCH 254/336] Core: Extdata should not have a size < 0 --- src/core/serialize.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/serialize.c b/src/core/serialize.c index 203ed809a..4f7c07a4a 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -131,6 +131,9 @@ bool mStateExtdataDeserialize(struct mStateExtdata* extdata, struct VFile* vf) { if (vf->seek(vf, header.offset, SEEK_SET) < 0) { return false; } + if (header.size <= 0) { + continue; + } struct mStateExtdataItem item = { .data = malloc(header.size), .size = header.size, From a5ea157c9a73aca2247f34c2e9ed461ec2861c2f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 01:56:52 -0700 Subject: [PATCH 255/336] GBA Video: Add stubs for saving/loading extra data out of the video renderers --- include/mgba/feature/video-logger.h | 6 ++++ include/mgba/internal/gba/serialize.h | 5 +++ include/mgba/internal/gba/video.h | 4 +++ src/gba/core.c | 41 ++++++++++++++++++++--- src/gba/extra/proxy.c | 47 +++++++++++++++++++++++++++ src/gba/renderers/gl.c | 29 +++++++++++++++++ src/gba/renderers/video-software.c | 30 ++++++++++++++++- 7 files changed, 156 insertions(+), 6 deletions(-) diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index cf50dd58e..373ea8069 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -35,6 +35,8 @@ enum mVideoLoggerEvent { LOGGER_EVENT_DEINIT, LOGGER_EVENT_RESET, LOGGER_EVENT_GET_PIXELS, + LOGGER_EVENT_LOAD_STATE, + LOGGER_EVENT_SAVE_STATE, }; enum mVideoLoggerInjectionPoint { @@ -85,6 +87,10 @@ struct mVideoLogger { const void* pixelBuffer; size_t pixelStride; + + void* stateBuffer; + size_t stateSize; + bool stateStatus; }; void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly); diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index b31fd0f5a..9bd21821a 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -285,6 +285,11 @@ DECL_BIT(GBASerializedMiscFlags, IrqPending, 2); DECL_BIT(GBASerializedMiscFlags, Blocked, 3); DECL_BITS(GBASerializedMiscFlags, KeyIRQKeys, 4, 11); +enum { + GBA_SUBSYSTEM_VIDEO_RENDERER = 0, + GBA_SUBSYSTEM_MAX, +}; + struct GBASerializedState { uint32_t versionMagic; uint32_t biosChecksum; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index b29b3d607..924772660 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -182,6 +182,10 @@ struct GBAVideoRenderer { void (*reset)(struct GBAVideoRenderer* renderer); void (*deinit)(struct GBAVideoRenderer* renderer); + uint32_t (*rendererId)(const struct GBAVideoRenderer* renderer); + bool (*loadState)(struct GBAVideoRenderer* renderer, const void* state, size_t size); + void (*saveState)(struct GBAVideoRenderer* renderer, void** state, size_t* size); + uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); void (*writeVRAM)(struct GBAVideoRenderer* renderer, uint32_t address); void (*writePalette)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); diff --git a/src/gba/core.c b/src/gba/core.c index 904d85c20..e9cf2b81c 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -833,14 +834,44 @@ static bool _GBACoreSaveState(struct mCore* core, void* state) { } static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdata* extdata) { - UNUSED(core); - UNUSED(extdata); - return true; + struct GBA* gba = core->board; + struct mStateExtdataItem item; + bool ok = true; + if (mStateExtdataGet(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_VIDEO_RENDERER, &item)) { + if ((uint32_t) item.size > sizeof(uint32_t)) { + uint32_t type; + LOAD_32(type, 0, item.data); + if (type == gba->video.renderer->rendererId(gba->video.renderer)) { + ok = gba->video.renderer->loadState(gba->video.renderer, + (void*) ((uintptr_t) item.data + sizeof(uint32_t)), + item.size - sizeof(type)); + } + } else if (item.data) { + ok = false; + } + } + return ok; } static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* extdata) { - UNUSED(core); - UNUSED(extdata); + struct GBA* gba = core->board; + void* buffer = NULL; + size_t size = 0; + gba->video.renderer->saveState(gba->video.renderer, &buffer, &size); + if (size > 0 && buffer) { + struct mStateExtdataItem item; + item.size = size + sizeof(uint32_t); + item.data = malloc(item.size); + item.clean = free; + uint32_t type = gba->video.renderer->rendererId(gba->video.renderer); + STORE_32(type, 0, item.data); + memcpy((void*) ((uintptr_t) item.data + sizeof(uint32_t)), buffer, size); + mStateExtdataPut(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_VIDEO_RENDERER, &item); + } + if (buffer) { + free(buffer); + } + return true; } diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 7842bef1f..0847e1f4a 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -13,6 +13,9 @@ static void GBAVideoProxyRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoProxyRendererReset(struct GBAVideoRenderer* renderer); static void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer); +static uint32_t GBAVideoProxyRendererId(const struct GBAVideoRenderer* renderer); +static bool GBAVideoProxyRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size); +static void GBAVideoProxyRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size); static uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); static void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); static void GBAVideoProxyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); @@ -27,9 +30,13 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address); void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoProxyRendererInit; renderer->d.reset = GBAVideoProxyRendererReset; renderer->d.deinit = GBAVideoProxyRendererDeinit; + renderer->d.rendererId = GBAVideoProxyRendererId; + renderer->d.loadState = GBAVideoProxyRendererLoadState; + renderer->d.saveState = GBAVideoProxyRendererSaveState; renderer->d.writeVideoRegister = GBAVideoProxyRendererWriteVideoRegister; renderer->d.writeVRAM = GBAVideoProxyRendererWriteVRAM; renderer->d.writeOAM = GBAVideoProxyRendererWriteOAM; @@ -172,6 +179,11 @@ void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer) { mVideoLoggerRendererDeinit(proxyRenderer->logger); } +uint32_t GBAVideoProxyRendererId(const struct GBAVideoRenderer* renderer) { + struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; + return proxyRenderer->backend->rendererId(proxyRenderer->backend); +} + static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event) { struct GBAVideoProxyRenderer* proxyRenderer = logger->context; switch (event) { @@ -189,6 +201,12 @@ static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent eve case LOGGER_EVENT_GET_PIXELS: proxyRenderer->backend->getPixels(proxyRenderer->backend, &logger->pixelStride, &logger->pixelBuffer); break; + case LOGGER_EVENT_LOAD_STATE: + logger->stateStatus = proxyRenderer->backend->loadState(proxyRenderer->backend, logger->stateBuffer, logger->stateSize); + break; + case LOGGER_EVENT_SAVE_STATE: + proxyRenderer->backend->saveState(proxyRenderer->backend, &logger->stateBuffer, &logger->stateSize); + break; } } @@ -279,6 +297,35 @@ uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* render return value; } +bool GBAVideoProxyRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size) { + struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; + if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->wait(proxyRenderer->logger); + proxyRenderer->logger->stateBuffer = (void*) state; + proxyRenderer->logger->stateSize = size; + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_LOAD_STATE); + proxyRenderer->logger->stateBuffer = NULL; + proxyRenderer->logger->stateSize = 0; + return proxyRenderer->logger->stateStatus; + } else { + return proxyRenderer->backend->loadState(proxyRenderer->backend, state, size); + } +} + +void GBAVideoProxyRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size) { + struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; + if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->wait(proxyRenderer->logger); + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_SAVE_STATE); + *state = proxyRenderer->logger->stateBuffer; + *size = proxyRenderer->logger->stateSize; + proxyRenderer->logger->stateBuffer = NULL; + proxyRenderer->logger->stateSize = 0; + } else { + proxyRenderer->backend->saveState(proxyRenderer->backend, state, size); + } +} + void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; mVideoLoggerRendererWriteVRAM(proxyRenderer->logger, address); diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index afc9c54ac..24fb092c7 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -13,9 +13,14 @@ #include #include +#define OPENGL_MAGIC 0x6E726C67 + static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer); +static uint32_t GBAVideoGLRendererId(const struct GBAVideoRenderer* renderer); +static bool GBAVideoGLRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size); +static void GBAVideoGLRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size); static void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); static void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); @@ -656,9 +661,13 @@ static const GLint _vertices[] = { }; void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoGLRendererInit; renderer->d.reset = GBAVideoGLRendererReset; renderer->d.deinit = GBAVideoGLRendererDeinit; + renderer->d.rendererId = GBAVideoGLRendererId; + renderer->d.loadState = GBAVideoGLRendererLoadState; + renderer->d.saveState = GBAVideoGLRendererSaveState; renderer->d.writeVideoRegister = GBAVideoGLRendererWriteVideoRegister; renderer->d.writeVRAM = GBAVideoGLRendererWriteVRAM; renderer->d.writeOAM = GBAVideoGLRendererWriteOAM; @@ -953,6 +962,26 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { } } +static uint32_t GBAVideoGLRendererId(const struct GBAVideoRenderer* renderer) { + UNUSED(renderer); + return OPENGL_MAGIC; +} + +static bool GBAVideoGLRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size) { + UNUSED(renderer); + UNUSED(state); + UNUSED(size); + // TODO + return false; +} + +static void GBAVideoGLRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size) { + UNUSED(renderer); + *state = NULL; + *size = 0; + // TODO +} + void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; if (renderer->cache) { diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 7eba88ba3..41f092937 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -14,10 +14,14 @@ #define DIRTY_SCANLINE(R, Y) R->scanlineDirty[Y >> 5] |= (1U << (Y & 0x1F)) #define CLEAN_SCANLINE(R, Y) R->scanlineDirty[Y >> 5] &= ~(1U << (Y & 0x1F)) +#define SOFTWARE_MAGIC 0x6E727773 static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer); +static uint32_t GBAVideoSoftwareRendererId(const struct GBAVideoRenderer* renderer); +static bool GBAVideoSoftwareRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size); +static void GBAVideoSoftwareRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size); static void GBAVideoSoftwareRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); static void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); @@ -47,9 +51,13 @@ static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, stru static void _breakWindowInner(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win); void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoSoftwareRendererInit; renderer->d.reset = GBAVideoSoftwareRendererReset; renderer->d.deinit = GBAVideoSoftwareRendererDeinit; + renderer->d.rendererId = GBAVideoSoftwareRendererId; + renderer->d.loadState = GBAVideoSoftwareRendererLoadState; + renderer->d.saveState = GBAVideoSoftwareRendererSaveState; renderer->d.writeVideoRegister = GBAVideoSoftwareRendererWriteVideoRegister; renderer->d.writeVRAM = GBAVideoSoftwareRendererWriteVRAM; renderer->d.writeOAM = GBAVideoSoftwareRendererWriteOAM; @@ -79,7 +87,7 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { renderer->d.highlightColor = M_COLOR_WHITE; renderer->d.highlightAmount = 0; - renderer->temporaryBuffer = 0; + renderer->temporaryBuffer = NULL; } static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) { @@ -155,6 +163,26 @@ static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer) { UNUSED(softwareRenderer); } +static uint32_t GBAVideoSoftwareRendererId(const struct GBAVideoRenderer* renderer) { + UNUSED(renderer); + return SOFTWARE_MAGIC; +} + +static bool GBAVideoSoftwareRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size) { + UNUSED(renderer); + UNUSED(state); + UNUSED(size); + // TODO + return false; +} + +static void GBAVideoSoftwareRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size) { + UNUSED(renderer); + *state = NULL; + *size = 0; + // TODO +} + static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; if (renderer->cache) { From 3a07834226d271ad15dd54476c0940e49e5b4ed2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 21:13:56 -0700 Subject: [PATCH 256/336] Test: Allow extdata fuzzing --- src/platform/test/fuzz-main.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/platform/test/fuzz-main.c b/src/platform/test/fuzz-main.c index af3bcf083..143edaba1 100644 --- a/src/platform/test/fuzz-main.c +++ b/src/platform/test/fuzz-main.c @@ -109,7 +109,7 @@ int main(int argc, char** argv) { } if (fuzzOpts.ssOverlay) { overlayOffset = fuzzOpts.overlayOffset; - if (overlayOffset < core->stateSize(core)) { + if (overlayOffset <= core->stateSize(core)) { savestateOverlay = VFileOpen(fuzzOpts.ssOverlay, O_RDONLY); } free(fuzzOpts.ssOverlay); @@ -137,19 +137,25 @@ int main(int argc, char** argv) { if (savestate) { if (!savestateOverlay) { - mCoreLoadStateNamed(core, savestate, 0); + mCoreLoadStateNamed(core, savestate, SAVESTATE_ALL); } else { - size_t size = core->stateSize(core); - uint8_t* state = malloc(size); - savestate->read(savestate, state, size); - savestateOverlay->read(savestateOverlay, state + overlayOffset, size - overlayOffset); - core->loadState(core, state); - free(state); + size_t size = savestate->size(savestate); + void* mapped = savestate->map(savestate, size, MAP_READ); + struct VFile* newState = VFileMemChunk(mapped, size); + savestate->unmap(savestate, mapped, size); + newState->seek(newState, overlayOffset, SEEK_SET); + uint8_t buffer[2048]; + int read; + while ((read = savestateOverlay->read(savestateOverlay, buffer, sizeof(buffer))) > 0) { + newState->write(newState, buffer, read); + } savestateOverlay->close(savestateOverlay); - savestateOverlay = 0; + savestateOverlay = NULL; + mCoreLoadStateNamed(core, newState, SAVESTATE_ALL); + newState->close(newState); } savestate->close(savestate); - savestate = 0; + savestate = NULL; } _fuzzRunloop(core, fuzzOpts.frames); From ae6cc33a5e6d2c0339d2ef586a6d186f4bc860ca Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 21:33:09 -0700 Subject: [PATCH 257/336] Core: Improve future-proofing of struct initialization --- src/core/interface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/interface.c b/src/core/interface.c index e5b7f8378..10d3433ab 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -101,9 +101,9 @@ static bool _rtcGenericDeserialize(struct mRTCSource* source, const struct mStat } void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core) { + memset(rtc, 0, sizeof(*rtc)); rtc->p = core; rtc->override = RTC_NO_OVERRIDE; - rtc->value = 0; rtc->d.sample = _rtcGenericSample; rtc->d.unixTime = _rtcGenericCallback; rtc->d.serialize = _rtcGenericSerialize; @@ -143,10 +143,8 @@ static void mRumbleIntegratorIntegrate(struct mRumble* rumble, uint32_t period) } void mRumbleIntegratorInit(struct mRumbleIntegrator* integrator) { + memset(integrator, 0, sizeof(*integrator)); integrator->d.reset = mRumbleIntegratorReset; integrator->d.setRumble = mRumbleIntegratorSetRumble; integrator->d.integrate = mRumbleIntegratorIntegrate; - - integrator->state = false; - integrator->timeOn = 0; } From b072cb40cb073a4bb6fdf38535d457c1a66865fc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 23:24:04 -0700 Subject: [PATCH 258/336] Core: Fix video proxy renderer creation and improve API --- include/mgba/internal/gb/renderers/proxy.h | 2 +- include/mgba/internal/gba/renderers/proxy.h | 2 +- src/gb/core.c | 16 +++++++-------- src/gb/extra/proxy.c | 16 ++++++++------- src/gba/core.c | 22 ++++++++++----------- src/gba/extra/proxy.c | 17 ++++++++-------- 6 files changed, 38 insertions(+), 37 deletions(-) diff --git a/include/mgba/internal/gb/renderers/proxy.h b/include/mgba/internal/gb/renderers/proxy.h index ca3b59f29..b7db8d00f 100644 --- a/include/mgba/internal/gb/renderers/proxy.h +++ b/include/mgba/internal/gb/renderers/proxy.h @@ -20,7 +20,7 @@ struct GBVideoProxyRenderer { enum GBModel model; }; -void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend); +void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend, struct mVideoLogger* logger); void GBVideoProxyRendererShim(struct GBVideo* video, struct GBVideoProxyRenderer* renderer); void GBVideoProxyRendererUnshim(struct GBVideo* video, struct GBVideoProxyRenderer* renderer); diff --git a/include/mgba/internal/gba/renderers/proxy.h b/include/mgba/internal/gba/renderers/proxy.h index c1044c77e..6cb58d092 100644 --- a/include/mgba/internal/gba/renderers/proxy.h +++ b/include/mgba/internal/gba/renderers/proxy.h @@ -19,7 +19,7 @@ struct GBAVideoProxyRenderer { struct mVideoLogger* logger; }; -void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend); +void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend, struct mVideoLogger* logger); void GBAVideoProxyRendererShim(struct GBAVideo* video, struct GBAVideoProxyRenderer* renderer); void GBAVideoProxyRendererUnshim(struct GBAVideo* video, struct GBAVideoProxyRenderer* renderer); diff --git a/src/gb/core.c b/src/gb/core.c index 17a474ed1..020bf8523 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -1266,12 +1266,12 @@ static void _GBCoreStartVideoLog(struct mCore* core, struct mVideoLogContext* co gbcore->logContext = context; int channelId = mVideoLoggerAddChannel(context); - gbcore->proxyRenderer.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbcore->proxyRenderer.logger, false); - mVideoLoggerAttachChannel(gbcore->proxyRenderer.logger, context, channelId); - gbcore->proxyRenderer.logger->block = false; + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, false); + mVideoLoggerAttachChannel(logger, context, channelId); + logger->block = false; - GBVideoProxyRendererCreate(&gbcore->proxyRenderer, &gbcore->renderer.d); + GBVideoProxyRendererCreate(&gbcore->proxyRenderer, &gbcore->renderer.d, logger); GBVideoProxyRendererShim(&gb->video, &gbcore->proxyRenderer); } @@ -1405,9 +1405,9 @@ static bool _GBVLPInit(struct mCore* core) { if (!_GBCoreInit(core)) { return false; } - gbcore->proxyRenderer.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbcore->proxyRenderer.logger, true); - GBVideoProxyRendererCreate(&gbcore->proxyRenderer, NULL); + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, true); + GBVideoProxyRendererCreate(&gbcore->proxyRenderer, NULL, logger); memset(&gbcore->logCallbacks, 0, sizeof(gbcore->logCallbacks)); gbcore->logCallbacks.videoFrameStarted = _GBVLPStartFrameCallback; gbcore->logCallbacks.context = core; diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index 54d46eef3..ba36c0090 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -29,7 +29,8 @@ static void GBVideoProxyRendererPutPixels(struct GBVideoRenderer* renderer, size static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet); static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address); -void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend) { +void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend, struct mVideoLogger* logger) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBVideoProxyRendererInit; renderer->d.deinit = GBVideoProxyRendererDeinit; renderer->d.writeVideoRegister = GBVideoProxyRendererWriteVideoRegister; @@ -57,12 +58,13 @@ void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GB renderer->d.highlightColor = M_COLOR_WHITE; renderer->d.highlightAmount = 0; - renderer->logger->context = renderer; - renderer->logger->parsePacket = _parsePacket; - renderer->logger->vramBlock = _vramBlock; - renderer->logger->paletteSize = 0; - renderer->logger->vramSize = GB_SIZE_VRAM; - renderer->logger->oamSize = GB_SIZE_OAM; + renderer->logger = logger; + logger->context = renderer; + logger->parsePacket = _parsePacket; + logger->vramBlock = _vramBlock; + logger->paletteSize = 0; + logger->vramSize = GB_SIZE_VRAM; + logger->oamSize = GB_SIZE_OAM; renderer->backend = backend; } diff --git a/src/gba/core.c b/src/gba/core.c index e9cf2b81c..ea6adfdf3 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -470,8 +470,7 @@ static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, c #endif #ifndef MINIMAL_CORE if (renderer && core->videoLogger) { - gbacore->proxyRenderer.logger = core->videoLogger; - GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); + GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer, core->videoLogger); renderer = &gbacore->proxyRenderer.d; } #endif @@ -712,8 +711,7 @@ static void _GBACoreReset(struct mCore* core) { #endif #ifndef MINIMAL_CORE if (renderer && core->videoLogger) { - gbacore->proxyRenderer.logger = core->videoLogger; - GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); + GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer, core->videoLogger); renderer = &gbacore->proxyRenderer.d; } #endif @@ -1516,12 +1514,12 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c state->cpu.gprs[ARM_PC] = GBA_BASE_EWRAM; int channelId = mVideoLoggerAddChannel(context); - gbacore->vlProxy.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbacore->vlProxy.logger, false); - mVideoLoggerAttachChannel(gbacore->vlProxy.logger, context, channelId); - gbacore->vlProxy.logger->block = false; + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, false); + mVideoLoggerAttachChannel(logger, context, channelId); + logger->block = false; - GBAVideoProxyRendererCreate(&gbacore->vlProxy, gba->video.renderer); + GBAVideoProxyRendererCreate(&gbacore->vlProxy, gba->video.renderer, logger); GBAVideoProxyRendererShim(&gba->video, &gbacore->vlProxy); } @@ -1654,9 +1652,9 @@ static bool _GBAVLPInit(struct mCore* core) { if (!_GBACoreInit(core)) { return false; } - gbacore->vlProxy.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbacore->vlProxy.logger, true); - GBAVideoProxyRendererCreate(&gbacore->vlProxy, NULL); + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, true); + GBAVideoProxyRendererCreate(&gbacore->vlProxy, NULL, logger); memset(&gbacore->logCallbacks, 0, sizeof(gbacore->logCallbacks)); gbacore->logCallbacks.videoFrameStarted = _GBAVLPStartFrameCallback; gbacore->logCallbacks.context = core; diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 0847e1f4a..ee611247b 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -29,7 +29,7 @@ static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent eve static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet); static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address); -void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend) { +void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend, struct mVideoLogger* logger) { memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoProxyRendererInit; renderer->d.reset = GBAVideoProxyRendererReset; @@ -66,13 +66,14 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct renderer->d.highlightColor = M_COLOR_WHITE; renderer->d.highlightAmount = 0; - renderer->logger->context = renderer; - renderer->logger->parsePacket = _parsePacket; - renderer->logger->handleEvent = _handleEvent; - renderer->logger->vramBlock = _vramBlock; - renderer->logger->paletteSize = GBA_SIZE_PALETTE_RAM; - renderer->logger->vramSize = GBA_SIZE_VRAM; - renderer->logger->oamSize = GBA_SIZE_OAM; + renderer->logger = logger; + logger->context = renderer; + logger->parsePacket = _parsePacket; + logger->handleEvent = _handleEvent; + logger->vramBlock = _vramBlock; + logger->paletteSize = GBA_SIZE_PALETTE_RAM; + logger->vramSize = GBA_SIZE_VRAM; + logger->oamSize = GBA_SIZE_OAM; renderer->backend = backend; } From 1c85dba0df52d7329b3aaa78a84338866d833124 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 23:22:06 -0700 Subject: [PATCH 259/336] Core: Fix creating mVL contexts dropping the savestate --- src/feature/video-logger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index adcbea276..4044a4928 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -516,7 +516,7 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) { context->initialStateSize = vf->size(vf); context->initialState = anonymousMemoryMap(context->initialStateSize); vf->seek(vf, 0, SEEK_SET); - vf->write(vf, context->initialState, context->initialStateSize); + vf->read(vf, context->initialState, context->initialStateSize); vf->close(vf); core->startVideoLog(core, context); } From a6914b2ddb865bb3e67250cd22cbdc307085284e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 22:43:42 -0700 Subject: [PATCH 260/336] Util: Rename color_t to avoid namespace conflicts --- include/mgba-util/image.h | 12 ++--- include/mgba/core/bitmap-cache.h | 8 +-- include/mgba/core/cache-set.h | 2 +- include/mgba/core/core.h | 2 +- include/mgba/core/interface.h | 2 +- include/mgba/core/map-cache.h | 4 +- include/mgba/core/tile-cache.h | 14 +++--- include/mgba/internal/gb/renderers/software.h | 4 +- include/mgba/internal/gb/video.h | 2 +- .../internal/gba/renderers/video-software.h | 10 ++-- include/mgba/internal/gba/video.h | 2 +- src/core/bitmap-cache.c | 14 +++--- src/core/cache-set.c | 2 +- src/core/map-cache.c | 50 +++++++++---------- src/core/test/scripting.c | 2 +- src/core/tile-cache.c | 30 +++++------ src/feature/ffmpeg/ffmpeg-decoder.c | 2 +- src/feature/ffmpeg/ffmpeg-encoder.c | 4 +- src/feature/gui/gui-runner.c | 2 +- src/feature/gui/gui-runner.h | 4 +- src/gb/core.c | 2 +- src/gb/gb.c | 2 +- src/gb/renderers/software.c | 8 +-- src/gba/core.c | 2 +- src/gba/gba.c | 2 +- src/gba/renderers/software-bg.c | 2 +- src/gba/renderers/software-mode0.c | 2 +- src/gba/renderers/software-obj.c | 4 +- src/gba/renderers/software-private.h | 4 +- src/gba/renderers/video-software.c | 8 +-- src/platform/3ds/main.c | 18 +++---- src/platform/libretro/libretro.c | 4 +- src/platform/psp2/psp2-context.h | 2 +- src/platform/python/mgba/image.py | 4 +- src/platform/python/mgba/tile.py | 4 +- src/platform/qt/AssetTile.cpp | 6 +-- src/platform/qt/AssetView.cpp | 2 +- src/platform/qt/CoreController.cpp | 20 ++++---- src/platform/qt/CoreController.h | 2 +- src/platform/qt/DisplayQt.cpp | 2 +- src/platform/qt/FrameView.cpp | 2 +- src/platform/qt/ObjView.cpp | 4 +- src/platform/qt/TilePainter.cpp | 2 +- src/platform/qt/TilePainter.h | 2 +- src/platform/qt/TileView.cpp | 10 ++-- src/platform/sdl/main.h | 2 +- src/platform/switch/main.c | 4 +- src/platform/test/cinema-main.c | 2 +- 48 files changed, 150 insertions(+), 150 deletions(-) diff --git a/include/mgba-util/image.h b/include/mgba-util/image.h index 681e0a3a6..dd135a0b4 100644 --- a/include/mgba-util/image.h +++ b/include/mgba-util/image.h @@ -11,10 +11,10 @@ CXX_GUARD_START #ifdef COLOR_16_BIT -typedef uint16_t color_t; +typedef uint16_t mColor; #define BYTES_PER_PIXEL 2 #else -typedef uint32_t color_t; +typedef uint32_t mColor; #define BYTES_PER_PIXEL 4 #endif @@ -210,18 +210,18 @@ static inline bool mColorFormatHasAlpha(enum mColorFormat format) { return false; } -static inline color_t mColorFrom555(uint16_t value) { +static inline mColor mColorFrom555(uint16_t value) { #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 - color_t color = 0; + mColor color = 0; color |= (value & 0x001F) << 11; color |= (value & 0x03E0) << 1; color |= (value & 0x7C00) >> 10; #else - color_t color = value; + mColor color = value; #endif #else - color_t color = M_RGB5_TO_BGR8(value); + mColor color = M_RGB5_TO_BGR8(value); color |= (color >> 5) & 0x070707; #endif return color; diff --git a/include/mgba/core/bitmap-cache.h b/include/mgba/core/bitmap-cache.h index d8bd416e9..1529fddc2 100644 --- a/include/mgba/core/bitmap-cache.h +++ b/include/mgba/core/bitmap-cache.h @@ -29,13 +29,13 @@ struct mBitmapCacheEntry { }; struct mBitmapCache { - color_t* cache; + mColor* cache; struct mBitmapCacheEntry* status; uint32_t globalPaletteVersion; uint8_t* vram; - color_t* palette; + mColor* palette; uint32_t bitsSize; uint32_t bitsStart[2]; @@ -53,11 +53,11 @@ void mBitmapCacheDeinit(struct mBitmapCache* cache); void mBitmapCacheConfigure(struct mBitmapCache* cache, mBitmapCacheConfiguration config); void mBitmapCacheConfigureSystem(struct mBitmapCache* cache, mBitmapCacheSystemInfo config); void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address); -void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color); +void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, mColor color); void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry* entry, unsigned y); bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheEntry* entry, unsigned y); -const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y); +const mColor* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y); CXX_GUARD_END diff --git a/include/mgba/core/cache-set.h b/include/mgba/core/cache-set.h index 5749c0e64..627a647c7 100644 --- a/include/mgba/core/cache-set.h +++ b/include/mgba/core/cache-set.h @@ -31,7 +31,7 @@ void mCacheSetDeinit(struct mCacheSet*); void mCacheSetAssignVRAM(struct mCacheSet*, void* vram); void mCacheSetWriteVRAM(struct mCacheSet*, uint32_t address); -void mCacheSetWritePalette(struct mCacheSet*, uint32_t entry, color_t color); +void mCacheSetWritePalette(struct mCacheSet*, uint32_t entry, mColor color); CXX_GUARD_END diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 04bca4689..e8c5df7bc 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -73,7 +73,7 @@ struct mCore { unsigned (*videoScale)(const struct mCore*); size_t (*screenRegions)(const struct mCore*, const struct mCoreScreenRegion**); - void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride); + void (*setVideoBuffer)(struct mCore*, mColor* buffer, size_t stride); void (*setVideoGLTex)(struct mCore*, unsigned texid); void (*getPixels)(struct mCore*, const void** buffer, size_t* stride); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 2f4e299dd..597387753 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -47,7 +47,7 @@ DECLARE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks); struct mAVStream { void (*videoDimensionsChanged)(struct mAVStream*, unsigned width, unsigned height); void (*audioRateChanged)(struct mAVStream*, unsigned rate); - void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride); + void (*postVideoFrame)(struct mAVStream*, const mColor* buffer, size_t stride); void (*postAudioFrame)(struct mAVStream*, int16_t left, int16_t right); void (*postAudioBuffer)(struct mAVStream*, struct mAudioBuffer*); }; diff --git a/include/mgba/core/map-cache.h b/include/mgba/core/map-cache.h index 349fc1663..29f17866c 100644 --- a/include/mgba/core/map-cache.h +++ b/include/mgba/core/map-cache.h @@ -44,7 +44,7 @@ struct mMapCacheEntry { struct mTileCache; struct mTileCacheEntry; struct mMapCache { - color_t* cache; + mColor* cache; struct mTileCache* tileCache; struct mMapCacheEntry* status; @@ -75,7 +75,7 @@ bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* en void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y); void mMapCacheCleanRow(struct mMapCache* cache, unsigned y); -const color_t* mMapCacheGetRow(struct mMapCache* cache, unsigned y); +const mColor* mMapCacheGetRow(struct mMapCache* cache, unsigned y); CXX_GUARD_END diff --git a/include/mgba/core/tile-cache.h b/include/mgba/core/tile-cache.h index f8600b3ad..24458b011 100644 --- a/include/mgba/core/tile-cache.h +++ b/include/mgba/core/tile-cache.h @@ -29,7 +29,7 @@ struct mTileCacheEntry { }; struct mTileCache { - color_t* cache; + mColor* cache; struct mTileCacheEntry* status; uint32_t* globalPaletteVersion; @@ -39,8 +39,8 @@ struct mTileCache { unsigned bpp; uint16_t* vram; - color_t* palette; - color_t temporaryTile[64]; + mColor* palette; + mColor temporaryTile[64]; mTileCacheConfiguration config; mTileCacheSystemInfo sysConfig; @@ -51,11 +51,11 @@ void mTileCacheDeinit(struct mTileCache* cache); void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config); void mTileCacheConfigureSystem(struct mTileCache* cache, mTileCacheSystemInfo config, uint32_t tileBase, uint32_t paletteBase); void mTileCacheWriteVRAM(struct mTileCache* cache, uint32_t address); -void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t color); +void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, mColor color); -const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId); -const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId); -const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId); +const mColor* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId); +const mColor* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId); +const mColor* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId); const uint16_t* mTileCacheGetVRAM(struct mTileCache* cache, unsigned tileId); CXX_GUARD_END diff --git a/include/mgba/internal/gb/renderers/software.h b/include/mgba/internal/gb/renderers/software.h index c61f2270d..4ca4c1c1f 100644 --- a/include/mgba/internal/gb/renderers/software.h +++ b/include/mgba/internal/gb/renderers/software.h @@ -22,13 +22,13 @@ struct GBVideoRendererSprite { struct GBVideoSoftwareRenderer { struct GBVideoRenderer d; - color_t* outputBuffer; + mColor* outputBuffer; int outputBufferStride; // TODO: Implement the pixel FIFO uint16_t row[GB_VIDEO_HORIZONTAL_PIXELS + 8]; - color_t palette[192]; + mColor palette[192]; uint8_t lookup[192]; uint32_t* temporaryBuffer; diff --git a/include/mgba/internal/gb/video.h b/include/mgba/internal/gb/video.h index c9b179739..fc0f650ca 100644 --- a/include/mgba/internal/gb/video.h +++ b/include/mgba/internal/gb/video.h @@ -109,7 +109,7 @@ struct GBVideoRenderer { bool highlightBG; bool highlightOBJ[GB_VIDEO_MAX_OBJ]; bool highlightWIN; - color_t highlightColor; + mColor highlightColor; uint8_t highlightAmount; }; diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index d03c52374..d9a012fa8 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -82,7 +82,7 @@ struct Window { struct GBAVideoSoftwareRenderer { struct GBAVideoRenderer d; - color_t* outputBuffer; + mColor* outputBuffer; int outputBufferStride; uint32_t* temporaryBuffer; @@ -100,10 +100,10 @@ struct GBAVideoSoftwareRenderer { unsigned target2Bd; bool blendDirty; enum GBAVideoBlendEffect blendEffect; - color_t normalPalette[512]; - color_t variantPalette[512]; - color_t highlightPalette[512]; - color_t highlightVariantPalette[512]; + mColor normalPalette[512]; + mColor variantPalette[512]; + mColor highlightPalette[512]; + mColor highlightVariantPalette[512]; uint16_t blda; uint16_t bldb; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 924772660..5fc68eb59 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -208,7 +208,7 @@ struct GBAVideoRenderer { bool highlightBG[4]; bool highlightOBJ[128]; - color_t highlightColor; + mColor highlightColor; uint8_t highlightAmount; }; diff --git a/src/core/bitmap-cache.c b/src/core/bitmap-cache.c index 6cb14eaf0..f42da90c5 100644 --- a/src/core/bitmap-cache.c +++ b/src/core/bitmap-cache.c @@ -20,7 +20,7 @@ void mBitmapCacheInit(struct mBitmapCache* cache) { static void _freeCache(struct mBitmapCache* cache) { size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); if (cache->cache) { - mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); + mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(mColor)); cache->cache = NULL; } if (cache->status) { @@ -39,10 +39,10 @@ static void _redoCacheSize(struct mBitmapCache* cache) { } size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); - cache->cache = anonymousMemoryMap(mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); + cache->cache = anonymousMemoryMap(mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(mColor)); cache->status = anonymousMemoryMap(size * sizeof(*cache->status)); if (mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) { - cache->palette = calloc((1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig))), sizeof(color_t)); + cache->palette = calloc((1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig))), sizeof(mColor)); } else { cache->palette = NULL; } @@ -101,7 +101,7 @@ void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address) { } } -void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color) { +void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, mColor color) { if (!mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) { return; } @@ -122,7 +122,7 @@ uint32_t _lookupEntry15(void* vram, uint32_t offset) { } void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry* entry, unsigned y) { - color_t* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)]; + mColor* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)]; size_t location = cache->buffer + mBitmapCacheSystemInfoGetBuffers(cache->sysConfig) * y; struct mBitmapCacheEntry* status = &cache->status[location]; struct mBitmapCacheEntry desiredStatus = { @@ -181,7 +181,7 @@ bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheE return memcmp(&entry[location], &desiredStatus, sizeof(*entry)) == 0; } -const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y) { - color_t* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)]; +const mColor* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y) { + mColor* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)]; return row; } diff --git a/src/core/cache-set.c b/src/core/cache-set.c index 04d42a233..098844bd9 100644 --- a/src/core/cache-set.c +++ b/src/core/cache-set.c @@ -72,7 +72,7 @@ void mCacheSetWriteVRAM(struct mCacheSet* cache, uint32_t address) { } } -void mCacheSetWritePalette(struct mCacheSet* cache, uint32_t entry, color_t color) { +void mCacheSetWritePalette(struct mCacheSet* cache, uint32_t entry, mColor color) { size_t i; for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) { mBitmapCacheWritePalette(mBitmapCacheSetGetPointer(&cache->bitmaps, i), entry, color); diff --git a/src/core/map-cache.c b/src/core/map-cache.c index d51800780..5668d82f3 100644 --- a/src/core/map-cache.c +++ b/src/core/map-cache.c @@ -18,7 +18,7 @@ void mMapCacheInit(struct mMapCache* cache) { static void _freeCache(struct mMapCache* cache) { size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig)); if (cache->cache) { - mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles); + mappedMemoryFree(cache->cache, 8 * 8 * sizeof(mColor) * tiles); cache->cache = NULL; } if (cache->status) { @@ -33,7 +33,7 @@ static void _redoCacheSize(struct mMapCache* cache) { } size_t tiles = mMapCacheTileCount(cache); - cache->cache = anonymousMemoryMap(8 * 8 * sizeof(color_t) * tiles); + cache->cache = anonymousMemoryMap(8 * 8 * sizeof(mColor) * tiles); cache->status = anonymousMemoryMap(tiles * sizeof(*cache->status)); } @@ -87,19 +87,19 @@ void mMapCacheWriteVRAM(struct mMapCache* cache, uint32_t address) { } } -static inline void _cleanTile(struct mMapCache* cache, const color_t* tile, color_t* mapOut, const struct mMapCacheEntry* status) { +static inline void _cleanTile(struct mMapCache* cache, const mColor* tile, mColor* mapOut, const struct mMapCacheEntry* status) { size_t stride = 8 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig); int x, y; switch (mMapCacheEntryFlagsGetMirror(status->flags)) { case 0: - memcpy(mapOut, tile, sizeof(color_t) * 8); - memcpy(&mapOut[stride], &tile[0x08], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 2], &tile[0x10], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 3], &tile[0x18], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 4], &tile[0x20], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 5], &tile[0x28], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 6], &tile[0x30], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 7], &tile[0x38], sizeof(color_t) * 8); + memcpy(mapOut, tile, sizeof(mColor) * 8); + memcpy(&mapOut[stride], &tile[0x08], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 2], &tile[0x10], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 3], &tile[0x18], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 4], &tile[0x20], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 5], &tile[0x28], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 6], &tile[0x30], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 7], &tile[0x38], sizeof(mColor) * 8); break; case 1: for (y = 0; y < 8; ++y) { @@ -109,14 +109,14 @@ static inline void _cleanTile(struct mMapCache* cache, const color_t* tile, colo } break; case 2: - memcpy(&mapOut[stride * 7], tile, sizeof(color_t) * 8); - memcpy(&mapOut[stride * 6], &tile[0x08], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 5], &tile[0x10], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 4], &tile[0x18], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 3], &tile[0x20], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 2], &tile[0x28], sizeof(color_t) * 8); - memcpy(&mapOut[stride], &tile[0x30], sizeof(color_t) * 8); - memcpy(mapOut, &tile[0x38], sizeof(color_t) * 8); + memcpy(&mapOut[stride * 7], tile, sizeof(mColor) * 8); + memcpy(&mapOut[stride * 6], &tile[0x08], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 5], &tile[0x10], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 4], &tile[0x18], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 3], &tile[0x20], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 2], &tile[0x28], sizeof(mColor) * 8); + memcpy(&mapOut[stride], &tile[0x30], sizeof(mColor) * 8); + memcpy(mapOut, &tile[0x38], sizeof(mColor) * 8); break; case 3: for (y = 0; y < 8; ++y) { @@ -146,7 +146,7 @@ uint32_t mMapCacheTileId(struct mMapCache* cache, unsigned x, unsigned y) { void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y) { size_t location = mMapCacheTileId(cache, x, y); struct mMapCacheEntry* status = &cache->status[location]; - const color_t* tile = NULL; + const mColor* tile = NULL; if (!mMapCacheEntryFlagsIsVramClean(status->flags)) { status->flags = mMapCacheEntryFlagsFillVramClean(status->flags); cache->mapParser(cache, status, &cache->vram[cache->mapStart + (location << mMapCacheSystemInfoGetMapAlign(cache->sysConfig))]); @@ -164,7 +164,7 @@ void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, u } size_t stride = 8 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig); - color_t* mapOut = &cache->cache[(y * stride + x) * 8]; + mColor* mapOut = &cache->cache[(y * stride + x) * 8]; _cleanTile(cache, tile, mapOut, status); entry[location] = *status; } @@ -173,7 +173,7 @@ bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* en size_t location = mMapCacheTileId(cache, x, y); struct mMapCacheEntry* status = &cache->status[location]; int paletteId = mMapCacheEntryFlagsGetPaletteId(status->flags); - const color_t* tile = NULL; + const mColor* tile = NULL; if (mMapCacheEntryFlagsIsVramClean(status->flags) && memcmp(status, &entry[location], sizeof(*entry)) == 0) { unsigned tileId = status->tileId + cache->tileStart; if (tileId >= mTileCacheSystemInfoGetMaxTiles(cache->tileCache->sysConfig)) { @@ -207,13 +207,13 @@ void mMapCacheCleanRow(struct mMapCache* cache, unsigned y) { if (tileId >= mTileCacheSystemInfoGetMaxTiles(cache->tileCache->sysConfig)) { tileId = 0; } - const color_t* tile = mTileCacheGetTile(cache->tileCache, tileId, mMapCacheEntryFlagsGetPaletteId(status->flags)); - color_t* mapOut = &cache->cache[(y * stride + x) * 8]; + const mColor* tile = mTileCacheGetTile(cache->tileCache, tileId, mMapCacheEntryFlagsGetPaletteId(status->flags)); + mColor* mapOut = &cache->cache[(y * stride + x) * 8]; _cleanTile(cache, tile, mapOut, status); } } -const color_t* mMapCacheGetRow(struct mMapCache* cache, unsigned y) { +const mColor* mMapCacheGetRow(struct mMapCache* cache, unsigned y) { size_t stride = 8 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig); return &cache->cache[y * stride]; } diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index e66f2a722..63927effe 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -312,7 +312,7 @@ M_TEST_DEFINE(logging) { M_TEST_DEFINE(screenshot) { SETUP_LUA; CREATE_CORE; - color_t* buffer = malloc(240 * 160 * sizeof(color_t)); + mColor* buffer = malloc(240 * 160 * sizeof(mColor)); core->setVideoBuffer(core, buffer, 240); core->reset(core); core->runFrame(core); diff --git a/src/core/tile-cache.c b/src/core/tile-cache.c index d9f68066c..26ea86416 100644 --- a/src/core/tile-cache.c +++ b/src/core/tile-cache.c @@ -20,7 +20,7 @@ static void _freeCache(struct mTileCache* cache) { unsigned size = 1 << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig); unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); if (cache->cache) { - mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles * size); + mappedMemoryFree(cache->cache, 8 * 8 * sizeof(mColor) * tiles * size); cache->cache = NULL; } if (cache->status) { @@ -44,7 +44,7 @@ static void _redoCacheSize(struct mTileCache* cache) { size = 1 << size; cache->entriesPerTile = size; unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); - cache->cache = anonymousMemoryMap(8 * 8 * sizeof(color_t) * tiles * size); + cache->cache = anonymousMemoryMap(8 * 8 * sizeof(mColor) * tiles * size); cache->status = anonymousMemoryMap(tiles * size * sizeof(*cache->status)); cache->globalPaletteVersion = calloc(size, sizeof(*cache->globalPaletteVersion)); cache->palette = calloc(size * bpp, sizeof(*cache->palette)); @@ -89,7 +89,7 @@ void mTileCacheWriteVRAM(struct mTileCache* cache, uint32_t address) { } } -void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t color) { +void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, mColor color) { if (entry < cache->paletteBase) { return; } @@ -103,10 +103,10 @@ void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t co ++cache->globalPaletteVersion[entry]; } -static void _regenerateTile4(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) { +static void _regenerateTile4(struct mTileCache* cache, mColor* tile, unsigned tileId, unsigned paletteId) { uint8_t* start = (uint8_t*) &cache->vram[tileId << 3]; paletteId <<= 2; - color_t* palette = &cache->palette[paletteId]; + mColor* palette = &cache->palette[paletteId]; int i; for (i = 0; i < 8; ++i) { uint8_t tileDataLower = start[0]; @@ -133,10 +133,10 @@ static void _regenerateTile4(struct mTileCache* cache, color_t* tile, unsigned t } } -static void _regenerateTile16(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) { +static void _regenerateTile16(struct mTileCache* cache, mColor* tile, unsigned tileId, unsigned paletteId) { uint32_t* start = (uint32_t*) &cache->vram[tileId << 4]; paletteId <<= 4; - color_t* palette = &cache->palette[paletteId]; + mColor* palette = &cache->palette[paletteId]; int i; for (i = 0; i < 8; ++i) { uint32_t line = *start; @@ -162,10 +162,10 @@ static void _regenerateTile16(struct mTileCache* cache, color_t* tile, unsigned } } -static void _regenerateTile256(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) { +static void _regenerateTile256(struct mTileCache* cache, mColor* tile, unsigned tileId, unsigned paletteId) { uint32_t* start = (uint32_t*) &cache->vram[tileId << 5]; paletteId <<= 8; - color_t* palette = &cache->palette[paletteId]; + mColor* palette = &cache->palette[paletteId]; int i; for (i = 0; i < 8; ++i) { uint32_t line = *start; @@ -194,7 +194,7 @@ static void _regenerateTile256(struct mTileCache* cache, color_t* tile, unsigned } } -static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { +static inline mColor* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { if (mTileCacheConfigurationIsShouldStore(cache->config)) { unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); mASSERT(tileId < tiles); @@ -205,7 +205,7 @@ static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, un } } -const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { +const mColor* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { unsigned count = cache->entriesPerTile; unsigned bpp = cache->bpp; struct mTileCacheEntry* status = &cache->status[tileId * count + paletteId]; @@ -215,7 +215,7 @@ const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsi .vramClean = 1, .paletteId = paletteId }; - color_t* tile = _tileLookup(cache, tileId, paletteId); + mColor* tile = _tileLookup(cache, tileId, paletteId); if (!mTileCacheConfigurationIsShouldStore(cache->config) || memcmp(status, &desiredStatus, sizeof(*status))) { switch (bpp) { case 0: @@ -235,7 +235,7 @@ const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsi return tile; } -const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId) { +const mColor* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId) { unsigned count = cache->entriesPerTile; unsigned bpp = cache->bpp; struct mTileCacheEntry* status = &cache->status[tileId * count + paletteId]; @@ -245,7 +245,7 @@ const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCa .vramClean = 1, .paletteId = paletteId }; - color_t* tile = NULL; + mColor* tile = NULL; if (memcmp(status, &desiredStatus, sizeof(*status))) { tile = _tileLookup(cache, tileId, paletteId); switch (bpp) { @@ -270,7 +270,7 @@ const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCa return tile; } -const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId) { +const mColor* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId) { return &cache->palette[paletteId << (1 << cache->bpp)]; } diff --git a/src/feature/ffmpeg/ffmpeg-decoder.c b/src/feature/ffmpeg/ffmpeg-decoder.c index daa47fbf2..09539ca61 100644 --- a/src/feature/ffmpeg/ffmpeg-decoder.c +++ b/src/feature/ffmpeg/ffmpeg-decoder.c @@ -190,7 +190,7 @@ bool FFmpegDecoderRead(struct FFmpegDecoder* decoder) { } int stride = decoder->width * BYTES_PER_PIXEL; sws_scale(decoder->scaleContext, (const uint8_t* const*) decoder->videoFrame->data, decoder->videoFrame->linesize, 0, decoder->videoFrame->height, &decoder->pixels, &stride); - decoder->out->postVideoFrame(decoder->out, (const color_t*) decoder->pixels, decoder->width); + decoder->out->postVideoFrame(decoder->out, (const mColor*) decoder->pixels, decoder->width); } } } diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index 220ce4d86..5ee54a5e8 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -34,7 +34,7 @@ #endif #include -static void _ffmpegPostVideoFrame(struct mAVStream*, const color_t* pixels, size_t stride); +static void _ffmpegPostVideoFrame(struct mAVStream*, const mColor* pixels, size_t stride); static void _ffmpegPostAudioFrame(struct mAVStream*, int16_t left, int16_t right); static void _ffmpegSetVideoDimensions(struct mAVStream*, unsigned width, unsigned height); static void _ffmpegSetAudioRate(struct mAVStream*, unsigned rate); @@ -784,7 +784,7 @@ bool _ffmpegWriteAudioFrame(struct FFmpegEncoder* encoder, struct AVFrame* audio return gotData; } -void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) { +void _ffmpegPostVideoFrame(struct mAVStream* stream, const mColor* pixels, size_t stride) { struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream; if (!encoder->context || !encoder->videoCodec) { return; diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index b3ce21ad9..035522f02 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -123,7 +123,7 @@ static void _drawState(struct GUIBackground* background, void* id) { struct mGUIBackground* gbaBackground = (struct mGUIBackground*) background; unsigned stateId = ((uint32_t) id) >> 16; if (gbaBackground->p->drawScreenshot) { - color_t* pixels = gbaBackground->image; + mColor* pixels = gbaBackground->image; if (pixels && gbaBackground->screenshotId == (stateId | SCREENSHOT_VALID)) { gbaBackground->p->drawScreenshot(gbaBackground->p, pixels, gbaBackground->w, gbaBackground->h, true); return; diff --git a/src/feature/gui/gui-runner.h b/src/feature/gui/gui-runner.h index 334ef57d9..e65ced52f 100644 --- a/src/feature/gui/gui-runner.h +++ b/src/feature/gui/gui-runner.h @@ -31,7 +31,7 @@ struct mGUIBackground { struct GUIBackground d; struct mGUIRunner* p; - color_t* image; + mColor* image; size_t imageSize; uint16_t w; uint16_t h; @@ -86,7 +86,7 @@ struct mGUIRunner { void (*gameUnloaded)(struct mGUIRunner*); void (*prepareForFrame)(struct mGUIRunner*); void (*drawFrame)(struct mGUIRunner*, bool faded); - void (*drawScreenshot)(struct mGUIRunner*, const color_t* pixels, unsigned width, unsigned height, bool faded); + void (*drawScreenshot)(struct mGUIRunner*, const mColor* pixels, unsigned width, unsigned height, bool faded); void (*paused)(struct mGUIRunner*); void (*unpaused)(struct mGUIRunner*); void (*incrementScreenMode)(struct mGUIRunner*); diff --git a/src/gb/core.c b/src/gb/core.c index 020bf8523..2bfea28ef 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -407,7 +407,7 @@ static size_t _GBCoreScreenRegions(const struct mCore* core, const struct mCoreS } } -static void _GBCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) { +static void _GBCoreSetVideoBuffer(struct mCore* core, mColor* buffer, size_t stride) { struct GBCore* gbcore = (struct GBCore*) core; gbcore->renderer.outputBuffer = buffer; gbcore->renderer.outputBufferStride = stride; diff --git a/src/gb/gb.c b/src/gb/gb.c index 282fc45c1..67dea55b8 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -1173,7 +1173,7 @@ void GBFrameEnded(struct GB* gb) { // TODO: Move to common code if (gb->stream && gb->stream->postVideoFrame) { - const color_t* pixels; + const mColor* pixels; size_t stride; gb->video.renderer->getPixels(gb->video.renderer, &stride, (const void**) &pixels); gb->stream->postVideoFrame(gb->stream, pixels, stride); diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index d157920fa..76a0c55da 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -44,7 +44,7 @@ static void _clearScreen(struct GBVideoSoftwareRenderer* renderer) { } int y; for (y = 0; y < GB_VIDEO_VERTICAL_PIXELS; ++y) { - color_t* row = &renderer->outputBuffer[renderer->outputBufferStride * y + sgbOffset]; + mColor* row = &renderer->outputBuffer[renderer->outputBufferStride * y + sgbOffset]; int x; for (x = 0; x < GB_VIDEO_HORIZONTAL_PIXELS; x += 4) { row[x + 0] = renderer->palette[0]; @@ -492,7 +492,7 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer, int index, uint16_t value) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; - color_t color = mColorFrom555(value); + mColor color = mColorFrom555(value); if (softwareRenderer->model & GB_MODEL_SGB) { if (index >= PAL_SGB_BORDER && !(index & 0xF)) { color = softwareRenderer->palette[0]; @@ -668,7 +668,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i if (softwareRenderer->model & GB_MODEL_SGB && softwareRenderer->sgbBorders) { sgbOffset = softwareRenderer->outputBufferStride * 40 + 48; } - color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y + sgbOffset]; + mColor* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y + sgbOffset]; int x = startX; int p = 0; switch (softwareRenderer->d.sgbRenderMode) { @@ -1161,7 +1161,7 @@ static void GBVideoSoftwareRendererPutPixels(struct GBVideoRenderer* renderer, s struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; // TODO: Share with GBAVideoSoftwareRendererGetPixels - const color_t* colorPixels = pixels; + const mColor* colorPixels = pixels; unsigned i; for (i = 0; i < GB_VIDEO_VERTICAL_PIXELS; ++i) { memmove(&softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * i], &colorPixels[stride * i], GB_VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); diff --git a/src/gba/core.c b/src/gba/core.c index ea6adfdf3..a6939406e 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -525,7 +525,7 @@ static size_t _GBACoreScreenRegions(const struct mCore* core, const struct mCore return 1; } -static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) { +static void _GBACoreSetVideoBuffer(struct mCore* core, mColor* buffer, size_t stride) { struct GBACore* gbacore = (struct GBACore*) core; gbacore->renderer.outputBuffer = buffer; gbacore->renderer.outputBufferStride = stride; diff --git a/src/gba/gba.c b/src/gba/gba.c index ce7e3478e..aab2cd3ec 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -980,7 +980,7 @@ void GBAFrameEnded(struct GBA* gba) { } if (gba->stream && gba->stream->postVideoFrame) { - const color_t* pixels; + const mColor* pixels; size_t stride; gba->video.renderer->getPixels(gba->video.renderer, &stride, (const void**) &pixels); gba->stream->postVideoFrame(gba->stream, pixels, stride); diff --git a/src/gba/renderers/software-bg.c b/src/gba/renderers/software-bg.c index 7d50b5088..6fa199b0d 100644 --- a/src/gba/renderers/software-bg.c +++ b/src/gba/renderers/software-bg.c @@ -173,7 +173,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer if (!objwinSlowPath) { _compositeBlendNoObjwin(renderer, pixel, palette[color] | flags, current); } else if (background->objwinForceEnable || (!(current & FLAG_OBJWIN)) == background->objwinOnly) { - color_t* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette; + mColor* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette; unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { mergedFlags = objwinFlags; diff --git a/src/gba/renderers/software-mode0.c b/src/gba/renderers/software-mode0.c index aa1d63924..4aada17b0 100644 --- a/src/gba/renderers/software-mode0.c +++ b/src/gba/renderers/software-mode0.c @@ -512,7 +512,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode0(struct GBAVideoSoftwareRenderer uint32_t screenBase; uint32_t charBase; - color_t* palette = renderer->normalPalette; + mColor* palette = renderer->normalPalette; if (renderer->d.highlightAmount && background->highlight) { palette = renderer->highlightPalette; } diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 3b44d86a5..4152685c6 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -182,11 +182,11 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re } } - color_t* palette = &renderer->normalPalette[0x100]; + mColor* palette = &renderer->normalPalette[0x100]; if (renderer->d.highlightAmount && renderer->d.highlightOBJ[index]) { palette = &renderer->highlightPalette[0x100]; } - color_t* objwinPalette = palette; + mColor* objwinPalette = palette; if (variant) { palette = &renderer->variantPalette[0x100]; diff --git a/src/gba/renderers/software-private.h b/src/gba/renderers/software-private.h index 8a195534b..4f7e9f8d6 100644 --- a/src/gba/renderers/software-private.h +++ b/src/gba/renderers/software-private.h @@ -155,7 +155,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re // TODO: Remove UNUSEDs after implementing OBJWIN for modes 3 - 5 #define PREPARE_OBJWIN \ int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); \ - color_t* objwinPalette = renderer->normalPalette; \ + mColor* objwinPalette = renderer->normalPalette; \ if (renderer->d.highlightAmount && background->highlight) { \ objwinPalette = renderer->highlightPalette; \ } \ @@ -194,7 +194,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re uint32_t flags = background->flags; \ uint32_t objwinFlags = background->objwinFlags; \ bool variant = background->variant; \ - color_t* palette = renderer->normalPalette; \ + mColor* palette = renderer->normalPalette; \ if (renderer->d.highlightAmount && background->highlight) { \ palette = renderer->highlightPalette; \ } \ diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 41f092937..83550bcfa 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -97,7 +97,7 @@ static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) { int y; for (y = 0; y < GBA_VIDEO_VERTICAL_PIXELS; ++y) { - color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; + mColor* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; int x; for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; ++x) { row[x] = M_COLOR_WHITE; @@ -422,7 +422,7 @@ static void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; - color_t color = mColorFrom555(value); + mColor color = mColorFrom555(value); softwareRenderer->normalPalette[address >> 1] = color; if (softwareRenderer->blendEffect == BLEND_BRIGHTEN) { softwareRenderer->variantPalette[address >> 1] = _brighten(color, softwareRenderer->bldy); @@ -610,7 +610,7 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render CLEAN_SCANLINE(softwareRenderer, y); - color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; + mColor* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) { int x; for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; ++x) { @@ -781,7 +781,7 @@ static void GBAVideoSoftwareRendererGetPixels(struct GBAVideoRenderer* renderer, static void GBAVideoSoftwareRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; - const color_t* colorPixels = pixels; + const mColor* colorPixels = pixels; unsigned i; for (i = 0; i < GBA_VIDEO_VERTICAL_PIXELS; ++i) { memmove(&softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * i], &colorPixels[stride * i], GBA_VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index de6575eff..2d7f80d15 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -85,8 +85,8 @@ static enum { } hasSound; // TODO: Move into context -static color_t* outputBuffer = NULL; -static color_t* screenshotBuffer = NULL; +static mColor* outputBuffer = NULL; +static mColor* screenshotBuffer = NULL; static struct mAVStream stream; static int16_t* audioLeft = 0; static size_t audioPos = 0; @@ -293,7 +293,7 @@ static void _setup(struct mGUIRunner* runner) { _map3DSKey(&runner->core->inputMap, KEY_L, GBA_KEY_L); _map3DSKey(&runner->core->inputMap, KEY_R, GBA_KEY_R); - memset(outputBuffer, 0, 256 * 224 * sizeof(color_t)); + memset(outputBuffer, 0, 256 * 224 * sizeof(mColor)); runner->core->setVideoBuffer(runner->core, outputBuffer, 256); unsigned mode; @@ -615,19 +615,19 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { _drawTex(runner->core, faded, interframeBlending); } -static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { +static void _drawScreenshot(struct mGUIRunner* runner, const mColor* pixels, unsigned width, unsigned height, bool faded) { C3D_Tex* tex = &outputTexture[activeOutputTexture]; if (!screenshotBuffer) { - screenshotBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); + screenshotBuffer = linearMemAlign(256 * 224 * sizeof(mColor), 0x80); } unsigned y; for (y = 0; y < height; ++y) { - memcpy(&screenshotBuffer[y * 256], &pixels[y * width], width * sizeof(color_t)); - memset(&screenshotBuffer[y * 256 + width], 0, (256 - width) * sizeof(color_t)); + memcpy(&screenshotBuffer[y * 256], &pixels[y * width], width * sizeof(mColor)); + memset(&screenshotBuffer[y * 256 + width], 0, (256 - width) * sizeof(mColor)); } - GSPGPU_FlushDataCache(screenshotBuffer, 256 * height * sizeof(color_t)); + GSPGPU_FlushDataCache(screenshotBuffer, 256 * height * sizeof(mColor)); C3D_SyncDisplayTransfer( (u32*) screenshotBuffer, GX_BUFFER_DIM(256, height), tex->data, GX_BUFFER_DIM(256, 256), @@ -917,7 +917,7 @@ int main(int argc, char* argv[]) { _cleanup(); return 1; } - outputBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); + outputBuffer = linearMemAlign(256 * 224 * sizeof(mColor), 0x80); struct mGUIRunner runner = { .params = { diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 88743b63e..232c4e6eb 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -37,7 +37,7 @@ #define VIDEO_WIDTH_MAX 256 #define VIDEO_HEIGHT_MAX 224 -#define VIDEO_BUFF_SIZE (VIDEO_WIDTH_MAX * VIDEO_HEIGHT_MAX * sizeof(color_t)) +#define VIDEO_BUFF_SIZE (VIDEO_WIDTH_MAX * VIDEO_HEIGHT_MAX * sizeof(mColor)) static retro_environment_t environCallback; static retro_video_refresh_t videoCallback; @@ -66,7 +66,7 @@ static int32_t _readTiltY(struct mRotationSource* source); static int32_t _readGyroZ(struct mRotationSource* source); static struct mCore* core; -static color_t* outputBuffer = NULL; +static mColor* outputBuffer = NULL; static int16_t *audioSampleBuffer = NULL; static size_t audioSampleBufferSize; static float audioSamplesPerFrameAvg; diff --git a/src/platform/psp2/psp2-context.h b/src/platform/psp2/psp2-context.h index 2c9a47e09..316dbd434 100644 --- a/src/platform/psp2/psp2-context.h +++ b/src/platform/psp2/psp2-context.h @@ -22,7 +22,7 @@ void mPSP2Paused(struct mGUIRunner* runner); void mPSP2Unpaused(struct mGUIRunner* runner); void mPSP2Swap(struct mGUIRunner* runner); void mPSP2Draw(struct mGUIRunner* runner, bool faded); -void mPSP2DrawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded); +void mPSP2DrawScreenshot(struct mGUIRunner* runner, const mColor* pixels, unsigned width, unsigned height, bool faded); void mPSP2IncrementScreenMode(struct mGUIRunner* runner); void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit); uint16_t mPSP2PollInput(struct mGUIRunner* runner); diff --git a/src/platform/python/mgba/image.py b/src/platform/python/mgba/image.py index 3b6679524..a67801021 100644 --- a/src/platform/python/mgba/image.py +++ b/src/platform/python/mgba/image.py @@ -23,7 +23,7 @@ class Image: def constitute(self): if self.stride <= 0: self.stride = self.width - self.buffer = ffi.new("color_t[{}]".format(self.stride * self.height)) + self.buffer = ffi.new("mColor[{}]".format(self.stride * self.height)) def save_png(self, fileobj): png_file = png.PNG(fileobj, mode=png.MODE_RGBA if self.alpha else png.MODE_RGB) @@ -65,7 +65,7 @@ def u32_to_u16(color): return abgr -if ffi.sizeof("color_t") == 2: +if ffi.sizeof("mColor") == 2: def color_to_u16(color): return color diff --git a/src/platform/python/mgba/tile.py b/src/platform/python/mgba/tile.py index 48812930c..5a9e5d713 100644 --- a/src/platform/python/mgba/tile.py +++ b/src/platform/python/mgba/tile.py @@ -18,7 +18,7 @@ class Tile: def composite(self, i, x, y): for iy in range(8): - ffi.memmove(ffi.addressof(i.buffer, x + (iy + y) * i.stride), ffi.addressof(self.buffer, iy * 8), 8 * ffi.sizeof("color_t")) + ffi.memmove(ffi.addressof(i.buffer, x + (iy + y) * i.stride), ffi.addressof(self.buffer, iy * 8), 8 * ffi.sizeof("mColor")) class CacheSet: @@ -55,7 +55,7 @@ class MapView: if not y & 7: lib.mMapCacheCleanRow(self.cache, y >> 3) row = lib.mMapCacheGetRow(self.cache, y) - ffi.memmove(ffi.addressof(i.buffer, i.stride * y), row, self.width * 8 * ffi.sizeof("color_t")) + ffi.memmove(ffi.addressof(i.buffer, i.stride * y), row, self.width * 8 * ffi.sizeof("mColor")) return i diff --git a/src/platform/qt/AssetTile.cpp b/src/platform/qt/AssetTile.cpp index 78db4ccd9..2661c9fde 100644 --- a/src/platform/qt/AssetTile.cpp +++ b/src/platform/qt/AssetTile.cpp @@ -86,7 +86,7 @@ void AssetTile::selectIndex(int index) { return; } m_index = index; - const color_t* data; + const mColor* data; mTileCache* tileCache = m_tileCaches[index >= m_boundary]; unsigned bpp = 8 << tileCache->bpp; @@ -130,10 +130,10 @@ void AssetTile::setFlip(bool h, bool v) { } void AssetTile::selectColor(int index) { - const color_t* data; + const mColor* data; mTileCache* tileCache = m_tileCaches[m_index >= m_boundary]; data = mTileCacheGetTile(tileCache, m_index >= m_boundary ? m_index - m_boundary : m_index, m_paletteId); - color_t color = data[index]; + mColor color = data[index]; m_ui.color->setColor(0, color); m_ui.color->update(); diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index c648982c6..17b745100 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -135,7 +135,7 @@ QImage AssetView::compositeMap(int map, QVector* mapStatus) { QImage AssetView::compositeObj(const ObjInfo& objInfo) { mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, objInfo.paletteSet); unsigned maxTiles = mTileCacheSystemInfoGetMaxTiles(tileCache->sysConfig); - const color_t* rawPalette = mTileCacheGetPalette(tileCache, objInfo.paletteId); + const mColor* rawPalette = mTileCacheGetPalette(tileCache, objInfo.paletteId); unsigned colors = 1 << objInfo.bits; QVector palette; diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 519ce45fb..08b96bd81 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -97,7 +97,7 @@ CoreController::CoreController(mCore* core, QObject* parent) controller->m_frameCounter = -1; if (!controller->m_hwaccel) { - context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer.data()), controller->screenDimensions().width()); + context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer.data()), controller->screenDimensions().width()); } QString message(tr("Reset r%1-%2 %3").arg(gitRevision).arg(QLatin1String(gitCommitShort)).arg(controller->m_crc32, 8, 16, QLatin1Char('0'))); @@ -236,12 +236,12 @@ void CoreController::setPath(const QString& path, const QString& base) { m_baseDirectory = base; } -const color_t* CoreController::drawContext() { +const mColor* CoreController::drawContext() { if (m_hwaccel) { return nullptr; } QMutexLocker locker(&m_bufferMutex); - return reinterpret_cast(m_completeBuffer.constData()); + return reinterpret_cast(m_completeBuffer.constData()); } QImage CoreController::getPixels() { @@ -307,14 +307,14 @@ void CoreController::loadConfig(ConfigController* config) { m_preload = config->getOption("preload").toInt(); QSize sizeBefore = screenDimensions(); - m_activeBuffer.resize(256 * 224 * sizeof(color_t)); - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeBefore.width()); + m_activeBuffer.resize(256 * 224 * sizeof(mColor)); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeBefore.width()); mCoreLoadForeignConfig(m_threadContext.core, config->config()); QSize sizeAfter = screenDimensions(); - m_activeBuffer.resize(sizeAfter.width() * sizeAfter.height() * sizeof(color_t)); - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeAfter.width()); + m_activeBuffer.resize(sizeAfter.width() * sizeAfter.height() * sizeof(mColor)); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeAfter.width()); if (hasStarted()) { updateFastForward(); @@ -461,11 +461,11 @@ void CoreController::setLogger(LogController* logger) { void CoreController::start() { QSize size(screenDimensions()); - m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t)); + m_activeBuffer.resize(size.width() * size.height() * sizeof(mColor)); m_activeBuffer.fill(0xFF); m_completeBuffer = m_activeBuffer; - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), size.width()); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), size.width()); if (!m_patched) { mCoreAutoloadPatch(m_threadContext.core); @@ -1194,7 +1194,7 @@ void CoreController::setFramebufferHandle(int fb) { if (hasStarted()) { m_threadContext.core->reloadConfigOption(m_threadContext.core, "hwaccelVideo", NULL); if (!m_hwaccel) { - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), screenDimensions().width()); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), screenDimensions().width()); } } } diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index 684d864d0..57eb9ffe0 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -87,7 +87,7 @@ public: QString baseDirectory() const { return m_baseDirectory; } QString savePath() const { return m_savePath; } - const color_t* drawContext(); + const mColor* drawContext(); QImage getPixels(); bool isPaused(); diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index 3723a8445..b71147c43 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -78,7 +78,7 @@ void DisplayQt::filter(bool filter) { void DisplayQt::framePosted() { update(); - const color_t* buffer = m_context->drawContext(); + const mColor* buffer = m_context->drawContext(); if (const_cast(m_layers[VIDEO_LAYER_IMAGE]).bits() == reinterpret_cast(buffer)) { return; } diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index ada077d74..245ebf4bb 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -574,7 +574,7 @@ void FrameView::newVl() { unsigned width, height; m_vl->baseVideoSize(m_vl, &width, &height); m_framebuffer = QImage(width, height, QImage::Format_RGBX8888); - m_vl->setVideoBuffer(m_vl, reinterpret_cast(m_framebuffer.bits()), width); + m_vl->setVideoBuffer(m_vl, reinterpret_cast(m_framebuffer.bits()), width); m_vl->reset(m_vl); } diff --git a/src/platform/qt/ObjView.cpp b/src/platform/qt/ObjView.cpp index f4482aba6..a29c621fb 100644 --- a/src/platform/qt/ObjView.cpp +++ b/src/platform/qt/ObjView.cpp @@ -138,7 +138,7 @@ void ObjView::updateTilesGBA(bool force) { for (unsigned y = 0; y < newInfo.height; ++y) { for (unsigned x = 0; x < newInfo.width; ++x, ++i, ++tile, ++tileBase) { if (tile < maxTiles) { - const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[16 * tileBase], tile, newInfo.paletteId); + const mColor* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[16 * tileBase], tile, newInfo.paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { @@ -233,7 +233,7 @@ void ObjView::updateTilesGB(bool force) { m_ui.tile->setPalette(newInfo.paletteId); for (unsigned y = 0; y < newInfo.height; ++y, ++i) { unsigned t = tile + i; - const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[8 * t], t, newInfo.paletteId); + const mColor* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[8 * t], t, newInfo.paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp index fcb62d420..b8c8075e6 100644 --- a/src/platform/qt/TilePainter.cpp +++ b/src/platform/qt/TilePainter.cpp @@ -62,7 +62,7 @@ void TilePainter::clearTile(int index) { update(r); } -void TilePainter::setTile(int index, const color_t* data) { +void TilePainter::setTile(int index, const mColor* data) { QPainter painter(&m_backing); int w = width() / m_size; int x = index % w; diff --git a/src/platform/qt/TilePainter.h b/src/platform/qt/TilePainter.h index 5ef4b0555..f1f4a86e0 100644 --- a/src/platform/qt/TilePainter.h +++ b/src/platform/qt/TilePainter.h @@ -23,7 +23,7 @@ public: public slots: void clearTile(int index); - void setTile(int index, const color_t*); + void setTile(int index, const mColor*); void setTileCount(int tiles); void setTileMagnification(int mag); diff --git a/src/platform/qt/TileView.cpp b/src/platform/qt/TileView.cpp index 7d8d1a71e..dbfc15531 100644 --- a/src/platform/qt/TileView.cpp +++ b/src/platform/qt/TileView.cpp @@ -142,7 +142,7 @@ void TileView::updateTilesGBA(bool force) { objOffset = 0; cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 1); for (int i = 0; i < 1024; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { @@ -153,7 +153,7 @@ void TileView::updateTilesGBA(bool force) { if (!m_ui.tilesBg->isChecked()) { cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 3); for (int i = 1024; i < 1536; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0); if (data) { m_ui.tiles->setTile(i - objOffset, data); } else if (force) { @@ -175,7 +175,7 @@ void TileView::updateTilesGBA(bool force) { objOffset = 0; cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0); for (int i = 0; i < 2048; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { @@ -186,7 +186,7 @@ void TileView::updateTilesGBA(bool force) { if (!m_ui.tilesBg->isChecked()) { cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 2); for (int i = 2048; i < 3072; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId); if (data) { m_ui.tiles->setTile(i - objOffset, data); } else if (force) { @@ -205,7 +205,7 @@ void TileView::updateTilesGB(bool force) { m_ui.tiles->setTileCount(count); mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0); for (int i = 0; i < count; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index 43701b3c2..8c2f517d7 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -30,7 +30,7 @@ CXX_GUARD_START struct mCore; struct mSDLRenderer { struct mCore* core; - color_t* outputBuffer; + mColor* outputBuffer; struct mSDLAudio audio; struct mSDLEvents events; diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index c829ab9b0..1f61cc279 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -79,7 +79,7 @@ static GLuint oldTex; static GLuint screenshotTex; static struct GUIFont* font; -static color_t* frameBuffer; +static mColor* frameBuffer; static struct mAVStream stream; static struct mSwitchRumble { struct mRumbleIntegrator d; @@ -517,7 +517,7 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { hidSendVibrationValues(vibrationDeviceHandles, values, 4); } -static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { +static void _drawScreenshot(struct mGUIRunner* runner, const mColor* pixels, unsigned width, unsigned height, bool faded) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, screenshotTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); diff --git a/src/platform/test/cinema-main.c b/src/platform/test/cinema-main.c index a990b5599..cc1bad862 100644 --- a/src/platform/test/cinema-main.c +++ b/src/platform/test/cinema-main.c @@ -684,7 +684,7 @@ static void _cinemaDimensionsChanged(struct mAVStream* stream, unsigned width, u } } -static void _cinemaVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) { +static void _cinemaVideoFrame(struct mAVStream* stream, const mColor* pixels, size_t stride) { struct CInemaStream* cistream = (struct CInemaStream*) stream; cistream->image->stride = stride; size_t bufferSize = cistream->image->stride * cistream->image->height * BYTES_PER_PIXEL; From bb8a6e05f9fb440efdf2121f08448814d6a7ed1f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 15 Sep 2024 03:18:16 -0700 Subject: [PATCH 261/336] GBA Memory: Add support for palette RAM, VRAM, and OAM to GBAPatch8 --- src/gba/memory.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/gba/memory.c b/src/gba/memory.c index 1ddd2eb99..09d3e7a74 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1350,10 +1350,22 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o } } +#define MUNGE8 \ + if (address & 1) { \ + oldValue = alignedValue >> 8; \ + alignedValue &= 0xFF; \ + alignedValue |= value << 8; \ + } else { \ + oldValue = alignedValue; \ + alignedValue &= 0xFF00; \ + alignedValue |= (uint8_t) value; \ + } + void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) { struct GBA* gba = (struct GBA*) cpu->master; struct GBAMemory* memory = &gba->memory; int8_t oldValue = -1; + int16_t alignedValue; switch (address >> BASE_OFFSET) { case GBA_REGION_EWRAM: @@ -1368,13 +1380,29 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); break; case GBA_REGION_PALETTE_RAM: - mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); + LOAD_16(alignedValue, address & (GBA_SIZE_PALETTE_RAM - 2), gba->video.palette); + MUNGE8; + STORE_16(alignedValue, address & (GBA_SIZE_PALETTE_RAM - 2), gba->video.palette); + gba->video.renderer->writePalette(gba->video.renderer, address & (GBA_SIZE_PALETTE_RAM - 2), alignedValue); break; case GBA_REGION_VRAM: - mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); + if ((address & 0x0001FFFF) < GBA_SIZE_VRAM) { + LOAD_16(alignedValue, address & 0x0001FFFE, gba->video.vram); + MUNGE8; + STORE_16(alignedValue, address & 0x0001FFFE, gba->video.vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); + } else { + LOAD_16(alignedValue, address & 0x00017FFE, gba->video.vram); + MUNGE8; + STORE_16(alignedValue, address & 0x00017FFE, gba->video.vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x00017FFE); + } break; case GBA_REGION_OAM: - mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); + LOAD_16(alignedValue, address & (GBA_SIZE_OAM - 2), gba->video.oam.raw); + MUNGE8; + STORE_16(alignedValue, address & (GBA_SIZE_OAM - 2), gba->video.oam.raw); + gba->video.renderer->writeOAM(gba->video.renderer, (address & (GBA_SIZE_OAM - 2)) >> 1); break; case GBA_REGION_ROM0: case GBA_REGION_ROM0_EX: From 3ad4e62b0248e1930c2d338810a272e7cc47d7d6 Mon Sep 17 00:00:00 2001 From: Hexaae Date: Wed, 17 Apr 2024 07:12:31 +0000 Subject: [PATCH 262/336] Qt: Update translation (Italian) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/it/ --- src/platform/qt/ts/mgba-it.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/platform/qt/ts/mgba-it.ts b/src/platform/qt/ts/mgba-it.ts index 12a018db7..6c2d16d4f 100644 --- a/src/platform/qt/ts/mgba-it.ts +++ b/src/platform/qt/ts/mgba-it.ts @@ -6,22 +6,22 @@ Game Boy Advance ROMs (%1) - ROM per Game Boy Advance (%1) + ROM per Game Boy Advance (%1) Game Boy ROMs (%1) - ROM per Game Boy (%1) + ROM per Game Boy (%1) All ROMs (%1) - Tutte le ROM (%1) + Tutte le ROM (%1) %1 Video Logs (*.mvl) - %1 log Video (*.mvl) + %1 log Video (*.mvl) @@ -561,7 +561,7 @@ Dimensione del download: %3 Background - Sfondo + Sfondo @@ -591,7 +591,7 @@ Dimensione del download: %3 Browse - Sfoglia + Sfoglia @@ -4759,12 +4759,12 @@ Dimensione del download: %3 Select image - Seleziona immagine + Seleziona immagine Image file (*.png *.jpg *.jpeg) - File immagine (*.png *.jpg *.jpeg) + File immagine (*.png *.jpg *.jpeg) @@ -4784,7 +4784,7 @@ Dimensione del download: %3 Less than an hour ago - Meno di un ora fa + Meno di un'ora fa @@ -4815,7 +4815,7 @@ Dimensione del download: %3 Gameplay - Gameplay + In gioco @@ -5555,7 +5555,7 @@ Dimensione del download: %3 by %1 - per %1 + di %1 @@ -6771,17 +6771,17 @@ Dimensione del download: %3 Super (L) - Super (L) + Super (L) Super (R) - Super (R) + Super (R) Menu - Menu + Menu From e4973a98d8dfd103d189d5363c7db24fc4da233b Mon Sep 17 00:00:00 2001 From: Milihraim Date: Tue, 7 May 2024 13:53:56 +0000 Subject: [PATCH 263/336] Qt: Update translation (Russian) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/ru/ --- src/platform/qt/ts/mgba-ru.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/ts/mgba-ru.ts b/src/platform/qt/ts/mgba-ru.ts index 17147a467..574a66861 100644 --- a/src/platform/qt/ts/mgba-ru.ts +++ b/src/platform/qt/ts/mgba-ru.ts @@ -5141,7 +5141,7 @@ Download size: %3 Rewind speed: - + СкороÑÑ‚ÑŒ перемотки: @@ -5231,7 +5231,7 @@ Download size: %3 Language - + Язык @@ -5322,7 +5322,7 @@ Download size: %3 Fast forward speed: - СкороÑÑ‚ÑŒ перемотки: + СкороÑÑ‚ÑŒ перемотки (уÑкр.): From a60448d7bcde4d720c8e98b84b27c4fb8c502de9 Mon Sep 17 00:00:00 2001 From: Evrins Hu Date: Sat, 11 May 2024 01:20:53 +0000 Subject: [PATCH 264/336] Qt: Update translation (Chinese (Simplified)) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/zh_Hans/ --- src/platform/qt/ts/mgba-zh_CN.ts | 104 +++++++++++++++---------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index 6992a6280..4e570c196 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -6,22 +6,22 @@ Game Boy Advance ROMs (%1) - Game Boy Advance ROM (%1) + Game Boy Advance ROMs (%1) Game Boy ROMs (%1) - Game Boy ROM (%1) + Game Boy ROMs (%1) All ROMs (%1) - 所有 ROM (%1) + 所有 ROMs (%1) %1 Video Logs (*.mvl) - %1 视频日志 (*.mvl) + %1 视频日志 (*.mvl) @@ -530,12 +530,12 @@ Download size: %3 3DS - + 3DS Vita - + Vita @@ -561,7 +561,7 @@ Download size: %3 Background - 背景 + 背景 @@ -591,7 +591,7 @@ Download size: %3 Browse - æµè§ˆ + æµè§ˆ @@ -631,12 +631,12 @@ Download size: %3 3DS - + 3DS Vita - + Vita @@ -716,7 +716,7 @@ Download size: %3 Image files (*.png *.jpg *.bmp) - + 图åƒæ–‡ä»¶ (*.png *.jpg *.bmp) @@ -975,37 +975,37 @@ Download size: %3 Game Boy (DMG) - + Game Boy (DMG) Game Boy Pocket (MGB) - + Game Boy Pocket (MGB) Super Game Boy (SGB) - + Super Game Boy (SGB) Super Game Boy 2 (SGB) - + Super Game Boy 2 (SGB) Game Boy Color (CGB) - + Game Boy Color (CGB) Game Boy Advance (AGB) - + Game Boy Advance (AGB) Super Game Boy Color (SGB + CGB) - + Super Game Boy Color (SGB + CGB) @@ -1015,27 +1015,27 @@ Download size: %3 MBC1 - + MBC1 MBC2 - + MBC2 MBC3 - + MBC3 MBC3 + RTC - + MBC3 + 实时时钟 MBC5 - + MBC5 @@ -1045,7 +1045,7 @@ Download size: %3 MBC6 - + MBC6 @@ -1055,17 +1055,17 @@ Download size: %3 MMM01 - + MMM01 HuC-1 - + HuC-1 HuC-3 - + HuC-3 @@ -1080,17 +1080,17 @@ Download size: %3 Wisdom Tree - + Wisdom Tree NT (old 1) - + NT (æ—§ 1) NT (old 2) - + NT (æ—§ 2) @@ -1105,32 +1105,32 @@ Download size: %3 BBD - + BBD Hitek - + Hitek GGB-81 - + GGB-81 Li Cheng - + Li Cheng Sachen (MMC1) - + Sachen (MMC1) Sachen (MMC2) - + Sachen (MMC2) @@ -3752,17 +3752,17 @@ Download size: %3 Trying to detach a multiplayer player that's not attached - + å°è¯•æ–­å¼€ä¸Žæœªè¿žæŽ¥çš„多人玩家的连接 Trying to get player ID for a multiplayer player that's not attached - + å°è¯•èŽ·å–未连接的多人玩家的 ID Trying to get save ID for a multiplayer player that's not attached - + å°è¯•èŽ·å–未连接的多人玩家的存档 ID @@ -4310,7 +4310,7 @@ Download size: %3 Save file: - + ä¿å­˜æ–‡ä»¶: @@ -4759,12 +4759,12 @@ Download size: %3 Select image - 选择图片 + 选择图片 Image file (*.png *.jpg *.jpeg) - 图åƒæ–‡ä»¶ï¼ˆ*.png *.jpg *.jpeg) + 图åƒæ–‡ä»¶ï¼ˆ*.png *.jpg *.jpeg) @@ -5247,7 +5247,7 @@ Download size: %3 Custom border: - + 自定义边框: @@ -5283,7 +5283,7 @@ Download size: %3 Rewind speed: - + 倒带速度: @@ -5879,7 +5879,7 @@ Download size: %3 WavPack - + WavPack @@ -6099,7 +6099,7 @@ Download size: %3 %1 - %2 (%3 fps) - %4 - + %1 - %2 (%3 fps) - %4 @@ -6401,12 +6401,12 @@ Download size: %3 Increase fast forward speed - + 加快快进速度 Decrease fast forward speed - + é™ä½Žå¿«è¿›é€Ÿåº¦ @@ -6744,7 +6744,7 @@ Download size: %3 %1 kiB - + %1 åƒå­—节 @@ -6769,17 +6769,17 @@ Download size: %3 Super (L) - Super(L) + Super (L) Super (R) - Super(R) + Super (R) Menu - èœå• + èœå• From 9d9cb7450f083ec6beb8af5344f3ca71471f1b00 Mon Sep 17 00:00:00 2001 From: Imre Kristoffer Eilertsen Date: Sun, 9 Jun 2024 07:14:59 +0000 Subject: [PATCH 265/336] =?UTF-8?q?Qt:=20Update=20translation=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/nb_NO/ --- src/platform/qt/ts/mgba-nb_NO.ts | 243 ++++++++++++++++--------------- 1 file changed, 122 insertions(+), 121 deletions(-) diff --git a/src/platform/qt/ts/mgba-nb_NO.ts b/src/platform/qt/ts/mgba-nb_NO.ts index 4a97f0c60..6c06c2fe6 100644 --- a/src/platform/qt/ts/mgba-nb_NO.ts +++ b/src/platform/qt/ts/mgba-nb_NO.ts @@ -6,12 +6,12 @@ Game Boy Advance ROMs (%1) - + Game Boy Advance ROM-filer (%1) Game Boy ROMs (%1) - + Game Boy ROM-filer (%1) @@ -21,7 +21,7 @@ %1 Video Logs (*.mvl) - + %1-videologger (*.mvl) @@ -34,7 +34,7 @@ <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> - <a href="http://mgba.io/">Nettside</a> • <a href="https://forums.mgba.io/">Forum / støtte</a> • <a href="https://patreon.com/mgba">Doner</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Kildekode</a> + <a href="https://mgba.io/">Nettside</a> • <a href="https://forums.mgba.io/">Forum / støtte</a> • <a href="https://patreon.com/mgba">Doner</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Kildekode</a> @@ -70,7 +70,8 @@ Game Boy Advance er et registrert varemerke tilhørende Nintendo Co., Ltd. An update to %1 is available. - + En oppdatering til %1 er tilgjengelig. + @@ -101,12 +102,12 @@ Nedlastningsstørrelse: %3 Downloading failed. Please update manually. - + Nedlastingen mislyktes. Vennligst oppdater manuelt. Downloading done. Press OK to restart %1 and install the update. - + Nedlastingen er fullført. Trykk OK for Ã¥ starte %1 pÃ¥ nytt og installere oppdateringen. @@ -137,7 +138,7 @@ Nedlastningsstørrelse: %3 Open in archive... - Ã…pne i arkiv … + Ã…pne i arkiv … @@ -244,7 +245,7 @@ Nedlastningsstørrelse: %3 Load - Last inn + Last inn @@ -313,7 +314,7 @@ Nedlastningsstørrelse: %3 (untitled) - + (uten tittel) @@ -346,7 +347,7 @@ Nedlastningsstørrelse: %3 Code type - + Kodetype @@ -373,7 +374,7 @@ Nedlastningsstørrelse: %3 Select cheats file - Velg juksekodefil + Velg juksekodefil @@ -397,7 +398,7 @@ Nedlastningsstørrelse: %3 Reset the game? - + Vil du starte spillet pÃ¥ nytt? @@ -532,7 +533,7 @@ Nedlastningsstørrelse: %3 Vita - + Vita @@ -545,7 +546,7 @@ Nedlastningsstørrelse: %3 Banner - + Plakat @@ -588,7 +589,7 @@ Nedlastningsstørrelse: %3 Browse - + Bla @@ -761,7 +762,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -781,7 +782,7 @@ Nedlastningsstørrelse: %3 Objwin - + Objwin @@ -817,12 +818,12 @@ Nedlastningsstørrelse: %3 Clear Button - + Tøm knapper Clear Analog - + Tøm analoge @@ -832,7 +833,7 @@ Nedlastningsstørrelse: %3 Set all - + Sett alle @@ -860,7 +861,7 @@ Nedlastningsstørrelse: %3 Standard GDB - + Standard GDB @@ -1082,27 +1083,27 @@ Nedlastningsstørrelse: %3 NT (old 1) - + NT (gammel 1) NT (old 2) - + NT (gammel 2) NT (new) - + NT (ny) Pokémon Jade/Diamond - + Pokémon Jade/Diamond BBD - + BBD @@ -1122,12 +1123,12 @@ Nedlastningsstørrelse: %3 Sachen (MMC1) - + Sachen (MMC1) Sachen (MMC2) - + Sachen (MMC2) @@ -1212,22 +1213,22 @@ Nedlastningsstørrelse: %3 Enable background 0 - + Skru pÃ¥ bakgrunn 0 Enable background 1 - + Skru pÃ¥ bakgrunn 1 Enable background 2 - + Skru pÃ¥ bakgrunn 2 Enable background 3 - + Skru pÃ¥ bakgrunn 3 @@ -1237,12 +1238,12 @@ Nedlastningsstørrelse: %3 Enable Window 0 - + Skru pÃ¥ vindu 1 Enable Window 1 - + Skru pÃ¥ vindu 1 @@ -1311,7 +1312,7 @@ Nedlastningsstørrelse: %3 Enable mosaic - + Skru pÃ¥ flislegging @@ -1609,7 +1610,7 @@ Nedlastningsstørrelse: %3 Blend mode - + Blendmodus @@ -1876,49 +1877,49 @@ Nedlastningsstørrelse: %3 Enable channel 1 right - + Skru pÃ¥ kanal 1 høyre Enable channel 2 right - + Skru pÃ¥ kanal 2 høyre Enable channel 3 right - + Skru pÃ¥ kanal 3 høyre Enable channel 4 right - + Skru pÃ¥ kanal 4 høyre Enable channel 1 left - + Skru pÃ¥ kanal 1 venstre Enable channel 2 left - + Skru pÃ¥ kanal 2 venstre Enable channel 3 left - + Skru pÃ¥ kanal 3 venstre Enable channel 4 left - + Skru pÃ¥ kanal 4 venstre @@ -2211,7 +2212,7 @@ Nedlastningsstørrelse: %3 Joypad - + Kontroller @@ -2271,13 +2272,13 @@ Nedlastningsstørrelse: %3 0x9800 – 0x9BFF - + 0x9800 – 0x9BFF 0x9C00 – 0x9FFF - + 0x9C00 – 0x9FFF @@ -2287,12 +2288,12 @@ Nedlastningsstørrelse: %3 0x8800 – 0x87FF - + 0x8800 – 0x87FF 0x8000 – 0x8FFF - + 0x8000 – 0x8FFF @@ -2317,12 +2318,12 @@ Nedlastningsstørrelse: %3 0: HBlank - + 0: HBlank 1: VBlank - + 1: VBlank @@ -2517,7 +2518,7 @@ Nedlastningsstørrelse: %3 WRAM bank - + WRAM-bank @@ -2569,7 +2570,7 @@ Nedlastningsstørrelse: %3 Fixed - + Fastsatt @@ -2654,7 +2655,7 @@ Nedlastningsstørrelse: %3 IRQ - + IRQ @@ -2804,22 +2805,22 @@ Nedlastningsstørrelse: %3 SC - + SC SD - + SD SI - + SI SO - + SO @@ -2855,37 +2856,37 @@ Nedlastningsstørrelse: %3 SIO - + SIO DMA 0 - + DMA 0 DMA 1 - + DMA 1 DMA 2 - + DMA 2 DMA 3 - + DMA 3 Keypad - + Talltastatur @@ -3056,7 +3057,7 @@ Nedlastningsstørrelse: %3 No Save - + Ingen lagrefil @@ -3236,7 +3237,7 @@ Nedlastningsstørrelse: %3 Enabled Levels - + PÃ¥skrudde nivÃ¥er @@ -3266,7 +3267,7 @@ Nedlastningsstørrelse: %3 Fatal - Kritisk + Kritisk @@ -3286,7 +3287,7 @@ Nedlastningsstørrelse: %3 Max Lines - + Maks antall linjer @@ -3342,7 +3343,7 @@ Nedlastningsstørrelse: %3 Xform - + Xform @@ -3422,7 +3423,7 @@ Nedlastningsstørrelse: %3 Failed to open output file: %1 - Klarte ikke Ã¥ Ã¥pne utdatafil: %1 + Klarte ikke Ã¥ Ã¥pne utdatafil: %1 @@ -3445,7 +3446,7 @@ Nedlastningsstørrelse: %3 Load - Last inn + Last inn @@ -3465,7 +3466,7 @@ Nedlastningsstørrelse: %3 Failed to open output file: %1 - Klarte ikke Ã¥ Ã¥pne utdatafil: %1 + Klarte ikke Ã¥ Ã¥pne utdatafil: %1 @@ -3708,7 +3709,7 @@ Nedlastningsstørrelse: %3 Load TBL - + Last inn TBL @@ -3733,7 +3734,7 @@ Nedlastningsstørrelse: %3 Load - Last inn + Last inn @@ -3937,7 +3938,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -4250,7 +4251,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -4335,7 +4336,7 @@ Nedlastningsstørrelse: %3 Generate report - + Generer rapport @@ -4363,7 +4364,7 @@ Nedlastningsstørrelse: %3 Save games and save states (%1) - + Lagrefiler og lagringstilstander @@ -4373,7 +4374,7 @@ Nedlastningsstørrelse: %3 Save games (%1) - + Lagrefiler (%1) @@ -4428,13 +4429,13 @@ Nedlastningsstørrelse: %3 Input file - + Inndatafil Browse - + Bla @@ -4484,7 +4485,7 @@ Nedlastningsstørrelse: %3 %1 SRAM - + %1 SRAM @@ -4613,7 +4614,7 @@ Nedlastningsstørrelse: %3 Fixed time - + Fastsatt tid @@ -4623,7 +4624,7 @@ Nedlastningsstørrelse: %3 Start time at - + Start tiden pÃ¥ @@ -4633,7 +4634,7 @@ Nedlastningsstørrelse: %3 Offset time - + Tidsavvik @@ -4664,13 +4665,13 @@ Nedlastningsstørrelse: %3 Set Y - + Sett Y Set X - + Sett X @@ -4710,7 +4711,7 @@ Nedlastningsstørrelse: %3 OpenGL (force version 1.x) - + OpenGL (tving versjon 1.x) @@ -4908,7 +4909,7 @@ Nedlastningsstørrelse: %3 Sample rate: - + Datapunktfrekvens: @@ -4957,7 +4958,7 @@ Nedlastningsstørrelse: %3 Audio in multiplayer: - + Lyd i flerspiller: @@ -4967,7 +4968,7 @@ Nedlastningsstørrelse: %3 Player 1 window only - + Kun spiller 1 sitt vindu @@ -5277,12 +5278,12 @@ Nedlastningsstørrelse: %3 Rewind history: - + Tilbakestillingshistorikk: Rewind speed: - + Tilbakespolingsfart: @@ -5420,7 +5421,7 @@ Nedlastningsstørrelse: %3 GB BIOS file: - + GB BIOS-fil: @@ -5434,12 +5435,12 @@ Nedlastningsstørrelse: %3 Browse - + Bla Use BIOS file if found - + Bruk BIOS-filen hvis den blir funnet @@ -5464,7 +5465,7 @@ Nedlastningsstørrelse: %3 Save games - + Lagrefiler @@ -5483,7 +5484,7 @@ Nedlastningsstørrelse: %3 Screenshots - + Skjermklipp @@ -5493,7 +5494,7 @@ Nedlastningsstørrelse: %3 Cheats - Juks + Juks @@ -5572,7 +5573,7 @@ Nedlastningsstørrelse: %3 Active Shader: - + Aktiv skyggelegger: @@ -5652,7 +5653,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -5662,7 +5663,7 @@ Nedlastningsstørrelse: %3 Tiles - + Fliser @@ -5687,7 +5688,7 @@ Nedlastningsstørrelse: %3 Magnification - Forstørrelse + Forstørrelse @@ -5722,7 +5723,7 @@ Nedlastningsstørrelse: %3 Copy Selected - + Kopier valgte @@ -5745,7 +5746,7 @@ Nedlastningsstørrelse: %3 Select output file - Velg utdatafil + Velg utdatafil @@ -5872,7 +5873,7 @@ Nedlastningsstørrelse: %3 FFV1 - + FFV1 @@ -6024,7 +6025,7 @@ Nedlastningsstørrelse: %3 Crash - Krasj + Krasj @@ -6121,7 +6122,7 @@ Nedlastningsstørrelse: %3 Save games (%1) - + Lagrefiler (%1) @@ -6197,7 +6198,7 @@ Nedlastningsstørrelse: %3 ROM &info... - + ROM-&info ... @@ -6232,12 +6233,12 @@ Nedlastningsstørrelse: %3 Quick load - + Hurtiginnlasting Quick save - + Hurtiglagring @@ -6278,12 +6279,12 @@ Nedlastningsstørrelse: %3 GameShark saves (*.gsv *.sps *.xps) - + GameShark-lagrefiler (*.gsv *.sps *.xps) Reset needed - + Tilbakestilling kreves @@ -6293,7 +6294,7 @@ Nedlastningsstørrelse: %3 Save games - + Lagrefiler @@ -6318,7 +6319,7 @@ Nedlastningsstørrelse: %3 New multiplayer window - + Nytt flerspillervindu @@ -6413,7 +6414,7 @@ Nedlastningsstørrelse: %3 Re&wind - + Spol ti&lbake @@ -6463,7 +6464,7 @@ Nedlastningsstørrelse: %3 Audio/&Video - + Lyd/&Video @@ -6568,7 +6569,7 @@ Nedlastningsstørrelse: %3 Game &overrides... - + Spilloverstyringer ... @@ -6638,12 +6639,12 @@ Nedlastningsstørrelse: %3 View memory... - + Vis minne ... Search memory... - + Søk i minne ... From 3853b699f427c928ea7c170b9e739042c7864d97 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 16 Sep 2024 02:48:17 -0700 Subject: [PATCH 266/336] Qt: Fix how some languages are shown in settings --- src/platform/qt/ts/{mgba-es.ts => mgba-es_419.ts} | 0 src/platform/qt/ts/{mgba-pt.ts => mgba-pt_PT.ts} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/platform/qt/ts/{mgba-es.ts => mgba-es_419.ts} (100%) rename src/platform/qt/ts/{mgba-pt.ts => mgba-pt_PT.ts} (99%) diff --git a/src/platform/qt/ts/mgba-es.ts b/src/platform/qt/ts/mgba-es_419.ts similarity index 100% rename from src/platform/qt/ts/mgba-es.ts rename to src/platform/qt/ts/mgba-es_419.ts diff --git a/src/platform/qt/ts/mgba-pt.ts b/src/platform/qt/ts/mgba-pt_PT.ts similarity index 99% rename from src/platform/qt/ts/mgba-pt.ts rename to src/platform/qt/ts/mgba-pt_PT.ts index cddb1dd8c..f3aa6bdc1 100644 --- a/src/platform/qt/ts/mgba-pt.ts +++ b/src/platform/qt/ts/mgba-pt_PT.ts @@ -1,6 +1,6 @@ - + QGBA From b37bd308f2b9947450cea783c952ff9a64bc95b8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 16 Sep 2024 02:57:54 -0700 Subject: [PATCH 267/336] Qt: Update translations --- src/platform/qt/ts/mgba-de.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-en.ts | 892 +++++++++++++-------------- src/platform/qt/ts/mgba-es_419.ts | 870 +++++++++++++-------------- src/platform/qt/ts/mgba-fr.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-hu.ts | 894 ++++++++++++++-------------- src/platform/qt/ts/mgba-it.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-ja.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-ko.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-ms.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-nb_NO.ts | 870 +++++++++++++-------------- src/platform/qt/ts/mgba-pl.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-pt_BR.ts | 870 +++++++++++++-------------- src/platform/qt/ts/mgba-pt_PT.ts | 870 +++++++++++++-------------- src/platform/qt/ts/mgba-ru.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-sv.ts | 892 +++++++++++++-------------- src/platform/qt/ts/mgba-template.ts | 892 +++++++++++++-------------- src/platform/qt/ts/mgba-tr.ts | 868 +++++++++++++-------------- src/platform/qt/ts/mgba-zh_CN.ts | 868 +++++++++++++-------------- 18 files changed, 7898 insertions(+), 7832 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index ce7f38c30..4e65105da 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) - + Game Boy ROMs (%1) Game Boy-ROMs (%1) - + All ROMs (%1) Alle ROMs (%1) - + %1 Video Logs (*.mvl) %1 Video-Logs (*.mvl) @@ -191,17 +191,17 @@ Download-Größe: %3 QGBA::AudioDevice - + Can't set format of context-less audio device Format des kontextlosen Audio-Gerätes konnte nicht gesetzt werden - + Audio device is missing its core Dem Audio-Gerät fehlt sein Core - + Writing data to read-only audio device Schreibe Daten an ein schreibgeschütztes Audio-Gerät @@ -209,7 +209,7 @@ Download-Größe: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input Ohne Eingabe kann ein Audio-Prozessor nicht gestartet werden @@ -285,28 +285,28 @@ Download-Größe: %3 Erweiterte Optionen anzeigen - + BattleChip data missing BattleChip-Daten fehlen - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? BattleChip-Daten fehlen. BattleChip Gates wird weiterhin funktionieren, einige Grafiken werden jedoch fehlen. Möchtest Du die Daten jetzt herunterladen? - - + + Select deck file Deck-Datei auswählen - + Incompatible deck Inkompatibles Deck - + The selected deck is not compatible with this Chip Gate Das gewählte Deck ist nicht mit diesem Chip Gate kompatibel @@ -367,19 +367,19 @@ Download-Größe: %3 Codes hier eingeben... - - + + Autodetect (recommended) Automatisch erkennen (empfohlen) - - + + Select cheats file Cheat-Datei auswählen - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Einige Cheats konnten nicht hinzugefügt werden. Bitte stelle sicher, dass sie korrekt formatiert sind und/oder probiere es mit anderen Cheat-Typen. @@ -398,37 +398,37 @@ Download-Größe: %3 Zurückspulen ist derzeit nicht aktiviert - + Reset the game? Spiel zurücksetzen? - + Most games will require a reset to load the new save. Do you want to reset now? Die meisten Spiele müssen zurückgesetzt werden, um einen neuen Spielstand zu laden. Möchtest Du das Spiel jetzt zurücksetzen? - + Failed to open save file: %1 Fehler beim Öffnen der Speicherdatei: %1 - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Can't yank pack in unexpected platform! Das GamePak kann nur auf unterstützten Plattformen herausgezogen werden! - + Failed to open snapshot file for reading: %1 Konnte Snapshot-Datei %1 nicht zum Lesen öffnen - + Failed to open snapshot file for writing: %1 Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen @@ -477,6 +477,14 @@ Download-Größe: %3 CLI-Verlauf kann nicht gespeichert werden + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Download-Größe: %3 Zurücksetzen - + Export frame Bild exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Keine - + Background Hintergrund - + Window Fenster - + Objwin Objwin - + Sprite Sprite - + Backdrop Hintergrund - + Frame Frame - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Download-Größe: %3 QGBA::GBAKeyEditor - + Clear Button Button löschen - + Clear Analog Analog löschen - + Refresh Aktualisieren - + Set all Alle belegen @@ -3006,8 +3014,8 @@ Download-Größe: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Download-Größe: %3 Vertikal - - - + + + N/A Nicht verfügbar - + Export map Map exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Durchsuchen + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + Start + + + + Stop + Stopp + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Download-Größe: %3 Aktualisieren - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3750,17 +3822,17 @@ Download-Größe: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached Versuch Multiplayer-Spieler zu trennen der nicht verbunden ist - + Trying to get player ID for a multiplayer player that's not attached Versuch Spieler-ID festzustellen von einem Multiplayer-Spieler der nicht verbunden ist - + Trying to get save ID for a multiplayer player that's not attached Versuch Speicherstand-ID festzustellen von einem Multiplayer-Spieler der nicht verbunden ist @@ -4157,35 +4229,35 @@ Download-Größe: %3 OBJ exportieren - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Palette exportieren - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 Fehler beim Öffnen der Ausgabe-Palettendatei: %1 @@ -4259,7 +4331,7 @@ Download-Größe: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Download-Größe: %3 + Maker Code: + + + + + Revision: + + + + File size: Dateigröße: - + CRC32: CRC32: - + Save file: Speicherstand: @@ -4364,62 +4446,62 @@ Download-Größe: %3 QGBA::SaveConverter - + Save games and save states (%1) Spielstände und Savestates (%1) - + Select save game or save state Spielstand oder Savestate auswählen - + Save games (%1) Spielstände (%1) - + Select save game Spielstand auswählen - + Conversion failed Konvertierung fehlgeschlagen - + Failed to convert the save game. This is probably a bug. Fehler beim Konvertieren des Spielstands. Es handelt sich möglicherweise um einen Programmfehler. - + No file selected Keine Datei ausgewählt - + Could not open file Datei konnte nicht geöffnet werden - + No valid formats found Keine gültigen Formate gefunden - + Please select a valid input file Bitte wähle eine gültige Eingabedatei - + No valid conversions found Keine gültigen Konvertierungen gefunden - + Cannot convert save games between platforms Der Spielstand konnte nicht zwischen verschiedenen Plattformen konvertiert werden @@ -4445,97 +4527,97 @@ Download-Größe: %3 Ausgabedatei - + %1 %2 save game Spielstand %1 %2 - + little endian little-endian - + big endian big-endian - + SRAM SRAM - + %1 flash %1 Flash - + %1 EEPROM %1 EEPROM - + + RTC + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 MBC2, komprimiert - + unpacked MBC2 MBC2, entpackt - + MBC6 flash MBC6 Flash-Speicher - + MBC6 combined SRAM + flash MBC6 SRAM + Flash-Speicher - + MBC6 SRAM MBC6 SRAM - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game Savestate %1 mit eingebettetem Spielstand %2 - + %1 SharkPort %2 save game SharkPort %1 Spielstand %2 - + %1 GameShark Advance SP %2 save game %1 GameShark Advance SP %2 Spielstand @@ -4571,32 +4653,37 @@ Download-Größe: %3 Kürzlich geöffnetes Skript laden - + Load script... Skript laden... - + + &Load most recent + + + + &Reset Zu&rücksetzen - + 0 0 - + Select script to load Skript auswählen, welches geladen werden soll - + Lua scripts (*.lua) Lua-Skripte (*.lua) - + All files (*.*) Alle Dateien (*.*) @@ -4689,105 +4776,105 @@ Download-Größe: %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (erzwinge Version 1.x) - + None Keiner - + None (Still Image) Keiner (Standbild) - + Keyboard Tastatur - + Controllers Gamepads - + Shortcuts Tastenkürzel - - + + Shaders Shader - + Select BIOS BIOS auswählen - + Select directory Verzeichnis auswählen - + Select image Bild auswählen - + Image file (*.png *.jpg *.jpeg) Bilddatei (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never Nie - + Just now Gerade eben - + Less than an hour ago Vor weniger als einer Stunde - + %n hour(s) ago Vor %n Stunde @@ -4795,7 +4882,7 @@ Download-Größe: %3 - + %n day(s) ago Vor %n Tag @@ -5122,37 +5209,37 @@ Download-Größe: %3 Zurückspulgeschwindigkeit: - + Default color palette only Nur Standard-Farbpalette - + SGB color palette if available SGB-Farbpalette, sofern verfügbar - + GBC color palette if available GBC-Farbpalette, sofern verfügbar - + SGB (preferred) or GBC color palette if available SGB (bevorzugt) oder GBC-Farbpalette, sofern verfügbar - + Game Boy Camera Game Boy Camera - + Driver: Treiber: - + Source: Quelle: @@ -5223,42 +5310,42 @@ Download-Größe: %3 Zusätzliche Savestate-Daten laden: - + Models Modelle - + GB only: Nur GB: - + SGB compatible: SGB-kompatibel: - + GBC only: Nur GBC: - + GBC compatible: GBC-kompatibel: - + SGB and GBC compatible: SGB- und GBC-kompatibel: - + Game Boy palette Game Boy-Palette - + Preset: Voreinstellungen: @@ -5303,57 +5390,52 @@ Download-Größe: %3 Software - + OpenGL enhancements OpenGL-Verbesserungen - + High-resolution scale: Hochauflösende Skalierung: - - XQ GBA audio (experimental) - XQ GBA-Audio (experimentell) - - - + Cheats Cheats - + Log to file In Datei protokollieren - + Log to console Auf die Konsole protokollieren - + Select Log File Protokoll-Datei auswählen - + Default BG colors: Standard-Hintergrundfarben: - + Default sprite colors 1: Standard-Sprite-Farben 1: - + Default sprite colors 2: Standard-Sprite-Farben 2: - + Super Game Boy borders Super Game Boy-Rahmen @@ -5384,25 +5466,25 @@ Download-Größe: %3 - - - - - - - - - + + + + + + + + + Browse Durchsuchen - + Use BIOS file if found BIOS-Datei verwenden, wenn vorhanden - + Skip BIOS intro BIOS-Intro überspringen @@ -5480,56 +5562,56 @@ Download-Größe: %3 Autofeuer-Intervall: - + (240×160) (240×160) - + GB BIOS file: Datei mit GB-BIOS: - + GBA BIOS file: Datei mit GBA-BIOS: - + GBC BIOS file: Datei mit GBC-BIOS: - + SGB BIOS file: Datei mit SGB-BIOS: - + Save games Spielstände - - - - - + + + + + Same directory as the ROM Verzeichnis der ROM-Datei - + Save states Savestates - + Screenshots Bildschirmfotos - + Patches Korrekturen @@ -5777,7 +5859,6 @@ Download-Größe: %3 - WebM WebM @@ -5786,19 +5867,8 @@ Download-Größe: %3 Format Format - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 @@ -5842,72 +5912,6 @@ Download-Größe: %3 &Native &Nativ - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Leer - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Unkomprimiert - Bitrate (kbps) @@ -5918,16 +5922,6 @@ Download-Größe: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5957,85 +5951,85 @@ Download-Größe: %3 QGBA::Window - + Archives (%1) Archive (%1) - - + + Select ROM ROM auswählen - - + + Select save Speicherdatei wählen - + Select patch Patch wählen - + Patches (*.ips *.ups *.bps) Korrekturen (*.ips *.ups *.bps) - + Select e-Reader card images Bilder der Lesegerät-Karte auswählen - + Image file (*.png *.jpg *.jpeg) Bilddatei (*.png *.jpg *.jpeg) - + Conversion finished Konvertierung abgeschlossen - + %1 of %2 e-Reader cards converted successfully. %1 von %2 Lesegerät-Karten erfolgreich konvertiert. - + Select image Bild auswählen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*) - + GameShark saves (*.sps *.xps) GameShark-Speicherdaten (*.sps *.xps) - + Select video log Video-Log auswählen - + Video logs (*.mvl) Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -6044,694 +6038,704 @@ Download-Größe: %3 %1 - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Es konnte kein geeignetes Ausgabegerät erstellt werden, stattdessen wird Software-Rendering als Rückfalloption genutzt. Spiele laufen möglicherweise langsamer, besonders innerhalb großer Fenster. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Save games Spielstände - + Automatically determine Automatisch erkennen - + Use player %0 save game Verwende Spielstand von Spieler %0 - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + Convert e-Reader card image to raw... Lesegerät-Kartenbild in Rohdaten umwandeln â€¦ - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren - + &Load state Savestate (aktueller Zustand) &laden - + Load state file... Savestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - + Undo save state Speichern des Savestate rückgängig machen - - + + State &%1 Savestate &%1 - + Load camera image... Lade Kamerabild... - + Convert save game... Spielstand konvertieren... - + Reset needed Zurücksetzen erforderlich - + Some changes will not take effect until the game is reset. Einige Änderungen werden erst dann wirksam, wenn das Spiel zurückgesetzt wird. - + New multiplayer window Neues Multiplayer-Fenster - + Connect to Dolphin... Mit Dolphin verbinden... - + Report bug... Fehler melden... - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - + &Next frame &Nächstes Bild - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Increase fast forward speed Vorspulgeschwindigkeit erhöhen - + Decrease fast forward speed Vorspulgeschwindigkeit senken - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - + Step backwards Schrittweiser Rücklauf - + Solar sensor Sonnen-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Bildgröße - + Toggle fullscreen Vollbildmodus umschalten - + + &Lock frame size + + + + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + Interframe blending Interframe-Ãœberblendung - + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - + Scripting... Scripting... - + Create forwarder... Forwarder erzeugen... - + Game state views Spiel-Zustände ansehen - + + Log memory &accesses... + + + + Clear Leeren - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Ãœberschreibungen... - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... - + Select folder Ordner auswählen - + Save games (%1) Spielstände (%1) - + Select save game Spielstand auswählen - + mGBA save state files (%1) mGBA-Savestates (%1) - - + + Select save state Savestate auswählen - + Select e-Reader dotcode e-Reader-Code auswählen - + e-Reader card (*.raw *.bin *.bmp) e-Reader-Karte (*.raw *.bin *.bmp) - + GameShark saves (*.gsv *.sps *.xps) GameShark-Spielstände (*.gsv *.sps *.xps) - + Couldn't Start Konnte nicht gestartet werden - + Could not start game. Spiel konnte nicht gestartet werden. - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + Load alternate save game... Alternativen Spielstand laden... - + Load temporary save game... Temporären Spielstand laden... - + Scan e-Reader dotcodes... e-Reader-Code einlesen... - + Import GameShark Save... GameShare-Speicherstand importieren... - + Export GameShark Save... GameShark-Speicherstand exportieren... - + About... Ãœber... - + %1× %1x - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + Record A/V... Audio/Video aufzeichnen... - + Record GIF/WebP/APNG... GIF/WebP/APNG aufzeichnen... - + Game Pak sensors... Spielmodul-Sensoren... - + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + &Frame inspector... &Bildbetrachter... - + View memory... Speicher betrachten... - + Search memory... Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + Record debug video log... Video-Protokoll aufzeichnen... - + Stop debug video log Aufzeichnen des Video-Protokolls beenden - + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links @@ -6769,17 +6773,17 @@ Download-Größe: %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu Menü @@ -6787,22 +6791,22 @@ Download-Größe: %3 QShortcut - + Shift Shift - + Control Strg - + Alt Alt - + Meta AltGr diff --git a/src/platform/qt/ts/mgba-en.ts b/src/platform/qt/ts/mgba-en.ts index 4b67efd50..cdb0f81b4 100644 --- a/src/platform/qt/ts/mgba-en.ts +++ b/src/platform/qt/ts/mgba-en.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) - + Game Boy ROMs (%1) - + All ROMs (%1) - + %1 Video Logs (*.mvl) @@ -185,17 +185,17 @@ Download size: %3 QGBA::AudioDevice - + Can't set format of context-less audio device - + Audio device is missing its core - + Writing data to read-only audio device @@ -203,7 +203,7 @@ Download size: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input @@ -279,28 +279,28 @@ Download size: %3 - + BattleChip data missing - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - + + Select deck file - + Incompatible deck - + The selected deck is not compatible with this Chip Gate @@ -361,19 +361,19 @@ Download size: %3 - - + + Autodetect (recommended) - - + + Select cheats file - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. @@ -392,37 +392,37 @@ Download size: %3 - + Reset the game? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 - + Failed to open game file: %1 - + Can't yank pack in unexpected platform! - + Failed to open snapshot file for reading: %1 - + Failed to open snapshot file for writing: %1 @@ -471,6 +471,14 @@ Download size: %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -751,52 +759,52 @@ Download size: %3 - + Export frame - + Portable Network Graphics (*.png) - + None - + Background - + Window - + Objwin - + Sprite - + Backdrop - + Frame - + %1 %2 @@ -812,22 +820,22 @@ Download size: %3 QGBA::GBAKeyEditor - + Clear Button - + Clear Analog - + Refresh - + Set all @@ -3000,8 +3008,8 @@ Download size: %3 QGBA::KeyEditor - - + + --- @@ -3372,23 +3380,87 @@ Download size: %3 - - - + + + N/A - + Export map - + Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3635,22 +3707,22 @@ Download size: %3 - + (%0/%1×) - + (â…Ÿ%0×) - + (%0×) - + %1 byte%2 @@ -3744,17 +3816,17 @@ Download size: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4151,35 +4223,35 @@ Download size: %3 - + #%0 - + 0x%0 + + - - 0x%0 (%1) - + Export palette - + Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 @@ -4253,7 +4325,7 @@ Download size: %3 QGBA::ROMInfo - + @@ -4293,16 +4365,26 @@ Download size: %3 - File size: + Maker Code: - CRC32: + Revision: + File size: + + + + + CRC32: + + + + Save file: @@ -4358,62 +4440,62 @@ Download size: %3 QGBA::SaveConverter - + Save games and save states (%1) - + Select save game or save state - + Save games (%1) - + Select save game - + Conversion failed - + Failed to convert the save game. This is probably a bug. - + No file selected - + Could not open file - + No valid formats found - + Please select a valid input file - + No valid conversions found - + Cannot convert save games between platforms @@ -4439,97 +4521,97 @@ Download size: %3 - + %1 %2 save game - + little endian - + big endian - + SRAM - + %1 flash - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM - + TAMA5 - + %1 (%2) - + %1 save state with embedded %2 save game - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4565,32 +4647,37 @@ Download size: %3 - + Load script... - + + &Load most recent + + + + &Reset - + 0 - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4683,105 +4770,105 @@ Download size: %3 QGBA::SettingsView - - + + Qt Multimedia - + SDL - + Software (Qt) - + OpenGL - + OpenGL (force version 1.x) - + None - + None (Still Image) - + Keyboard - + Controllers - + Shortcuts - - + + Shaders - + Select BIOS - + Select directory - + Select image - + Image file (*.png *.jpg *.jpeg) - + (%1×%2) - + Never - + Just now - + Less than an hour ago - + %n hour(s) ago @@ -4789,7 +4876,7 @@ Download size: %3 - + %n day(s) ago @@ -5116,37 +5203,37 @@ Download size: %3 - + Default color palette only - + SGB color palette if available - + GBC color palette if available - + SGB (preferred) or GBC color palette if available - + Game Boy Camera - + Driver: - + Source: @@ -5323,42 +5410,42 @@ Download size: %3 - + Models - + GB only: - + SGB compatible: - + GBC only: - + GBC compatible: - + SGB and GBC compatible: - + Game Boy palette - + Preset: @@ -5395,135 +5482,130 @@ Download size: %3 - + OpenGL enhancements - + High-resolution scale: - + (240×160) - - XQ GBA audio (experimental) - - - - + GB BIOS file: - - - - - - - - - + + + + + + + + + Browse - + Use BIOS file if found - + Skip BIOS intro - + GBA BIOS file: - + GBC BIOS file: - + SGB BIOS file: - + Save games - - - - - + + + + + Same directory as the ROM - + Save states - + Screenshots - + Patches - + Cheats - + Log to file - + Log to console - + Select Log File - + Default BG colors: - + Default sprite colors 1: - + Default sprite colors 2: - + Super Game Boy borders @@ -5781,13 +5863,11 @@ Download size: %3 - WebM - MP4 @@ -5826,82 +5906,6 @@ Download size: %3 Format - - - MKV - - - - - AVI - - - - - HEVC - - - - - HEVC (NVENC) - - - - - VP8 - - - - - VP9 - - - - - FFV1 - - - - - - None - - - - - FLAC - - - - - WavPack - - - - - Opus - - - - - Vorbis - - - - - MP3 - - - - - AAC - - - - - Uncompressed - - Bitrate (kbps) @@ -5912,16 +5916,6 @@ Download size: %3 ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5951,779 +5945,789 @@ Download size: %3 QGBA::Window - + Archives (%1) - - + + Select ROM - + Select folder - - + + Select save - + Select patch - + Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode - + e-Reader card (*.raw *.bin *.bmp) - + Select image - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) - + GameShark saves (*.sps *.xps) - + Select video log - + Video logs (*.mvl) - + Crash - + The game has crashed with the following error: %1 - + Couldn't Start - + Could not start game. - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + Load ROM in archive... - + Add folder to library... - + Save games (%1) - + Select save game - + mGBA save state files (%1) - - + + Select save state - + Select e-Reader card images - + Image file (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Load alternate save game... - + Load temporary save game... - + Load &patch... - + Boot BIOS - + Replace ROM... - + Scan e-Reader dotcodes... - + Convert e-Reader card image to raw... - + ROM &info... - + Recent - + Make portable - + &Load state - + Load state file... - + &Save state - + Save state file... - + Quick load - + Quick save - + Load recent - + Save recent - + Undo load state - + Undo save state - - + + State &%1 - + Load camera image... - + Convert save game... - + GameShark saves (*.gsv *.sps *.xps) - + Reset needed - + Some changes will not take effect until the game is reset. - + Save games - + Import GameShark Save... - + Export GameShark Save... - + Automatically determine - + Use player %0 save game - + New multiplayer window - + Connect to Dolphin... - + Report bug... - + About... - + E&xit - + &Emulation - + &Reset - + Sh&utdown - + Yank game pak - + &Pause - + &Next frame - + Fast forward (held) - + &Fast forward - + Fast forward speed - + Unbounded - + %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) - + Re&wind - + Step backwards - + Solar sensor - + Increase solar level - + Decrease solar level - + Brightest solar level - + Darkest solar level - + Brightness %1 - + Game Boy Printer... - + BattleChip Gate... - + Audio/&Video - + Frame size - + %1× - + Toggle fullscreen - - Lock aspect ratio - - - - - Force integer scaling - - - - - Interframe blending - - - - - Bilinear filtering + + &Lock frame size + Lock aspect ratio + + + + + Force integer scaling + + + + + Interframe blending + + + + + Bilinear filtering + + + + Frame&skip - + Mute - + FPS target - + Native (59.7275) - + Take &screenshot - + F12 - + Record A/V... - + Record GIF/WebP/APNG... - + Video layers - + Audio channels - + Adjust layer placement... - + &Tools - + View &logs... - + Game &overrides... - + Game Pak sensors... - + &Cheats... - + Create forwarder... - + Settings... - + Open debugger console... - + Start &GDB server... - + Scripting... - + Game state views - + View &palette... - + View &sprites... - + View &tiles... - + View &map... - + &Frame inspector... - + View memory... - + Search memory... - + View &I/O registers... - + + Log memory &accesses... + + + + Record debug video log... - + Stop debug video log - + Exit fullscreen - + GameShark Button (held) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear @@ -6761,17 +6765,17 @@ Download size: %3 - + Super (L) - + Super (R) - + Menu @@ -6779,22 +6783,22 @@ Download size: %3 QShortcut - + Shift - + Control - + Alt - + Meta diff --git a/src/platform/qt/ts/mgba-es_419.ts b/src/platform/qt/ts/mgba-es_419.ts index 7dfe054c7..cc40f84f7 100644 --- a/src/platform/qt/ts/mgba-es_419.ts +++ b/src/platform/qt/ts/mgba-es_419.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ROMs para Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMs para Game Boy Advance (%1) - + All ROMs (%1) Todas las ROMs (%1) - + %1 Video Logs (*.mvl) %1 Registros de vídeo (*.mvl) @@ -191,17 +191,17 @@ Tamaño de descarga: %3 QGBA::AudioDevice - + Can't set format of context-less audio device No se puede establecer el formato de un dispositivo de audio sin contexto - + Audio device is missing its core No se encuentra el sistema del dispositivo de audio - + Writing data to read-only audio device Escribiendo datos a dispositivo de audio de sólo lectura @@ -209,7 +209,7 @@ Tamaño de descarga: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input No se puede iniciar el procesador de audio sin entrada @@ -285,28 +285,28 @@ Tamaño de descarga: %3 Mostrar configuración avanzada - + BattleChip data missing Faltan los datos del BattleChip - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? Faltan los datos de BattleChip. Los BattleChip Gates seguirán funcionando pero faltarán algunos gráficos. ¿Quieres descargar los datos ahora? - - + + Select deck file Seleccionar fichero de baraja - + Incompatible deck Baraja no compatible - + The selected deck is not compatible with this Chip Gate La baraja seleccionada no es compatible con este Chip Gate @@ -367,19 +367,19 @@ Tamaño de descarga: %3 Ingresa los códigos aquí... - - + + Autodetect (recommended) Autodetectar (recomendado) - - + + Select cheats file Seleccionar archivo de trucos - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Algunos trucos no se pudieron añadir. Asegúrate de que están en el formato correcto y/o prueba otro tipo de trucos. @@ -398,37 +398,37 @@ Tamaño de descarga: %3 Rebobinado desactivado actualmente - + Reset the game? ¿Reiniciar el juego? - + Most games will require a reset to load the new save. Do you want to reset now? La mayoría de juegos requieren reiniciar para cargar la nueva partida guardada. ¿Quieres reiniciar ahora? - + Failed to open save file: %1 Error al abrir el archivo de guardado: %1 - + Failed to open game file: %1 Error al abrir el archivo del juego: %1 - + Can't yank pack in unexpected platform! ¡No se puede quitar el cartucho en esta plataforma! - + Failed to open snapshot file for reading: %1 Error al leer del archivo de captura: %1 - + Failed to open snapshot file for writing: %1 Error al escribir al archivo de captura: %1 @@ -477,6 +477,14 @@ Tamaño de descarga: %3 No se ha podido abrir el historial de la línea de comandos para escritura + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Tamaño de descarga: %3 Reiniciar - + Export frame Exportar cuadro - + Portable Network Graphics (*.png) Gráficos de red portátiles (*.png) - + None Ninguno - + Background Fondo - + Window Ventana - + Objwin Objwin - + Sprite Sprite - + Backdrop Telón de fondo (backdrop) - + Frame Cuadro - + %1 %2 %1× {1 %2?} @@ -818,22 +826,22 @@ Tamaño de descarga: %3 QGBA::GBAKeyEditor - + Clear Button Reestablecer botones - + Clear Analog Reestablecer sticks analógicos - + Refresh Actualizar - + Set all Configurar todo @@ -3006,8 +3014,8 @@ Tamaño de descarga: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Tamaño de descarga: %3 Vertical - - - + + + N/A n/d - + Export map Exportar mapa - + Portable Network Graphics (*.png) Gráficos de red portátiles (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + Detener + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Tamaño de descarga: %3 Actualizar - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3750,17 +3822,17 @@ Tamaño de descarga: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached Intentando desvincular a un multijugador que no está conectado - + Trying to get player ID for a multiplayer player that's not attached Intentando obtener el ID de un multijugador que no está conectado - + Trying to get save ID for a multiplayer player that's not attached Intentando obtener ID de guardado para un jugador multijugador que no está conectado @@ -4157,35 +4229,35 @@ Tamaño de descarga: %3 Exportar OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Exportar paleta - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 Error al abrir el archivo de paleta de salida: %1 @@ -4259,7 +4331,7 @@ Tamaño de descarga: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Tamaño de descarga: %3 + Maker Code: + + + + + Revision: + + + + File size: Tamaño del archivo: - + CRC32: CRC32: - + Save file: Guardar: @@ -4364,62 +4446,62 @@ Tamaño de descarga: %3 QGBA::SaveConverter - + Save games and save states (%1) Juegos y estados guardados (%1) - + Select save game or save state Seleccionar juego o estado guardado - + Save games (%1) Datos de guardado (%1) - + Select save game Seleccionar juego guardado - + Conversion failed Conversión fallada - + Failed to convert the save game. This is probably a bug. No se pudo convertir el estado guardado. Esto probablemente es un error. - + No file selected Archivo no seleccionado - + Could not open file Error al abrir el archivo - + No valid formats found No se encontraron formatos válidos - + Please select a valid input file Seleccione un archivo de entrada válido - + No valid conversions found No se encontraron conversiones validas - + Cannot convert save games between platforms No se pueden convertir los estados guardados entre plataformas distintas @@ -4445,97 +4527,97 @@ Tamaño de descarga: %3 Archivo de salida - + %1 %2 save game %1 %2 juego guardado - + little endian little-endian - + big endian big-endian - + SRAM SRAM - + %1 flash %1 flash - + %1 EEPROM %1 EEPROM - + + RTC + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 MBC2 empacado - + unpacked MBC2 MBC2 desempacado - + MBC6 flash flash MBC6 - + MBC6 combined SRAM + flash SRAM + flash combinados MBC6 - + MBC6 SRAM SRAM MBC6 - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game %1 estado guardado con juego guardado %2 integrado - + %1 SharkPort %2 save game %1 SharkPort %2 partida guardada - + %1 GameShark Advance SP %2 save game %1 GameShark Advance SP %2 partida guardada @@ -4571,32 +4653,37 @@ Tamaño de descarga: %3 Cargar script reciente - + Load script... Cargar script... - + + &Load most recent + + + + &Reset &Reiniciar - + 0 0 - + Select script to load Elegir script - + Lua scripts (*.lua) Scripts de Lua (*.lua) - + All files (*.*) Todos los archivos (*.*) @@ -4689,119 +4776,117 @@ Tamaño de descarga: %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (forzar versión 1.x) - + None Ninguno - + None (Still Image) Nada (imagen estática) - + Keyboard Teclado - + Controllers Mandos - + Shortcuts Atajos de teclado - - + + Shaders Shaders - + Select BIOS Seleccionar BIOS - + Select directory Elegir carpeta - + Select image Seleccionar imagen - + Image file (*.png *.jpg *.jpeg) Archivo de imagen (*.png *.jpg *.jpeg) - + (%1×%2) - + Never Nunca - + Just now Ahora mismo - + Less than an hour ago Hace menos de una hora - + %n hour(s) ago Hace %n hora Hace %n horas - Hace %n horas - + %n day(s) ago Hace %n día Hace %n días - Hace %n días @@ -5139,37 +5224,37 @@ Tamaño de descarga: %3 Velocidad de rebobinado: - + Default color palette only Sólo paleta de colores predeterminada - + SGB color palette if available Paleta de color SGB si está disponible - + GBC color palette if available Paleta de color GBC si está disponible - + SGB (preferred) or GBC color palette if available Paleta de colores SGB (preferida) o GBC si está disponible - + Game Boy Camera Cámara Game Boy - + Driver: Controlador: - + Source: Fuente: @@ -5215,7 +5300,7 @@ Tamaño de descarga: %3 Activar modo de compatibilidad VBA en ROM hacks - + Preset: Ajustes: @@ -5230,22 +5315,22 @@ Tamaño de descarga: %3 Avance rápido (mantenido): - + (240×160) (240×160) - + Log to file Guardar en archivo - + Log to console Escribir en consola - + Select Log File Seleccionar @@ -5383,61 +5468,56 @@ Tamaño de descarga: %3 Software - + OpenGL enhancements Mejoras para OpenGL - + High-resolution scale: Escala de alta resolución: - - XQ GBA audio (experimental) - Mejorar audio GBA (experimental) - - - + GB BIOS file: Archivo BIOS GB: - - - - - - - - - + + + + + + + + + Browse Examinar - + Use BIOS file if found Usar archivo BIOS si está disponible - + Skip BIOS intro Saltar animación de entrada de la BIOS - + GBA BIOS file: Archivo BIOS GBA: - + GBC BIOS file: Archivo BIOS GBC: - + SGB BIOS file: Archivo BIOS SGB: @@ -5447,91 +5527,91 @@ Tamaño de descarga: %3 Guardar estado automáticamente - + Save games Datos de guardado - - - - - + + + + + Same directory as the ROM En el mismo directorio que la ROM - + Save states Estados de guardado - + Screenshots Capturas de pantalla - + Patches Parches - + Cheats Trucos - + Models Modelos - + GB only: Sólo GB: - + SGB compatible: Compatible con SGB: - + GBC only: Sólo GBC: - + GBC compatible: Compatible con GBC: - + SGB and GBC compatible: Compatible con SGB y GBC: - + Game Boy palette Paleta de Game Boy - + Default BG colors: Colores de fondo por defecto: - + Super Game Boy borders Bordes de Super Game Boy - + Default sprite colors 1: Colores de sprite 1 por defecto: - + Default sprite colors 2: Colores de sprite 2 por defecto: @@ -5779,7 +5859,6 @@ Tamaño de descarga: %3 - WebM WebM @@ -5788,19 +5867,8 @@ Tamaño de descarga: %3 Format Formato - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 @@ -5844,72 +5912,6 @@ Tamaño de descarga: %3 &Native &Nativo - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Ninguno - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Sin comprimir - Bitrate (kbps) @@ -5920,16 +5922,6 @@ Tamaño de descarga: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5959,80 +5951,80 @@ Tamaño de descarga: %3 QGBA::Window - + Archives (%1) Contenedores (%1) - - + + Select ROM Seleccionar ROM - + Select folder Seleccionar carpeta - - + + Select save Seleccionar guardado - + Select patch Seleccionar parche - + Patches (*.ips *.ups *.bps) Parches (*.ips *.ups *.bps) - + Select e-Reader dotcode Seleccionar dotcode del e-Reader - + e-Reader card (*.raw *.bin *.bmp) Tarjeta e-Reader (*.raw *.bin *.bmp) - + Select image Seleccionar imagen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Archivo de imagen (*.png *.gif *.jpg *.jpeg);;Todos los archivos (*) - + GameShark saves (*.sps *.xps) Guardados de GameShark (*.sps *.xps) - + Select video log Seleccionar registro de vídeo - + Video logs (*.mvl) Registros de vídeo (*.mvl) - + Crash Cierre inesperado - + The game has crashed with the following error: %1 @@ -6041,699 +6033,709 @@ Tamaño de descarga: %3 %1 - + Unimplemented BIOS call Llamada a BIOS no implementada - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Este juego utiliza una llamada al BIOS que no se ha implementado. Utiliza el BIOS oficial para obtener la mejor experiencia. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. No se pudo crear un dispositivo de pantalla apropiado, recurriendo a software. Los juegos pueden funcionar lentamente, especialmente con ventanas grandes. - + Really make portable? ¿Hacer "portable"? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Esto hará que el emulador cargue su configuración desde el mismo directorio que el ejecutable. ¿Quieres continuar? - + Restart needed Reinicio necesario - + Some changes will not take effect until the emulator is restarted. Algunos cambios no surtirán efecto hasta que se reinicie el emulador. - + - Player %1 of %2 - Jugador %1 de %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &Archivo - + Load &ROM... Cargar &ROM... - + Load ROM in archive... Cargar ROM desde archivo comprimido... - + Add folder to library... Agregar carpeta a la biblioteca... - + Save games Datos de guardado - + Automatically determine Determinar automáticamente - + Use player %0 save game Usar la partida guardada del jugador %0 - + Load &patch... Cargar &parche... - + Boot BIOS Arrancar BIOS - + Replace ROM... Reemplazar ROM... - + ROM &info... &Información de la ROM... - + Recent Reciente - + Make portable Crear instalación portable - + &Load state Ca&rgar estado - + Report bug... Reportar error... - + About... Acerca de... - + Game Pak sensors... Sensores del cartucho... - + Clear Limpiar - + Load state file... Cargar archivo de estado... - + Save games (%1) Juegos guardados (%1) - + Select save game Elegir juego guardado - + mGBA save state files (%1) Archivos estados guardados mGBA (%1) - - + + Select save state Elegir estado guardado - + Select e-Reader card images Elegir imágenes de tarjeta e-Reader - + Image file (*.png *.jpg *.jpeg) Archivo de imagen (*.png *.jpg *.jpeg) - + Conversion finished Conversión terminada - + %1 of %2 e-Reader cards converted successfully. %1 de %2 tarjetas e-Reader convertidas con éxito. - + Load alternate save game... Cargar partida guardada alternativa... - + Load temporary save game... Cargar partida guardada temporal... - + Convert e-Reader card image to raw... Convertir imagen de tarjeta e-Reader a archivo en bruto... - + &Save state Guardar e&stado - + Save state file... Guardar archivo de estado... - + Quick load Cargado rápido - + Quick save Guardado rápido - + Load recent Cargar reciente - + Save recent Guardar reciente - + Undo load state Deshacer cargar estado - + Undo save state Deshacer guardar estado - - + + State &%1 Estado &%1 - + Load camera image... Cargar imagen para cámara... - + Convert save game... Convertir juego guardado... - + GameShark saves (*.gsv *.sps *.xps) Partidas guardadas de GameShark (*.gsv *.sps *.xps) - + Reset needed Reinicio necesario - + Some changes will not take effect until the game is reset. Algunos cambios no tendrán efecto hasta que se reinicie el juego. - + New multiplayer window Nueva ventana multijugador - + Connect to Dolphin... Conectar a Dolphin... - + E&xit Salir (&X) - + &Emulation &Emulación - + &Reset &Reiniciar - + Sh&utdown Apagar (&U) - + Yank game pak Sacar cartucho - + &Pause &Pausar - + &Next frame Cuadro siguie&nte - + Fast forward (held) Avance rápido (mantener) - + &Fast forward &Avance rápido - + Fast forward speed Velocidad de avance rápido - + Unbounded Sin límite - + %0x %0x - + Increase fast forward speed Aumentar la velocidad de avance rápido - + Decrease fast forward speed Disminuir velocidad de avance rápido - + Rewind (held) Rebobinar (mantener) - + Re&wind Re&bobinar - + Step backwards Paso hacia atrás - + Solar sensor Sensor solar - + Increase solar level Subir nivel - + Decrease solar level Bajar nivel - + Brightest solar level Más claro - + Darkest solar level Más oscuro - + Brightness %1 Brillo %1 - + Audio/&Video Audio/&vídeo - + Frame size Tamaño del cuadro - + Toggle fullscreen Pantalla completa - + + &Lock frame size + + + + Lock aspect ratio Bloquear proporción de aspecto - + Force integer scaling Forzar escala a enteros - + Bilinear filtering Filtro bilineal - + Frame&skip &Salto de cuadros - + Mute Silenciar - + FPS target Objetivo de FPS - + Native (59.7275) Nativo (59,7275) - + Take &screenshot Tomar pan&tallazo - + F12 F12 - + Game Boy Printer... Game Boy Printer... - + BattleChip Gate... BattleChip Gate... - + %1× %1× - + Interframe blending Mezcla entre cuadros - + Record A/V... Grabar A/V... - + Video layers Capas de vídeo - + Audio channels Canales de audio - + Adjust layer placement... Ajustar ubicación de capas... - + &Tools Herramien&tas - + View &logs... Ver re&gistros... - + Game &overrides... Ajustes específic&os por juego... - + Couldn't Start No se pudo iniciar - + Could not start game. No se pudo iniciar el juego. - + Scan e-Reader dotcodes... Escanear dotcodes del e-Reader... - + Import GameShark Save... Importar desde GameShark... - + Export GameShark Save... Exportar a GameShark... - + Record GIF/WebP/APNG... Grabar GIF/WebP/APNG... - + &Cheats... Tru&cos... - + Settings... Ajustes... - + Open debugger console... Abrir consola de depuración... - + Start &GDB server... Iniciar servidor &GDB... - + Scripting... Scripts... - + Create forwarder... Crear autocargador... - + Game state views Estado del juego - + View &palette... Ver &paleta... - + View &sprites... Ver &sprites... - + View &tiles... Ver m&osaicos... - + View &map... Ver &mapa... - + &Frame inspector... Inspec&tor de cuadros... - + View memory... Ver memoria... - + Search memory... Buscar memoria... - + View &I/O registers... Ver registros &I/O... - + + Log memory &accesses... + + + + Record debug video log... Grabar registro de depuración de vídeo... - + Stop debug video log Detener registro de depuración de vídeo - + Exit fullscreen Salir de pantalla completa - + GameShark Button (held) Botón GameShark (mantener) - + Autofire Disparo automático - + Autofire A Disparo automático A - + Autofire B Disparo automático B - + Autofire L Disparo automático L - + Autofire R Disparo automático R - + Autofire Start Disparo automático Start - + Autofire Select Disparo automático Select - + Autofire Up Disparo automático arriba - + Autofire Right Disparo automático derecha - + Autofire Down Disparo automático abajo - + Autofire Left Disparo automático izquierda @@ -6771,17 +6773,17 @@ Tamaño de descarga: %3 ? - + Super (L) Súper (L) - + Super (R) Súper (R) - + Menu Menú @@ -6789,22 +6791,22 @@ Tamaño de descarga: %3 QShortcut - + Shift Mayús - + Control Ctrl - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-fr.ts b/src/platform/qt/ts/mgba-fr.ts index 7efbfef1c..27eb207a9 100644 --- a/src/platform/qt/ts/mgba-fr.ts +++ b/src/platform/qt/ts/mgba-fr.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ROMs de Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMs de Game Boy (%1) - + All ROMs (%1) Toutes les ROM (%1) - + %1 Video Logs (*.mvl) %1 Journaux vidéo (*.mvl) @@ -191,17 +191,17 @@ Taille du téléchargement : %3 QGBA::AudioDevice - + Can't set format of context-less audio device - + Audio device is missing its core - + Writing data to read-only audio device @@ -209,7 +209,7 @@ Taille du téléchargement : %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input @@ -285,28 +285,28 @@ Taille du téléchargement : %3 Paramètres avancés - + BattleChip data missing - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - + + Select deck file - + Incompatible deck - + The selected deck is not compatible with this Chip Gate @@ -368,19 +368,19 @@ Taille du téléchargement : %3 Entrez les codes ici… - - + + Autodetect (recommended) Détecter automatiquement (recommandé) - - + + Select cheats file Choisir un fichier de cheats - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. @@ -399,37 +399,37 @@ Taille du téléchargement : %3 Le rembobinage n'est pas actuellement activé - + Reset the game? Réinitialiser le jeu ? - + Most games will require a reset to load the new save. Do you want to reset now? La plupart des jeux nécessitent une réinitialisation pour charger la nouvelle sauvegarde. Voulez-vous réinitialiser maintenant ? - + Failed to open save file: %1 Échec de l'ouverture du fichier de sauvegarde : %1 - + Failed to open game file: %1 Échec de l'ouverture du fichier de jeu : %1 - + Can't yank pack in unexpected platform! - + Failed to open snapshot file for reading: %1 Échec de l'ouverture de l'instantané pour lire : %1 - + Failed to open snapshot file for writing: %1 Échec de l'ouverture de l'instantané pour écrire : %1 @@ -478,6 +478,14 @@ Taille du téléchargement : %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -758,52 +766,52 @@ Taille du téléchargement : %3 Réinitialiser - + Export frame Exporter l'image - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Aucun - + Background Arrière plan - + Window Fenêtre - + Objwin Objwin - + Sprite Sprite - + Backdrop Toile de fond - + Frame Cadre - + %1 %2 %1 %2 @@ -819,22 +827,22 @@ Taille du téléchargement : %3 QGBA::GBAKeyEditor - + Clear Button Bouton d'effacement - + Clear Analog Effacer l'analogique - + Refresh Rafraîchir - + Set all Tout définir @@ -3017,8 +3025,8 @@ Taille du téléchargement : %3 QGBA::KeyEditor - - + + --- --- @@ -3396,23 +3404,87 @@ Taille du téléchargement : %3 Vertical - - - + + + N/A s.o. - + Export map Exporter la map - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Parcourir + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + Arrêter + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3659,22 +3731,22 @@ Taille du téléchargement : %3 Rafraîchir - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 octet%2 @@ -3768,17 +3840,17 @@ Taille du téléchargement : %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4175,35 +4247,35 @@ Taille du téléchargement : %3 Exporter l'OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Exporter la palette - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 Impossible d'ouvrir le fichier de la palette de sortie : %1 @@ -4277,7 +4349,7 @@ Taille du téléchargement : %3 QGBA::ROMInfo - + @@ -4317,16 +4389,26 @@ Taille du téléchargement : %3 + Maker Code: + + + + + Revision: + + + + File size: Taille du fichier : - + CRC32: CRC32 : - + Save file: @@ -4382,62 +4464,62 @@ Taille du téléchargement : %3 QGBA::SaveConverter - + Save games and save states (%1) - + Select save game or save state - + Save games (%1) - + Select save game - + Conversion failed - + Failed to convert the save game. This is probably a bug. - + No file selected - + Could not open file - + No valid formats found - + Please select a valid input file - + No valid conversions found - + Cannot convert save games between platforms @@ -4463,97 +4545,97 @@ Taille du téléchargement : %3 - + %1 %2 save game - + little endian - + big endian - + SRAM SRAM - + %1 flash - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM - + TAMA5 - + %1 (%2) - + %1 save state with embedded %2 save game - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4589,32 +4671,37 @@ Taille du téléchargement : %3 - + Load script... - + + &Load most recent + + + + &Reset &Réinitialiser - + 0 0 - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4708,105 +4795,105 @@ Taille du téléchargement : %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimédia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (version forcée 1.x) - + None Aucun - + None (Still Image) Aucun (Image fixe) - + Keyboard Clavier - + Controllers Contrôleurs - + Shortcuts Raccourcis - - + + Shaders Shaders - + Select BIOS Choisir le BIOS - + Select directory - + Select image Choisir une image - + Image file (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never - + Just now - + Less than an hour ago - + %n hour(s) ago @@ -4814,7 +4901,7 @@ Taille du téléchargement : %3 - + %n day(s) ago @@ -5182,77 +5269,77 @@ Taille du téléchargement : %3 - + Models - + GB only: - + SGB compatible: - + GBC only: - + GBC compatible: - + SGB and GBC compatible: - + Game Boy palette - + Preset: - + Default color palette only - + SGB color palette if available - + GBC color palette if available - + SGB (preferred) or GBC color palette if available - + Game Boy Camera - + Driver: - + Source: @@ -5262,17 +5349,17 @@ Taille du téléchargement : %3 - + Log to file Journalisation vers le fichier - + Log to console Journalisation vers la console - + Select Log File Sélectionner le fichier de journalisation @@ -5435,120 +5522,115 @@ Taille du téléchargement : %3 Logiciel(s) - + OpenGL enhancements Améliorations OpenGL - + High-resolution scale: Échelle haute résolution : - + (240×160) (240×160) - - XQ GBA audio (experimental) - XQ GBA audio (expérimental) - - - + GB BIOS file: GB BIOS : - - - - - - - - - + + + + + + + + + Browse Parcourir - + Use BIOS file if found Utiliser le fichier BIOS si trouvé - + Skip BIOS intro Passer l'intro du BIOS - + GBA BIOS file: GBA BIOS : - + GBC BIOS file: GBC BIOS : - + SGB BIOS file: SGB BIOS : - + Save games Sauvegarder les jeux - - - - - + + + + + Same directory as the ROM Même répertoire que la ROM - + Save states Sauvegarder les états - + Screenshots Captures d'écran - + Patches Correctifs - + Cheats Cheats - + Default BG colors: Couleurs par défaut de l'arrière plan : - + Super Game Boy borders Bordures Super Game Boy - + Default sprite colors 1: Couleurs par défaut de la sprite nº 1 : - + Default sprite colors 2: Couleurs par défaut de la sprite n°2 : @@ -5796,7 +5878,6 @@ Taille du téléchargement : %3 - WebM WebM @@ -5805,19 +5886,8 @@ Taille du téléchargement : %3 Format Format - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 @@ -5861,72 +5931,6 @@ Taille du téléchargement : %3 &Native &Natif - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Aucun - - - - FLAC - FLAC - - - - WavPack - - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Non compressé - Bitrate (kbps) @@ -5937,16 +5941,6 @@ Taille du téléchargement : %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5976,100 +5970,100 @@ Taille du téléchargement : %3 QGBA::Window - + Archives (%1) Archives (%1) - - + + Select ROM Choisir une ROM - + Select folder Choisir un dossier - - + + Select save Choisir une sauvegarde - + Select patch Sélectionner un correctif - + Patches (*.ips *.ups *.bps) Correctifs/Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode Sélectionnez le numéro de point du e-Reader - + e-Reader card (*.raw *.bin *.bmp) e-Reader carte (*.raw *.bin *.bmp) - + Select e-Reader card images - + Image file (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Select image Choisir une image - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Image (*.png *.gif *.jpg *.jpeg);;Tous les fichiers (*) - + GameShark saves (*.sps *.xps) Sauvegardes GameShark (*.sps *.xps) - + Select video log Sélectionner un journal vidéo - + Video logs (*.mvl) Journaux vidéo (*.mvl) - + Crash Plantage - + The game has crashed with the following error: %1 @@ -6078,679 +6072,689 @@ Taille du téléchargement : %3 %1 - + Unimplemented BIOS call Requête au BIOS non supporté - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Ce jeu utilise un appel BIOS qui n'est pas implémenté. Veuillez utiliser le BIOS officiel pour une meilleure expérience. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Échec de la création d'un périphérique d'affichage approprié, retour à l'affichage du logiciel. Les jeux peuvent fonctionner lentement, en particulier avec des fenêtres plus grandes. - + Really make portable? Vraiment rendre portable ? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Cela amènera l'émulateur à charger sa configuration depuis le même répertoire que l'exécutable. Souhaitez vous continuer ? - + Restart needed Un redémarrage est nécessaire - + Some changes will not take effect until the emulator is restarted. Certains changements ne prendront effet qu'après le redémarrage de l'émulateur. - + - Player %1 of %2 - Joueur %1 of %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &Fichier - + Load &ROM... Charger une &ROM… - + Load ROM in archive... Charger la ROM d'une archive… - + Add folder to library... Ajouter un dossier à la bibliothèque… - + Load &patch... Charger un c&orrectif… - + Boot BIOS Démarrer le BIOS - + Replace ROM... Remplacer la ROM… - + Increase fast forward speed - + Decrease fast forward speed - + + &Lock frame size + + + + Create forwarder... - + Game state views - + + Log memory &accesses... + + + + Convert e-Reader card image to raw... - + ROM &info... &Infos sur la ROM… - + Recent Récent - + Make portable Rendre portable - + &Load state &Charger un état - + &Save state &Sauvegarder un état - + Quick load Chargement rapide - + Quick save Sauvegarde rapide - + Load recent Charger un fichier récent - + Save recent Sauvegarder un fichier récent - + Undo load state Annuler le chargement de l'état - + Undo save state Annuler la sauvegarde de l'état - - + + State &%1 État &%1 - + Load camera image... Charger une image de la caméra… - + Convert save game... - + New multiplayer window Nouvelle fenêtre multijoueur - + Connect to Dolphin... - + Report bug... Signalement de l'erreur… - + E&xit &Quitter - + &Emulation &Émulation - + &Reset &Réinitialiser - + Sh&utdown Extin&ction - + Yank game pak Yank game pak - + &Pause &Pause - + &Next frame &Image suivante - + Fast forward (held) Avance rapide (maintenir) - + &Fast forward A&vance rapide - + Fast forward speed Vitesse de l'avance rapide - + Unbounded Sans limites - + %0x %0x - + Rewind (held) Rembobiner (maintenir) - + Re&wind Rem&bobiner - + Step backwards Retour en arrière - + Solar sensor Capteur solaire - + Increase solar level Augmenter le niveau solaire - + Decrease solar level Diminuer le niveau solaire - + Brightest solar level Tester le niveau solaire - + Darkest solar level Assombrir le niveau solaire - + Brightness %1 Luminosité %1 - + Audio/&Video Audio/&Vidéo - + Frame size Taille de l'image - + Toggle fullscreen Basculer en plein écran - + Lock aspect ratio Bloquer les proportions - + Force integer scaling Forcer la mise à l'échelle par des nombres entiers - + Bilinear filtering Filtrage bilinèaire - + Frame&skip &Saut d'image - + Mute Muet - + FPS target FPS ciblé - + Take &screenshot Prendre une ca&pture d'écran - + F12 F12 - + Game Boy Printer... Imprimante GameBoy… - + Video layers Couches vidéo - + Audio channels Canaux audio - + Adjust layer placement... Ajuster la disposition… - + &Tools Ou&tils - + View &logs... Voir les &journaux… - + Game &overrides... - + Couldn't Start N'a pas pu démarrer - + Save games (%1) - + Select save game - + mGBA save state files (%1) - - + + Select save state - + GameShark saves (*.gsv *.sps *.xps) - + Could not start game. Impossible de démarrer le jeu. - + Load alternate save game... - + Load temporary save game... - + Scan e-Reader dotcodes... Scanner les dotcodes e-Reader... - + Load state file... Charger le fichier d'état... - + Save state file... Enregistrer le fichier d'état... - + Import GameShark Save... Importer la sauvegarde de GameShark... - + Reset needed - + Some changes will not take effect until the game is reset. - + Save games Sauvegarder les jeux - + Export GameShark Save... Exporter la sauvegarde de GameShark... - + Automatically determine - + Use player %0 save game - + About... À propos de… - + BattleChip Gate... - + %1× %1× - + Interframe blending Mélange d'images - + Native (59.7275) Natif (59.7275) - + Record A/V... Enregistrer A/V... - + Record GIF/WebP/APNG... Enregistrer GIF/WebP/APNG... - + Game Pak sensors... Capteurs de la Game Pak... - + &Cheats... &Cheats… - + Settings... Paramètres… - + Open debugger console... Ouvrir la console de débug… - + Start &GDB server... Démarrer le serveur &GDB… - + Scripting... - + View &palette... Voir la &palette… - + View &sprites... Voir les &sprites… - + View &tiles... Voir les &tiles… - + View &map... Voir la &map… - + &Frame inspector... Inspecteur de &frame... - + View memory... Voir la mémoire… - + Search memory... Recherche dans la mémoire… - + View &I/O registers... Voir les registres d'&E/S... - + Record debug video log... Enregistrer le journal vidéo de débogage... - + Stop debug video log Arrêter le journal vidéo de débogage - + Exit fullscreen Quitter le plein écran - + GameShark Button (held) Bouton GameShark (maintenir) - + Autofire Tir automatique - + Autofire A Tir automatique A - + Autofire B Tir automatique B - + Autofire L Tir automatique L - + Autofire R Tir automatique R - + Autofire Start Tir automatique Start - + Autofire Select Tir automatique Select - + Autofire Up Tir automatique Up - + Autofire Right Tir automatique Right - + Autofire Down Tir automatique Down - + Autofire Left Tir automatique Gauche - + Clear Vider @@ -6788,17 +6792,17 @@ Taille du téléchargement : %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu Menu @@ -6806,22 +6810,22 @@ Taille du téléchargement : %3 QShortcut - + Shift Shift - + Control Control - + Alt Alt - + Meta Méta/Super diff --git a/src/platform/qt/ts/mgba-hu.ts b/src/platform/qt/ts/mgba-hu.ts index 6db9b2da9..a51655410 100644 --- a/src/platform/qt/ts/mgba-hu.ts +++ b/src/platform/qt/ts/mgba-hu.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) Game Boy Advance ROMok (%1) - + Game Boy ROMs (%1) Game Boy ROMok (%1) - + All ROMs (%1) Összes ROM (%1) - + %1 Video Logs (*.mvl) %1 Videonaplók (*.mvl) @@ -192,17 +192,17 @@ LetöltendÅ‘ adat: %3 QGBA::AudioDevice - + Can't set format of context-less audio device - + Audio device is missing its core - + Writing data to read-only audio device @@ -210,7 +210,7 @@ LetöltendÅ‘ adat: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input @@ -286,28 +286,28 @@ LetöltendÅ‘ adat: %3 - + BattleChip data missing - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - + + Select deck file - + Incompatible deck - + The selected deck is not compatible with this Chip Gate @@ -368,19 +368,19 @@ LetöltendÅ‘ adat: %3 Ãrd ide a kódokat... - - + + Autodetect (recommended) Automatikus felisnerés (javasolt) - - + + Select cheats file Csalásfájl kiválasztása - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Néhány csalást nem sikerült betölteni. EllenÅ‘rizze, hogy helyesen formázottak-e és/vagy próbáljon ki más csalástípust! @@ -399,37 +399,37 @@ LetöltendÅ‘ adat: %3 Visszatekerés jelenleg nem engedélyezett - + Reset the game? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 Nem sikerült a mentésfájl megnyitása: %1 - + Failed to open game file: %1 Nem sikerült a játékfájl megnyitása: %1 - + Can't yank pack in unexpected platform! A játékkazettát nem lehet kirántani ismeretlen platformon! - + Failed to open snapshot file for reading: %1 A pillanatkép fájljának olvasásra való megnyitása sikertelen: %1 - + Failed to open snapshot file for writing: %1 A pillanatkép fájljának írásra való megnyitása sikertelen: %1 @@ -478,6 +478,14 @@ LetöltendÅ‘ adat: %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -758,52 +766,52 @@ LetöltendÅ‘ adat: %3 Visszaállítás - + Export frame Képkocka exportálása - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Nincs - + Background Háttér - + Window Ablak - + Objwin Objektumablak - + Sprite Sprite - + Backdrop Háttérréteg - + Frame Képkocka - + %1 %2 %1 %2 @@ -819,22 +827,22 @@ LetöltendÅ‘ adat: %3 QGBA::GBAKeyEditor - + Clear Button Gombhozzárendelés törlése - + Clear Analog Analóg hozzárendelések törlése - + Refresh Frissítés - + Set all Mind beállítása @@ -2957,7 +2965,7 @@ LetöltendÅ‘ adat: %3 Unknown - + Nem ismert @@ -3007,8 +3015,8 @@ LetöltendÅ‘ adat: %3 QGBA::KeyEditor - - + + --- @@ -3379,23 +3387,87 @@ LetöltendÅ‘ adat: %3 - - - + + + N/A - + Export map - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3642,22 +3714,22 @@ LetöltendÅ‘ adat: %3 Frissítés - + (%0/%1×) - + (â…Ÿ%0×) - + (%0×) - + %1 byte%2 @@ -3751,17 +3823,17 @@ LetöltendÅ‘ adat: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4158,35 +4230,35 @@ LetöltendÅ‘ adat: %3 Objektumpaletta exportálása - + #%0 - + 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette - + Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 @@ -4260,7 +4332,7 @@ LetöltendÅ‘ adat: %3 QGBA::ROMInfo - + @@ -4300,16 +4372,26 @@ LetöltendÅ‘ adat: %3 - File size: + Maker Code: - CRC32: + Revision: + File size: + + + + + CRC32: + + + + Save file: @@ -4365,62 +4447,62 @@ LetöltendÅ‘ adat: %3 QGBA::SaveConverter - + Save games and save states (%1) - + Select save game or save state - + Save games (%1) - + Select save game - + Conversion failed - + Failed to convert the save game. This is probably a bug. - + No file selected - + Could not open file - + No valid formats found - + Please select a valid input file - + No valid conversions found - + Cannot convert save games between platforms @@ -4446,97 +4528,97 @@ LetöltendÅ‘ adat: %3 - + %1 %2 save game - + little endian - + big endian - + SRAM SRAM - + %1 flash - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM - + TAMA5 - + %1 (%2) - + %1 save state with embedded %2 save game - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4572,32 +4654,37 @@ LetöltendÅ‘ adat: %3 - + Load script... - + + &Load most recent + + + + &Reset - + 0 0 - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4690,112 +4777,112 @@ LetöltendÅ‘ adat: %3 QGBA::SettingsView - - + + Qt Multimedia - + SDL - + Software (Qt) - + OpenGL - + OpenGL (force version 1.x) - + None Nincs - + None (Still Image) - + Keyboard - + Controllers - + Shortcuts - - + + Shaders - + Select BIOS - + Select directory - + Select image - + Image file (*.png *.jpg *.jpeg) - + (%1×%2) - + Never - + Just now - + Less than an hour ago - + %n hour(s) ago - + %n day(s) ago @@ -5060,37 +5147,37 @@ LetöltendÅ‘ adat: %3 - + Default color palette only - + SGB color palette if available - + GBC color palette if available - + SGB (preferred) or GBC color palette if available - + Game Boy Camera - + Driver: - + Source: @@ -5328,42 +5415,42 @@ LetöltendÅ‘ adat: %3 - + Models - + GB only: - + SGB compatible: - + GBC only: - + GBC compatible: - + SGB and GBC compatible: - + Game Boy palette - + Preset: @@ -5400,135 +5487,130 @@ LetöltendÅ‘ adat: %3 - + OpenGL enhancements - + High-resolution scale: - + (240×160) - - XQ GBA audio (experimental) - - - - + GB BIOS file: - - - - - - - - - + + + + + + + + + Browse - + Use BIOS file if found - + Skip BIOS intro - + GBA BIOS file: - + GBC BIOS file: - + SGB BIOS file: - + Save games - - - - - + + + + + Same directory as the ROM - + Save states - + Screenshots - + Patches - + Cheats Csalások - + Log to file - + Log to console - + Select Log File - + Default BG colors: - + Default sprite colors 1: - + Default sprite colors 2: - + Super Game Boy borders @@ -5786,13 +5868,11 @@ LetöltendÅ‘ adat: %3 - WebM - MP4 @@ -5831,82 +5911,6 @@ LetöltendÅ‘ adat: %3 Format - - - MKV - - - - - AVI - - - - - HEVC - - - - - HEVC (NVENC) - - - - - VP8 - - - - - VP9 - - - - - FFV1 - - - - - - None - Nincs - - - - FLAC - - - - - WavPack - - - - - Opus - - - - - Vorbis - - - - - MP3 - - - - - AAC - - - - - Uncompressed - - Bitrate (kbps) @@ -5917,16 +5921,6 @@ LetöltendÅ‘ adat: %3 ABR - - - H.264 - - - - - H.264 (NVENC) - - VBR @@ -5956,779 +5950,789 @@ LetöltendÅ‘ adat: %3 QGBA::Window - + Archives (%1) - - + + Select ROM - + Select folder - - + + Select save - + Select patch - + Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode - + e-Reader card (*.raw *.bin *.bmp) - + Select image - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) - + GameShark saves (*.sps *.xps) - + Select video log - + Video logs (*.mvl) - + Crash - + The game has crashed with the following error: %1 - + Couldn't Start - + Could not start game. - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + Load ROM in archive... - + Add folder to library... - + Save games (%1) - + Select save game - + mGBA save state files (%1) - - + + Select save state - + Select e-Reader card images - + Image file (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Load alternate save game... - + Load temporary save game... - + Load &patch... - + Boot BIOS - + Replace ROM... - + Scan e-Reader dotcodes... - + Convert e-Reader card image to raw... - + ROM &info... - + Recent - + Make portable - + &Load state - + Load state file... - + &Save state - + Save state file... - + Quick load - + Quick save - + Load recent - + Save recent - + Undo load state - + Undo save state - - + + State &%1 - + Load camera image... - + Convert save game... - + GameShark saves (*.gsv *.sps *.xps) - + Reset needed - + Some changes will not take effect until the game is reset. - + Save games - + Import GameShark Save... - + Export GameShark Save... - + Automatically determine - + Use player %0 save game - + New multiplayer window - + Connect to Dolphin... - + Report bug... - + About... - + E&xit - + &Emulation - + &Reset - + Sh&utdown - + Yank game pak - + &Pause - + &Next frame - + Fast forward (held) - + &Fast forward - + Fast forward speed - + Unbounded - + %0x %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) - + Re&wind - + Step backwards - + Solar sensor - + Increase solar level - + Decrease solar level - + Brightest solar level - + Darkest solar level - + Brightness %1 - + Game Boy Printer... - + BattleChip Gate... - + Audio/&Video - + Frame size - + %1× %1× - + Toggle fullscreen - - Lock aspect ratio - - - - - Force integer scaling - - - - - Interframe blending - - - - - Bilinear filtering + + &Lock frame size + Lock aspect ratio + + + + + Force integer scaling + + + + + Interframe blending + + + + + Bilinear filtering + + + + Frame&skip - + Mute - + FPS target - + Native (59.7275) - + Take &screenshot - + F12 - + Record A/V... - + Record GIF/WebP/APNG... - + Video layers - + Audio channels - + Adjust layer placement... - + &Tools - + View &logs... - + Game &overrides... - + Game Pak sensors... - + &Cheats... - + Create forwarder... - + Settings... - + Open debugger console... - + Start &GDB server... - + Scripting... - + Game state views - + View &palette... - + View &sprites... - + View &tiles... - + View &map... - + &Frame inspector... - + View memory... - + Search memory... - + View &I/O registers... - + + Log memory &accesses... + + + + Record debug video log... - + Stop debug video log - + Exit fullscreen - + GameShark Button (held) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear Napló törlése @@ -6766,17 +6770,17 @@ LetöltendÅ‘ adat: %3 - + Super (L) - + Super (R) - + Menu @@ -6784,22 +6788,22 @@ LetöltendÅ‘ adat: %3 QShortcut - + Shift - + Control - + Alt - + Meta diff --git a/src/platform/qt/ts/mgba-it.ts b/src/platform/qt/ts/mgba-it.ts index 6c2d16d4f..7338f41f6 100644 --- a/src/platform/qt/ts/mgba-it.ts +++ b/src/platform/qt/ts/mgba-it.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ROM per Game Boy Advance (%1) - + Game Boy ROMs (%1) ROM per Game Boy (%1) - + All ROMs (%1) Tutte le ROM (%1) - + %1 Video Logs (*.mvl) %1 log Video (*.mvl) @@ -191,17 +191,17 @@ Dimensione del download: %3 QGBA::AudioDevice - + Can't set format of context-less audio device Non è stato possibile impostare il formato per il dispositivo audio - + Audio device is missing its core Il dispositivo audio è mancante di un core - + Writing data to read-only audio device Scrittura dati sul dispositivo in modalità sola lettura @@ -209,7 +209,7 @@ Dimensione del download: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input Impossibile avviare un processore audio senza input @@ -285,28 +285,28 @@ Dimensione del download: %3 Mostra avanzate - + BattleChip data missing Dati Battlechip mancanti - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? Dati Battlechip mancanti. I Battlechip Gates continueranno a funzionare ma alcuni elementi grafici mancheranno. Sei sicuro di voler scaricare questi dati adesso? - - + + Select deck file Selezione file mazzo - + Incompatible deck Mazzo non compatibile - + The selected deck is not compatible with this Chip Gate Il mazzo selezionato non è compatibile con questo Chip Gate @@ -367,19 +367,19 @@ Dimensione del download: %3 Inserisci i codici qui.. - - + + Autodetect (recommended) Rilevamento automatico (consigliato) - - + + Select cheats file Seleziona il file cheats - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Non è stato possibile aggiungere alcuni trucchi. Assicurati che siano formattati correttamente e / o prova altri tipi di trucchi. @@ -398,37 +398,37 @@ Dimensione del download: %3 La funzione 'riavvolgi' non è attualmente abilitata - + Reset the game? Riavviare il gioco? - + Most games will require a reset to load the new save. Do you want to reset now? La maggior parte dei giochi richiede un riavvio per caricare il nuovo salvataggio. Vuoi riavviare ora? - + Failed to open save file: %1 Impossibile aprire il file di salvataggio: %1 - + Failed to open game file: %1 Impossibile aprire il file di gioco: %1 - + Can't yank pack in unexpected platform! Non riesco a strappare il pacchetto in una piattaforma inaspettata! - + Failed to open snapshot file for reading: %1 Impossibile aprire il file snapshot per la lettura: %1 - + Failed to open snapshot file for writing: %1 Impossibile aprire il file snapshot per la scrittura: %1 @@ -477,6 +477,14 @@ Dimensione del download: %3 Impossibile aprire lo storico della riga di comando in scrittura + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Dimensione del download: %3 Reset - + Export frame Esporta Frame - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Nessuno - + Background Sfondo - + Window Finestra - + Objwin Objwin - + Sprite Sprite - + Backdrop Sfondo - + Frame Inquadratura - + %1 %2 %1x {1 %2?} @@ -818,22 +826,22 @@ Dimensione del download: %3 QGBA::GBAKeyEditor - + Clear Button Svuota i pulsanti - + Clear Analog Svuota Analogici - + Refresh Aggiorna - + Set all Imposta tutti @@ -3006,8 +3014,8 @@ Dimensione del download: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Dimensione del download: %3 Verticale - - - + + + N/A N/D - + Export map Esporta Mappa - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Sfoglia + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + Ferma + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Dimensione del download: %3 Aggiorna - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3750,17 +3822,17 @@ Dimensione del download: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached Tentativo di scollegare un giocatore in multi che non è collegato - + Trying to get player ID for a multiplayer player that's not attached Cerco di ottenere l'ID giocatore per un giocatore in multi non collegato - + Trying to get save ID for a multiplayer player that's not attached Cerco di ottenere l'ID di salvataggio per un giocatore in multi non collegato @@ -4157,35 +4229,35 @@ Dimensione del download: %3 Esporta OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Esporta palette - + Windows PAL (*.pal);;Adobe Color Table (*.act) WIndows PAL (*.pal);;Tabella dei colori Adobe (*.act) - + Failed to open output palette file: %1 Errore nell'aprire il file palette di output: %1 @@ -4259,7 +4331,7 @@ Dimensione del download: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Dimensione del download: %3 + Maker Code: + + + + + Revision: + + + + File size: Dimensioni del file: - + CRC32: CRC32: - + Save file: Salva file: @@ -4364,62 +4446,62 @@ Dimensione del download: %3 QGBA::SaveConverter - + Save games and save states (%1) Salvataggi e stati di salvataggio dei giochi (%1) - + Select save game or save state Seleziona salvataggio o stato di salvataggio - + Save games (%1) Salvataggi (%1) - + Select save game Seleziona salvataggio - + Conversion failed Conversione fallita - + Failed to convert the save game. This is probably a bug. Impossibile convertire il salvataggio. Molto probabilmente è dovuto ad un bug. - + No file selected Nessun file selezionato - + Could not open file Non è stato possibile aprire il file - + No valid formats found Nessun formato valido trovato - + Please select a valid input file Si prega di selezionare un file di input valido - + No valid conversions found Nessune conversioni valide trovate - + Cannot convert save games between platforms Impossibile convertire salvataggi tra piattaforme @@ -4445,97 +4527,97 @@ Dimensione del download: %3 File output - + %1 %2 save game %1 %2 salvataggio - + little endian little endian - + big endian big endian - + SRAM SRAM - + %1 flash %1 flash - + %1 EEPROM %1 EEPROM - + + RTC + RTC - + %1 SRAM + RTC %1 SRAM + OTR - + %1 SRAM %1 SRAM - + packed MBC2 MBC2 compresso - + unpacked MBC2 MBC2 non compresso - + MBC6 flash MBC6 flash - + MBC6 combined SRAM + flash MBC6 combinato con la SRAM + flash - + MBC6 SRAM SRAM MBC6 - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game %1 stato di salvataggio incorporato con il salvataggio %2 - + %1 SharkPort %2 save game %1 SharkPort %2 salvataggio gioco - + %1 GameShark Advance SP %2 save game %1 GameShark Advance SP %2 salvataggio gioco @@ -4571,32 +4653,37 @@ Dimensione del download: %3 Carica script recente - + Load script... Carica script... - + + &Load most recent + + + + &Reset &Ripristina - + 0 0 - + Select script to load Selezionare lo script da caricare - + Lua scripts (*.lua) Script Lua (*.lua) - + All files (*.*) Tutti i file (*.*) @@ -4689,105 +4776,105 @@ Dimensione del download: %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (forza la versione 1.x) - + None Nessuno - + None (Still Image) nessuno (immagine fissa) - + Keyboard Tastiera - + Controllers Controller - + Shortcuts Scorciatoie - - + + Shaders Shader - + Select BIOS Seleziona BIOS - + Select directory Seleziona directory - + Select image Seleziona immagine - + Image file (*.png *.jpg *.jpeg) File immagine (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never Mai - + Just now Proprio adesso - + Less than an hour ago Meno di un'ora fa - + %n hour(s) ago %n ora fa @@ -4795,7 +4882,7 @@ Dimensione del download: %3 - + %n day(s) ago %n giorno fa @@ -5127,72 +5214,72 @@ Dimensione del download: %3 Velocità riavvolgimento: - + Models Modelli - + GB only: Solo GB: - + SGB compatible: Compatibile SGB: - + GBC only: Solo GBC: - + GBC compatible: Compatibile BGC: - + SGB and GBC compatible: Compatibile SGB e GBC: - + Game Boy palette Tavolozza Game Boy - + Default color palette only Solo tavolozza colori predefinita - + SGB color palette if available Tavolozza colori SGB se disponibile - + GBC color palette if available Tavolozza colori GBC se disponibile - + SGB (preferred) or GBC color palette if available Tavolozza colori SGB (preferita) o GBC se disponibile - + Game Boy Camera Videocamera Game Boy - + Driver: Driver: - + Source: Sorgente: @@ -5238,7 +5325,7 @@ Dimensione del download: %3 Abilita compatibilità con i bug di VBA nelle hack delle ROM - + Preset: Profilo: @@ -5278,62 +5365,57 @@ Dimensione del download: %3 Software - + OpenGL enhancements Miglioramenti OpenGL - + High-resolution scale: Rapporto alta risoluzione: - + (240×160) (240×160) - - XQ GBA audio (experimental) - audio XQ GBA (sperimentale) - - - + Cheats Trucchi - + Log to file Registro log in file - + Log to console Registro log in console - + Select Log File Seleziona file log - + Default BG colors: Colori predefiniti sfondo: - + Super Game Boy borders Bordi Super Game Boy - + Default sprite colors 1: Colori predefiniti sprite 1: - + Default sprite colors 2: Colori predefiniti sprite 2: @@ -5359,25 +5441,25 @@ Dimensione del download: %3 - - - - - - - - - + + + + + + + + + Browse Sfoglia - + Use BIOS file if found Usa il file del BIOS se è presente - + Skip BIOS intro Salta intro del BIOS @@ -5485,51 +5567,51 @@ Dimensione del download: %3 Intervallo Autofire: - + GB BIOS file: File BIOS del GB: - + GBA BIOS file: File BIOS del GBA: - + GBC BIOS file: File BIOS del GBC: - + SGB BIOS file: File BIOS del SGB: - + Save games Salva le partite - - - - - + + + + + Same directory as the ROM Stessa cartella della ROM - + Save states Salvataggio Stati - + Screenshots Schermate - + Patches Patch @@ -5777,7 +5859,6 @@ Dimensione del download: %3 - WebM WebM @@ -5786,32 +5867,11 @@ Dimensione del download: %3 Format Formato - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 - - - HEVC - HEVC - - - - VP8 - VP8 - High &Quality @@ -5852,72 +5912,6 @@ Dimensione del download: %3 &Native &Nativa - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Nessuno - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Senza compressione - Bitrate (kbps) @@ -5957,95 +5951,95 @@ Dimensione del download: %3 QGBA::Window - + Archives (%1) Archivi (%1) - - + + Select ROM Seleziona ROM - - + + Select save Seleziona salvataggio - + Select patch Seleziona patch - + Patches (*.ips *.ups *.bps) Patch (*.ips *.ups *.bps) - + Select e-Reader dotcode Selezione e-Reader dotcode - + e-Reader card (*.raw *.bin *.bmp) Scheda e-Reader (*.raw *.bin *.bmp) - + Select e-Reader card images Seleziona immagini carte e-Reader - + Image file (*.png *.jpg *.jpeg) File immagine (*.png *.jpg *.jpeg) - + Conversion finished Conversione terminata - + %1 of %2 e-Reader cards converted successfully. %1 di %2 carte e-Reader convertite con successo. - + Select image Seleziona immagine - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) File immagine (*.png *.gif *.jpg *.jpeg);;Tutti i file (*) - + GameShark saves (*.sps *.xps) Salvataggi GameShark (*.sps *.xps) - + Select video log Seleziona log video - + Video logs (*.mvl) Log video (*.mvl) - + Crash Errore fatale - + The game has crashed with the following error: %1 @@ -6054,684 +6048,694 @@ Dimensione del download: %3 %1 - + Unimplemented BIOS call BIOS non implementato - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Questo gioco utilizza una chiamata BIOS non implementata. Utilizza il BIOS ufficiale per una migliore esperienza. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Impossibile creare un dispositivo di visualizzazione appropriato, tornando alla visualizzazione software. I giochi possono funzionare lentamente, specialmente con finestre più grandi. - + Really make portable? Vuoi davvero rendere portatile l'applicazione? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? In questo modo l'emulatore carica la propria configurazione dalla stessa cartella dell'eseguibile. Vuoi continuare? - + Restart needed È necessario riavviare - + Some changes will not take effect until the emulator is restarted. Alcune modifiche non avranno effetto finché l'emulatore non verrà riavviato. - + - Player %1 of %2 - Giocatore %1 di %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File File - + Load &ROM... Carica ROM... - + Load ROM in archive... Carica la ROM in archivio... - + Load &patch... Carica patch... - + Boot BIOS Avvia BIOS - + Replace ROM... Sostituisci la ROM... - + Scan e-Reader dotcodes... Scansiona e-Reader dotcode... - + Convert e-Reader card image to raw... Converti immagini carte e-Reader in raw... - + ROM &info... Informazioni ROM... - + Recent Recenti - + Make portable Rendi portatile - + &Load state Carica stato - + &Save state Salva stato - + Quick load Caricamento rapido - + Quick save Salvataggio rapido - + Load recent Carica recente - + Save recent Salva recente - + Undo load state Annulla il caricamento dello stato - + Undo save state Annulla salvataggio stato - - + + State &%1 Stato %1 - + Load camera image... Carica immagine fotocamera... - + Convert save game... Converti salvataggi... - + GameShark saves (*.gsv *.sps *.xps) Salvataggi GameShark (*.gsv *.sps *.xps) - + Reset needed Reset necessario - + Some changes will not take effect until the game is reset. Alcune modifiche non si applicheranno finché il gioco non viene resettato. - + New multiplayer window Nuova finestra multigiocatore - + Connect to Dolphin... Connessione a Dolphin... - + Report bug... Segnala bug... - + E&xit Esci (&X) - + &Emulation Emulazione - + &Reset Reset - + Sh&utdown Spegni (&U) - + Yank game pak Stacca game pak - + &Pause Pausa - + &Next frame Salta il prossimo frame (&N) - + Fast forward (held) Avanzamento rapido (tieni premuto) - + &Fast forward Avanzamento rapido (&F) - + Fast forward speed Velocità di avanzamento rapido - + Unbounded Illimitata - + %0x %0x - + Increase fast forward speed Aumenta la velocità di avvolgimento veloce - + Decrease fast forward speed Diminuisci la velocità di avvolgimento veloce - + Rewind (held) Riavvolgimento (tieni premuto) - + Re&wind Riavvolgimento (&W) - + Step backwards Torna indietro - + Solar sensor Sensore solare - + Increase solar level Incrementa il livello solare - + Decrease solar level Riduci il livello solare - + Brightest solar level Livello solare massimo - + Darkest solar level Livello solare minimo - + Brightness %1 Luminosità %1 - + Audio/&Video Audio/Video - + Frame size Dimensione frame - + Toggle fullscreen Abilita schermo Intero - + + &Lock frame size + + + + Lock aspect ratio Blocca rapporti aspetto - + Frame&skip Salto frame - + Mute Muto - + FPS target FPS finali - + Take &screenshot Acquisisci schermata - + F12 F12 - + Record GIF/WebP/APNG... Registra GIF / WebP / APNG ... - + Video layers Layers video - + Audio channels Canali audio - + &Tools Strumenti - + View &logs... Visualizza registri (&log)... - + Game &overrides... Valore specifico per il gioco... - + &Cheats... Trucchi... - + Create forwarder... Crea Icona di avvio... - + Open debugger console... Apri console debugger... - + Start &GDB server... Avvia server GDB... - + Settings... Impostazioni... - + Select folder Seleziona cartella - + Couldn't Start Non è stato possibile avviare - + Could not start game. Non è stato possibile avviare il gioco. - + Add folder to library... Aggiungi cartella alla libreria... - + Load state file... Carica stato di salvataggio... - + Save state file... Salva stato di salvataggio... - + Import GameShark Save... Importa Salvataggio GameShark... - + Export GameShark Save... Esporta Salvataggio GameShark... - + About... Informazioni… - + Force integer scaling Forza ridimensionamento a interi - + Bilinear filtering Filtro bilineare - + Game Boy Printer... Stampante Game Boy... - + Save games (%1) Salvataggi (%1) - + Select save game Seleziona salvataggio - + mGBA save state files (%1) file di stati di salvataggio mGBA (%1) - - + + Select save state Seleziona stato di salvataggio - + Save games Salvataggi - + Load alternate save game... Carica stato di salvataggio alternativo... - + Load temporary save game... Carica salvataggio temporaneo... - + Automatically determine Determina automaticamente - + Use player %0 save game Usa il salvataggio del giocatore %0 - + BattleChip Gate... BattleChip Gate... - + %1× %1x - + Interframe blending Miscelazione dei frame - + Native (59.7275) Nativo (59.7) - + Record A/V... Registra A/V... - + Adjust layer placement... Regola posizionamento layer... - + Game Pak sensors... Sensori Game Pak... - + Scripting... Scripting... - + Game state views Viste degli stati del gioco - + View &palette... Mostra palette... - + View &sprites... Mostra sprites... - + View &tiles... Mostra tiles... - + View &map... Mostra mappa... - + &Frame inspector... &Frame inspector... - + View memory... Mostra memoria... - + Search memory... Ricerca memoria... - + View &I/O registers... Mostra registri I/O... - + + Log memory &accesses... + + + + Record debug video log... Registra video log di debug... - + Stop debug video log Ferma video log di debug - + Exit fullscreen Esci da Schermo Intero - + GameShark Button (held) Pulsante GameShark (tieni premuto) - + Autofire Pulsanti Autofire - + Autofire A Autofire A - + Autofire B Autofire B - + Autofire L Autofire L - + Autofire R Autofire R - + Autofire Start Autofire Start - + Autofire Select Autofire Select - + Autofire Up Autofire Su - + Autofire Right AAutofire Destra - + Autofire Down Autofire Giù - + Autofire Left Autofire Sinistra - + Clear Pulisci @@ -6769,17 +6773,17 @@ Dimensione del download: %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu Menu @@ -6787,22 +6791,22 @@ Dimensione del download: %3 QShortcut - + Shift Shift - + Control Control - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-ja.ts b/src/platform/qt/ts/mgba-ja.ts index 29e56717f..dfb056123 100644 --- a/src/platform/qt/ts/mgba-ja.ts +++ b/src/platform/qt/ts/mgba-ja.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ゲームボーイアドãƒãƒ³ã‚¹ãƒ•ã‚¡ã‚¤ãƒ« (%1) - + Game Boy ROMs (%1) ゲームボーイファイル (%1) - + All ROMs (%1) ã™ã¹ã¦ã®ROM (%1) - + %1 Video Logs (*.mvl) %1ビデオログ (*.mvl) @@ -191,17 +191,17 @@ Download size: %3 QGBA::AudioDevice - + Can't set format of context-less audio device - + Audio device is missing its core オーディオ デãƒã‚¤ã‚¹ã«ã‚³ã‚¢ãŒã‚ã‚Šã¾ã›ã‚“ - + Writing data to read-only audio device @@ -209,7 +209,7 @@ Download size: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input @@ -285,28 +285,28 @@ Download size: %3 詳細表示 - + BattleChip data missing ãƒãƒˆãƒ«ãƒãƒƒãƒ—ã®ãƒ‡ãƒ¼ã‚¿ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? ãƒãƒˆãƒ«ãƒãƒƒãƒ—ã®ç”»åƒãƒ‡ãƒ¼ã‚¿ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。ã“ã®ã¾ã¾ã§ã‚‚ãƒãƒƒãƒ—ゲートã¯å‹•ä½œã—ã¾ã™ãŒã€ãƒãƒƒãƒ—ã®ç”»åƒãŒè¡¨ç¤ºã•ã‚Œãªã„ã¾ã¾ä½¿ã†äº‹ã«ãªã‚Šã¾ã™ã€‚今ã™ãダウンロードã—ã¾ã™ã‹ï¼Ÿ - - + + Select deck file デッキファイルをé¸æŠž - + Incompatible deck 互æ›æ€§ã®ãªã„デッキ - + The selected deck is not compatible with this Chip Gate é¸æŠžã—ãŸãƒ‡ãƒƒã‚­ã¯ã“ã®ãƒãƒƒãƒ—ゲートã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“ @@ -367,19 +367,19 @@ Download size: %3 ã“ã“ã«ã‚³ãƒ¼ãƒ‰ã‚’入力ã—ã¦ãã ã•ã„... - - + + Autodetect (recommended) 自動検出 (推奨) - - + + Select cheats file ãƒãƒ¼ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. 一部ã®ã‚³ãƒ¼ãƒ‰ãŒè¿½åŠ ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚フォーマットãŒæ­£å¸¸ã‹ã©ã†ã‹ã‚’確èªã—ã¦ãã ã•ã„。もã—ãã¯ã€é•ã†å½¢å¼ã«å¤‰æ›ã—ã¦è©¦ã—ã¦ã¿ã¦ãã ã•ã„。 @@ -398,37 +398,37 @@ Download size: %3 - + Reset the game? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 セーブファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %1 - + Failed to open game file: %1 ゲームファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %1 - + Can't yank pack in unexpected platform! 予期ã—ãªã„プラットフォームã§ãƒ‘ックをヤンクã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ï¼ - + Failed to open snapshot file for reading: %1 読ã¿å–り用ã®ã‚¹ãƒŠãƒƒãƒ—ショットファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %1 - + Failed to open snapshot file for writing: %1 書ãè¾¼ã¿ç”¨ã®ã‚¹ãƒŠãƒƒãƒ—ショットファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %1 @@ -477,6 +477,14 @@ Download size: %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Download size: %3 リセット - + Export frame フレームを書ã出㙠- + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None ãªã— - + Background ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ - + Window ウインドウ - + Objwin Objwin - + Sprite スプライト - + Backdrop 背景 - + Frame フレーム - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Download size: %3 QGBA::GBAKeyEditor - + Clear Button ボタンクリア - + Clear Analog アナログクリア - + Refresh æ›´æ–° - + Set all ã™ã¹ã¦è¨­å®š @@ -3006,8 +3014,8 @@ Download size: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Download size: %3 縦 - - - + + + N/A N/A - + Export map マップを書ã出㙠- + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + å‚ç…§ + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + åœæ­¢ + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Download size: %3 æ›´æ–° - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3750,17 +3822,17 @@ Download size: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4157,35 +4229,35 @@ Download size: %3 OBJを書ã出㙠- + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette パレットを書ã出㙠- + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 出力パレットファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: %1 @@ -4259,7 +4331,7 @@ Download size: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Download size: %3 + Maker Code: + + + + + Revision: + + + + File size: ファイルサイズ: - + CRC32: CRC32: - + Save file: @@ -4364,62 +4446,62 @@ Download size: %3 QGBA::SaveConverter - + Save games and save states (%1) セーブデータ ã¾ãŸã¯ ステートセーブ (%1) - + Select save game or save state セーブゲームã¾ãŸã¯ã‚¹ãƒ†ãƒ¼ãƒˆã‚»ãƒ¼ãƒ–ã‚’é¸æŠž - + Save games (%1) セーブデータ (%1) - + Select save game セーブデータをé¸æŠž - + Conversion failed 変æ›ã«å¤±æ•—ã—ã¾ã—㟠- + Failed to convert the save game. This is probably a bug. セーブデータã®å¤‰æ›ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ãƒã‚°ã«ã‚ˆã‚‹ã‚‚ã®ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ - + No file selected ファイルãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“ - + Could not open file - + No valid formats found - + Please select a valid input file 有効ãªå…¥åŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„ - + No valid conversions found 利用å¯èƒ½ãªå¤‰æ›å…ˆãŒã‚ã‚Šã¾ã›ã‚“ - + Cannot convert save games between platforms @@ -4445,97 +4527,97 @@ Download size: %3 出力 - + %1 %2 save game - + little endian リトルエンディアン - + big endian ビッグエンディアン - + SRAM SRAM - + %1 flash - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM - + TAMA5 - + %1 (%2) - + %1 save state with embedded %2 save game %2 å½¢å¼ã®ã‚»ãƒ¼ãƒ–データãŒåŸ‹ã‚è¾¼ã¾ã‚ŒãŸ %1 ã®ã‚¹ãƒ†ãƒ¼ãƒˆã‚»ãƒ¼ãƒ– - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4571,32 +4653,37 @@ Download size: %3 - + Load script... - + + &Load most recent + + + + &Reset リセット (&R) - + 0 0 - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4689,112 +4776,112 @@ Download size: %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) ソフト(Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL(ãƒãƒ¼ã‚¸ãƒ§ãƒ³1.xを強制) - + None ãªã— - + None (Still Image) ãªã—(é™æ­¢ç”») - + Keyboard キーボード - + Controllers コントローラー - + Shortcuts ショートカット - - + + Shaders シェーダー - + Select BIOS BIOSã‚’é¸æŠž - + Select directory フォルダをé¸æŠž - + Select image ç”»åƒã‚’é–‹ã - + Image file (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never 一度もã—ã¦ã„ãªã„ - + Just now ãŸã£ãŸä»Š - + Less than an hour ago 1時間以内 - + %n hour(s) ago %n æ™‚é–“å‰ - + %n day(s) ago %n æ—¥å‰ @@ -5135,37 +5222,37 @@ Download size: %3 - + Default color palette only - + SGB color palette if available - + GBC color palette if available - + SGB (preferred) or GBC color palette if available - + Game Boy Camera - + Driver: - + Source: @@ -5216,42 +5303,42 @@ Download size: %3 ステートロード時ã«èª­ã¿è¾¼ã‚€: - + Models - + GB only: - + SGB compatible: - + GBC only: - + GBC compatible: - + SGB and GBC compatible: - + Game Boy palette - + Preset: @@ -5261,22 +5348,22 @@ Download size: %3 ゲームボーイプレーヤーã®æ©Ÿèƒ½ã‚’デフォルトã§æœ‰åŠ¹åŒ– - + (240×160) (240×160) - + Log to file ファイルã«å‡ºåŠ›ã™ã‚‹ - + Log to console コンソールã«å‡ºåŠ›ã™ã‚‹ - + Select Log File ログファイルをé¸æŠž @@ -5419,115 +5506,110 @@ Download size: %3 ソフト - + OpenGL enhancements OpenGL機能強化 - + High-resolution scale: 高解åƒåº¦ã‚¹ã‚±ãƒ¼ãƒ«: - - XQ GBA audio (experimental) - XQ GBA オーディオ機能(実験的) - - - + GB BIOS file: ゲームボーイ: - - - - - - - - - + + + + + + + + + Browse å‚ç…§ - + Use BIOS file if found 存在ã™ã‚‹å ´åˆã«BIOSファイルを使用 - + Skip BIOS intro BIOSイントロをスキップ - + GBA BIOS file: ゲームボーイアドãƒãƒ³ã‚¹: - + GBC BIOS file: ゲームボーイカラー: - + SGB BIOS file: スーパーゲームボーイ: - + Save games セーブデータ - - - - - + + + + + Same directory as the ROM ROMファイルã¨åŒã˜ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª - + Save states セーブステート - + Screenshots スクリーンショット - + Patches パッム- + Cheats ãƒãƒ¼ãƒˆ - + Default BG colors: デフォルト背景色: - + Super Game Boy borders スーパーゲームボーイã®ãƒœãƒ¼ãƒ€ãƒ¼ - + Default sprite colors 1: デフォルトスプライト1: - + Default sprite colors 2: デフォルトスプライト2: @@ -5775,7 +5857,6 @@ Download size: %3 - WebM WebM @@ -5784,19 +5865,8 @@ Download size: %3 Format フォーマット - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 @@ -5840,72 +5910,6 @@ Download size: %3 &Native ãƒã‚¤ãƒ†ã‚£ãƒ– (&N) - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC(NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - ãªã— - - - - FLAC - FLAC - - - - WavPack - - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - 圧縮ãªã— - Bitrate (kbps) @@ -5916,16 +5920,6 @@ Download size: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5955,80 +5949,80 @@ Download size: %3 QGBA::Window - + Archives (%1) アーカイブファイル (%1) - - + + Select ROM ROMã‚’é–‹ã - + Select folder フォルダを開ã - - + + Select save セーブを開ã - + Select patch パッãƒã‚’é–‹ã - + Patches (*.ips *.ups *.bps) パッãƒãƒ•ã‚¡ã‚¤ãƒ« (*.ips *.ups *.bps) - + Select e-Reader dotcode カードeã‚’é–‹ã - + e-Reader card (*.raw *.bin *.bmp) カードe (*.raw *.bin *.bmp) - + Select image ç”»åƒã‚’é–‹ã - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) ç”»åƒãƒ•ã‚¡ã‚¤ãƒ« (*.png *.gif *.jpg *.jpeg);;ã™ã¹ã¦ã®ãƒ•ã‚¡ã‚¤ãƒ« (*) - + GameShark saves (*.sps *.xps) GameSharkセーブファイル (*.sps *.xps) - + Select video log ビデオログを開ã - + Video logs (*.mvl) ビデオログ (*.mvl) - + Crash クラッシュ - + The game has crashed with the following error: %1 @@ -6037,699 +6031,709 @@ Download size: %3 %1 - + Couldn't Start 起動失敗 - + Could not start game. ゲームを起動ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ - + Unimplemented BIOS call 未実装ã®BIOS呼ã³å‡ºã— - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. ã“ã®ã‚²ãƒ¼ãƒ ã¯å®Ÿè£…ã•ã‚Œã¦ã„ãªã„BIOS呼ã³å‡ºã—を使用ã—ã¾ã™ã€‚最高ã®ã‚¨ã‚¯ã‚¹ãƒšãƒªã‚¨ãƒ³ã‚¹ã‚’å¾—ã‚‹ã«ã¯å…¬å¼ã®BIOSを使用ã—ã¦ãã ã•ã„。 - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. é©åˆ‡ãªãƒ‡ã‚£ã‚¹ãƒ—レイデãƒã‚¤ã‚¹ã®ä½œæˆã«å¤±æ•—ã—ã€ã‚½ãƒ•ãƒˆãƒ‡ã‚£ã‚¹ãƒ—レイã«ãƒ•ã‚©ãƒ¼ãƒ«ãƒãƒƒã‚¯ã—ã¾ã—ãŸã€‚特ã«å¤§ããªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ã¯ã€ã‚²ãƒ¼ãƒ ã®å®Ÿè¡ŒãŒé…ã„å ´åˆãŒã‚ã‚Šã¾ã™ã€‚ - + Really make portable? 本当ã«ãƒãƒ¼ã‚¿ãƒ–ル化ã—ã¾ã™ã‹ï¼Ÿ - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? ãƒãƒ¼ã‚¿ãƒ–ル化ã™ã‚‹ã¨ã€ä»¥é™ã¯å®Ÿè¡Œãƒ•ã‚¡ã‚¤ãƒ«ã¨åŒã˜ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«ãŒç½®ã‹ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚続行ã—ã¾ã™ã‹ï¼Ÿ - + Restart needed å†èµ·å‹•ãŒå¿…è¦ - + Some changes will not take effect until the emulator is restarted. 一部ã®å¤‰æ›´ã¯ã€ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚¿ã‚’å†èµ·å‹•ã™ã‚‹ã¾ã§æœ‰åŠ¹ã«ãªã‚Šã¾ã›ã‚“。 - + - Player %1 of %2 - プレーヤー %1 of %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &ファイル (&F) - + Load &ROM... ROMをロード... - + Load ROM in archive... アーカイブã«ROMをロード... - + Add folder to library... ライブラリーã«ãƒ•ã‚©ãƒ«ãƒ€ã‚’追加... - + Load &patch... パッãƒã‚’ロード... (&P) - + Boot BIOS BIOSã‚’èµ·å‹• - + Replace ROM... ROMを交æ›... - + Scan e-Reader dotcodes... カードeをスキャン... - + ROM &info... ROM情報... (&I) - + Recent 最近開ã„ãŸROM - + Make portable ãƒãƒ¼ã‚¿ãƒ–ル化 - + &Load state ステートをロード (&L) - + Report bug... ãƒã‚°å ±å‘Š - + About... ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±... - + Record GIF/WebP/APNG... GIF/WebP/APNGを記録 - + Game Pak sensors... カートリッジセンサー... - + Clear 消去 - + Load state file... ステートファイルをロード... - + Save games (%1) セーブデータ (%1) - + Select save game セーブデータをé¸æŠž - + mGBA save state files (%1) - - + + Select save state - + Select e-Reader card images - + Image file (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Load alternate save game... - + Load temporary save game... - + Convert e-Reader card image to raw... - + &Save state ステートをセーブ (&S) - + Save state file... ステートファイルをセーブ... - + Quick load クイックロード - + Quick save クイックセーブ - + Load recent 最後ã«ä½¿ã£ãŸã‚¯ã‚¤ãƒƒã‚¯ã‚¹ãƒ­ãƒƒãƒˆã‹ã‚‰ãƒ­ãƒ¼ãƒ‰ - + Save recent 最後ã«ä½¿ã£ãŸã‚¯ã‚¤ãƒƒã‚¯ã‚¹ãƒ­ãƒƒãƒˆã«ã‚»ãƒ¼ãƒ– - + Undo load state クイックロードを元ã«æˆ»ã™ - + Undo save state クイックセーブを元ã«æˆ»ã™ - - + + State &%1 クイックスロット &%1 - + Load camera image... カメラ画åƒã‚’ロード... - + Convert save game... セーブデータを変æ›... - + GameShark saves (*.gsv *.sps *.xps) - + Import GameShark Save... GameSharkスナップショットを読ã¿è¾¼ã‚€ - + Export GameShark Save... GameSharkスナップショットを書ã出㙠- + New multiplayer window æ–°ã—ã„ウィンドウ(マルãƒãƒ—レイ) - + Connect to Dolphin... Dolphinã«æŽ¥ç¶š... - + E&xit 終了 (&X) - + &Emulation エミュレーション (&E) - + &Reset リセット (&R) - + Sh&utdown é–‰ã˜ã‚‹ (&U) - + Yank game pak カートリッジを抜ã - + &Pause 一時åœæ­¢ (&P) - + &Next frame 次ã®ãƒ•ãƒ¬ãƒ¼ãƒ  (&N) - + Fast forward (held) æ—©é€ã‚Š(押ã—) - + &Fast forward æ—©é€ã‚Š (&F) - + Fast forward speed æ—©é€ã‚Šé€Ÿåº¦ - + Unbounded 制é™ãªã— - + %0x %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) 巻戻ã—(押ã—) - + Re&wind 巻戻㗠(&R) - + Step backwards 1フレーム巻ã戻㙠- + Solar sensor 太陽センサー - + Increase solar level 明るã•ã‚’上ã’ã‚‹ - + Decrease solar level 明るã•ã‚’下ã’ã‚‹ - + Brightest solar level 明るã•æœ€é«˜ - + Darkest solar level 明るã•æœ€ä½Ž - + Brightness %1 明る㕠%1 - + Audio/&Video オーディオ/ビデオ (&V) - + Frame size ç”»é¢ã‚µã‚¤ã‚º - + Toggle fullscreen 全画é¢è¡¨ç¤º - + + &Lock frame size + + + + Lock aspect ratio 縦横比を固定 - + Force integer scaling 整数スケーリングを強制 - + Bilinear filtering ãƒã‚¤ãƒªãƒ‹ã‚¢ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚° - + Frame&skip フレームスキップ (&S) - + Mute ミュート - + FPS target FPS - + Native (59.7275) ãƒã‚¤ãƒ†ã‚£ãƒ–(59.7275) - + Take &screenshot スクリーンショット (&S) - + F12 F12 - + Game Boy Printer... ãƒã‚±ãƒƒãƒˆãƒ—リンタ... - + Reset needed - + Some changes will not take effect until the game is reset. - + Save games セーブデータ - + Automatically determine - + Use player %0 save game - + BattleChip Gate... ãƒãƒˆãƒ«ãƒãƒƒãƒ—ゲート... - + %1× %1× - + Interframe blending ãƒ•ãƒ¬ãƒ¼ãƒ é–“æ··åˆ - + Record A/V... ビデオ録画... - + Video layers ビデオレイヤー - + Audio channels オーディオãƒãƒ£ãƒ³ãƒãƒ« - + Adjust layer placement... レイヤーã®é…置を調整... - + &Tools ツール (&T) - + View &logs... ログビューアー... (&L) - + Game &overrides... ゲーム別設定... (&O) - + &Cheats... ãƒãƒ¼ãƒˆ... (&C) - + Settings... 設定... - + Open debugger console... デãƒãƒƒã‚¬ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã‚’é–‹ã... - + Start &GDB server... GDBサーãƒã‚’èµ·å‹•... (&G) - + Scripting... - + Create forwarder... - + Game state views - + View &palette... パレットビューアー... (&P) - + View &sprites... スプライトビューアー... (&S) - + View &tiles... タイルビューアー... (&T) - + View &map... マップビューアー... (&M) - + &Frame inspector... フレームインスペクタ... (&F) - + View memory... メモリビューアー... - + Search memory... メモリ検索... - + View &I/O registers... IOビューアー... (&I) - + + Log memory &accesses... + + + + Record debug video log... デãƒãƒƒã‚°ãƒ“デオログ... - + Stop debug video log デãƒãƒƒã‚°ãƒ“デオログをåœæ­¢ - + Exit fullscreen 全画é¢è¡¨ç¤ºã‚’終了 - + GameShark Button (held) GameSharkボタン(押ã—) - + Autofire 連打 - + Autofire A 連打 A - + Autofire B 連打 B - + Autofire L 連打 L - + Autofire R 連打 R - + Autofire Start 連打 Start - + Autofire Select 連打 Select - + Autofire Up 連打 上 - + Autofire Right 連打 å³ - + Autofire Down 連打 下 - + Autofire Left 連打 å·¦ @@ -6767,17 +6771,17 @@ Download size: %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu メニュー @@ -6785,22 +6789,22 @@ Download size: %3 QShortcut - + Shift Shift - + Control Control - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-ko.ts b/src/platform/qt/ts/mgba-ko.ts index 05a8dc604..5eb684915 100644 --- a/src/platform/qt/ts/mgba-ko.ts +++ b/src/platform/qt/ts/mgba-ko.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ê²Œìž„ë³´ì´ ì–´ë“œë°´ìŠ¤ 롬 (%1) - + Game Boy ROMs (%1) ê²Œìž„ë³´ì´ ë¡¬ (%1) - + All ROMs (%1) 모든 롬 (%1) - + %1 Video Logs (*.mvl) %1 비디오 로그 (*.mvl) @@ -191,17 +191,17 @@ Download size: %3 QGBA::AudioDevice - + Can't set format of context-less audio device 컨í…스트 없는 오디오 ìž¥ì¹˜ì˜ í˜•ì‹ì„ 설정할 수 ì—†ìŒ - + Audio device is missing its core 오디오 ìž¥ì¹˜ì— ì½”ì–´ê°€ ì—†ìŒ - + Writing data to read-only audio device ì½ê¸° ì „ìš© 오디오 ìž¥ì¹˜ì— ë°ì´í„° 쓰기 @@ -209,7 +209,7 @@ Download size: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input ìž…ë ¥ ì—†ì´ ì˜¤ë””ì˜¤ 프로세서를 시작할 수 ì—†ìŒ @@ -285,28 +285,28 @@ Download size: %3 고급 보기 - + BattleChip data missing 배틀칩 ë°ì´í„° ëˆ„ë½ - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? 배트칩 ë°ì´í„°ê°€ 없습니다. 배틀칩 게ì´íŠ¸ëŠ” ê³„ì† ìž‘ë™í•˜ì§€ë§Œ ì¼ë¶€ ê·¸ëž˜í”½ì´ ëˆ„ë½ë©ë‹ˆë‹¤. 지금 ë°ì´í„°ë¥¼ 다운로드하겠습니까? - - + + Select deck file ë± íŒŒì¼ ì„ íƒ - + Incompatible deck 호환ë˜ì§€ 않는 ë± - + The selected deck is not compatible with this Chip Gate ì„ íƒí•œ ë±ì€ ì´ ì¹© 게ì´íŠ¸ì™€ 호환ë˜ì§€ ì•ŠìŒ @@ -367,19 +367,19 @@ Download size: %3 ì—¬ê¸°ì— ì½”ë“œë¥¼ 입력하세요... - - + + Autodetect (recommended) ìžë™ ê°ì§€ (권장) - - + + Select cheats file 치트 íŒŒì¼ ì„ íƒ - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. ì¼ë¶€ 치트를 추가할 수 없습니다. 형ì‹ì´ 올바른지 확ì¸í•˜ê³  다른 치트 ìœ í˜•ì„ ì‹œë„하세요. @@ -398,37 +398,37 @@ Download size: %3 현재 활성화ë˜ì§€ ì•Šì€ ë˜ê°ê¸° - + Reset the game? ê²Œìž„ì„ ìž¬ì„¤ì •í•˜ê² ìŠµë‹ˆê¹Œ? - + Most games will require a reset to load the new save. Do you want to reset now? ëŒ€ë¶€ë¶„ì˜ ê²Œìž„ì€ ìƒˆë¡œìš´ ì €ìž¥ì„ ë¡œë“œí•˜ë ¤ë©´ ìž¬ì„¤ì •ì´ í•„ìš”í•©ë‹ˆë‹¤. 지금 재설정하겠습니까? - + Failed to open save file: %1 저장 파ì¼ì„ 열지 못했습니다: %1 - + Failed to open game file: %1 게임 파ì¼ì„ 열지 못했습니다: %1 - + Can't yank pack in unexpected platform! 예기치 ì•Šì€ í”Œëž«í¼ì—ì„œ íŒ©ì„ ìž¡ì•„ë‹¹ê¸¸ 수 없습니다! - + Failed to open snapshot file for reading: %1 ì½ê¸° ìš© 스냅샷 파ì¼ì„ 열지 못했습니다: %1 - + Failed to open snapshot file for writing: %1 쓰기 ìš© 스냅샷 파ì¼ì„ 열지 못했습니다: %1 @@ -477,6 +477,14 @@ Download size: %3 쓰기 위해 CLI 기ë¡ì„ ì—´ 수 ì—†ìŒ + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Download size: %3 재설정 - + Export frame 프레임 내보내기 - + Portable Network Graphics (*.png) 휴대용 ë„¤íŠ¸ì›Œí¬ ê·¸ëž˜í”½ (*.png) - + None ì—†ìŒ - + Background ë°°ê²½ - + Window ì°½ - + Objwin Objwin - + Sprite 스프ë¼ì´íŠ¸ - + Backdrop ë°°ê²½ - + Frame 프레임 - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Download size: %3 QGBA::GBAKeyEditor - + Clear Button 버튼 정리 - + Clear Analog 아날로그 정리 - + Refresh 새로 고침 - + Set all ëª¨ë‘ ì„¤ì • @@ -3006,8 +3014,8 @@ Download size: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Download size: %3 ìˆ˜ì§ - - - + + + N/A 해당 ì—†ìŒ - + Export map 맵 내보내기 - + Portable Network Graphics (*.png) 휴대용 ë„¤íŠ¸ì›Œí¬ ê·¸ëž˜í”½ (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + 시작 + + + + Stop + 정지 + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Download size: %3 새로 고침 - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 ë°”ì´íŠ¸%2 @@ -3750,17 +3822,17 @@ Download size: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached ì—°ê²°ë˜ì§€ ì•Šì€ ë©€í‹°í”Œë ˆì´ì–´ 플레ì´ì–´ë¥¼ 분리하려고 함 - + Trying to get player ID for a multiplayer player that's not attached ì—°ê²°ë˜ì§€ ì•Šì€ ë©€í‹°í”Œë ˆì´ì–´ 플레ì´ì–´ì˜ 플레ì´ì–´ ID를 가져오려고 함 - + Trying to get save ID for a multiplayer player that's not attached ì—°ê²°ë˜ì§€ ì•Šì€ ë©€í‹°í”Œë ˆì´ì–´ 플레ì´ì–´ì˜ 저장 ID를 얻으려고 함 @@ -4157,35 +4229,35 @@ Download size: %3 보트 타기 내보내기 - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette 팔레트 내보내기 - + Windows PAL (*.pal);;Adobe Color Table (*.act) ì°½ PAL (*.pal);;ì–´ë„비 컬러 í…Œì´ë¸” (*.act) - + Failed to open output palette file: %1 출력 팔레트 파ì¼ì„ 열지 못했습니다: %1 @@ -4259,7 +4331,7 @@ Download size: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Download size: %3 + Maker Code: + + + + + Revision: + + + + File size: íŒŒì¼ í¬ê¸°: - + CRC32: CRC32: - + Save file: 저장 파ì¼: @@ -4364,62 +4446,62 @@ Download size: %3 QGBA::SaveConverter - + Save games and save states (%1) 게임 저장 ë° ìƒíƒœ 저장 (%1) - + Select save game or save state 게임 저장 ë˜ëŠ” ìƒíƒœ 저장 ì„ íƒ - + Save games (%1) 게임 (%1) 저장 - + Select save game 저장 게임 ì„ íƒ - + Conversion failed 변환 실패 - + Failed to convert the save game. This is probably a bug. 저장 ê²Œìž„ì„ ë³€í™˜í•˜ì§€ 못했습니다. ì´ê²ƒì€ ì•„ë§ˆë„ ë²„ê·¸ì¼ ê²ƒìž…ë‹ˆë‹¤. - + No file selected íŒŒì¼ ì„ íƒë˜ì§€ ì•Šì•˜ìŒ - + Could not open file íŒŒì¼ ì—´ 수 ì—†ìŒ - + No valid formats found 유효한 í˜•ì‹ ì—†ìŒ - + Please select a valid input file 유효한 ìž…ë ¥ íŒŒì¼ ì„ íƒ - + No valid conversions found 유효한 전환 ì—†ìŒ - + Cannot convert save games between platforms í”Œëž«í¼ ê°„ì— ì €ìž¥ 게임 변환할 수 ì—†ìŒ @@ -4445,97 +4527,97 @@ Download size: %3 출력 íŒŒì¼ - + %1 %2 save game %1 %2 저장 게임 - + little endian 리틀 엔디안 - + big endian ë¹… 엔디안 - + SRAM SRAM - + %1 flash %1 플래시 - + %1 EEPROM %1 EEPROM - + + RTC + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 íŒ©í‚¹ëœ MBC2 - + unpacked MBC2 ì–¸íŒ©í‚¹ëœ MBC2 - + MBC6 flash MBC6 플래시 - + MBC6 combined SRAM + flash MBC6 ê²°í•© SRAM + 플래시 - + MBC6 SRAM MBC6 SRAM - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game í¬í•¨ëœ %2 저장 ê²Œìž„ì´ ìžˆëŠ” %1 저장 ìƒíƒœ - + %1 SharkPort %2 save game %1 샤í¬í¬íŠ¸ %2 게임 저장 - + %1 GameShark Advance SP %2 save game %1 ê²Œìž„ìƒ¤í¬ ì–´ë“œë°´ìŠ¤ SP %2 게임 저장 @@ -4571,32 +4653,37 @@ Download size: %3 최근 스í¬ë¦½íŠ¸ 로드 - + Load script... 스í¬ë¦½íŠ¸ 로드... - + + &Load most recent + + + + &Reset 재설정 (&R) - + 0 0 - + Select script to load 로드할 스í¬ë¦½íŠ¸ ì„ íƒ - + Lua scripts (*.lua) 루아 스í¬ë¦½íŠ¸ (*.lua) - + All files (*.*) 모든 íŒŒì¼ (*.*) @@ -4689,112 +4776,112 @@ Download size: %3 QGBA::SettingsView - - + + Qt Multimedia Qt 멀티미디어 - + SDL SDL - + Software (Qt) 소프트웨어 (Qt) - + OpenGL 오픈GL - + OpenGL (force version 1.x) 오픈GL (버전 1.x ê°•ì œ) - + None ì—†ìŒ - + None (Still Image) ì—†ìŒ (정지 ì´ë¯¸ì§€) - + Keyboard 키보드 - + Controllers 컨트롤러 - + Shortcuts 단축키 - - + + Shaders ì‰ì´ë” - + Select BIOS ë°”ì´ì˜¤ìŠ¤ ì„ íƒ - + Select directory 디렉토리 ì„ íƒ - + Select image ì´ë¯¸ì§€ ì„ íƒ - + Image file (*.png *.jpg *.jpeg) ì´ë¯¸ì§€ íŒŒì¼ (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never 절대 - + Just now 방금 - + Less than an hour ago 1시간 미만 ì „ - + %n hour(s) ago %n 시간 ì „ - + %n day(s) ago %n ì¼ ì „ @@ -5115,37 +5202,37 @@ Download size: %3 ë˜ê°ê¸° ì†ë„: - + Default color palette only 기본 ìƒ‰ìƒ íŒ”ë ˆíŠ¸ë§Œ - + SGB color palette if available 가능한 경우 SGB ìƒ‰ìƒ íŒ”ë ˆíŠ¸ - + GBC color palette if available 가능한 경우 GBC ìƒ‰ìƒ íŒ”ë ˆíŠ¸ - + SGB (preferred) or GBC color palette if available 사용 가능한 경우 SGB (선호) ë˜ëŠ” GBC ìƒ‰ìƒ íŒ”ë ˆíŠ¸ - + Game Boy Camera 게임 ë³´ì´ ì¹´ë©”ë¼ - + Driver: ë“œë¼ì´ë²„: - + Source: 소스: @@ -5216,42 +5303,42 @@ Download size: %3 ìƒíƒœ 추가 ë°ì´í„° 로드: - + Models ëª¨ë¸ - + GB only: GB ì „ìš©: - + SGB compatible: SGB 호환: - + GBC only: GBC ì „ìš©: - + GBC compatible: GBC 호환: - + SGB and GBC compatible: SGB 와 GBC 호환: - + Game Boy palette 게임 ë³´ì´ íŒ”ë ˆíŠ¸ - + Preset: 사전 설정: @@ -5276,62 +5363,57 @@ Download size: %3 소프트웨어 - + OpenGL enhancements OpenGL 개선 사항 - + High-resolution scale: ê³ í•´ìƒë„ 스케ì¼: - + (240×160) (240×160) - - XQ GBA audio (experimental) - XQ GBA 오디오 (시험용) - - - + Cheats 치트 - + Default BG colors: 기본 ë°°ê²½ 색ìƒ: - + Super Game Boy borders ìŠˆí¼ ê²Œìž„ ë³´ì´ í…Œë‘리 - + Default sprite colors 1: 기본 스프ë¼ì´íŠ¸ ìƒ‰ìƒ 1: - + Log to file 파ì¼ì— ê¸°ë¡ - + Log to console ì½˜ì†”ì— ê¸°ë¡ - + Select Log File 로그 íŒŒì¼ ì„ íƒ - + Default sprite colors 2: 기본 스프ë¼ì´íŠ¸ ìƒ‰ìƒ 2: @@ -5357,25 +5439,25 @@ Download size: %3 - - - - - - - - - + + + + + + + + + Browse 브ë¼ìš°ì € - + Use BIOS file if found 발견ë˜ë©´ ë°”ì´ì˜¤ìŠ¤ íŒŒì¼ ì‚¬ìš© - + Skip BIOS intro ë°”ì´ì˜¤ìŠ¤ 소개 건너 뛰기 @@ -5483,51 +5565,51 @@ Download size: %3 Intervallo Autofire: - + GB BIOS file: GB ë°”ì´ì˜¤ìŠ¤ 파ì¼: - + GBA BIOS file: GBA ë°”ì´ì˜¤ìŠ¤ 파ì¼: - + GBC BIOS file: GBC ë°”ì´ì˜¤ìŠ¤ 파ì¼: - + SGB BIOS file: SGB ë°”ì´ì˜¤ìŠ¤ 파ì¼: - + Save games 게임 저장 - - - - - + + + + + Same directory as the ROM 롬과 ê°™ì€ ë””ë ‰í† ë¦¬ - + Save states 저장 íŒŒì¼ ìƒíƒœ - + Screenshots 스í¬ë¦°ìƒ· - + Patches 패치 @@ -5775,7 +5857,6 @@ Download size: %3 - WebM WebM @@ -5784,32 +5865,11 @@ Download size: %3 Format í˜•ì‹ - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 - - - HEVC - HEVC - - - - VP8 - VP8 - High &Quality @@ -5850,72 +5910,6 @@ Download size: %3 &Native 실기 (&N) - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - ì—†ìŒ - - - - FLAC - FLAC - - - - WavPack - Wav팩 - - - - Opus - 오푸스 - - - - Vorbis - 보비스 - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - 미압축 - Bitrate (kbps) @@ -5955,95 +5949,95 @@ Download size: %3 QGBA::Window - + Archives (%1) ì•„ì¹´ì´ë¸Œ (%1) - - + + Select ROM 롬 ì„ íƒ - - + + Select save 저장 íŒŒì¼ ì„ íƒ - + Select patch 패치 ì„ íƒ - + Patches (*.ips *.ups *.bps) 패치 (*.ips *.ups *.bps) - + Select e-Reader dotcode e-ë¦¬ë” ë„트코드 ì„ íƒ - + e-Reader card (*.raw *.bin *.bmp) e-ë¦¬ë” ì¹´ë“œ (*.raw *.bin *.bmp) - + Select e-Reader card images e-ë¦¬ë” ì¹´ë“œ ì´ë¯¸ì§€ ì„ íƒ - + Image file (*.png *.jpg *.jpeg) ì´ë¯¸ì§€ íŒŒì¼ (*.png *.jpg *.jpeg) - + Conversion finished 변환 완료 - + %1 of %2 e-Reader cards converted successfully. %2 e-ë¦¬ë” ì¹´ë“œ 중 %1ì´(ê°€) 성공ì ìœ¼ë¡œ 변환ë˜ì—ˆìŠµë‹ˆë‹¤. - + Select image ì´ë¯¸ì§€ ì„ íƒ - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) ì´ë¯¸ì§€ íŒŒì¼ (*.png *.gif *.jpg *.jpeg);;모든 íŒŒì¼ (*) - + GameShark saves (*.sps *.xps) ê²Œìž„ìƒ¤í¬ ì €ìž¥ íŒŒì¼ (*.sps *.xps) - + Select video log 비디오 로그 ì„ íƒ - + Video logs (*.mvl) 비디오 로그 (*.mvl) - + Crash 치명ì ì¸ 오류 - + The game has crashed with the following error: %1 @@ -6052,684 +6046,694 @@ Download size: %3 %1 - + Unimplemented BIOS call 구현ë˜ì§€ ì•Šì€ ë°”ì´ì˜¤ìŠ¤ 호출 - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. ì´ ê²Œìž„ì€ êµ¬í˜„ë˜ì§€ ì•Šì€ ë°”ì´ì˜¤ìŠ¤ í˜¸ì¶œì„ ì‚¬ìš©í•©ë‹ˆë‹¤. 최ìƒì˜ ì„±ëŠ¥ì„ ì–»ìœ¼ë ¤ë©´ ê³µì‹ ë°”ì´ì˜¤ìŠ¤ë¥¼ 사용하십시오. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. ì ì ˆí•œ ë””ìŠ¤í”Œë ˆì´ ìž¥ì¹˜ë¥¼ ìƒì„±í•˜ì§€ 못했습니다. 소프트웨어 디스플레ì´ë¡œ ëŒì•„갑니다. 특히 í° ì°½ì—서는 ê²Œìž„ì´ ëŠë¦¬ê²Œ ì‹¤í–‰ë  ìˆ˜ 있습니다. - + Really make portable? ì •ë§ë¡œ íœ´ëŒ€ìš©ì„ ë§Œë“­ë‹ˆê¹Œ? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? ì´ë ‡ê²Œí•˜ë©´ ì—뮬레ì´í„°ê°€ 실행 파ì¼ê³¼ ë™ì¼í•œ 디렉토리ì—ì„œ êµ¬ì„±ì„ ë¡œë“œí•˜ê²Œë©ë‹ˆë‹¤. ê³„ì† í•˜ì‹œê² ìŠµë‹ˆê¹Œ? - + Restart needed 재시작 í•„ìš” - + Some changes will not take effect until the emulator is restarted. ì¼ë¶€ 변경 ì‚¬í•­ì€ ì—뮬레ì´í„°ê°€ 다시 ì‹œìž‘ë  ë•Œê¹Œì§€ ì ìš©ë˜ì§€ 않습니다. - + Reset needed 재설정 í•„ìš” - + Some changes will not take effect until the game is reset. ì¼ë¶€ 변경 ì‚¬í•­ì€ ê²Œìž„ì´ ìž¬ì„¤ì •ë  ë•Œê¹Œì§€ ì ìš©ë˜ì§€ 않습니다. - + - Player %1 of %2 - 플레ì´ì–´ %1 ì˜ %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &íŒŒì¼ - + Load &ROM... 로드 &롬... - + Load ROM in archive... ë¡¬ì„ ì•„ì¹´ì´ë¸Œì— 로드... - + Save games 게임 저장 - + Automatically determine ìžë™ìœ¼ë¡œ ê²°ì • - + Use player %0 save game 플레ì´ì–´ %0 저장 게임 사용 - + Load &patch... 로드 &패치... - + Boot BIOS BIOS 부팅 - + Replace ROM... 롬 êµì²´... - + Scan e-Reader dotcodes... e-ë¦¬ë” ë„트코드 스캔... - + Game state views 게임 ìƒíƒœ 보기 - + Convert e-Reader card image to raw... e-ë¦¬ë” ì¹´ë“œ ì´ë¯¸ì§€ë¥¼ ì›ì‹œ ë°ì´í„°ë¡œ 변환... - + ROM &info... 롬 &ì •ë³´... - + Recent 최근 실행 - + Make portable 휴대용 만들기 - + &Load state &로드 íŒŒì¼ ìƒíƒœ - + &Save state &저장 íŒŒì¼ ìƒíƒœ - + Quick load 빠른 로드 - + Quick save 빠른 저장 - + Load recent 최근 실행 로드 - + Save recent 최근 실행 저장 - + Undo load state 로드 íŒŒì¼ ìƒíƒœ ë³µì› - + Undo save state 저장 íŒŒì¼ ìƒíƒœ ë³µì› - - + + State &%1 ìƒíƒœ &%1 - + Load camera image... ì¹´ë©”ë¼ ì´ë¯¸ì§€ 로드... - + Convert save game... 저장 게임 변환... - + GameShark saves (*.gsv *.sps *.xps) ê²Œìž„ìƒ¤í¬ ì €ìž¥ (*.gsv *.sps *.xps) - + New multiplayer window 새로운 멀티 플레ì´ì–´ ì°½ - + Connect to Dolphin... ëŒí•€ì— ì—°ê²°... - + E&xit 종&료 - + &Emulation &ì—뮬레ì´ì…˜ - + &Reset &재설정 - + Sh&utdown 종&료 - + Yank game pak 양키 게임 팩 - + &Pause &정지 - + &Next frame &ë‹¤ìŒ í”„ë ˆìž„ - + Fast forward (held) 빨리 ê°ê¸° (누름) - + &Fast forward &빨리 ê°ê¸° - + Fast forward speed 빨리 ê°ê¸° ì†ë„ - + Unbounded 무제한 - + %0x %0x - + Increase fast forward speed 빨리 ê°ê¸° ì†ë„ í–¥ìƒ - + Decrease fast forward speed 빨리 ê°ê¸° ì†ë„ 줄ì´ê¸° - + Rewind (held) ë˜ê¹€ê¸° (누름) - + Re&wind 리&와ì¸ë“œ - + Step backwards ëŒì•„가기 - + Brightest solar level 가장 ë°ì€ 태양 수준 - + Darkest solar level 가장 ì–´ë‘ìš´ 태양 수준 - + Brightness %1 ë°ê¸° %1 - + Audio/&Video 오디오/&비디오 - + Frame size 프레임 í¬ê¸° - + Toggle fullscreen 전체화면 전환 - + + &Lock frame size + + + + Lock aspect ratio 화면비 잠금 - + Frame&skip 프레임&건너뛰기 - + Mute ë¬´ìŒ - + FPS target FPS ëŒ€ìƒ - + Take &screenshot 스í¬ë¦°ìƒ· &ì°ê¸° - + F12 F12 - + Video layers 비디오 ë ˆì´ì–´ - + Audio channels 오디오 ì±„ë„ - + &Tools &ë„구 - + View &logs... 로그 &보기... - + Game &overrides... 게임 &오버ë¼ì´ë“œ... - + &Cheats... &치트.. - + Create forwarder... ì „ë‹¬ìž ìƒì„±... - + Open debugger console... 디버거 콘솔 열기... - + Start &GDB server... GDB 서버 &시작... - + Settings... 설정... - + Select folder í´ë” ì„ íƒ - + Couldn't Start 시작할 수 ì—†ìŒ - + Could not start game. ê²Œìž„ì„ ì‹œìž‘í•  수 없습니다. - + Add folder to library... ë¼ì´ë¸ŒëŸ¬ë¦¬ì— í´ë” 추가... - + Load state file... ìƒíƒœ íŒŒì¼ ë¡œë“œ... - + Save state file... ìƒíƒœ íŒŒì¼ ì €ìž¥... - + Import GameShark Save... ê²Œìž„ìƒ¤í¬ ì €ìž¥ 가져오기... - + Export GameShark Save... ê²Œìž„ìƒ¤í¬ ì €ìž¥ 내보내기... - + Report bug... 버그를 제보하기... - + About... ì •ë³´... - + Solar sensor 태양광 센서 - + Increase solar level 태양광 레벨 ì¦ê°€ - + Decrease solar level 태양광 레벨 ê°ì†Œ - + Force integer scaling 정수 스케ì¼ë§ ê°•ì œ 수행 - + Bilinear filtering ì´ì¤‘선형 í•„í„°ë§ - + Game Boy Printer... 게임 ë³´ì´ í”„ë¦°í„°... - + Save games (%1) 게임 (%1) 저장 - + Select save game 저장 게임 ì„ íƒ - + mGBA save state files (%1) mGBA 저장 ìƒíƒœ íŒŒì¼ (%1) - - + + Select save state 저장 ìƒíƒœ ì„ íƒ - + Load alternate save game... 대체 저장 게임 로드... - + Load temporary save game... ìž„ì‹œ 저장 게임 로드... - + BattleChip Gate... 배틀칩 게ì´íŠ¸... - + %1× %1× - + Interframe blending 프레임간 ì¡°í•© - + Native (59.7275) 실기 (59.7275) - + Record A/V... A/V 녹화... - + Record GIF/WebP/APNG... GIF/WebP/APNG 녹화... - + Adjust layer placement... ë ˆì´ì–´ 배치 ì¡°ì •... - + Game Pak sensors... 게임 팩 센서... - + Scripting... 스í¬ë¦½íŒ…... - + View &palette... 팔레트 &보기... - + View &sprites... 스프ë¼ì´íŠ¸ &보기... - + View &tiles... íƒ€ì¼ &보기... - + View &map... ì§€ë„ &보기... - + &Frame inspector... 프레임 검사기 (&F)... - + View memory... 메모리 보기... - + Search memory... 메모리 검색... - + View &I/O registers... I/O 레지스터 &보기... - + + Log memory &accesses... + + + + Record debug video log... 디버그 비디오 로그 녹화... - + Stop debug video log 디버그 비디오 로그 중지 - + Exit fullscreen 전체화면 종료 - + GameShark Button (held) ê²Œìž„ìƒ¤í¬ ë²„íŠ¼ (누름) - + Autofire 연사 - + Autofire A 연사 A - + Autofire B 연사 B - + Autofire L 연사 L - + Autofire R 연사 R - + Autofire Start 연사 시작 - + Autofire Select 연사 ì„ íƒ - + Clear 지움 - + Autofire Up 연사 위쪽 - + Autofire Right 연사 오른쪽 - + Autofire Down 연사 아래쪽 - + Autofire Left 연사 왼쪽 @@ -6767,17 +6771,17 @@ Download size: %3 ? - + Super (L) ìŠˆí¼ (L) - + Super (R) ìŠˆí¼ (R) - + Menu 메뉴 @@ -6785,22 +6789,22 @@ Download size: %3 QShortcut - + Shift 시프트 키 - + Control 콘트롤 키 - + Alt 알트 키 - + Meta 메타 diff --git a/src/platform/qt/ts/mgba-ms.ts b/src/platform/qt/ts/mgba-ms.ts index cb327e334..e606a3a96 100644 --- a/src/platform/qt/ts/mgba-ms.ts +++ b/src/platform/qt/ts/mgba-ms.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ROM Game Boy Advance (%1) - + Game Boy ROMs (%1) ROM Game Boy (%1) - + All ROMs (%1) Semua ROM (%1) - + %1 Video Logs (*.mvl) %1 Log Video (*.mvl) @@ -185,17 +185,17 @@ Download size: %3 QGBA::AudioDevice - + Can't set format of context-less audio device - + Audio device is missing its core - + Writing data to read-only audio device @@ -203,7 +203,7 @@ Download size: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input @@ -279,28 +279,28 @@ Download size: %3 Lanjutan - + BattleChip data missing - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - + + Select deck file - + Incompatible deck - + The selected deck is not compatible with this Chip Gate @@ -361,19 +361,19 @@ Download size: %3 Masuk kod di sini... - - + + Autodetect (recommended) - - + + Select cheats file Pilih fail tipu - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. @@ -392,37 +392,37 @@ Download size: %3 - + Reset the game? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 Gagal membuka fail tersimpan: %1 - + Failed to open game file: %1 Gagal membuka fail permainan: %1 - + Can't yank pack in unexpected platform! - + Failed to open snapshot file for reading: %1 Gagal membuka fail snapshot untuk baca: %1 - + Failed to open snapshot file for writing: %1 Gagal membuka fail snapshot untuk menulis: %1 @@ -471,6 +471,14 @@ Download size: %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -751,52 +759,52 @@ Download size: %3 Tetap semula - + Export frame Eksport bingkai - + Portable Network Graphics (*.png) Grafik Rangkaian Mudah Alih (*.png) - + None Tiada - + Background Latar belakang - + Window Tetingkap - + Objwin Objwin - + Sprite - + Backdrop - + Frame Bingkai - + %1 %2 %1 %2 @@ -812,22 +820,22 @@ Download size: %3 QGBA::GBAKeyEditor - + Clear Button - + Clear Analog - + Refresh Segar Semula - + Set all @@ -3000,8 +3008,8 @@ Download size: %3 QGBA::KeyEditor - - + + --- --- @@ -3372,23 +3380,87 @@ Download size: %3 - - - + + + N/A - + Export map Eksport peta - + Portable Network Graphics (*.png) Grafik Rangkaian Mudah Alih (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Pilih fail + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + Mula + + + + Stop + Henti + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3635,22 +3707,22 @@ Download size: %3 Segar Semula - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 bait%2 @@ -3744,17 +3816,17 @@ Download size: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4151,35 +4223,35 @@ Download size: %3 Eksport OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Eksport palet - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Jadual Warna Adobe(*.act) - + Failed to open output palette file: %1 Gagal membuka fail palet output: %1 @@ -4253,7 +4325,7 @@ Download size: %3 QGBA::ROMInfo - + @@ -4293,16 +4365,26 @@ Download size: %3 + Maker Code: + + + + + Revision: + + + + File size: Saiz fail: - + CRC32: CRC32: - + Save file: @@ -4358,62 +4440,62 @@ Download size: %3 QGBA::SaveConverter - + Save games and save states (%1) Simpanan permainan dan keadaan tersimpan (%1) - + Select save game or save state Pilih simpanan permainan atau keadaan tersimpan - + Save games (%1) Simpanan permainan (%1) - + Select save game Pilih simpanan permainan - + Conversion failed Penukaran gagal - + Failed to convert the save game. This is probably a bug. Gagal menukar simpanan permainan. Mungkin ini suatu pepijat. - + No file selected Tiada pilihan - + Could not open file Tidak dapat membuka fail - + No valid formats found Tiada format yang sah ditemui - + Please select a valid input file Sila pilih fail input yang sah - + No valid conversions found Tiada penukaran yang sah ditemui - + Cannot convert save games between platforms Tidak boleh menukar simpanan permainan antara platform @@ -4439,97 +4521,97 @@ Download size: %3 Fail output - + %1 %2 save game Simpanan permainan %1 %2 - + little endian little-endian - + big endian big-endian - + SRAM SRAM - + %1 flash %1 kilat - + %1 EEPROM %1 EEPROM - + + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash Kilat MBC6 - + MBC6 combined SRAM + flash MBC6 bergabung SRAM + kilat - + MBC6 SRAM SRAM MBC6 - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game Keadaan tersimpan %1 dgn simpanan permainan terbenam %2 - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4565,32 +4647,37 @@ Download size: %3 - + Load script... - + + &Load most recent + + + + &Reset - + 0 4K {0?} - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4683,112 +4770,112 @@ Download size: %3 QGBA::SettingsView - - + + Qt Multimedia Multimedia Qt - + SDL SDL - + Software (Qt) Perisian (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (paksa versi 1.x) - + None Tiada - + None (Still Image) Tiada (Gambar Tenang) - + Keyboard Papan Kekunci - + Controllers Pengawal - + Shortcuts Pintas - - + + Shaders - + Select BIOS Pilih BIOS - + Select directory Pilih direktori - + Select image Pilih gambar - + Image file (*.png *.jpg *.jpeg) Fail gambar (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never - + Just now - + Less than an hour ago - + %n hour(s) ago - + %n day(s) ago @@ -5114,37 +5201,37 @@ Download size: %3 - + Default color palette only Palet warna piawai sahaja - + SGB color palette if available Palet warna SGB jika ada - + GBC color palette if available Palet warna GBC jika ada - + SGB (preferred) or GBC color palette if available SGB (pilihan utama) atau palet warna GBC jika ada - + Game Boy Camera Game Boy Camera - + Driver: Pemacu: - + Source: Sumber: @@ -5321,42 +5408,42 @@ Download size: %3 Data ekstra keadaan muat: - + Models Model - + GB only: GB sahaja: - + SGB compatible: SGB serasi: - + GBC only: GBC sahaja: - + GBC compatible: GBC serasi: - + SGB and GBC compatible: SGB dan GBC serasi: - + Game Boy palette Palet Game Boy - + Preset: Praset: @@ -5393,135 +5480,130 @@ Download size: %3 Perisian - + OpenGL enhancements - + High-resolution scale: - + (240×160) (240×160) - - XQ GBA audio (experimental) - - - - + GB BIOS file: Fail BIOS GB: - - - - - - - - - + + + + + + + + + Browse Pilih fail - + Use BIOS file if found Guna fail BIOS jika ada - + Skip BIOS intro Langkau pendahuluan BIOS - + GBA BIOS file: Fail BIOS GBA: - + GBC BIOS file: Fail BIOS GBC: - + SGB BIOS file: Fail BIOS SGB: - + Save games Simpanan permainan - - - - - + + + + + Same directory as the ROM Direktori sama dengan ROM - + Save states Keadaan tersimpan - + Screenshots Cekupan skrin - + Patches - + Cheats Tipuan - + Log to file Log dalam fail - + Log to console Log dalam konsol - + Select Log File Pilih fail log - + Default BG colors: Warna LB piawai: - + Default sprite colors 1: - + Default sprite colors 2: - + Super Game Boy borders @@ -5779,13 +5861,11 @@ Download size: %3 - WebM WebM - MP4 MP4 @@ -5824,82 +5904,6 @@ Download size: %3 Format Format - - - MKV - MKV - - - - AVI - AVI - - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Tiada - - - - FLAC - FLAC - - - - WavPack - - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - - Bitrate (kbps) @@ -5910,16 +5914,6 @@ Download size: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5949,80 +5943,80 @@ Download size: %3 QGBA::Window - + Archives (%1) Arkib (%1) - - + + Select ROM Pilih ROM - + Select folder Pilih folder - - + + Select save - + Select patch - + Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode - + e-Reader card (*.raw *.bin *.bmp) - + Select image Pilih gambar - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Fail gambar (*.png *.gif *.jpg *.jpeg);;Semua fail (*) - + GameShark saves (*.sps *.xps) Simpanan GameShark (*.sps *.xps) - + Select video log Pilih log video - + Video logs (*.mvl) Log video (*.mvl) - + Crash Nahas - + The game has crashed with the following error: %1 @@ -6031,699 +6025,709 @@ Download size: %3 %1 - + Couldn't Start Tidak dapat memula - + Could not start game. Permainan tidak dapat bermula. - + Unimplemented BIOS call Panggilan BIOS yg belum dilaksanakan - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Permainan ini menggunakan panggilan BIOS yang belum dilaksanakan. Sila pakai BIOS rasmi untuk pengalaman yang lebih baik. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Gagal mencipta peranti paparan yang sesuai, berbalik ke paparan perisian. Permainan mungkin menjadi lembap, terutamanya dengan tetingkap besar. - + Really make portable? Betulkah mahu buat jadi mudah alih? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Ini akan menetapkan pelagak untuk muat konfigurasi dari direktori yang sama dengan fail bolehlakunya. Teruskan? - + Restart needed Mula semula diperlukan - + Some changes will not take effect until the emulator is restarted. Beberapa perubahan tidak akan dilaksanakan sehingga pelagak dimula semula. - + - Player %1 of %2 - Pemain %1 dari %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &File - + Load &ROM... Muat %ROM... - + Load ROM in archive... Muat ROM daripada arkib... - + Add folder to library... Tambah folder ke perpustakaan... - + Save games (%1) Simpanan permainan (%1) - + Select save game Pilih simpanan permainan - + mGBA save state files (%1) mGBA fail keadaan tersimpan (%1) - - + + Select save state Pilih keadaan tersimpan - + Select e-Reader card images - + Image file (*.png *.jpg *.jpeg) Fail gambar (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Load alternate save game... Muat simpanan permainan alternatif... - + Load temporary save game... Muat simpanan permainan sementara... - + Load &patch... - + Boot BIOS But BIOS - + Replace ROM... Ganti ROM... - + Scan e-Reader dotcodes... - + Convert e-Reader card image to raw... - + ROM &info... &Perihal ROM... - + Recent Terkini - + Make portable Buat jadi mudah alih - + &Load state &Muat keadaan - + Load state file... Muat fail keadaan... - + &Save state &Simpan keadaan - + Save state file... Simpan fail keadaan... - + Quick load - + Quick save - + Load recent Muat terkini - + Save recent Simpan terkini - + Undo load state Buat asal keadaan termuat - + Undo save state Buat asal keadaan tersimpan - - + + State &%1 Keadaan &%1 - + Load camera image... Muat gambar kamera... - + Convert save game... Tukar simpanan permainan... - + GameShark saves (*.gsv *.sps *.xps) - + Reset needed - + Some changes will not take effect until the game is reset. - + Save games Simpanan permainan - + Import GameShark Save... Import Simpanan GameShark... - + Export GameShark Save... Eksport Simpanan GameShark... - + Automatically determine - + Use player %0 save game - + New multiplayer window Tetingkap multipemain baru - + Connect to Dolphin... Sambung ke Dolphin... - + Report bug... Laporkan pepijat... - + About... Perihal... - + E&xit &Keluar - + &Emulation Pe&lagak - + &Reset - + Sh&utdown &Matikan - + Yank game pak Alih keluar Game Pak - + &Pause &Jeda - + &Next frame Bingkai se&terusnya - + Fast forward (held) Mundar laju (pegang) - + &Fast forward Mundar &laju - + Fast forward speed Kelajuan mundar laju - + Unbounded Tidak terbatas - + %0x %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) Putar balik (pegang) - + Re&wind Ma&ndir - + Step backwards Langkah belakang - + Solar sensor Pengesan suria - + Increase solar level Meningkatkan aras suria - + Decrease solar level Mengurangkan aras suria - + Brightest solar level Aras suria paling terang - + Darkest solar level Aras suria paling gelap - + Brightness %1 Kecerahan %1 - + Game Boy Printer... Pencetak Game Boy... - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Saiz bingkai - + %1× %1× - + Toggle fullscreen Togol skrinpenuh - + + &Lock frame size + + + + Lock aspect ratio Kekalkan nisbah aspek - + Force integer scaling Paksa skala integer - + Interframe blending Persebatian antarabingkai - + Bilinear filtering Penapisan bilinear - + Frame&skip Langkauan &bingkai - + Mute Senyap - + FPS target Sasaran FPS - + Native (59.7275) Asal (59.7275) - + Take &screenshot Ambil &cekupan skrin - + F12 F12 - + Record A/V... Rakam A/V... - + Record GIF/WebP/APNG... Rakam GIF/WebP/APNG... - + Video layers Lapisan video - + Audio channels Saluran audio - + Adjust layer placement... Melaras peletakan lapisan... - + &Tools &Alat - + View &logs... Lihat &log... - + Game &overrides... - + Game Pak sensors... Pengesan Game Pak... - + &Cheats... &Tipu... - + Create forwarder... - + Settings... Tetapan... - + Open debugger console... Buka konsol penyahpepijat... - + Start &GDB server... Mula pelayan &GDB... - + Scripting... - + Game state views - + View &palette... Pelihat &palet... - + View &sprites... - + View &tiles... Pelihat &jubin... - + View &map... Pelihat pe&ta... - + &Frame inspector... Periksa &bingkai... - + View memory... Lihat ingatan... - + Search memory... Cari ingatan... - + View &I/O registers... Lihat daftar &I/O... - + + Log memory &accesses... + + + + Record debug video log... Rakam log video nyahpepijat... - + Stop debug video log Henti log video nyahpepijat - + Exit fullscreen Keluar skrinpenuh - + GameShark Button (held) Butang GameShark (pegang) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear Kosongkan @@ -6761,17 +6765,17 @@ Download size: %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu Menu @@ -6779,22 +6783,22 @@ Download size: %3 QShortcut - + Shift Shift - + Control Ctrl - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-nb_NO.ts b/src/platform/qt/ts/mgba-nb_NO.ts index 6c06c2fe6..789faa1f0 100644 --- a/src/platform/qt/ts/mgba-nb_NO.ts +++ b/src/platform/qt/ts/mgba-nb_NO.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) Game Boy Advance ROM-filer (%1) - + Game Boy ROMs (%1) Game Boy ROM-filer (%1) - + All ROMs (%1) Alle ROM-filer (%1) - + %1 Video Logs (*.mvl) %1-videologger (*.mvl) @@ -189,17 +189,17 @@ Nedlastningsstørrelse: %3 QGBA::AudioDevice - + Can't set format of context-less audio device - + Audio device is missing its core - + Writing data to read-only audio device Skriver data til skrivebeskyttet lydenhet @@ -207,7 +207,7 @@ Nedlastningsstørrelse: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input @@ -283,28 +283,28 @@ Nedlastningsstørrelse: %3 Vis avanserte innstillinger - + BattleChip data missing - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - + + Select deck file - + Incompatible deck - + The selected deck is not compatible with this Chip Gate @@ -365,19 +365,19 @@ Nedlastningsstørrelse: %3 Skriv inn koder her … - - + + Autodetect (recommended) Auto-oppdag (anbefales) - - + + Select cheats file Velg juksekodefil - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. @@ -396,37 +396,37 @@ Nedlastningsstørrelse: %3 - + Reset the game? Vil du starte spillet pÃ¥ nytt? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 - + Failed to open game file: %1 Klarte ikke Ã¥ Ã¥pne spillfil: %1 - + Can't yank pack in unexpected platform! - + Failed to open snapshot file for reading: %1 - + Failed to open snapshot file for writing: %1 @@ -475,6 +475,14 @@ Nedlastningsstørrelse: %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -755,52 +763,52 @@ Nedlastningsstørrelse: %3 Tilbakestill - + Export frame - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Ingen - + Background Bakgrunn - + Window Vindu - + Objwin Objwin - + Sprite - + Backdrop Bakgrunn - + Frame Ramme - + %1 %2 %1 %2 @@ -816,22 +824,22 @@ Nedlastningsstørrelse: %3 QGBA::GBAKeyEditor - + Clear Button Tøm knapper - + Clear Analog Tøm analoge - + Refresh Gjenoppfrisk - + Set all Sett alle @@ -3004,8 +3012,8 @@ Nedlastningsstørrelse: %3 QGBA::KeyEditor - - + + --- --- @@ -3376,23 +3384,87 @@ Nedlastningsstørrelse: %3 Vertikal - - - + + + N/A I/T - + Export map - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Bla + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + Stopp + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3456,7 +3528,7 @@ Nedlastningsstørrelse: %3 Load TBL - + Last inn TBL @@ -3639,22 +3711,22 @@ Nedlastningsstørrelse: %3 Gjenoppfrisk - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 @@ -3748,17 +3820,17 @@ Nedlastningsstørrelse: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4155,35 +4227,35 @@ Nedlastningsstørrelse: %3 Eksporter OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Eksporter palett - + Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 @@ -4257,7 +4329,7 @@ Nedlastningsstørrelse: %3 QGBA::ROMInfo - + @@ -4297,16 +4369,26 @@ Nedlastningsstørrelse: %3 + Maker Code: + + + + + Revision: + + + + File size: Filstørrelse: - + CRC32: CRC32: - + Save file: @@ -4362,62 +4444,62 @@ Nedlastningsstørrelse: %3 QGBA::SaveConverter - + Save games and save states (%1) Lagrefiler og lagringstilstander - + Select save game or save state - + Save games (%1) Lagrefiler (%1) - + Select save game Velg lagrefil - + Conversion failed Konvertering mislyktes - + Failed to convert the save game. This is probably a bug. - + No file selected Ingen fil valgt - + Could not open file Kunne ikke Ã¥pne fil - + No valid formats found - + Please select a valid input file Velg en gyldig inndatafil - + No valid conversions found - + Cannot convert save games between platforms @@ -4443,97 +4525,97 @@ Nedlastningsstørrelse: %3 Utdatafil - + %1 %2 save game - + little endian - + big endian - + SRAM SRAM - + %1 flash - + %1 EEPROM %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM MBC6-SRAM - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4569,32 +4651,37 @@ Nedlastningsstørrelse: %3 - + Load script... Last inn skript... - + + &Load most recent + + + + &Reset &Omstart - + 0 0 - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) Alle filer (*.*) @@ -4687,105 +4774,105 @@ Nedlastningsstørrelse: %3 QGBA::SettingsView - - + + Qt Multimedia - + SDL SDL - + Software (Qt) Programvare (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (tving versjon 1.x) - + None Ingen - + None (Still Image) Ingen (stillbilde) - + Keyboard Tastatur - + Controllers Kontrollere - + Shortcuts Snarveier - - + + Shaders Skyggeleggere - + Select BIOS Velg BIOS - + Select directory Velg mappe - + Select image Velg bilde - + Image file (*.png *.jpg *.jpeg) Bildefil (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never Aldri - + Just now Akkurat nÃ¥ - + Less than an hour ago Mindre enn én time siden - + %n hour(s) ago @@ -4793,7 +4880,7 @@ Nedlastningsstørrelse: %3 - + %n day(s) ago @@ -5120,37 +5207,37 @@ Nedlastningsstørrelse: %3 Sjekk nÃ¥ - + Default color palette only - + SGB color palette if available SGB-fargepalett hvis tilgjengelig - + GBC color palette if available GBC-fargepalett hvis tilgjengelig - + SGB (preferred) or GBC color palette if available SGB (foretrukket) eller GBC-fargepalett hvis tilgjengelig - + Game Boy Camera Game Boy Camera - + Driver: Driver: - + Source: Kilde: @@ -5327,42 +5414,42 @@ Nedlastningsstørrelse: %3 - + Models Modeller - + GB only: Kun GB: - + SGB compatible: SGB-kompatibel: - + GBC only: Kun GBC: - + GBC compatible: GBC-kompatibel: - + SGB and GBC compatible: SGB- og GBC-kompatible: - + Game Boy palette Game Boy-fargepalett - + Preset: ForhÃ¥ndsinnstilling: @@ -5399,135 +5486,130 @@ Nedlastningsstørrelse: %3 Programvare - + OpenGL enhancements - + High-resolution scale: - + (240×160) (240×160) - - XQ GBA audio (experimental) - - - - + GB BIOS file: GB BIOS-fil: - - - - - - - - - + + + + + + + + + Browse Bla - + Use BIOS file if found Bruk BIOS-filen hvis den blir funnet - + Skip BIOS intro Hopp over BIOS-introen - + GBA BIOS file: GBA-BIOS-fil: - + GBC BIOS file: GBC-BIOS-fil: - + SGB BIOS file: SGB-BIOS-fil: - + Save games Lagrefiler - - - - - + + + + + Same directory as the ROM - + Save states - + Screenshots Skjermklipp - + Patches Patcher - + Cheats Juks - + Log to file Loggfør til en fil - + Log to console - + Select Log File - + Default BG colors: - + Default sprite colors 1: - + Default sprite colors 2: - + Super Game Boy borders Super Game Boy-kanter @@ -5785,13 +5867,11 @@ Nedlastningsstørrelse: %3 - WebM WebM - MP4 MP4 @@ -5830,92 +5910,6 @@ Nedlastningsstørrelse: %3 Format Format - - - MKV - MKV - - - - AVI - AVI - - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Ingen - - - - FLAC - FLAC - - - - WavPack - - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Ukomprimert - Bitrate (kbps) @@ -5955,779 +5949,789 @@ Nedlastningsstørrelse: %3 QGBA::Window - + Archives (%1) Arkiv (%1) - - + + Select ROM Velg ROM - + Select folder Velg mappe - - + + Select save Velg lagrefil - + Select patch Velg feilfiks - + Patches (*.ips *.ups *.bps) Feilfikser (*.ips *.ups *.bps) - + Select e-Reader dotcode Velg e-Reader-punktkode - + e-Reader card (*.raw *.bin *.bmp) e-Reader-kort (*.raw *.bin *.bmp) - + Select image Velg bilde - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bildefil (*.png *.gif *.jpg *.jpeg);;All filer (*) - + GameShark saves (*.sps *.xps) - + Select video log - + Video logs (*.mvl) Videologgføringer (*.mvl) - + Crash Krasj - + The game has crashed with the following error: %1 - + Couldn't Start Klarte ikke Ã¥ starte opp - + Could not start game. Klarte ikke Ã¥ starte opp spillet. - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed Gjennomfør omstart - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File &Fil - + Load &ROM... Last inn &ROM... - + Load ROM in archive... - + Add folder to library... - + Save games (%1) Lagrefiler (%1) - + Select save game Velg lagrefil - + mGBA save state files (%1) - - + + Select save state - + Select e-Reader card images Velg e-Reader-kortavbildninger - + Image file (*.png *.jpg *.jpeg) Bildefil (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Load alternate save game... - + Load temporary save game... - + Load &patch... - + Boot BIOS Oppstarts-BIOS - + Replace ROM... Bytt ROM.... - + Scan e-Reader dotcodes... Skann e-Reader-punktkoder... - + Convert e-Reader card image to raw... - + ROM &info... ROM-&info ... - + Recent Nylig - + Make portable - + &Load state &Last inn tilstand - + Load state file... - + &Save state &Lagre en tilstand - + Save state file... - + Quick load Hurtiginnlasting - + Quick save Hurtiglagring - + Load recent - + Save recent - + Undo load state - + Undo save state - - + + State &%1 - + Load camera image... - + Convert save game... - + GameShark saves (*.gsv *.sps *.xps) GameShark-lagrefiler (*.gsv *.sps *.xps) - + Reset needed Tilbakestilling kreves - + Some changes will not take effect until the game is reset. - + Save games Lagrefiler - + Import GameShark Save... - + Export GameShark Save... - + Automatically determine - + Use player %0 save game - + New multiplayer window Nytt flerspillervindu - + Connect to Dolphin... Koble til Dolphin... - + Report bug... Rapporter inn feil... - + About... Om … - + E&xit A&vslutt - + &Emulation &Emulering - + &Reset &Omstart - + Sh&utdown Skr&u av - + Yank game pak Dra ut spillkassetten - + &Pause &Pause - + &Next frame - + Fast forward (held) - + &Fast forward - + Fast forward speed - + Unbounded - + %0x %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) Spol tilbake (holdt) - + Re&wind Spol ti&lbake - + Step backwards - + Solar sensor Solsensor - + Increase solar level Øke solnivÃ¥et - + Decrease solar level Reduser solnivÃ¥et - + Brightest solar level Lyseste solnivÃ¥ - + Darkest solar level Mørkeste solnivÃ¥ - + Brightness %1 Lysstyrke %1 - + Game Boy Printer... Game Boy Printer... - + BattleChip Gate... - + Audio/&Video Lyd/&Video - + Frame size Rammestørrelse - + %1× %1× - + Toggle fullscreen Skru pÃ¥/av fullskjerm - + + &Lock frame size + + + + Lock aspect ratio LÃ¥s visningsforhold - + Force integer scaling - + Interframe blending - + Bilinear filtering Bilineær filtrering - + Frame&skip - + Mute Demp lyd - + FPS target - + Native (59.7275) Systemstandard (59.7275) - + Take &screenshot Ta &skjermbilde - + F12 F12 - + Record A/V... - + Record GIF/WebP/APNG... - + Video layers - + Audio channels Lydkanaler - + Adjust layer placement... - + &Tools Verk&tøy - + View &logs... - + Game &overrides... Spilloverstyringer ... - + Game Pak sensors... Game Pak-sensorer ... - + &Cheats... - + Create forwarder... - + Settings... Innstillinger… - + Open debugger console... - + Start &GDB server... - + Scripting... - + Game state views - + View &palette... Vis &palett ... - + View &sprites... - + View &tiles... - + View &map... Vis &kart … - + &Frame inspector... - + View memory... Vis minne ... - + Search memory... Søk i minne ... - + View &I/O registers... - + + Log memory &accesses... + + + + Record debug video log... - + Stop debug video log - + Exit fullscreen GÃ¥ ut av fullskjerm - + GameShark Button (held) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear Tøm @@ -6765,17 +6769,17 @@ Nedlastningsstørrelse: %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu Meny @@ -6783,22 +6787,22 @@ Nedlastningsstørrelse: %3 QShortcut - + Shift Shift - + Control Kontroll - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-pl.ts b/src/platform/qt/ts/mgba-pl.ts index 650563e2e..12ce34462 100644 --- a/src/platform/qt/ts/mgba-pl.ts +++ b/src/platform/qt/ts/mgba-pl.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ROMy Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMy Game Boy (%1) - + All ROMs (%1) Wszystkie ROMy (%1) - + %1 Video Logs (*.mvl) Dzienniki wideo %1 (*.mvl) @@ -191,17 +191,17 @@ Rozmiar pobierania: %3 QGBA::AudioDevice - + Can't set format of context-less audio device Nie można ustawić formatu bezkontekstowego urzÄ…dzenia audio - + Audio device is missing its core UrzÄ…dzenie audio nie ma rdzenia - + Writing data to read-only audio device Zapisywanie danych na urzÄ…dzeniu audio tylko do odczytu @@ -209,7 +209,7 @@ Rozmiar pobierania: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input Nie można uruchomić procesora dźwiÄ™ku bez wejÅ›cia @@ -285,28 +285,28 @@ Rozmiar pobierania: %3 Pokaż zaawansowane opcje - + BattleChip data missing Brak danych BattleChip - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? Brak danych BattleChip. BattleChip Gates nadal bÄ™dzie dziaÅ‚ać, ale bÄ™dzie brakować niektórych elementów graficznych. Czy chcesz teraz pobrać dane? - - + + Select deck file Wybierz plik deck - + Incompatible deck Niezgodny deck - + The selected deck is not compatible with this Chip Gate Wybrany deck nie jest kompatybilny z tym Chip Gate @@ -367,19 +367,19 @@ Rozmiar pobierania: %3 Wpisz kody tutaj... - - + + Autodetect (recommended) Automatyczne wykrywanie (zalecane) - - + + Select cheats file Wybierz plik z kodami - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Nie udaÅ‚o siÄ™ dodać niektórych kodów. Upewnij siÄ™, że sÄ… poprawnie sformatowane i/lub wypróbuj inne typy kodów. @@ -398,37 +398,37 @@ Rozmiar pobierania: %3 Przewijanie nie jest obecnie wÅ‚Ä…czone - + Reset the game? Zresetować grÄ™? - + Most games will require a reset to load the new save. Do you want to reset now? WiÄ™kszość gier wymaga zresetowania, aby wczytać nowy zapis. Czy chcesz teraz zresetować? - + Failed to open save file: %1 Nie udaÅ‚o siÄ™ otworzyć pliku zapisu: %1 - + Failed to open game file: %1 Nie udaÅ‚o siÄ™ otworzyć pliku gry: %1 - + Can't yank pack in unexpected platform! Nie można wyciÄ…gnąć pack na nieoczekiwanej platformie! - + Failed to open snapshot file for reading: %1 Nie udaÅ‚o siÄ™ otworzyć pliku snapshot do odczytu: %1 - + Failed to open snapshot file for writing: %1 Nie udaÅ‚o siÄ™ otworzyć pliku snapshot do zapisu: %1 @@ -477,6 +477,14 @@ Rozmiar pobierania: %3 Nie można otworzyć historii CLI do zapisu + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Rozmiar pobierania: %3 Resetuj - + Export frame Eksportuj klatkÄ™ - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Nic - + Background TÅ‚o - + Window Okno - + Objwin Obiwin - + Sprite Sprite - + Backdrop ZasÅ‚ona - + Frame Klatka - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Rozmiar pobierania: %3 QGBA::GBAKeyEditor - + Clear Button Wyczyść Przycisk - + Clear Analog Wyczyść Analog - + Refresh OdÅ›wież - + Set all Ustaw wszystko @@ -3006,8 +3014,8 @@ Rozmiar pobierania: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Rozmiar pobierania: %3 Pionowy - - - + + + N/A N/D - + Export map Eksportuj mapÄ™ - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + PrzeglÄ…daj + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + Start + + + + Stop + Stop + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Rozmiar pobierania: %3 OdÅ›wież - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 bajt%2 @@ -3750,17 +3822,17 @@ Rozmiar pobierania: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached Próba odÅ‚Ä…czenia gracza multiplayer, który nie jest doÅ‚Ä…czony - + Trying to get player ID for a multiplayer player that's not attached Próba uzyskania ID gracza w trybie wieloosobowym, który nie jest poÅ‚Ä…czony - + Trying to get save ID for a multiplayer player that's not attached Próba uzyskania identyfikatora zapisu dla gracza multiplayer, który nie jest poÅ‚Ä…czony @@ -4157,35 +4229,35 @@ Rozmiar pobierania: %3 Eksportuj OBI - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Eksportuj paletÄ™ - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 Nie udaÅ‚o siÄ™ otworzyć pliku palety wyjÅ›ciowej: %1 @@ -4259,7 +4331,7 @@ Rozmiar pobierania: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Rozmiar pobierania: %3 + Maker Code: + + + + + Revision: + + + + File size: Rozmiar pliku: - + CRC32: CRC32: - + Save file: Zapisz plik: @@ -4364,62 +4446,62 @@ Rozmiar pobierania: %3 QGBA::SaveConverter - + Save games and save states (%1) Zapisane gry i stany zapisu (%1) - + Select save game or save state Wybierz zapis gry lub stan zapisu - + Save games (%1) Zapisane gry (%1) - + Select save game Wybierz zapis gry - + Conversion failed Konwersja nie powiodÅ‚a siÄ™ - + Failed to convert the save game. This is probably a bug. Nie udaÅ‚o siÄ™ przekonwertować zapisanej gry. To prawdopodobnie bÅ‚Ä…d. - + No file selected Nie wybrano pliku - + Could not open file Nie można otworzyć pliku - + No valid formats found Nie znaleziono prawidÅ‚owych formatów - + Please select a valid input file Wybierz prawidÅ‚owy plik wejÅ›ciowy - + No valid conversions found Nie znaleziono prawidÅ‚owych konwersji - + Cannot convert save games between platforms Nie można konwertować zapisanych gier miÄ™dzy platformami @@ -4445,97 +4527,97 @@ Rozmiar pobierania: %3 Plik wyjÅ›ciowy - + %1 %2 save game %1 %2 zapis gry - + little endian little endian - + big endian big endian - + SRAM SRAM - + %1 flash %1 flash - + %1 EEPROM %1 EEPROM - + + RTC + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 MBC2 skompresowane - + unpacked MBC2 MBC2 nieskompresowany - + MBC6 flash MBC6 Flash - + MBC6 combined SRAM + flash MBC6 Å‚Ä…czny SRAM + flash - + MBC6 SRAM MBC6 SRAM - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game %1 stan gry z osadzonym %2 zapisem gry - + %1 SharkPort %2 save game %1 SharkPort %2 zapis gry - + %1 GameShark Advance SP %2 save game %1 GameShark Advance SP %2 zapis gry @@ -4571,32 +4653,37 @@ Rozmiar pobierania: %3 ZaÅ‚aduj ostatni skrypt - + Load script... ZaÅ‚aduj skrypt... - + + &Load most recent + + + + &Reset &Resetuj - + 0 0 - + Select script to load Wybierz skrypt do zaÅ‚adowania - + Lua scripts (*.lua) Skrypty Lua (*.lua) - + All files (*.*) Wszystkie pliki (*.*) @@ -4689,105 +4776,105 @@ Rozmiar pobierania: %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (wymuÅ› wersjÄ™ 1.x) - + None Nic - + None (Still Image) Brak (Obraz Nieruchomy) - + Keyboard Klawiatura - + Controllers Kontrolery - + Shortcuts Skróty - - + + Shaders Shadery - + Select BIOS Wybierz BIOS - + Select directory Wybierz katalog - + Select image Wybierz obraz - + Image file (*.png *.jpg *.jpeg) Plik graficzny (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never Nigdy - + Just now WÅ‚aÅ›nie teraz - + Less than an hour ago Mniej niż godzinÄ™ temu - + %n hour(s) ago %n godzinÄ™ temu @@ -4796,7 +4883,7 @@ Rozmiar pobierania: %3 - + %n day(s) ago %n dzieÅ„ temu @@ -5124,37 +5211,37 @@ Rozmiar pobierania: %3 Sprawdź teraz - + Default color palette only Tylko domyÅ›lna paleta kolorów - + SGB color palette if available Paleta kolorów SGB, jeÅ›li jest dostÄ™pna - + GBC color palette if available Paleta kolorów GBC, jeÅ›li jest dostÄ™pna - + SGB (preferred) or GBC color palette if available Paleta kolorów SGB (preferowana) lub GBC, jeÅ›li jest dostÄ™pna - + Game Boy Camera Game Boy Camera - + Driver: Sterownik: - + Source: ŹródÅ‚o: @@ -5331,42 +5418,42 @@ Rozmiar pobierania: %3 Dodatkowe dane Å‚adowania stanu gry: - + Models Modele - + GB only: Tylko GB: - + SGB compatible: Kompatybilny z SGB: - + GBC only: Tylko GBC: - + GBC compatible: Kompatybilny z GBC: - + SGB and GBC compatible: Kompatybilny z SGB i GBC: - + Game Boy palette Paleta Game Boy - + Preset: Ustawienie wstÄ™pne: @@ -5403,135 +5490,130 @@ Rozmiar pobierania: %3 Software - + OpenGL enhancements Ulepszenia OpenGL - + High-resolution scale: Skala o wysokiej rozdzielczoÅ›ci: - + (240×160) (240×160) - - XQ GBA audio (experimental) - DźwiÄ™k wysokiej jakoÅ›ci GBA (eksperymentalny) - - - + GB BIOS file: Plik BIOS GB: - - - - - - - - - + + + + + + + + + Browse PrzeglÄ…daj - + Use BIOS file if found Użyj pliku BIOS, jeÅ›li zostanie znaleziony - + Skip BIOS intro PomiÅ„ wprowadzenie BIOS - + GBA BIOS file: Plik BIOS GBA: - + GBC BIOS file: Plik BIOS GBC: - + SGB BIOS file: Plik BIOS SGB: - + Save games Zapisane gry - - - - - + + + + + Same directory as the ROM Ten sam katalog co ROM - + Save states Stany gry - + Screenshots Zrzuty ekranu - + Patches Åatki - + Cheats Kody (cheaty) - + Log to file Loguj do pliku - + Log to console Loguj do konsoli - + Select Log File Wybierz plik dziennika - + Default BG colors: DomyÅ›lne kolory tÅ‚a: - + Default sprite colors 1: DomyÅ›lne kolory sprite'ów 1: - + Default sprite colors 2: DomyÅ›lne kolory sprite'ów 2: - + Super Game Boy borders Ramki Super Game Boy @@ -5789,13 +5871,11 @@ Rozmiar pobierania: %3 - WebM WebM - MP4 MP4 @@ -5834,82 +5914,6 @@ Rozmiar pobierania: %3 Format Format - - - MKV - MKV - - - - AVI - AVI - - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Nic - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Nieskompresowany - Bitrate (kbps) @@ -5920,16 +5924,6 @@ Rozmiar pobierania: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5959,80 +5953,80 @@ Rozmiar pobierania: %3 QGBA::Window - + Archives (%1) Archiwa (%1) - - + + Select ROM Wybierz ROM - + Select folder Wybierz katalog - - + + Select save Wybierz zapis - + Select patch Wybierz Å‚atkÄ™ - + Patches (*.ips *.ups *.bps) Åatki (*.ips *.ups *.bps) - + Select e-Reader dotcode Wybierz kod kropki e-Reader - + e-Reader card (*.raw *.bin *.bmp) Karta e-Reader (*.raw *.bin *.bmp) - + Select image Wybierz obraz - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Plik obrazu (*.png *.gif *.jpg *.jpeg);;Wszystkie pliki (*) - + GameShark saves (*.sps *.xps) Zapisy GameShark (*.sps *.xps) - + Select video log Wybierz dziennik wideo - + Video logs (*.mvl) Dzienniki wideo (*.mvl) - + Crash Crash - + The game has crashed with the following error: %1 @@ -6041,699 +6035,709 @@ Rozmiar pobierania: %3 %1 - + Couldn't Start Nie udaÅ‚o siÄ™ uruchomić - + Could not start game. Nie udaÅ‚o siÄ™ rozpocząć gry. - + Unimplemented BIOS call Niewdrożone wywoÅ‚anie BIOS - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Ta gra używa wywoÅ‚ania BIOS, które nie jest zaimplementowane. Aby uzyskać najlepsze wrażenia, użyj oficjalnego BIOS. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Nie udaÅ‚o siÄ™ utworzyć odpowiedniego urzÄ…dzenia wyÅ›wietlajÄ…cego, powracam do wyÅ›wietlania programowego. Gry mogÄ… dziaÅ‚ać wolno, zwÅ‚aszcza w przypadku wiÄ™kszych okien. - + Really make portable? NaprawdÄ™ stworzyć wersjÄ™ portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? To sprawi, że emulator zaÅ‚aduje swojÄ… konfiguracjÄ™ z tego samego katalogu, co plik wykonywalny. Czy chcesz kontynuować? - + Restart needed Wymagane ponowne uruchomienie - + Some changes will not take effect until the emulator is restarted. Niektóre zmiany nie zacznÄ… obowiÄ…zywać, dopóki emulator nie zostanie ponownie uruchomiony. - + - Player %1 of %2 - Gracz %1 z %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 FPS) - %4 - + &File &Plik - + Load &ROM... ZaÅ‚aduj &ROM... - + Load ROM in archive... ZaÅ‚aduj ROM w archiwum... - + Add folder to library... Dodaj folder do biblioteki... - + Save games (%1) Zapisane gry (%1) - + Select save game Wybierz zapis gry - + mGBA save state files (%1) Pliki stanu gry mGBA (%1) - - + + Select save state Wybierz stan - + Select e-Reader card images Wybierz obrazy kart e-Reader - + Image file (*.png *.jpg *.jpeg) Plik graficzny (*.png *.jpg *.jpeg) - + Conversion finished Konwersja zakoÅ„czona - + %1 of %2 e-Reader cards converted successfully. %1 z %2 kart czytnika e-Reader zostaÅ‚o pomyÅ›lnie przekonwertowanych. - + Load alternate save game... ZaÅ‚aduj alternatywny zapis gry... - + Load temporary save game... ZaÅ‚aduj tymczasowy zapis gry... - + Load &patch... Wczytaj &poprawkÄ™... - + Boot BIOS BIOS startowy - + Replace ROM... WymieÅ„ ROM... - + Scan e-Reader dotcodes... Skanuj kody kropkowe czytnika e-Reader... - + Convert e-Reader card image to raw... Konwertuj obraz karty czytnika e-Reader na surowy... - + ROM &info... &Informacje o pamiÄ™ci ROM... - + Recent Ostatnie - + Make portable Stwórz wersjÄ™ portable - + &Load state &ZaÅ‚aduj stan - + Load state file... ZaÅ‚aduj plik stanu… - + &Save state &Zapisz stan - + Save state file... Zapisz plik stanu... - + Quick load Szybkie zaÅ‚adowanie - + Quick save Szybki zapis - + Load recent ZaÅ‚aduj ostatnie - + Save recent Zapisz ostatnie - + Undo load state Cofnij zaÅ‚adowanie stanu - + Undo save state Cofnij zapisanie stanu - - + + State &%1 Stan &%1 - + Load camera image... ZaÅ‚aduj obraz do kamery... - + Convert save game... Konwertuj zapisanÄ… grÄ™... - + GameShark saves (*.gsv *.sps *.xps) Zapisy GameShark (*.gsv *.sps *.xps) - + Reset needed Wymagane zresetowanie - + Some changes will not take effect until the game is reset. Niektóre zmiany nie zacznÄ… obowiÄ…zywać, dopóki gra nie zostanie zresetowana. - + Save games Zapisy gry - + Import GameShark Save... Importuj Zapis GameShark... - + Export GameShark Save... Eksportuj Zapis GameShark... - + Automatically determine Wykryj automatycznie - + Use player %0 save game Użyj zapis gry gracza %0 - + New multiplayer window Nowe okno dla wielu graczy - + Connect to Dolphin... PoÅ‚Ä…cz z Dolphinem... - + Report bug... ZgÅ‚oÅ› bÅ‚Ä…d... - + About... O Aplikacji... - + E&xit Z&akoÅ„cz - + &Emulation &Emulacja - + &Reset &Resetuj - + Sh&utdown Za&mknij - + Yank game pak WyciÄ…gnij Game Pak - + &Pause &Pauza - + &Next frame &NastÄ™pna klatka - + Fast forward (held) Przewijanie (przytrzymaj) - + &Fast forward &Przewijanie do przodu - + Fast forward speed PrÄ™dkość przewijania do przodu - + Unbounded Bez ograniczeÅ„ - + %0x %0x - + Increase fast forward speed ZwiÄ™kszenie prÄ™dkoÅ›ci przewijania do przodu - + Decrease fast forward speed Zmiejszenie prÄ™dkoÅ›ci przewijania do przodu - + Rewind (held) Przewijanie (przytrzymaj) - + Re&wind Pr&zewijanie - + Step backwards Krok w tyÅ‚ - + Solar sensor Czujnik sÅ‚oneczny - + Increase solar level ZwiÄ™ksz poziom energii sÅ‚onecznej - + Decrease solar level Zmniejsz poziom energii sÅ‚onecznej - + Brightest solar level NajjaÅ›niejszy poziom energii sÅ‚onecznej - + Darkest solar level Najciemniejszy poziom energii sÅ‚onecznej - + Brightness %1 Jasność %1 - + Game Boy Printer... Game Boy Printer... - + BattleChip Gate... BattleChip Gate... - + Audio/&Video DźwiÄ™k/&Wideo - + Frame size Rozmiar klatki - + %1× %1× - + Toggle fullscreen PrzeÅ‚Ä…cz tryb peÅ‚noekranowy - + + &Lock frame size + + + + Lock aspect ratio Zablokuj proporcje - + Force integer scaling WymuÅ› skalowanie caÅ‚kowite - + Interframe blending Blendowanie miÄ™dzyklatkowe - + Bilinear filtering Filtrowanie dwuliniowe - + Frame&skip Klatko&wanie - + Mute Wycisz - + FPS target Cel KL./S - + Native (59.7275) Natywny (59.7275) - + Take &screenshot Wykonaj &zrzut ekranu - + F12 F12 - + Record A/V... Nagraj A/W... - + Record GIF/WebP/APNG... Nagraj GIF/WebP/APNG... - + Video layers Warstwy wideo - + Audio channels KanaÅ‚y audio - + Adjust layer placement... Dostosuj poÅ‚ożenie warstw... - + &Tools &NarzÄ™dzia - + View &logs... WyÅ›wietl &logi... - + Game &overrides... Nadpisania &ustawieÅ„ gry... - + Game Pak sensors... Czujniki Game Pak... - + &Cheats... &Kody... - + Create forwarder... Utwórz forwarder... - + Settings... Ustawienia... - + Open debugger console... Otwórz konsolÄ™ debugera... - + Start &GDB server... Uruchom serwer &GDB... - + Scripting... Skrypty... - + Game state views Widoki stanu gry - + View &palette... WyÅ›wietl &paletÄ™... - + View &sprites... WyÅ›wietl &sprite'y... - + View &tiles... WyÅ›wietl &kafelki... - + View &map... WyÅ›wietl &mapÄ™... - + &Frame inspector... Inspektor &klatek... - + View memory... WyÅ›wietl pamięć... - + Search memory... Przeszukaj pamięć... - + View &I/O registers... WyÅ›wietl rejestry &we/wy... - + + Log memory &accesses... + + + + Record debug video log... Nagraj dziennik wideo debugowania... - + Stop debug video log Zatrzymaj dziennik wideo debugowania - + Exit fullscreen WyÅ‚Ä…czyć tryb peÅ‚noekranowy - + GameShark Button (held) Przycisk GameShark (przytrzymany) - + Autofire Turbo - + Autofire A Turbo A - + Autofire B Turbo B - + Autofire L Turbo L - + Autofire R Turbo R - + Autofire Start Turbo Start - + Autofire Select Turbo Select - + Autofire Up Turbo Góra - + Autofire Right Turbo Prawo - + Autofire Down Turbo Dół - + Autofire Left Turbo Lewo - + Clear Wyczyść @@ -6771,17 +6775,17 @@ Rozmiar pobierania: %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu Menu @@ -6789,22 +6793,22 @@ Rozmiar pobierania: %3 QShortcut - + Shift Shift - + Control Control - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-pt_BR.ts b/src/platform/qt/ts/mgba-pt_BR.ts index 77573eb1b..5b8c0df52 100644 --- a/src/platform/qt/ts/mgba-pt_BR.ts +++ b/src/platform/qt/ts/mgba-pt_BR.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ROMs do Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMs do Game Boy (%1) - + All ROMs (%1) Todas as ROMs (%1) - + %1 Video Logs (*.mvl) %1 Registros do Vídeo (*.mvl) @@ -191,17 +191,17 @@ Tamanho do download: %3 QGBA::AudioDevice - + Can't set format of context-less audio device Não pôde definir o formato do dispositivo de áudio sem contexto - + Audio device is missing its core O núcleo do dispositivo de áudio está ausente - + Writing data to read-only audio device Gravando dados no dispositivo somente-leitura do áudio @@ -209,7 +209,7 @@ Tamanho do download: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input Não pôde iniciar um processador de áudio sem entrada @@ -285,28 +285,28 @@ Tamanho do download: %3 Mostrar as opções avançadas - + BattleChip data missing Dados do BattleChip ausentes - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? Os dados do BattleChip estão ausente. Os Portais do BattleChip Gates ainda funcionarão mas alguns gráficos estarão ausentes. Você gostaria de baixar os dados agora? - - + + Select deck file Selecionar o arquivo do deck - + Incompatible deck Deck incompatível - + The selected deck is not compatible with this Chip Gate O deck selecionado não é compatível com este Portal do Chip @@ -367,19 +367,19 @@ Tamanho do download: %3 Insira os códigos aqui... - - + + Autodetect (recommended) Auto-detectar (recomendado) - - + + Select cheats file Selecionar o arquivo das trapaças - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Algumas trapaças não puderam ser adicionadas. Por favor tenha certeza que eles estão formatadas corretamente e/ou tente outros tipos de trapaça. @@ -398,37 +398,37 @@ Tamanho do download: %3 O rebobinamento não está ativado atualmente - + Reset the game? Resetar o jogo? - + Most games will require a reset to load the new save. Do you want to reset now? A maioria dos jogos requerirão um reset pra carregar o novo save. Você quer resetar agora? - + Failed to open save file: %1 Falhou em abrir o arquivo do save: %1 - + Failed to open game file: %1 Falhou em abrir o arquivo do jogo: %1 - + Can't yank pack in unexpected platform! Não pode arrancar o pacote numa plataforma inesperada! - + Failed to open snapshot file for reading: %1 Falhou em abrir o arquivo do snapshot pra leitura: %1 - + Failed to open snapshot file for writing: %1 Falhou em abrir o arquivo do snapshot pra gravação: %1 @@ -477,6 +477,14 @@ Tamanho do download: %3 Não pôde abrir o histórico do CLI pra gravar + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Tamanho do download: %3 Resetar - + Export frame Exportar frame - + Portable Network Graphics (*.png) Gráficos Portáteis da Rede (*.png) - + None Nenhum - + Background 2º plano - + Window Janela - + Objwin Objwin - + Sprite Imagem Móvel - + Backdrop 2º Plano - + Frame Frame - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Tamanho do download: %3 QGBA::GBAKeyEditor - + Clear Button Limpar Botão - + Clear Analog Limpar Analógico - + Refresh Atualizar - + Set all Definir todos @@ -3006,8 +3014,8 @@ Tamanho do download: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Tamanho do download: %3 Vertical - - - + + + N/A N/D - + Export map Exportar mapa - + Portable Network Graphics (*.png) Gráficos Portáteis da Rede (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Explorar + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + Parar + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Tamanho do download: %3 Atualizar - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3750,17 +3822,17 @@ Tamanho do download: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached Tentando desconectar um jogador multiplayer que não está conectado - + Trying to get player ID for a multiplayer player that's not attached Tentando obter a ID do jogador pra um jogador multiplayer que não está conectado - + Trying to get save ID for a multiplayer player that's not attached Tentando obter a ID salva pra um jogador multiplayer que não está conectado @@ -4157,35 +4229,35 @@ Tamanho do download: %3 Exportar OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Exportar paleta - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Tabela de Cores da Adobe (*.act) - + Failed to open output palette file: %1 Falhou em abrir o arquivo de saída da paleta: %1 @@ -4259,7 +4331,7 @@ Tamanho do download: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Tamanho do download: %3 + Maker Code: + + + + + Revision: + + + + File size: Tamanho do arquivo: - + CRC32: CRC32: - + Save file: Arquivo do save: @@ -4364,62 +4446,62 @@ Tamanho do download: %3 QGBA::SaveConverter - + Save games and save states (%1) Saves dos jogos e save states (%1) - + Select save game or save state Selecione o save do jogo ou save state - + Save games (%1) Saves dos jogos (%1) - + Select save game Selecione o save do jogo - + Conversion failed A conversão falhou - + Failed to convert the save game. This is probably a bug. Falhou em converter o save do jogo. Isto é provavelmente um bug. - + No file selected Nenhum arquivo selecionado - + Could not open file Não pôde abrir o arquivo - + No valid formats found Não foram encontrados formatos válidos - + Please select a valid input file Por favor selecione um arquivo de entrada válido - + No valid conversions found Não foram encontradas conversões válidas - + Cannot convert save games between platforms Não pôde converter os saves do jogo entre as plataformas @@ -4445,97 +4527,97 @@ Tamanho do download: %3 Arquivo de saída - + %1 %2 save game %1 %2 save do jogo - + little endian little endian - + big endian big endian - + SRAM SRAM - + %1 flash %1 flash - + %1 EEPROM %1 EEPROM - + + RTC + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 Empacotou o MBC2 - + unpacked MBC2 Desempacotou o MBC2 - + MBC6 flash Flash do MBC6 - + MBC6 combined SRAM + flash MBC6 SRAM combinado + flash - + MBC6 SRAM SRAM do MBC6 - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game %1 save state com %2 saves do jogo embutido - + %1 SharkPort %2 save game %1 SharkPort %2 save do jogo - + %1 GameShark Advance SP %2 save game %1 GameShark Advance SP %2 save do jogo @@ -4571,32 +4653,37 @@ Tamanho do download: %3 Carregar script recente - + Load script... Carregar script... - + + &Load most recent + + + + &Reset &Resetar - + 0 0 - + Select script to load Selecione o script a carregar - + Lua scripts (*.lua) Scripts do lua (*.lua) - + All files (*.*) Todos os arquivos (*.*) @@ -4689,119 +4776,117 @@ Tamanho do download: %3 QGBA::SettingsView - - + + Qt Multimedia Multimídia do Qt - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (forçar a versão 1.x) - + None Nenhum - + None (Still Image) Nenhum (Imagem Parada) - + Keyboard Teclado - + Controllers Controles - + Shortcuts Atalhos - - + + Shaders Shaders - + Select BIOS Selecionar BIOS - + Select directory Selecione o diretório - + Select image Selecionar imagem - + Image file (*.png *.jpg *.jpeg) Arquivo da imagem (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never Nunca - + Just now Aconteceu agora - + Less than an hour ago Menos do que uma hora atrás - + %n hour(s) ago %n hora atrás %n horas atrás - - + %n day(s) ago %n dia atrás %n dias atrás - @@ -5139,37 +5224,37 @@ Tamanho do download: %3 Velocidade do retrocesso: - + Default color palette only Só a cor padrão da paleta - + SGB color palette if available Paleta das cores do SGB se disponível - + GBC color palette if available Paleta das cores do GBC se disponível - + SGB (preferred) or GBC color palette if available SGB (preferido) ou paleta das cores do GBC se disponível - + Game Boy Camera Câmera do Game Boy - + Driver: Driver: - + Source: Fonte: @@ -5215,7 +5300,7 @@ Tamanho do download: %3 Ativar compatibilidade dos bugs do VBA nos hacks das ROMs - + Preset: Pré-definições: @@ -5230,22 +5315,22 @@ Tamanho do download: %3 Velocidade do avanço rápido (pressionado): - + (240×160) (240×160) - + Log to file Registrar no arquivo - + Log to console Registrar no console - + Select Log File Selecionar Arquivo do Registro @@ -5383,61 +5468,56 @@ Tamanho do download: %3 Software - + OpenGL enhancements Melhorias do OpenGL - + High-resolution scale: Escala de alta-resolução: - - XQ GBA audio (experimental) - Ãudio do XQ GBA (experimental) - - - + GB BIOS file: Arquivo da BIOS do GB: - - - - - - - - - + + + + + + + + + Browse Explorar - + Use BIOS file if found Usar o arquivo da BIOS se encontrado - + Skip BIOS intro Ignorar a introdução da BIOS - + GBA BIOS file: Arquivo da BIOS do GBA: - + GBC BIOS file: Arquivo da BIOS do GBC: - + SGB BIOS file: Arquivo da BIOS do SGB: @@ -5447,91 +5527,91 @@ Tamanho do download: %3 Auto-salvar o state periodicamente - + Save games Saves dos jogos - - - - - + + + + + Same directory as the ROM O mesmo diretório que a ROM - + Save states Save states - + Screenshots Screenshots - + Patches Patches - + Cheats Trapaças - + Models Modelos - + GB only: Só pro GB: - + SGB compatible: Compatível com o SGB: - + GBC only: Só pro GBC: - + GBC compatible: Compatível com o GBC: - + SGB and GBC compatible: Compatível com o SGB e o GBC: - + Game Boy palette Paleta do Game Boy - + Default BG colors: Cores padrão do 2º plano: - + Super Game Boy borders Bordas do Super Game Boy - + Default sprite colors 1: Cores padrão da imagem móvel 1: - + Default sprite colors 2: Cores padrão da imagem móvel 2: @@ -5779,7 +5859,6 @@ Tamanho do download: %3 - WebM WebM @@ -5788,19 +5867,8 @@ Tamanho do download: %3 Format Formato - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 @@ -5844,72 +5912,6 @@ Tamanho do download: %3 &Native &Nativo - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Nenhum - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Descomprimido - Bitrate (kbps) @@ -5920,16 +5922,6 @@ Tamanho do download: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5959,80 +5951,80 @@ Tamanho do download: %3 QGBA::Window - + Archives (%1) Arquivos Compactados (%1) - - + + Select ROM Selecionar ROM - + Select folder Selecionar pasta - - + + Select save Selecionar save - + Select patch Selecionar patch - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode Selecionar dotcode do e-Reader - + e-Reader card (*.raw *.bin *.bmp) Cartão do e-Reader (*.raw *.bin *.bmp) - + Select image Selecionar imagem - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Arquivo de imagem (*.png *.gif *.jpg *.jpeg);;Todos os arquivos (*) - + GameShark saves (*.sps *.xps) Saves do GameShark (*.sps *.xps) - + Select video log Selecionar registro do vídeo - + Video logs (*.mvl) Registros do vídeo (*.mvl) - + Crash Crash - + The game has crashed with the following error: %1 @@ -6041,699 +6033,709 @@ Tamanho do download: %3 %1 - + Unimplemented BIOS call Chamada da BIOS não implementada - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Este jogo usa uma chamada de BIOS que não está implementada. Por favor use a BIOS oficial pra uma melhor experiência. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Falhou em criar um dispositivo de exibição apropriado, voltando a exibição por software. Os jogos podem executar lentamente, especialmente com janelas maiores. - + Really make portable? Realmente tornar portátil? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Isto fará o emulador carregar sua configuração do mesmo diretório que o executável. Você quer continuar? - + Restart needed Reiniciar é necessário - + Some changes will not take effect until the emulator is restarted. Algumas mudanças não terão efeito até o emulador ser reiniciado. - + - Player %1 of %2 - Jogador %1 de %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &Arquivo - + Load &ROM... Carregar &ROM... - + Load ROM in archive... Carregar ROM no arquivo compactado... - + Add folder to library... Adicionar pasta a biblioteca... - + Save games Saves dos jogos - + Automatically determine Determinar automaticamente - + Use player %0 save game Usar o save do jogo %0 do jogador - + Load &patch... Carregar &patch... - + Boot BIOS Dar Boot na BIOS - + Replace ROM... Substituir a ROM... - + ROM &info... Informações da &ROM... - + Recent Recentes - + Make portable Tornar portátil - + &Load state &Carregar state - + Report bug... Reportar bug... - + About... Sobre... - + Game Pak sensors... Sensores do Game Pak... - + Clear Limpar - + Load state file... Carregar arquivo do state... - + Save games (%1) Saves dos jogos (%1) - + Select save game Selecione save do jogo - + mGBA save state files (%1) Arquivos do save state do mGBA (%1) - - + + Select save state Selecione um save state - + Select e-Reader card images Selecionar imagens do cartão do e-Reader - + Image file (*.png *.jpg *.jpeg) Arquivo da imagem (*.png *.jpg *.jpeg) - + Conversion finished Conversão concluída - + %1 of %2 e-Reader cards converted successfully. %1 de %2 cartões do e-Reader convertidos com sucesso. - + Load alternate save game... Carregar save alternativo do jogo... - + Load temporary save game... Carregar save temporário do jogo... - + Convert e-Reader card image to raw... Converter imagem do cartão do e-Reader pro natural... - + &Save state &Salvar o state - + Save state file... Arquivo do save state... - + Quick load Carregamento rápido - + Quick save Salvamento rápido - + Load recent Carregar recentes - + Save recent Salvar recentes - + Undo load state Desfazer o carregamento do state - + Undo save state Desfazer o save state - - + + State &%1 State &%1 - + Load camera image... Carregar a imagem da câmera... - + Convert save game... Converter o save do jogo... - + GameShark saves (*.gsv *.sps *.xps) Saves do GameShark (*.gsv *.sps *.xps) - + Reset needed É necessário resetar - + Some changes will not take effect until the game is reset. Algumas mudanças não terão efeito até o jogo ser resetado. - + New multiplayer window Nova janela multi-jogador - + Connect to Dolphin... Conectar ao Dolphin... - + E&xit S&air - + &Emulation &Emulação - + &Reset &Resetar - + Sh&utdown De&sligar - + Yank game pak Arrancar o game pak - + &Pause &Pausar - + &Next frame &Próximo frame - + Fast forward (held) Avanço rápido (segurado) - + &Fast forward &Avanço rápido - + Fast forward speed Velocidade do avanço rápido - + Unbounded Ilimitado - + %0x %0x - + Increase fast forward speed Aumentar a velocidade do avanço rápido - + Decrease fast forward speed Diminuir a velocidade do avanço rápido - + Rewind (held) Retroceder (segurado) - + Re&wind Re&troceder - + Step backwards Voltar um passo - + Solar sensor Sensor solar - + Increase solar level Aumentar nível solar - + Decrease solar level Diminuir nível solar - + Brightest solar level Nível solar mais brilhante - + Darkest solar level Nível solar mais escuro - + Brightness %1 Brilho %1 - + Audio/&Video Ãudio/&Vídeo - + Frame size Tamanho do frame - + Toggle fullscreen Alternar tela cheia - + + &Lock frame size + + + + Lock aspect ratio Travar a proporção do aspecto - + Force integer scaling Forçar o dimensionamento do inteiro - + Bilinear filtering Filtragem bilinear - + Frame&skip Frame&skip - + Mute Mudo - + FPS target FPS alvo - + Native (59.7275) Nativo (59,7275) - + Take &screenshot Tirar &screenshot - + F12 F12 - + Game Boy Printer... Impressora do Game Boy... - + BattleChip Gate... Portal do BattleChip... - + %1× %1× - + Interframe blending Mistura do interframe - + Record A/V... Gravar A/V... - + Video layers Camadas do vídeo - + Audio channels Canais de áudio - + Adjust layer placement... Ajustar posicionamento da camada... - + &Tools &Ferramentas - + View &logs... Visualizar &registros... - + Game &overrides... Substituições &do jogo... - + Couldn't Start Não Pôde Iniciar - + Could not start game. Não pôde iniciar o jogo. - + Scan e-Reader dotcodes... Escanear dotcodes do e-Reader... - + Import GameShark Save... Importar Save do GameShark... - + Export GameShark Save... Exportar Save do GameShark... - + Record GIF/WebP/APNG... Gravar GIF/WebP/APNG... - + &Cheats... &Trapaças... - + Settings... Configurações... - + Open debugger console... Abrir console do debugger... - + Start &GDB server... Iniciar servidor do &GDB... - + Scripting... Scripting... - + Create forwarder... Criar encaminhador... - + Game state views Visualizações do estado do jogo - + View &palette... Visualizar &paleta... - + View &sprites... Visualizar &imagens móveis... - + View &tiles... Visualizar &mosaicos... - + View &map... Visualizar &mapa... - + &Frame inspector... Inspetor dos &frames... - + View memory... Visualizar memória... - + Search memory... Procurar na memória... - + View &I/O registers... Visualizar registros de &E/S... - + + Log memory &accesses... + + + + Record debug video log... Gravar registro do vídeo de debug... - + Stop debug video log Parar o registro do vídeo de debug - + Exit fullscreen Sair da tela cheia - + GameShark Button (held) Botão do GameShark (segurado) - + Autofire Auto-disparar - + Autofire A Auto-disparar A - + Autofire B Auto-disparar B - + Autofire L Auto-disparar L - + Autofire R Auto-disparar R - + Autofire Start Auto-disparar Start - + Autofire Select Auto-disparar Select - + Autofire Up Auto-disparar Pra Cima - + Autofire Right Auto-disparar Direita - + Autofire Down Auto-disparar Pra Baixo - + Autofire Left Auto-disparar Esquerda @@ -6771,17 +6773,17 @@ Tamanho do download: %3 ? - + Super (L) Super (E) - + Super (R) Super (D) - + Menu Menu @@ -6789,22 +6791,22 @@ Tamanho do download: %3 QShortcut - + Shift Shift - + Control Control - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-pt_PT.ts b/src/platform/qt/ts/mgba-pt_PT.ts index f3aa6bdc1..f6c819d37 100644 --- a/src/platform/qt/ts/mgba-pt_PT.ts +++ b/src/platform/qt/ts/mgba-pt_PT.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) ROMs do Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMs do Game Boy (%1) - + All ROMs (%1) Todas as ROMs (%1) - + %1 Video Logs (*.mvl) %1 Registos do Vídeo (*.mvl) @@ -191,17 +191,17 @@ Tamanho da descarga: %3 QGBA::AudioDevice - + Can't set format of context-less audio device Não pôde definir o formato do aparelho de áudio sem contexto - + Audio device is missing its core O núcleo do aparelho de áudio está ausente - + Writing data to read-only audio device Gravando dados no aparelho somente-leitura do áudio @@ -209,7 +209,7 @@ Tamanho da descarga: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input Não pôde iniciar um processador de áudio sem entrada @@ -285,28 +285,28 @@ Tamanho da descarga: %3 Mostrar as opções avançadas - + BattleChip data missing Portal do BattleChip - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? Os dados do BattleChip estão ausentes. O BattleChip Gates ainda funcionará, mas alguns gráficos estarão ausentes. Gostaria de descarregar os dados agora? - - + + Select deck file Selecionar o ficheiro do deck - + Incompatible deck Deck incompatível - + The selected deck is not compatible with this Chip Gate O deck selecionado não é compatível com este Portal do Chip @@ -367,19 +367,19 @@ Tamanho da descarga: %3 Insira os códigos aqui... - - + + Autodetect (recommended) Auto-detetar (recomendado) - - + + Select cheats file Selecionar o ficheiro das trapaças - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Algumas trapaças não puderam ser adicionadas. Por favor tenha certeza que eles estão formatadas corretamente e/ou tente outros tipos de trapaça. @@ -398,37 +398,37 @@ Tamanho da descarga: %3 O rebobinamento não está ativado atualmente - + Reset the game? Resetar o jogo? - + Most games will require a reset to load the new save. Do you want to reset now? A maioria dos jogos requerirão um reset para carregar o novo save. Quer resetar agora? - + Failed to open save file: %1 Falha ao abrir o ficheiro dde gravação: %1 - + Failed to open game file: %1 Falha ao abrir o ficheiro do jogo: %1 - + Can't yank pack in unexpected platform! Não pode arrancar o pacote numa plataforma inesperada! - + Failed to open snapshot file for reading: %1 Falha ao abrir o ficheiro do snapshot para leitura: %1 - + Failed to open snapshot file for writing: %1 Falha ao abrir o ficheiro do snapshot para gravação: %1 @@ -477,6 +477,14 @@ Tamanho da descarga: %3 Não pôde abrir o histórico do CLI para gravar + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Tamanho da descarga: %3 Resetar - + Export frame Exportar frame - + Portable Network Graphics (*.png) Gráficos Portáteis da Rede (*.png) - + None Nenhum - + Background 2º plano - + Window Janela - + Objwin Objwin - + Sprite Imagem Móvel - + Backdrop 2º Plano - + Frame Frame - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Tamanho da descarga: %3 QGBA::GBAKeyEditor - + Clear Button Limpar Botão - + Clear Analog Limpar Analógico - + Refresh Atualizar - + Set all Definir todos @@ -3006,8 +3014,8 @@ Tamanho da descarga: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Tamanho da descarga: %3 Vertical - - - + + + N/A N/D - + Export map Exportar mapa - + Portable Network Graphics (*.png) Gráficos Portáteis da Rede (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Explorar + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + Parar + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Tamanho da descarga: %3 Atualizar - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 byte%2 @@ -3750,17 +3822,17 @@ Tamanho da descarga: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached A tentar desconectar um jogador multiplayer que não está conectado - + Trying to get player ID for a multiplayer player that's not attached A tentar obter a ID do jogador para um jogador multiplayer que não está conectado - + Trying to get save ID for a multiplayer player that's not attached A tentar obter a ID gravada para um jogador multiplayer que não está conectado @@ -4157,35 +4229,35 @@ Tamanho da descarga: %3 Exportar OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette Exportar paleta - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Tabela de Cores da Adobe (*.act) - + Failed to open output palette file: %1 Falha ao abrir o ficheiro de saída da paleta: %1 @@ -4259,7 +4331,7 @@ Tamanho da descarga: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Tamanho da descarga: %3 + Maker Code: + + + + + Revision: + + + + File size: Tamanho do ficheiro: - + CRC32: CRC32: - + Save file: Ficheiro do save: @@ -4364,62 +4446,62 @@ Tamanho da descarga: %3 QGBA::SaveConverter - + Save games and save states (%1) Saves dos jogos e save states (%1) - + Select save game or save state Selecione o save do jogo ou save state - + Save games (%1) Saves dos jogos (%1) - + Select save game Selecione o save do jogo - + Conversion failed A conversão falhou - + Failed to convert the save game. This is probably a bug. Falhou em converter o save do jogo. Isto é provavelmente um bug. - + No file selected Nenhum ficheiro selecionado - + Could not open file Não pôde abrir o ficheiro - + No valid formats found Não foram encontrados formatos válidos - + Please select a valid input file Por favor selecione um ficheiro de entrada válido - + No valid conversions found Não foram encontradas conversões válidas - + Cannot convert save games between platforms Não pôde converter os saves do jogo entre as plataformas @@ -4445,97 +4527,97 @@ Tamanho da descarga: %3 Ficheiro de saída - + %1 %2 save game %1 %2 save do jogo - + little endian little endian - + big endian big endian - + SRAM SRAM - + %1 flash %1 flash - + %1 EEPROM %1 EEPROM - + + RTC + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 empacotou o MBC2 - + unpacked MBC2 desempacotou o MBC2 - + MBC6 flash Flash do MBC6 - + MBC6 combined SRAM + flash MBC6 SRAM combinado + flash - + MBC6 SRAM SRAM do MBC6 - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game %1 save state com %2 saves do jogo embutido - + %1 SharkPort %2 save game %1 SharkPort %2 save do jogo - + %1 GameShark Advance SP %2 save game %1 GameShark Advance SP %2 save do jogo @@ -4571,32 +4653,37 @@ Tamanho da descarga: %3 Carregar script recente - + Load script... Carregar script... - + + &Load most recent + + + + &Reset &Resetar - + 0 0 - + Select script to load Selecione o script a carregar - + Lua scripts (*.lua) Scripts do lua (*.lua) - + All files (*.*) Todos os ficheiros (*.*) @@ -4689,119 +4776,117 @@ Tamanho da descarga: %3 QGBA::SettingsView - - + + Qt Multimedia Multimídia do Qt - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (forçar a versão 1.x) - + None Nenhum - + None (Still Image) Nenhum (Imagem Parada) - + Keyboard Teclado - + Controllers Controles - + Shortcuts Atalhos - - + + Shaders Shaders - + Select BIOS Selecionar BIOS - + Select directory Selecione o diretório - + Select image Selecionar imagem - + Image file (*.png *.jpg *.jpeg) Ficheiro da imagem (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never Nunca - + Just now Aconteceu agora - + Less than an hour ago Menos do que uma hora atrás - + %n hour(s) ago %n hora atrás %n horas atrás - %n horas atrás - + %n day(s) ago %n dia atrás %n dias atrás - %n dias atrás @@ -5124,37 +5209,37 @@ Tamanho da descarga: %3 Verificar agora - + Default color palette only Só a cor padrão da paleta - + SGB color palette if available Paleta das cores do SGB se disponível - + GBC color palette if available Paleta das cores do GBC se disponível - + SGB (preferred) or GBC color palette if available SGB (preferido) ou paleta das cores do GBC se disponível - + Game Boy Camera Câmara do Game Boy - + Driver: Driver: - + Source: Fonte: @@ -5331,42 +5416,42 @@ Tamanho da descarga: %3 Carregar dados extras do state: - + Models Modelos - + GB only: Só para o GB: - + SGB compatible: Compatível com o SGB: - + GBC only: Só para o GBC: - + GBC compatible: Compatível com o GBC: - + SGB and GBC compatible: Compatível com o SGB e o GBC: - + Game Boy palette Paleta do Game Boy - + Preset: Pré-definições: @@ -5403,135 +5488,130 @@ Tamanho da descarga: %3 Software - + OpenGL enhancements Melhorias do OpenGL - + High-resolution scale: Escala de alta-resolução: - + (240×160) (240×160) - - XQ GBA audio (experimental) - Ãudio do XQ GBA (experimental) - - - + GB BIOS file: Ficheiro da BIOS do GB: - - - - - - - - - + + + + + + + + + Browse Explorar - + Use BIOS file if found Usar o ficheiro da BIOS se encontrado - + Skip BIOS intro Ignorar a introdução da BIOS - + GBA BIOS file: Ficheiro da BIOS do GBA: - + GBC BIOS file: Ficheiro da BIOS do GBC: - + SGB BIOS file: Ficheiro da BIOS do SGB: - + Save games Saves dos jogos - - - - - + + + + + Same directory as the ROM O mesmo diretório que a ROM - + Save states Save states - + Screenshots Screenshots - + Patches Patches - + Cheats Trapaças - + Log to file Registar ao ficheiro - + Log to console Registar à console - + Select Log File Selecionar Ficheiro de Registo - + Default BG colors: Cores padrão do 2º plano: - + Default sprite colors 1: Cores padrão da imagem móvel 1: - + Default sprite colors 2: Cores padrão da imagem móvel 2: - + Super Game Boy borders Bordas do Super Game Boy @@ -5789,13 +5869,11 @@ Tamanho da descarga: %3 - WebM WebM - MP4 MP4 @@ -5834,82 +5912,6 @@ Tamanho da descarga: %3 Format Formato - - - MKV - MKV - - - - AVI - AVI - - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Nenhum - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - Descomprimido - Bitrate (kbps) @@ -5920,16 +5922,6 @@ Tamanho da descarga: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5959,80 +5951,80 @@ Tamanho da descarga: %3 QGBA::Window - + Archives (%1) Ficheiros Compactados (%1) - - + + Select ROM Selecionar ROM - + Select folder Selecionar pasta - - + + Select save Selecionar save - + Select patch Selecionar patch - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode Selecionar dotcode do e-Reader - + e-Reader card (*.raw *.bin *.bmp) Cartão do e-Reader (*.raw *.bin *.bmp) - + Select image Selecionar imagem - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Ficheiro de imagem (*.png *.gif *.jpg *.jpeg);;Todos os ficheiros (*) - + GameShark saves (*.sps *.xps) Saves do GameShark (*.sps *.xps) - + Select video log Selecionar registo do vídeo - + Video logs (*.mvl) Registos do vídeo (*.mvl) - + Crash Crash - + The game has crashed with the following error: %1 @@ -6041,699 +6033,709 @@ Tamanho da descarga: %3 %1 - + Couldn't Start Não Pôde Iniciar - + Could not start game. Não pôde iniciar o jogo. - + Unimplemented BIOS call Chamada da BIOS não implementada - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Este jogo usa uma chamada de BIOS que não está implementada. Por favor use a BIOS oficial para uma melhor experiência. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Falhou em criar um aparelho de exibição apropriado, voltando a exibição por software. Os jogos podem executar lentamente, especialmente com janelas maiores. - + Really make portable? Realmente tornar portátil? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Isto fará o emulador carregar a configuração dele do mesmo diretório que o executável. Quer continuar? - + Restart needed Reiniciar é necessário - + Some changes will not take effect until the emulator is restarted. Algumas mudanças não terão efeito até o emulador ser reiniciado. - + - Player %1 of %2 - Jogador %1 de %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &Ficheiro - + Load &ROM... Carregar &ROM... - + Load ROM in archive... Carregar ROM no arquivo... - + Add folder to library... Adicionar pasta a biblioteca... - + Save games (%1) Saves dos jogos (%1) - + Select save game Selecione save do jogo - + mGBA save state files (%1) Ficheiro do save state do mGBA (%1) - - + + Select save state Selecione um save state - + Select e-Reader card images Selecionar imagens do cartão do e-Reader - + Image file (*.png *.jpg *.jpeg) Ficheiro da imagem (*.png *.jpg *.jpeg) - + Conversion finished Conversão concluída - + %1 of %2 e-Reader cards converted successfully. %1 de %2 cartões do e-Reader convertidos com sucesso. - + Load alternate save game... Carregar save alternativo do jogo... - + Load temporary save game... Carregar save temporário do jogo... - + Load &patch... Carregar &patch... - + Boot BIOS Dar Boot na BIOS - + Replace ROM... Substituir a ROM... - + Scan e-Reader dotcodes... Escanear dotcodes do e-Reader... - + Convert e-Reader card image to raw... Converter imagem do cartão do e-Reader para natural... - + ROM &info... Informações da &ROM... - + Recent Recentes - + Make portable Tornar portátil - + &Load state &Carregar state - + Load state file... Carregar ficheiro do state... - + &Save state &Gravar o state - + Save state file... Ficheiro do save state... - + Quick load Carregamento rápido - + Quick save Salvamento rápido - + Load recent Carregar recentes - + Save recent Gravar recentes - + Undo load state Desfazer o carregamento do state - + Undo save state Desfazer o save state - - + + State &%1 State &%1 - + Load camera image... Carregar a imagem da câmara... - + Convert save game... Converter o save do jogo... - + GameShark saves (*.gsv *.sps *.xps) Saves do GameShark (*.gsv *.sps *.xps) - + Reset needed É necessário resetar - + Some changes will not take effect until the game is reset. Algumas mudanças não terão efeito até o jogo ser resetado. - + Save games Saves dos jogos - + Import GameShark Save... Importar Save do GameShark... - + Export GameShark Save... Exportar Save do GameShark... - + Automatically determine Determinar automaticamente - + Use player %0 save game Usar o save do jogo %0 do jogador - + New multiplayer window Nova janela multi-jogador - + Connect to Dolphin... Conectar ao Dolphin... - + Report bug... Reportar bug... - + About... Sobre... - + E&xit S&air - + &Emulation &Emulação - + &Reset &Resetar - + Sh&utdown De&sligar - + Yank game pak Arrancar o game pak - + &Pause &Pausar - + &Next frame &Próximo frame - + Fast forward (held) Avanço rápido (segurado) - + &Fast forward &Avanço rápido - + Fast forward speed Velocidade do avanço rápido - + Unbounded Ilimitado - + %0x %0x - + Increase fast forward speed Aumentar a velocidade do avanço rápido - + Decrease fast forward speed Diminuir a velocidade do avanço rápido - + Rewind (held) Retroceder (segurado) - + Re&wind Re&troceder - + Step backwards Voltar um passo - + Solar sensor Sensor solar - + Increase solar level Aumentar nível solar - + Decrease solar level Diminuir nível solar - + Brightest solar level Nível solar mais brilhante - + Darkest solar level Nível solar mais escuro - + Brightness %1 Brilho %1 - + Game Boy Printer... Impressora do Game Boy... - + BattleChip Gate... Portal do BattleChip... - + Audio/&Video Ãudio/&Vídeo - + Frame size Tamanho do frame - + %1× %1× - + Toggle fullscreen Alternar ecrã inteiro - + + &Lock frame size + + + + Lock aspect ratio Travar a proporção do aspeto - + Force integer scaling Forçar o dimensionamento do inteiro - + Interframe blending Mistura do interframe - + Bilinear filtering Filtragem bilinear - + Frame&skip Frame&skip - + Mute Mudo - + FPS target FPS alvo - + Native (59.7275) Nativo (59,7275) - + Take &screenshot Tirar &screenshot - + F12 F12 - + Record A/V... Gravar A/V... - + Record GIF/WebP/APNG... Gravar GIF/WebP/APNG... - + Video layers Camadas do vídeo - + Audio channels Canais de áudio - + Adjust layer placement... Ajustar posicionamento da camada... - + &Tools &Ferramentas - + View &logs... Visualizar &registos... - + Game &overrides... Substituições &do jogo... - + Game Pak sensors... Sensores do Game Pak... - + &Cheats... &Trapaças... - + Create forwarder... Criar encaminhador... - + Settings... Configurações... - + Open debugger console... Abrir console do debugger... - + Start &GDB server... Iniciar servidor do &GDB... - + Scripting... Scripting... - + Game state views Visualizações do estado do jogo - + View &palette... Visualizar &paleta... - + View &sprites... Visualizar &imagens móveis... - + View &tiles... Visualizar &ladrilhos... - + View &map... Visualizar &mapa... - + &Frame inspector... Inspetor dos &frames... - + View memory... Visualizar memória... - + Search memory... Procurar na memória... - + View &I/O registers... Visualizar registos de &E/S... - + + Log memory &accesses... + + + + Record debug video log... Gravar registo do vídeo de debug... - + Stop debug video log Parar o registo do vídeo de debug - + Exit fullscreen Sair do ecrã inteiro - + GameShark Button (held) Botão do GameShark (segurado) - + Autofire Auto-disparar - + Autofire A Auto-disparar A - + Autofire B Auto-disparar B - + Autofire L Auto-disparar L - + Autofire R Auto-disparar R - + Autofire Start Auto-disparar Start - + Autofire Select Auto-disparar Select - + Autofire Up Auto-disparar Para Cima - + Autofire Right Auto-disparar Direita - + Autofire Down Auto-disparar Para Baixo - + Autofire Left Auto-disparar Esquerda - + Clear Limpar @@ -6771,17 +6773,17 @@ Tamanho da descarga: %3 ? - + Super (L) Super (E) - + Super (R) Super (D) - + Menu Menu @@ -6789,22 +6791,22 @@ Tamanho da descarga: %3 QShortcut - + Shift Shift - + Control Control - + Alt Alt - + Meta Meta diff --git a/src/platform/qt/ts/mgba-ru.ts b/src/platform/qt/ts/mgba-ru.ts index 574a66861..5f130f18e 100644 --- a/src/platform/qt/ts/mgba-ru.ts +++ b/src/platform/qt/ts/mgba-ru.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) Игры Game Boy Advance (%1) - + Game Boy ROMs (%1) Игры Game Boy (%1) - + All ROMs (%1) Ð’Ñе игры (%1) - + %1 Video Logs (*.mvl) Журналы видео %1 (*.mvl) @@ -191,17 +191,17 @@ Download size: %3 QGBA::AudioDevice - + Can't set format of context-less audio device Ðевозможно уÑтановить формат Ð´Ð»Ñ Ð°ÑƒÐ´Ð¸Ð¾ÑƒÑтройÑтва без контекÑта - + Audio device is missing its core ОтÑутÑтвует Ñдро аудиоуÑтройÑтва - + Writing data to read-only audio device ЗапиÑÑŒ данных в аудиоуÑтройÑтво только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ @@ -209,7 +209,7 @@ Download size: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input Ðевозможно запуÑтить аудиопроцеÑÑор без входных данных @@ -285,28 +285,28 @@ Download size: %3 РаÑширенные наÑтройки - + BattleChip data missing ОтÑутÑтвуют данные BattleChip - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? ОтÑутÑтвуют данные BattleChip. BattleChip Gates будут работать, но чаÑÑ‚ÑŒ графики будет отÑутÑтвовать. Скачать данные ÑейчаÑ? - - + + Select deck file Выберите файл колоды - + Incompatible deck Колода неÑовмеÑтима - + The selected deck is not compatible with this Chip Gate Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ ÐºÐ¾Ð»Ð¾Ð´Ð° неÑовмеÑтима Ñ Ñтим Chip Gate @@ -367,19 +367,19 @@ Download size: %3 Введите Ñвои читкоды Ñюда... - - + + Autodetect (recommended) Ðвтоопределение (рекомендовано) - - + + Select cheats file Выберите файл Ñ Ñ‡Ð¸Ñ‚-кодами - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Ðекоторые читы не были добавлены. УбедитеÑÑŒ, что они правильного формата, и/или измените тип чита. @@ -398,37 +398,37 @@ Download size: %3 ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼Ð¾Ñ‚ÐºÐ° выключена - + Reset the game? Перезагрузить игру? - + Most games will require a reset to load the new save. Do you want to reset now? БольшинÑтву игр нужна перезагрузка, чтобы загрузить новое Ñохранение. Перезагрузить ÑейчаÑ? - + Failed to open save file: %1 Ðе удалоÑÑŒ открыть файл ÑохранениÑ: %1 - + Failed to open game file: %1 Ðе удалоÑÑŒ открыть файл игры: %1 - + Can't yank pack in unexpected platform! Ðевозможно пнуть картридж на неожиданной платформе! - + Failed to open snapshot file for reading: %1 Ðе удалоÑÑŒ открыть файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑчитываниÑ: %1 - + Failed to open snapshot file for writing: %1 Ðе удалоÑÑŒ открыть файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи: %1 @@ -477,6 +477,14 @@ Download size: %3 Ðе удалоÑÑŒ открыть иÑторию CLI на запиÑÑŒ + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Download size: %3 Ð¡Ð±Ñ€Ð¾Ñ - + Export frame ЭкÑпорт кадра - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Ðет - + Background Фон - + Window Окно - + Objwin Objwin - + Sprite Спрайт - + Backdrop Подложка - + Frame Кадр - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Download size: %3 QGBA::GBAKeyEditor - + Clear Button Ð¡Ð±Ñ€Ð¾Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ - + Clear Analog Ð¡Ð±Ñ€Ð¾Ñ Ð°Ð½Ð°Ð»Ð¾Ð³Ð° - + Refresh Обновить - + Set all Ðазначить вÑе @@ -3006,8 +3014,8 @@ Download size: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Download size: %3 Вертикально - - - + + + N/A Ð/Д - + Export map ЭкÑпорт карты - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Открыть + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Download size: %3 Обновить - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 @@ -3750,17 +3822,17 @@ Download size: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4157,35 +4229,35 @@ Download size: %3 ЭкÑпорт OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette ЭкÑпорт палитры - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 Ðе удалоÑÑŒ открыть файл палитры: %1 @@ -4259,7 +4331,7 @@ Download size: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Download size: %3 + Maker Code: + + + + + Revision: + + + + File size: Размер файла: - + CRC32: CRC32: - + Save file: @@ -4364,62 +4446,62 @@ Download size: %3 QGBA::SaveConverter - + Save games and save states (%1) Игровые ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑоÑтоÑний (%1) - + Select save game or save state Выбор игрового ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑоÑтоÑÐ½Ð¸Ñ - + Save games (%1) Игровые ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ (%1) - + Select save game Выбор игрового ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ - + Conversion failed Ошибка конвертации - + Failed to convert the save game. This is probably a bug. Ðе удалоÑÑŒ Ñконвертировать игровое Ñохранение. Возможно, Ñто баг. - + No file selected Ðе выбран файл - + Could not open file Ðе удалоÑÑŒ открыть файл - + No valid formats found СовмеÑтимые форматы не найдены - + Please select a valid input file ПожалуйÑта, выберите ÑовмеÑтимый входной файл - + No valid conversions found СовмеÑтимые конверÑии не найдены - + Cannot convert save games between platforms ÐÐµÐ»ÑŒÐ·Ñ Ñконвертировать ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… платформ @@ -4445,97 +4527,97 @@ Download size: %3 Выходной файл - + %1 %2 save game - + little endian - + big endian - + SRAM SRAM - + %1 flash - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM - + TAMA5 - + %1 (%2) - + %1 save state with embedded %2 save game - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4571,32 +4653,37 @@ Download size: %3 Загрузить недавний Ñкрипт - + Load script... Загрузить Ñкрипт... - + + &Load most recent + + + + &Reset Перезагрузить (&R/&К) - + 0 0 - + Select script to load Выбрать Ñкрипт Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ - + Lua scripts (*.lua) Скрипты Lua (*.lua) - + All files (*.*) Ð’Ñе файлы (*.*) @@ -4689,105 +4776,105 @@ Download size: %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Программный рендеринг (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) - + None Ðет - + None (Still Image) Ðет (Ñтатичное изображение) - + Keyboard Клавиатура - + Controllers Контроллеры - + Shortcuts Ð¡Ð¾Ñ‡ÐµÑ‚Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ - - + + Shaders Шейдеры - + Select BIOS Выбор BIOS - + Select directory Выбор папки - + Select image Выбор Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ - + Image file (*.png *.jpg *.jpeg) Файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never Ðикогда - + Just now Только ÑÐµÐ¹Ñ‡Ð°Ñ - + Less than an hour ago Менее чаÑа назад - + %n hour(s) ago %n Ñ‡Ð°Ñ Ð½Ð°Ð·Ð°Ð´ @@ -4796,7 +4883,7 @@ Download size: %3 - + %n day(s) ago %n день назад @@ -5144,72 +5231,72 @@ Download size: %3 СкороÑÑ‚ÑŒ перемотки: - + Models Модели - + GB only: Только GB: - + SGB compatible: СовмеÑтимоÑÑ‚ÑŒ Ñ SGB: - + GBC only: Только GBC: - + GBC compatible: СовмеÑтимоÑÑ‚ÑŒ Ñ GBC: - + SGB and GBC compatible: СовмеÑтимоÑÑ‚ÑŒ Ñ GBC и SGB: - + Game Boy palette Палитра Game Boy - + Default color palette only Только Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð° по умолчанию - + SGB color palette if available Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð° SGB (еÑли доÑтупна) - + GBC color palette if available Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð° GBC (еÑли доÑтупна) - + SGB (preferred) or GBC color palette if available Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð° SGB (предпочтительно) или GBC (еÑли доÑтупны) - + Game Boy Camera - + Driver: Драйвер: - + Source: ИÑточник: @@ -5300,7 +5387,7 @@ Download size: %3 Включить ÑовмеÑтимоÑÑ‚ÑŒ Ñ VBA Ð´Ð»Ñ ROM-хаков - + Preset: ПреÑет: @@ -5403,135 +5490,130 @@ Download size: %3 Программный - + OpenGL enhancements Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ OpenGL - + High-resolution scale: МаÑштаб выÑокого разрешениÑ: - + (240×160) (240×160) - - XQ GBA audio (experimental) - Ðудио XQ GBA (ÑкÑпериментально) - - - + GB BIOS file: Файл GB BIOS: - - - - - - - - - + + + + + + + + + Browse Открыть - + Use BIOS file if found ИÑпользовать файл BIOS, еÑли найден - + Skip BIOS intro ПропуÑтить интро BIOS - + GBA BIOS file: Файл GBA BIOS: - + GBC BIOS file: Файл GBC BIOS: - + SGB BIOS file: Файл SGB BIOS: - + Save games Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ - - - - - + + + + + Same directory as the ROM ДиректориÑ, в которой находитÑÑ ROM - + Save states Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑоÑтоÑÐ½Ð¸Ñ - + Screenshots Скриншоты - + Patches Патчи - + Cheats Читы - + Log to file СохранÑÑ‚ÑŒ журнал в файл - + Log to console Выводить на конÑоль - + Select Log File Выбрать файл журнала - + Default BG colors: Цвета фона по умолчанию: - + Super Game Boy borders Рамки Super Game Boy - + Default sprite colors 1: 1-е цвета по умолчанию Ð´Ð»Ñ Ñпрайта: - + Default sprite colors 2: 2-е цвета по умолчанию Ð´Ð»Ñ Ñпрайта: @@ -5789,7 +5871,6 @@ Download size: %3 - WebM WebM @@ -5823,19 +5904,8 @@ Download size: %3 Format Формат - - - MKV - MKV - - - - AVI - AVI - - MP4 MP4 @@ -5844,72 +5914,6 @@ Download size: %3 4K 4K - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - Ðет - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - - - - - MP3 - MP3 - - - - AAC - - - - - Uncompressed - Без ÑÐ¶Ð°Ñ‚Ð¸Ñ - Bitrate (kbps) @@ -5920,16 +5924,6 @@ Download size: %3 ABR - - - H.264 - - - - - H.264 (NVENC) - - VBR @@ -5959,80 +5953,80 @@ Download size: %3 QGBA::Window - + Archives (%1) Ðрхивы (%1) - - + + Select ROM Выбор игры - + Select folder Выбор папки - - + + Select save Выбор ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ - + Select patch Выбор патча - + Patches (*.ips *.ups *.bps) Патчи (*.ips *.ups *.bps) - + Select e-Reader dotcode Выбор карточки e-Reader - + e-Reader card (*.raw *.bin *.bmp) Карточка e-Reader (*.raw *.bin *.bmp) - + Select image Выбор Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png *.gif *.jpg *.jpeg);;All files (*) - + GameShark saves (*.sps *.xps) Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ GameShark (*.sps *.xps) - + Select video log Выбор видеолога - + Video logs (*.mvl) Видеологи (*.mvl) - + Crash Сбой - + The game has crashed with the following error: %1 @@ -6041,699 +6035,709 @@ Download size: %3 %1 - + Couldn't Start ЗапуÑк не удалÑÑ - + Could not start game. Ðе удалоÑÑŒ запуÑтить игру. - + Unimplemented BIOS call ÐеизвеÑтный вызов BIOS - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Игра иÑпользует нереализованный вызов BIOS. ПожалуйÑта, воÑпользуйтеÑÑŒ официальным BIOS Ð´Ð»Ñ Ð»ÑƒÑ‡ÑˆÐµÐ¹ ÑовмеÑтимоÑти. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Ðе удалоÑÑŒ Ñоздать уÑтройÑтво отображениÑ, возврат к программному режиму. Игры могут идти медленнее, оÑобенно в окнах больших размеров. - + Really make portable? Перейти в портативный режим? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? ПоÑле Ñтого ÑмулÑтор будет загружать конфигурацию из папки Ñ Ð¸ÑполнÑемым файлом. Продолжить? - + Restart needed ТребуетÑÑ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑк - + Some changes will not take effect until the emulator is restarted. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… изменений требуетÑÑ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑтить ÑмулÑтор. - + - Player %1 of %2 - Игрок %1 из %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File &Файл - + Load &ROM... Загрузить &ROM... - + Load ROM in archive... Загрузить игру из архива... - + Add folder to library... Добавить папку в библиотеку... - + Save games (%1) Игровые ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ (%1) - + Select save game Выбор игрового ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ - + mGBA save state files (%1) Файл ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑоÑтоÑÐ½Ð¸Ñ mGBA (%1) - - + + Select save state Выбор ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑоÑтоÑÐ½Ð¸Ñ - + Select e-Reader card images Выбор Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ð¾Ñ‡ÐºÐ¸ e-Reader - + Image file (*.png *.jpg *.jpeg) Файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png *.jpg *.jpeg) - + Conversion finished ÐšÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ð¸Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð° - + %1 of %2 e-Reader cards converted successfully. %1 из %2 карточек e-Reader уÑпешно Ñконвертировано. - + Load alternate save game... Загрузить альтернативное Ñохранение... - + Load temporary save game... Загрузить временное Ñохранение... - + Load &patch... Загрузить &патч... - + Boot BIOS ЗагрузитьÑÑ Ð² BIOS - + Replace ROM... Заменить ROM... - + Scan e-Reader dotcodes... Сканировать dot-коды e-Reader... - + Convert e-Reader card image to raw... Конвертировать карту e-Reader в raw... - + ROM &info... Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± &игре... - + Recent Ðедавние - + Make portable Портативный режим - + &Load state &Загрузить ÑоÑтоÑние - + Load state file... Загрузить ÑоÑтоÑние из файла... - + &Save state &Сохранить ÑоÑтоÑние - + Save state file... Сохранить ÑоÑтоÑние в файл... - + Quick load БыÑÑ‚Ñ€Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° - + Quick save БыÑтрое Ñохранение - + Load recent Загрузить недавнее - + Save recent Сохранить в недавнее - + Undo load state Отмена загрузки ÑоÑтоÑÐ½Ð¸Ñ - + Undo save state Отмена ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑоÑтоÑÐ½Ð¸Ñ - - + + State &%1 Слот &%1 - + Load camera image... Загрузить изображение Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹... - + Convert save game... Конвертировать игровое Ñохранение... - + GameShark saves (*.gsv *.sps *.xps) Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ GameShark (*.gsv *.sps *.xps) - + Reset needed Ðеобходима перезагрузка - + Some changes will not take effect until the game is reset. Ðекоторые Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ войдут в Ñилу, пока игра не перезагружена. - + Save games Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ - + Import GameShark Save... Импорт ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ GameShark... - + Export GameShark Save... ЭкÑпорт ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ GameShark... - + Automatically determine Определить автоматичеÑки - + Use player %0 save game ИÑпользовать Ñохранение игрока %0 - + New multiplayer window Ðовое окно мультиплеера - + Connect to Dolphin... Соединение Ñ Dolphin... - + Report bug... Сообщить об ошибке... - + About... О программе... - + E&xit &Выход - + &Emulation &ЭмулÑÑ†Ð¸Ñ - + &Reset Перезагрузить (&R/&К) - + Sh&utdown Выключить (&U/&Г) - + Yank game pak Пнуть картридж - + &Pause Пау&за - + &Next frame Следующий кадр (&N/&Т) - + Fast forward (held) Перемотка (удержание) - + &Fast forward Перемотк&а - + Fast forward speed СкороÑÑ‚ÑŒ перемотки - + Unbounded ÐÐµÐ¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð½Ð°Ñ - + %0x %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼Ð¾Ñ‚ÐºÐ° (удержание) - + Re&wind ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼Ð¾Ñ‚ÐºÐ° (&W/&Ц) - + Step backwards Шаг назад - + Solar sensor Датчик Ñолнца - + Increase solar level УÑилить Ñолнечный Ñвет - + Decrease solar level ОÑлабить Ñолнечный Ñвет - + Brightest solar level Ярчайшее Ñолнце - + Darkest solar level ТуÑклейшее Ñолнце - + Brightness %1 ЯркоÑÑ‚ÑŒ %1 - + Game Boy Printer... - + BattleChip Gate... - + Audio/&Video Ðудио/Видео (&V/&Ðœ) - + Frame size Размер кадра - + %1× %1× - + Toggle fullscreen Переключить полноÑкранный режим - + + &Lock frame size + + + + Lock aspect ratio ЗафикÑировать Ñоотношение Ñторон - + Force integer scaling Принудительное целочиÑленное маÑштабирование - + Interframe blending Межкадровое Ñмешение - + Bilinear filtering Ð‘Ð¸Ð»Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ - + Frame&skip ПропуÑк кадров (&S/&Ы) - + Mute Выключить звук - + FPS target Целевой FPS - + Native (59.7275) Родной (59.7275) - + Take &screenshot СнÑÑ‚ÑŒ Ñкриншот (&S/&Ы) - + F12 F12 - + Record A/V... ЗапиÑать аудио/видео... - + Record GIF/WebP/APNG... ЗапиÑать GIF/WebP/APNG... - + Video layers ВидеоÑлои - + Audio channels Ðудиоканалы - + Adjust layer placement... ÐаÑтроить раÑположение Ñлоёв... - + &Tools ИнÑтрум&енты - + View &logs... ПоÑмотреть в журнал... (&L/&Д) - + Game &overrides... ÐŸÐµÑ€ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтой игры... (&О/&Щ) - + Game Pak sensors... Датчики в Game Pak... - + &Cheats... Читы... (&C/&С) - + Create forwarder... - + Settings... ÐаÑтройки... - + Open debugger console... Открыть конÑоль отладки... - + Start &GDB server... ЗапуÑтить Ñервер &GDB... - + Scripting... Скрипты... - + Game state views ПроÑмотр ÑоÑтоÑÐ½Ð¸Ñ Ð¸Ð³Ñ€Ñ‹ - + View &palette... ПроÑмотр палитры... (&P/&З) - + View &sprites... ПроÑмотр Ñпрайтов... (&S/&Ы) - + View &tiles... ПроÑмотр тайлов... (&T/&Е) - + View &map... ПроÑмотр карты... (&M/&Ь) - + &Frame inspector... Изучение фрейм&а... - + View memory... ПроÑмотр памÑти... - + Search memory... ПоиÑк в памÑти... - + View &I/O registers... ПроÑмотр региÑтров &I/O... - + + Log memory &accesses... + + + + Record debug video log... ЗапиÑÑŒ отладочного видеожурнала... - + Stop debug video log Закончить запиÑÑŒ отладочного видеожурнала - + Exit fullscreen Выйти из полноÑкранного режима - + GameShark Button (held) Кнопка GameShark (удерживаетÑÑ) - + Autofire ÐвтоÑтрельба - + Autofire A A (автоÑтрельба) - + Autofire B B (автоÑтрельба) - + Autofire L L (автоÑтрельба) - + Autofire R R (автоÑтрельба) - + Autofire Start Start (автоÑтрельба) - + Autofire Select Select (автоÑтрельба) - + Autofire Up Вверх (автоÑтрельба) - + Autofire Right Вправо (автоÑтрельба) - + Autofire Down Вниз (автоÑтрельба) - + Autofire Left Влево (автоÑтрельба) - + Clear ОчиÑтить @@ -6771,17 +6775,17 @@ Download size: %3 ? - + Super (L) - + Super (R) - + Menu Меню @@ -6789,22 +6793,22 @@ Download size: %3 QShortcut - + Shift - + Control - + Alt - + Meta diff --git a/src/platform/qt/ts/mgba-sv.ts b/src/platform/qt/ts/mgba-sv.ts index 55df22b52..4017ea489 100644 --- a/src/platform/qt/ts/mgba-sv.ts +++ b/src/platform/qt/ts/mgba-sv.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) - + Game Boy ROMs (%1) - + All ROMs (%1) - + %1 Video Logs (*.mvl) @@ -191,17 +191,17 @@ Nedladdningsstorlek: %3 QGBA::AudioDevice - + Can't set format of context-less audio device Det gÃ¥r inte att ställa in formatet för kontextlös ljudenhet - + Audio device is missing its core Ljudenheten saknar kärnan - + Writing data to read-only audio device Skriver data till skrivskyddad ljudenhet @@ -209,7 +209,7 @@ Nedladdningsstorlek: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input Kan inte starta en ljudprocessor utan ingÃ¥ng @@ -285,28 +285,28 @@ Nedladdningsstorlek: %3 Visa avancerat - + BattleChip data missing BattleChip-data saknas - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? BattleChip-data saknas. BattleChip Gates fungerar fortfarande, men viss grafik kommer att saknas. Vill du ladda ner datan nu? - - + + Select deck file Välj deck-fil - + Incompatible deck Inkompatibelt deck - + The selected deck is not compatible with this Chip Gate Den valda deck är inte kompatibel med denna Chip Gate @@ -367,19 +367,19 @@ Nedladdningsstorlek: %3 - - + + Autodetect (recommended) - - + + Select cheats file - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. @@ -398,37 +398,37 @@ Nedladdningsstorlek: %3 - + Reset the game? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 - + Failed to open game file: %1 - + Can't yank pack in unexpected platform! - + Failed to open snapshot file for reading: %1 - + Failed to open snapshot file for writing: %1 @@ -477,6 +477,14 @@ Nedladdningsstorlek: %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Nedladdningsstorlek: %3 - + Export frame - + Portable Network Graphics (*.png) - + None - + Background - + Window - + Objwin - + Sprite - + Backdrop - + Frame - + %1 %2 @@ -818,22 +826,22 @@ Nedladdningsstorlek: %3 QGBA::GBAKeyEditor - + Clear Button - + Clear Analog - + Refresh - + Set all @@ -3006,8 +3014,8 @@ Nedladdningsstorlek: %3 QGBA::KeyEditor - - + + --- @@ -3378,23 +3386,87 @@ Nedladdningsstorlek: %3 - - - + + + N/A - + Export map - + Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Nedladdningsstorlek: %3 - + (%0/%1×) - + (â…Ÿ%0×) - + (%0×) - + %1 byte%2 @@ -3750,17 +3822,17 @@ Nedladdningsstorlek: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4157,35 +4229,35 @@ Nedladdningsstorlek: %3 - + #%0 - + 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette - + Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 @@ -4259,7 +4331,7 @@ Nedladdningsstorlek: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Nedladdningsstorlek: %3 - File size: + Maker Code: - CRC32: + Revision: + File size: + + + + + CRC32: + + + + Save file: @@ -4364,62 +4446,62 @@ Nedladdningsstorlek: %3 QGBA::SaveConverter - + Save games and save states (%1) - + Select save game or save state - + Save games (%1) - + Select save game - + Conversion failed - + Failed to convert the save game. This is probably a bug. - + No file selected - + Could not open file - + No valid formats found - + Please select a valid input file - + No valid conversions found - + Cannot convert save games between platforms @@ -4445,97 +4527,97 @@ Nedladdningsstorlek: %3 - + %1 %2 save game - + little endian - + big endian - + SRAM - + %1 flash - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM - + TAMA5 - + %1 (%2) - + %1 save state with embedded %2 save game - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4571,32 +4653,37 @@ Nedladdningsstorlek: %3 - + Load script... - + + &Load most recent + + + + &Reset - + 0 - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4689,105 +4776,105 @@ Nedladdningsstorlek: %3 QGBA::SettingsView - - + + Qt Multimedia - + SDL - + Software (Qt) - + OpenGL - + OpenGL (force version 1.x) - + None - + None (Still Image) - + Keyboard - + Controllers - + Shortcuts - - + + Shaders - + Select BIOS - + Select directory - + Select image - + Image file (*.png *.jpg *.jpeg) - + (%1×%2) - + Never - + Just now - + Less than an hour ago - + %n hour(s) ago @@ -4795,7 +4882,7 @@ Nedladdningsstorlek: %3 - + %n day(s) ago @@ -5122,37 +5209,37 @@ Nedladdningsstorlek: %3 - + Default color palette only - + SGB color palette if available - + GBC color palette if available - + SGB (preferred) or GBC color palette if available - + Game Boy Camera - + Driver: - + Source: @@ -5329,42 +5416,42 @@ Nedladdningsstorlek: %3 - + Models - + GB only: - + SGB compatible: - + GBC only: - + GBC compatible: - + SGB and GBC compatible: - + Game Boy palette - + Preset: @@ -5401,135 +5488,130 @@ Nedladdningsstorlek: %3 - + OpenGL enhancements - + High-resolution scale: - + (240×160) - - XQ GBA audio (experimental) - - - - + GB BIOS file: - - - - - - - - - + + + + + + + + + Browse - + Use BIOS file if found - + Skip BIOS intro - + GBA BIOS file: - + GBC BIOS file: - + SGB BIOS file: - + Save games - - - - - + + + + + Same directory as the ROM - + Save states - + Screenshots - + Patches - + Cheats Cheats - + Log to file - + Log to console - + Select Log File - + Default BG colors: - + Default sprite colors 1: - + Default sprite colors 2: - + Super Game Boy borders @@ -5787,13 +5869,11 @@ Nedladdningsstorlek: %3 - WebM - MP4 @@ -5832,82 +5912,6 @@ Nedladdningsstorlek: %3 Format - - - MKV - - - - - AVI - - - - - HEVC - - - - - HEVC (NVENC) - - - - - VP8 - - - - - VP9 - - - - - FFV1 - - - - - - None - - - - - FLAC - - - - - WavPack - - - - - Opus - - - - - Vorbis - - - - - MP3 - - - - - AAC - - - - - Uncompressed - - Bitrate (kbps) @@ -5918,16 +5922,6 @@ Nedladdningsstorlek: %3 ABR - - - H.264 - - - - - H.264 (NVENC) - - VBR @@ -5957,779 +5951,789 @@ Nedladdningsstorlek: %3 QGBA::Window - + Archives (%1) - - + + Select ROM - + Select folder - - + + Select save - + Select patch - + Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode - + e-Reader card (*.raw *.bin *.bmp) - + Select image - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) - + GameShark saves (*.sps *.xps) - + Select video log - + Video logs (*.mvl) - + Crash - + The game has crashed with the following error: %1 - + Couldn't Start - + Could not start game. - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + Load ROM in archive... - + Add folder to library... - + Save games (%1) - + Select save game - + mGBA save state files (%1) - - + + Select save state - + Select e-Reader card images - + Image file (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Load alternate save game... - + Load temporary save game... - + Load &patch... - + Boot BIOS - + Replace ROM... - + Scan e-Reader dotcodes... - + Convert e-Reader card image to raw... - + ROM &info... - + Recent - + Make portable - + &Load state - + Load state file... - + &Save state - + Save state file... - + Quick load - + Quick save - + Load recent - + Save recent - + Undo load state - + Undo save state - - + + State &%1 - + Load camera image... - + Convert save game... - + GameShark saves (*.gsv *.sps *.xps) - + Reset needed - + Some changes will not take effect until the game is reset. - + Save games - + Import GameShark Save... - + Export GameShark Save... - + Automatically determine - + Use player %0 save game - + New multiplayer window - + Connect to Dolphin... - + Report bug... - + About... - + E&xit - + &Emulation - + &Reset - + Sh&utdown - + Yank game pak - + &Pause - + &Next frame - + Fast forward (held) - + &Fast forward - + Fast forward speed - + Unbounded - + %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) - + Re&wind - + Step backwards - + Solar sensor - + Increase solar level - + Decrease solar level - + Brightest solar level - + Darkest solar level - + Brightness %1 - + Game Boy Printer... - + BattleChip Gate... - + Audio/&Video - + Frame size - + %1× - + Toggle fullscreen - - Lock aspect ratio - - - - - Force integer scaling - - - - - Interframe blending - - - - - Bilinear filtering + + &Lock frame size + Lock aspect ratio + + + + + Force integer scaling + + + + + Interframe blending + + + + + Bilinear filtering + + + + Frame&skip - + Mute - + FPS target - + Native (59.7275) - + Take &screenshot - + F12 - + Record A/V... - + Record GIF/WebP/APNG... - + Video layers - + Audio channels - + Adjust layer placement... - + &Tools - + View &logs... - + Game &overrides... - + Game Pak sensors... - + &Cheats... - + Create forwarder... - + Settings... - + Open debugger console... - + Start &GDB server... - + Scripting... - + Game state views - + View &palette... - + View &sprites... - + View &tiles... - + View &map... - + &Frame inspector... - + View memory... - + Search memory... - + View &I/O registers... - + + Log memory &accesses... + + + + Record debug video log... - + Stop debug video log - + Exit fullscreen - + GameShark Button (held) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear @@ -6767,17 +6771,17 @@ Nedladdningsstorlek: %3 - + Super (L) - + Super (R) - + Menu @@ -6785,22 +6789,22 @@ Nedladdningsstorlek: %3 QShortcut - + Shift - + Control - + Alt - + Meta diff --git a/src/platform/qt/ts/mgba-template.ts b/src/platform/qt/ts/mgba-template.ts index 61b57b820..8cd293d9b 100644 --- a/src/platform/qt/ts/mgba-template.ts +++ b/src/platform/qt/ts/mgba-template.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) - + Game Boy ROMs (%1) - + All ROMs (%1) - + %1 Video Logs (*.mvl) @@ -185,17 +185,17 @@ Download size: %3 QGBA::AudioDevice - + Can't set format of context-less audio device - + Audio device is missing its core - + Writing data to read-only audio device @@ -203,7 +203,7 @@ Download size: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input @@ -279,28 +279,28 @@ Download size: %3 - + BattleChip data missing - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? - - + + Select deck file - + Incompatible deck - + The selected deck is not compatible with this Chip Gate @@ -361,19 +361,19 @@ Download size: %3 - - + + Autodetect (recommended) - - + + Select cheats file - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. @@ -392,37 +392,37 @@ Download size: %3 - + Reset the game? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 - + Failed to open game file: %1 - + Can't yank pack in unexpected platform! - + Failed to open snapshot file for reading: %1 - + Failed to open snapshot file for writing: %1 @@ -471,6 +471,14 @@ Download size: %3 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -751,52 +759,52 @@ Download size: %3 - + Export frame - + Portable Network Graphics (*.png) - + None - + Background - + Window - + Objwin - + Sprite - + Backdrop - + Frame - + %1 %2 @@ -812,22 +820,22 @@ Download size: %3 QGBA::GBAKeyEditor - + Clear Button - + Clear Analog - + Refresh - + Set all @@ -3000,8 +3008,8 @@ Download size: %3 QGBA::KeyEditor - - + + --- @@ -3372,23 +3380,87 @@ Download size: %3 - - - + + + N/A - + Export map - + Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3635,22 +3707,22 @@ Download size: %3 - + (%0/%1×) - + (â…Ÿ%0×) - + (%0×) - + %1 byte%2 @@ -3744,17 +3816,17 @@ Download size: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4151,35 +4223,35 @@ Download size: %3 - + #%0 - + 0x%0 + + - - 0x%0 (%1) - + Export palette - + Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 @@ -4253,7 +4325,7 @@ Download size: %3 QGBA::ROMInfo - + @@ -4293,16 +4365,26 @@ Download size: %3 - File size: + Maker Code: - CRC32: + Revision: + File size: + + + + + CRC32: + + + + Save file: @@ -4358,62 +4440,62 @@ Download size: %3 QGBA::SaveConverter - + Save games and save states (%1) - + Select save game or save state - + Save games (%1) - + Select save game - + Conversion failed - + Failed to convert the save game. This is probably a bug. - + No file selected - + Could not open file - + No valid formats found - + Please select a valid input file - + No valid conversions found - + Cannot convert save games between platforms @@ -4439,97 +4521,97 @@ Download size: %3 - + %1 %2 save game - + little endian - + big endian - + SRAM - + %1 flash - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 - + unpacked MBC2 - + MBC6 flash - + MBC6 combined SRAM + flash - + MBC6 SRAM - + TAMA5 - + %1 (%2) - + %1 save state with embedded %2 save game - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4565,32 +4647,37 @@ Download size: %3 - + Load script... - + + &Load most recent + + + + &Reset - + 0 - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4683,112 +4770,112 @@ Download size: %3 QGBA::SettingsView - - + + Qt Multimedia - + SDL - + Software (Qt) - + OpenGL - + OpenGL (force version 1.x) - + None - + None (Still Image) - + Keyboard - + Controllers - + Shortcuts - - + + Shaders - + Select BIOS - + Select directory - + Select image - + Image file (*.png *.jpg *.jpeg) - + (%1×%2) - + Never - + Just now - + Less than an hour ago - + %n hour(s) ago - + %n day(s) ago @@ -5114,37 +5201,37 @@ Download size: %3 - + Default color palette only - + SGB color palette if available - + GBC color palette if available - + SGB (preferred) or GBC color palette if available - + Game Boy Camera - + Driver: - + Source: @@ -5321,42 +5408,42 @@ Download size: %3 - + Models - + GB only: - + SGB compatible: - + GBC only: - + GBC compatible: - + SGB and GBC compatible: - + Game Boy palette - + Preset: @@ -5393,135 +5480,130 @@ Download size: %3 - + OpenGL enhancements - + High-resolution scale: - + (240×160) - - XQ GBA audio (experimental) - - - - + GB BIOS file: - - - - - - - - - + + + + + + + + + Browse - + Use BIOS file if found - + Skip BIOS intro - + GBA BIOS file: - + GBC BIOS file: - + SGB BIOS file: - + Save games - - - - - + + + + + Same directory as the ROM - + Save states - + Screenshots - + Patches - + Cheats - + Log to file - + Log to console - + Select Log File - + Default BG colors: - + Default sprite colors 1: - + Default sprite colors 2: - + Super Game Boy borders @@ -5779,13 +5861,11 @@ Download size: %3 - WebM - MP4 @@ -5824,82 +5904,6 @@ Download size: %3 Format - - - MKV - - - - - AVI - - - - - HEVC - - - - - HEVC (NVENC) - - - - - VP8 - - - - - VP9 - - - - - FFV1 - - - - - - None - - - - - FLAC - - - - - WavPack - - - - - Opus - - - - - Vorbis - - - - - MP3 - - - - - AAC - - - - - Uncompressed - - Bitrate (kbps) @@ -5910,16 +5914,6 @@ Download size: %3 ABR - - - H.264 - - - - - H.264 (NVENC) - - VBR @@ -5949,779 +5943,789 @@ Download size: %3 QGBA::Window - + Archives (%1) - - + + Select ROM - + Select folder - - + + Select save - + Select patch - + Patches (*.ips *.ups *.bps) - + Select e-Reader dotcode - + e-Reader card (*.raw *.bin *.bmp) - + Select image - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) - + GameShark saves (*.sps *.xps) - + Select video log - + Video logs (*.mvl) - + Crash - + The game has crashed with the following error: %1 - + Couldn't Start - + Could not start game. - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + Load ROM in archive... - + Add folder to library... - + Save games (%1) - + Select save game - + mGBA save state files (%1) - - + + Select save state - + Select e-Reader card images - + Image file (*.png *.jpg *.jpeg) - + Conversion finished - + %1 of %2 e-Reader cards converted successfully. - + Load alternate save game... - + Load temporary save game... - + Load &patch... - + Boot BIOS - + Replace ROM... - + Scan e-Reader dotcodes... - + Convert e-Reader card image to raw... - + ROM &info... - + Recent - + Make portable - + &Load state - + Load state file... - + &Save state - + Save state file... - + Quick load - + Quick save - + Load recent - + Save recent - + Undo load state - + Undo save state - - + + State &%1 - + Load camera image... - + Convert save game... - + GameShark saves (*.gsv *.sps *.xps) - + Reset needed - + Some changes will not take effect until the game is reset. - + Save games - + Import GameShark Save... - + Export GameShark Save... - + Automatically determine - + Use player %0 save game - + New multiplayer window - + Connect to Dolphin... - + Report bug... - + About... - + E&xit - + &Emulation - + &Reset - + Sh&utdown - + Yank game pak - + &Pause - + &Next frame - + Fast forward (held) - + &Fast forward - + Fast forward speed - + Unbounded - + %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) - + Re&wind - + Step backwards - + Solar sensor - + Increase solar level - + Decrease solar level - + Brightest solar level - + Darkest solar level - + Brightness %1 - + Game Boy Printer... - + BattleChip Gate... - + Audio/&Video - + Frame size - + %1× - + Toggle fullscreen - - Lock aspect ratio - - - - - Force integer scaling - - - - - Interframe blending - - - - - Bilinear filtering + + &Lock frame size + Lock aspect ratio + + + + + Force integer scaling + + + + + Interframe blending + + + + + Bilinear filtering + + + + Frame&skip - + Mute - + FPS target - + Native (59.7275) - + Take &screenshot - + F12 - + Record A/V... - + Record GIF/WebP/APNG... - + Video layers - + Audio channels - + Adjust layer placement... - + &Tools - + View &logs... - + Game &overrides... - + Game Pak sensors... - + &Cheats... - + Create forwarder... - + Settings... - + Open debugger console... - + Start &GDB server... - + Scripting... - + Game state views - + View &palette... - + View &sprites... - + View &tiles... - + View &map... - + &Frame inspector... - + View memory... - + Search memory... - + View &I/O registers... - + + Log memory &accesses... + + + + Record debug video log... - + Stop debug video log - + Exit fullscreen - + GameShark Button (held) - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left - + Clear @@ -6759,17 +6763,17 @@ Download size: %3 - + Super (L) - + Super (R) - + Menu @@ -6777,22 +6781,22 @@ Download size: %3 QShortcut - + Shift - + Control - + Alt - + Meta diff --git a/src/platform/qt/ts/mgba-tr.ts b/src/platform/qt/ts/mgba-tr.ts index a98e0639b..59e085531 100644 --- a/src/platform/qt/ts/mgba-tr.ts +++ b/src/platform/qt/ts/mgba-tr.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) Game Boy Advance ROM'ları (%1) - + Game Boy ROMs (%1) Game Boy ROM'ları (%1) - + All ROMs (%1) Bütün ROM'lar (%1) - + %1 Video Logs (*.mvl) %1 Video Günlükleri (*.mvl) @@ -191,17 +191,17 @@ Yeni sürüm: %2 QGBA::AudioDevice - + Can't set format of context-less audio device BaÄŸlamdan bağımsız ses cihazının formatı ayarlanamıyor - + Audio device is missing its core Ses cihazının çekirdeÄŸi eksik - + Writing data to read-only audio device Salt okunur ses cihazına veri yazma @@ -209,7 +209,7 @@ Yeni sürüm: %2 QGBA::AudioProcessorQt - + Can't start an audio processor without input GiriÅŸsiz ses iÅŸlemcisi baÅŸlatılamaz @@ -285,28 +285,28 @@ Yeni sürüm: %2 GeliÅŸmiÅŸi göster - + BattleChip data missing BattleChip verisi yok - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? BattleChip verisi yok. Bazı grafikler olmadan BattleChip Gates hala çalışır. Verileri ÅŸimdi indirmek istermisin? - - + + Select deck file Deste dosyası seç - + Incompatible deck Uyumsuz deste - + The selected deck is not compatible with this Chip Gate Seçilen deste bu Chip Gate ile uyumlu deÄŸildir @@ -367,19 +367,19 @@ Yeni sürüm: %2 Kodları buraya gir... - - + + Autodetect (recommended) Otoseç (tavsiye edilir) - - + + Select cheats file Oyun hileleri seçin - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. Bazı hileler eklenemedi. Lütfen onların doÄŸru formatlandığından emin ol ve/yada baÅŸa hile tiplerini dene. @@ -398,37 +398,37 @@ Yeni sürüm: %2 - + Reset the game? Oyun sıfırlansım mı? - + Most games will require a reset to load the new save. Do you want to reset now? - + Failed to open save file: %1 Kayıt dosyası açılamadı: %1 - + Failed to open game file: %1 Oyun dosyası açılamadı: %1 - + Can't yank pack in unexpected platform! Beklenmedik bir platformda kartı çıkaramazsın! - + Failed to open snapshot file for reading: %1 Anlık görüntü dosyası okuma için açılamadı: %1 - + Failed to open snapshot file for writing: %1 Anlık görüntü dosyası yazma için açılamadı: %1 @@ -477,6 +477,14 @@ Yeni sürüm: %2 + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Yeni sürüm: %2 Sıfırla - + Export frame Kareyi Dışarı Aktar - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Hiçbiri - + Background Arka Plan - + Window Pencere - + Objwin Nes. Pen. - + Sprite Sprite - + Backdrop Arka fon - + Frame Kare - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Yeni sürüm: %2 QGBA::GBAKeyEditor - + Clear Button TuÅŸu Temizle - + Clear Analog Analogu Temizle - + Refresh Yenile - + Set all Tümüne ayarla @@ -3006,8 +3014,8 @@ Yeni sürüm: %2 QGBA::KeyEditor - - + + --- @@ -3378,23 +3386,87 @@ Yeni sürüm: %2 Dikey - - - + + + N/A N/A - + Export map Haritayı dışarı aktar - + Portable Network Graphics (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + Gözat + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + BaÅŸlat + + + + Stop + Durdur + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Yeni sürüm: %2 Yenile - + (%0/%1×) - + (â…Ÿ%0×) - + (%0×) - + %1 byte%2 @@ -3750,17 +3822,17 @@ Yeni sürüm: %2 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached - + Trying to get player ID for a multiplayer player that's not attached - + Trying to get save ID for a multiplayer player that's not attached @@ -4157,35 +4229,35 @@ Yeni sürüm: %2 OBJ dışarı aktar - + #%0 - + 0x%0 + + - - 0x%0 (%1) - + Export palette Paleti dışarı aktar - + Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 Çıkış paleti dosyası açılamadı:%1 @@ -4259,7 +4331,7 @@ Yeni sürüm: %2 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Yeni sürüm: %2 + Maker Code: + + + + + Revision: + + + + File size: Dosya boyutu: - + CRC32: - + Save file: @@ -4364,62 +4446,62 @@ Yeni sürüm: %2 QGBA::SaveConverter - + Save games and save states (%1) Kayıtlı oyunlar ve kayıtlı durumlar (%1) - + Select save game or save state Kayıtlı oyun veya kayıtlı durum seç - + Save games (%1) Kayıtlı oyunlar (%1) - + Select save game Kayıtlı oyun seç - + Conversion failed Dönüştürme baÅŸarısız - + Failed to convert the save game. This is probably a bug. Kayıtlı oyunu dönüştürme baÅŸarısız. Muhtemelen bir hata meydana geldi. - + No file selected Seçili dosya yok - + Could not open file Dosya açılamadı - + No valid formats found Geçerli türler bulunamadı - + Please select a valid input file Lütfen geçerli bir giriÅŸ dosyası seç - + No valid conversions found Geçerli dönüştürme bulunamadı - + Cannot convert save games between platforms Kayıtlı oyunlar platformlar arasında dönüştürülemez @@ -4445,97 +4527,97 @@ Yeni sürüm: %2 Çıkış dosyası - + %1 %2 save game %1 %2 kayıtlı oyun - + little endian little endian - + big endian big endian - + SRAM SRAM - + %1 flash %1 flash - + %1 EEPROM %1 EEPROM - + + RTC - + %1 SRAM + RTC %1 SRAM + RTC - + %1 SRAM %1 SRAM - + packed MBC2 paketli MBC2 - + unpacked MBC2 paketlenmemiÅŸ MBC2 - + MBC6 flash MBC6 flash - + MBC6 combined SRAM + flash MBC6 ile birleÅŸtirilmiÅŸ SRAM + flash - + MBC6 SRAM MBC6 SRAM - + TAMA5 TAMA5 - + %1 (%2) %1 (%2) - + %1 save state with embedded %2 save game Gömülü %2 kayıtlı oyunla %1 kayıt durumu - + %1 SharkPort %2 save game - + %1 GameShark Advance SP %2 save game @@ -4571,32 +4653,37 @@ Yeni sürüm: %2 - + Load script... - + + &Load most recent + + + + &Reset &Reset - + 0 4K {0?} - + Select script to load - + Lua scripts (*.lua) - + All files (*.*) @@ -4689,112 +4776,112 @@ Yeni sürüm: %2 QGBA::SettingsView - - + + Qt Multimedia - + SDL - + Software (Qt) Yazılım - + OpenGL OpenGL - + OpenGL (force version 1.x) - + None Hiçbiri - + None (Still Image) - + Keyboard Klavye - + Controllers - + Shortcuts Kısayollar - - + + Shaders Gölgelendiricler - + Select BIOS BIOS seç - + Select directory Yolu seç - + Select image Resim seç - + Image file (*.png *.jpg *.jpeg) Görüntü dosyası (*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never - + Just now - + Less than an hour ago - + %n hour(s) ago - + %n day(s) ago @@ -5140,72 +5227,72 @@ Yeni sürüm: %2 - + Models Modeller - + GB only: Sadece GB: - + SGB compatible: SGB uyumlu: - + GBC only: Sadece GBC: - + GBC compatible: Uyumlu GBC: - + SGB and GBC compatible: Uyumlu SGB ve GBC: - + Game Boy palette Game Boy paleti - + Default color palette only Sadece varsayılan renk paleti - + SGB color palette if available Mevcutsa SGB renk paketi - + GBC color palette if available Mevcutsa GBC renk paketi - + SGB (preferred) or GBC color palette if available Mevcutsa SGB (tercih edilen) ya da GBC renk paketi - + Game Boy Camera Game Boy Kamera - + Driver: Sürücü: - + Source: Kaynak: @@ -5296,7 +5383,7 @@ Yeni sürüm: %2 ROM hacklerinde VBA hata uyumluluÄŸunu etkinleÅŸtir - + Preset: Ön ayar: @@ -5399,135 +5486,130 @@ Yeni sürüm: %2 Yazılım - + OpenGL enhancements OpenGL geliÅŸtirmeleri - + High-resolution scale: Yüksek kalite ölçeÄŸi: - + (240×160) (240×160) - - XQ GBA audio (experimental) - XQ GBA ses (deneysel) - - - + GB BIOS file: GB BIOS dosyası: - - - - - - - - - + + + + + + + + + Browse Gözat - + Use BIOS file if found Varsa BIOS dosyasını kullan - + Skip BIOS intro BIOS giriÅŸini atla - + GBA BIOS file: GBA BIOS dosyası: - + GBC BIOS file: GBC BIOS dosyası: - + SGB BIOS file: SGB BIOS dosyası: - + Save games Oyunları kaydet - - - - - + + + + + Same directory as the ROM ROM ile aynı dizin - + Save states Konum kaydedici - + Screenshots Ekran Görüntüleri - + Patches Yamalar - + Cheats Hileler - + Log to file Dosyaya günlüğünü gir - + Log to console Konsola günlüğünü gir - + Select Log File Günlük Dosyasını Seç - + Default BG colors: - + Super Game Boy borders Super Game Boy sınırları - + Default sprite colors 1: Varsayılan sprite renkleri 1: - + Default sprite colors 2: Varsayılan sprite renkleri 2: @@ -5785,7 +5867,6 @@ Yeni sürüm: %2 - WebM @@ -5819,19 +5900,8 @@ Yeni sürüm: %2 Format Format - - - MKV - - - - - AVI - - - MP4 @@ -5840,72 +5910,6 @@ Yeni sürüm: %2 4K 4K - - - HEVC - - - - - HEVC (NVENC) - - - - - VP8 - - - - - VP9 - - - - - FFV1 - - - - - - None - Hiçbiri - - - - FLAC - - - - - WavPack - - - - - Opus - - - - - Vorbis - - - - - MP3 - - - - - AAC - - - - - Uncompressed - Sıkıştırılmamış - Bitrate (kbps) @@ -5916,16 +5920,6 @@ Yeni sürüm: %2 ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5955,100 +5949,100 @@ Yeni sürüm: %2 QGBA::Window - + Archives (%1) ArÅŸivler (%1) - - + + Select ROM ROM seç - + Select folder Klasör seç - - + + Select save Kayıt seç - + Select patch Yama seç - + Patches (*.ips *.ups *.bps) Yamalar (*.ips *.ups *.bps) - + Select e-Reader dotcode e-Okuyucu nokta kodunu seç - + e-Reader card (*.raw *.bin *.bmp) e-Okuyucu kart (*.raw *.bin *.bmp) - + Select e-Reader card images e-Okuyucu kartından görüntüleri seç - + Image file (*.png *.jpg *.jpeg) Görüntü dosyası (*.png *.jpg *.jpeg) - + Conversion finished Dönüştürme tamamlandı - + %1 of %2 e-Reader cards converted successfully. %1 / %2 e-Okuyucu kartları dönüştürme tamamlandı. - + Select image Resim seç - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Resim dosyası (*.png *.gif *.jpg *.jpeg);;All files (*) - + GameShark saves (*.sps *.xps) GameShark kayıtları (*.sps *.xps) - + Select video log Video günlüğü seç - + Video logs (*.mvl) Video günlükleri (*.mvl) - + Crash Çökme - + The game has crashed with the following error: %1 @@ -6057,679 +6051,689 @@ Yeni sürüm: %2 %1 - + Unimplemented BIOS call Uygulanmamış BIOS giriÅŸi - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Oyun BIOS dosyasına ihtiyacı var. Lütfen en iyi deneyim için resmi BIOS'u kullanın. - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. Uygun görüntü cihazı oluÅŸturma baÅŸarısız, yazılım ekranına dönülüyor. Oyunlar özellikle daha büyük ekranlarda yavaÅŸ çalışabilir. - + Really make portable? Taşınabilir yapılsın mı? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Öyküncünün yapılandırmasını yürütülebilir dosya ile aynı dizinden yüklemesini saÄŸlar. Devam etmek istiyor musunuz? - + Restart needed Yeniden baÅŸlatma gerekli - + Some changes will not take effect until the emulator is restarted. Bazı deÄŸiÅŸiklikler öyküncü yeniden baÅŸlatılıncaya kadar etkili olmaz. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... &ROM yükle... - + Load ROM in archive... ROM'u arÅŸivden yükle ... - + Add folder to library... Kütüphaneye klasör ekle ... - + Save games Oyunları kaydet - + Automatically determine - + Use player %0 save game - + Load &patch... &Patch yükle... - + Boot BIOS BIOS boot et - + Replace ROM... ROM deÄŸiÅŸti... - + Create forwarder... - + Game state views - + + Log memory &accesses... + + + + Convert e-Reader card image to raw... e-Okuyucu kart resimlerini rawa dönüştür... - + ROM &info... ROM &info... - + Recent Son kullanılanlar - + Make portable Portatif yap - + &Load state &KaydedilmiÅŸ konum yükle - + Load state file... KaydedilmiÅŸ konum dosyası yükle... - + &Save state &Konumu kaydet - + Save state file... Konum dosyasını kaydet... - + Quick load Hızlı Yükle - + Quick save Hızlı kaydet - + Load recent En son yükle - + Save recent Hızlı kaydet - + Undo load state Kaydedilen konum yüklemeyi geri al - + Undo save state Konum kaydetmeyi geri al - - + + State &%1 Konum &%1 - + Load camera image... Kamera resmini yükle ... - + Convert save game... Kayıtlı oyun dömnüştürülüyor... - + GameShark saves (*.gsv *.sps *.xps) - + Reset needed - + Some changes will not take effect until the game is reset. - + New multiplayer window Yeni çokoyunculu ekranı - + Connect to Dolphin... Dolphin'e BaÄŸlan... - + Report bug... Hata rapor et... - + About... Hakkında... - + E&xit Çıkış - + &Emulation Emülasyon - + &Reset &Reset - + Sh&utdown Kapat - + Yank game pak - + &Pause &Durdur - + &Next frame &Sonraki kare - + Fast forward (held) Ä°leriye sar(basılı tutun) - + &Fast forward &Ä°leriye sar - + Fast forward speed Ä°leriye sarma hızı - + Unbounded - + %0x - + Increase fast forward speed - + Decrease fast forward speed - + Rewind (held) Geri sar (basılı tutun) - + Re&wind Geri sar - + Step backwards Geriye doÄŸru adım - + Solar sensor - + Increase solar level Solar seviyesini arttır - + Decrease solar level Solar seviyesini düşür - + Brightest solar level En parlak solar seviyesi - + Darkest solar level En karanlık solar seviyesi - + Brightness %1 Parlaklık:%1 - + Game Boy Printer... Game Boy yazıcısı... - + BattleChip Gate... - + Audio/&Video Ses/&Video - + Frame size Çerçeve boyutu - + Toggle fullscreen Tamekranı aç/kapa - + + &Lock frame size + + + + Lock aspect ratio En boy oranını kilitle - + Force integer scaling Tamsayılı ölçeklendirmeyi zorla - + Bilinear filtering Bilinear filtreleme - + Frame&skip Kare atlama - + Mute Sessiz - + FPS target FPS hedefi - + Native (59.7275) - + Take &screenshot Ekran görüntüsü al - + F12 - + Video layers - + Audio channels Ses kanalları - + Adjust layer placement... Katman yerleÅŸimini ayarlayın... - + &Tools &Araçlar - + View &logs... Kayıtları görüntüle... - + Game &overrides... & Oyunun üzerine yazılanlar... - + Couldn't Start BaÅŸlatılamadı - + Save games (%1) Kayıtlı oyunlar (%1) - + Select save game Kayıtlı oyun seç - + mGBA save state files (%1) mGBA kayıt durum dosyası (%1) - - + + Select save state Kayıt durumu seç - + Could not start game. Oyun baÅŸlatılamadı. - + Load alternate save game... Alternatif kayıtlı oyun yükle... - + Load temporary save game... Geçici kayıtlı oyunu yükle... - + Scan e-Reader dotcodes... e-Okuyucu noktakodları tara... - + Import GameShark Save... GameShark kaydını içeri aktar... - + Export GameShark Save... GameShark kaydını dışarı aktar... - + %1× %1× - + Interframe blending Kareler-arası Karıştırma - + Record A/V... A/V Kayıt... - + Record GIF/WebP/APNG... GIF/WebP/APNG Kayıt... - + Game Pak sensors... Oyun KartuÅŸ sensörleri... - + &Cheats... &Hileler... - + Settings... Ayarlar... - + Open debugger console... Hata ayıklayıcı konsolunu aç ... - + Start &GDB server... &GDB sunucusunu baÅŸlat... - + Scripting... - + View &palette... &Renk Paletini gör... - + View &sprites... &Spriteları gör... - + View &tiles... &Desenleri gör... - + View &map... &Haritayı gör - + &Frame inspector... &Kare denetçisi... - + View memory... Hafıza gör... - + Search memory... Hafızada ara... - + View &I/O registers... &I/O kayıtlarını görüntüle - + Record debug video log... Hata ayıklama video günlüğünü kaydet... - + Stop debug video log Hata ayıklama video günlüğünü durdur - + Exit fullscreen Tam ekrandan çık - + GameShark Button (held) GameShark Butonu (basılı tutun) - + Autofire Otomatik basma - + Autofire A Otomatik basma A - + Autofire B Otomatik basma B - + Autofire L Otomatik basma L - + Autofire R Otomatik basma R - + Autofire Start Otomatik basma Start - + Autofire Select Otomatik basma Select - + Autofire Up Otomatik basma Up - + Autofire Right Otomatik basma Right - + Autofire Down Otomatik basma Down - + Autofire Left Otomatik basma Sol - + Clear Temizle @@ -6767,17 +6771,17 @@ Yeni sürüm: %2 - + Super (L) Süper (L) - + Super (R) Süper (R) - + Menu Menü @@ -6785,22 +6789,22 @@ Yeni sürüm: %2 QShortcut - + Shift Shift - + Control Kontrol - + Alt Alt - + Meta Derece diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index 4e570c196..0a0dfef75 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -4,22 +4,22 @@ QGBA - + Game Boy Advance ROMs (%1) Game Boy Advance ROMs (%1) - + Game Boy ROMs (%1) Game Boy ROMs (%1) - + All ROMs (%1) 所有 ROMs (%1) - + %1 Video Logs (*.mvl) %1 视频日志 (*.mvl) @@ -191,17 +191,17 @@ Download size: %3 QGBA::AudioDevice - + Can't set format of context-less audio device æ— æ³•è®¾ç½®æ— ä¸Šä¸‹æ–‡éŸ³é¢‘è®¾å¤‡çš„æ ¼å¼ - + Audio device is missing its core 音频设备缺少其核心 - + Writing data to read-only audio device 将数æ®å†™å…¥åªè¯»éŸ³é¢‘设备 @@ -209,7 +209,7 @@ Download size: %3 QGBA::AudioProcessorQt - + Can't start an audio processor without input 没有输入无法å¯åŠ¨éŸ³é¢‘处ç†å™¨ @@ -285,28 +285,28 @@ Download size: %3 显示高级选项 - + BattleChip data missing 缺失 BattleChip æ•°æ® - + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? 缺少 BattleChip æ•°æ®ã€‚BattleChip Gate ä»ç„¶å¯ä»¥ä½¿ç”¨,但一些图形将会丢失。您è¦ç«‹å³ä¸‹è½½æ•°æ®å—? - - + + Select deck file 选择å¡åº§æ–‡ä»¶ - + Incompatible deck ä¸å…¼å®¹çš„å¡åº§ - + The selected deck is not compatible with this Chip Gate 选定的å¡åº§ä¸Žæ­¤ Chip Gate ä¸å…¼å®¹ @@ -367,19 +367,19 @@ Download size: %3 在此处输入代ç ... - - + + Autodetect (recommended) 自动检测(推è) - - + + Select cheats file 选择作弊ç æ–‡ä»¶ - + Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types. 无法添加æŸäº›ä½œå¼Šç ã€‚请确认它们的格å¼æ˜¯å¦æ­£ç¡®å¹¶ä¸”/或å°è¯•å…¶å®ƒçš„作弊类型。 @@ -398,37 +398,37 @@ Download size: %3 当å‰æœªå¼€å¯å€’带 - + Reset the game? è¦é‡ç½®æ¸¸æˆå—? - + Most games will require a reset to load the new save. Do you want to reset now? 大多数游æˆéœ€è¦é‡ç½®æ‰èƒ½åŠ è½½æ–°çš„存档。您è¦ç«‹å³é‡å¯å—? - + Failed to open save file: %1 打开存档失败: %1 - + Failed to open game file: %1 打开游æˆæ–‡ä»¶å¤±è´¥: %1 - + Can't yank pack in unexpected platform! 无法在æ„外平å°ä¸ŠæŠ½å‡ºå¡å¸¦ï¼ - + Failed to open snapshot file for reading: %1 读å–快照文件失败: %1 - + Failed to open snapshot file for writing: %1 写入快照文件失败: %1 @@ -477,6 +477,14 @@ Download size: %3 无法打开用于写入的 CLI åŽ†å² + + QGBA::DisplayGL + + + Failed to create an OpenGL 3 context, trying old-style... + + + QGBA::DolphinConnector @@ -757,52 +765,52 @@ Download size: %3 é‡ç½® - + Export frame 导出框架 - + Portable Network Graphics (*.png) 便æºå¼ç½‘络图形 (*.png) - + None æ—  - + Background 背景 - + Window çª—å£ - + Objwin Objwin - + Sprite ç²¾çµå›¾ - + Backdrop 背幕 - + Frame 帧 - + %1 %2 %1 %2 @@ -818,22 +826,22 @@ Download size: %3 QGBA::GBAKeyEditor - + Clear Button 清除按键 - + Clear Analog 清除模拟控制 - + Refresh 刷新 - + Set all 全部设置 @@ -3006,8 +3014,8 @@ Download size: %3 QGBA::KeyEditor - - + + --- --- @@ -3378,23 +3386,87 @@ Download size: %3 åž‚ç›´ - - - + + + N/A æ—  - + Export map 导出映射 - + Portable Network Graphics (*.png) 便æºå¼ç½‘络图形 (*.png) + + QGBA::MemoryAccessLogView + + + Memory access logging + + + + + Log file + + + + + Browse + æµè§ˆ + + + + Log additional information (uses 3× space) + + + + + Load existing file if present + + + + + Regions + + + + + Export ROM snapshot + + + + + Start + + + + + Stop + åœæ­¢ + + + + Failed to open memory log file + + + + + + Select access log file + + + + + Memory access logs (*.mal) + + + QGBA::MemoryDump @@ -3641,22 +3713,22 @@ Download size: %3 刷新 - + (%0/%1×) (%0/%1×) - + (â…Ÿ%0×) (â…Ÿ%0×) - + (%0×) (%0×) - + %1 byte%2 %1 字节%2 @@ -3750,17 +3822,17 @@ Download size: %3 QGBA::MultiplayerController - + Trying to detach a multiplayer player that's not attached å°è¯•æ–­å¼€ä¸Žæœªè¿žæŽ¥çš„多人玩家的连接 - + Trying to get player ID for a multiplayer player that's not attached å°è¯•èŽ·å–未连接的多人玩家的 ID - + Trying to get save ID for a multiplayer player that's not attached å°è¯•èŽ·å–未连接的多人玩家的存档 ID @@ -4157,35 +4229,35 @@ Download size: %3 导出 OBJ - + #%0 #%0 - + 0x%0 0x%0 + + - - 0x%0 (%1) 0x%0 (%1) - + Export palette å¯¼å‡ºè°ƒè‰²æ¿ - + Windows PAL (*.pal);;Adobe Color Table (*.act) Windows è°ƒè‰²æ¿ (*.pal);;Adobe 颜色表 (*.act) - + Failed to open output palette file: %1 打开输出调色æ¿æ–‡ä»¶å¤±è´¥: %1 @@ -4259,7 +4331,7 @@ Download size: %3 QGBA::ROMInfo - + @@ -4299,16 +4371,26 @@ Download size: %3 + Maker Code: + + + + + Revision: + + + + File size: 文件大å°: - + CRC32: CRC32: - + Save file: ä¿å­˜æ–‡ä»¶: @@ -4364,62 +4446,62 @@ Download size: %3 QGBA::SaveConverter - + Save games and save states (%1) ä¿å­˜æ¸¸æˆå’Œå³æ—¶å­˜æ¡£ (%1) - + Select save game or save state 选择ä¿å­˜æ¸¸æˆæˆ–å³æ—¶å­˜æ¡£ - + Save games (%1) ä¿å­˜æ¸¸æˆ (%1) - + Select save game 选择ä¿å­˜æ¸¸æˆ - + Conversion failed 转æ¢å¤±è´¥ - + Failed to convert the save game. This is probably a bug. 未能转æ¢ä¿å­˜æ¸¸æˆã€‚è¿™å¯èƒ½æ˜¯ä¸€ä¸ªé”™è¯¯ã€‚ - + No file selected 未选择文件 - + Could not open file 无法打开文件 - + No valid formats found æœªæ‰¾åˆ°æœ‰æ•ˆæ ¼å¼ - + Please select a valid input file 请选择一个有效的输入文件 - + No valid conversions found 未å‘çŽ°æœ‰æ•ˆè½¬æ¢ - + Cannot convert save games between platforms 无法在平å°ä¹‹é—´è½¬æ¢ä¿å­˜æ¸¸æˆ @@ -4445,97 +4527,97 @@ Download size: %3 输出文件 - + %1 %2 save game %1 %2 ä¿å­˜æ¸¸æˆ - + little endian å°ç«¯ - + big endian 大端 - + SRAM - + %1 flash %1 闪存 - + %1 EEPROM - + + RTC - + %1 SRAM + RTC - + %1 SRAM - + packed MBC2 包装的 MBC2 - + unpacked MBC2 未包装的 MBC2 - + MBC6 flash MBC6 闪存 - + MBC6 combined SRAM + flash MBC6组åˆSRAM+闪存 - + MBC6 SRAM MBC6 SRAM - + TAMA5 - + %1 (%2) %1(%2) - + %1 save state with embedded %2 save game 带嵌入的 %2 ä¿å­˜æ¸¸æˆçš„ %1 ä¿å­˜çŠ¶æ€ - + %1 SharkPort %2 save game %1 SharkPort %2 存档 - + %1 GameShark Advance SP %2 save game %1 GameShark Advance SP %2 存档 @@ -4571,32 +4653,37 @@ Download size: %3 载入历å²è„šæœ¬ - + Load script... 载入脚本... - + + &Load most recent + + + + &Reset é‡ç½®(&R) - + 0 - + Select script to load 选择è¦è½½å…¥çš„脚本 - + Lua scripts (*.lua) Lua 脚本 (*.lua) - + All files (*.*) 所有文件 (*.*) @@ -4689,112 +4776,112 @@ Download size: %3 QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) 软件渲染 (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (强制版本 1.x) - + None æ—  - + None (Still Image) æ—  (é™æ­¢å›¾åƒ) - + Keyboard 键盘 - + Controllers 控制器 - + Shortcuts å¿«æ·é”® - - + + Shaders ç€è‰²å™¨ - + Select BIOS 选择 BIOS - + Select directory 选择目录 - + Select image 选择图片 - + Image file (*.png *.jpg *.jpeg) 图åƒæ–‡ä»¶ï¼ˆ*.png *.jpg *.jpeg) - + (%1×%2) (%1×%2) - + Never ä»Žä¸ - + Just now 刚刚 - + Less than an hour ago ä¸åˆ°ä¸€å°æ—¶å‰ - + %n hour(s) ago %n å°æ—¶å‰ - + %n day(s) ago %n å¤©å‰ @@ -5120,37 +5207,37 @@ Download size: %3 ç«‹å³æ£€æŸ¥æ›´æ–° - + Default color palette only åªä½¿ç”¨é»˜è®¤è°ƒè‰²æ¿ - + SGB color palette if available å¯ç”¨æ—¶ä½¿ç”¨ SGB è°ƒè‰²æ¿ - + GBC color palette if available å¯ç”¨æ—¶ä½¿ç”¨ GBC è°ƒè‰²æ¿ - + SGB (preferred) or GBC color palette if available å¯ç”¨æ—¶ä½¿ç”¨ SGB(首选)或 GBC è°ƒè‰²æ¿ - + Game Boy Camera Game Boy Camera - + Driver: 驱动: - + Source: æ¥æºï¼š @@ -5327,42 +5414,42 @@ Download size: %3 载入存档附加数æ®ï¼š - + Models åž‹å· - + GB only: ä»… GB: - + SGB compatible: 兼容 SGB: - + GBC only: ä»… GBC: - + GBC compatible: 兼容 GBC: - + SGB and GBC compatible: 兼容 SGB å’Œ GBC: - + Game Boy palette Game Boy è°ƒè‰²æ¿ - + Preset: 预设: @@ -5399,135 +5486,130 @@ Download size: %3 软件 - + OpenGL enhancements OpenGL 增强 - + High-resolution scale: 高分辨率比例: - + (240×160) (240×160) - - XQ GBA audio (experimental) - XQ GBA 音频 (实验性) - - - + GB BIOS file: GB BIOS 文件: - - - - - - - - - + + + + + + + + + Browse æµè§ˆ - + Use BIOS file if found 当å¯ç”¨æ—¶ä½¿ç”¨ BIOS 文件 - + Skip BIOS intro 跳过 BIOS å¯åŠ¨ç”»é¢ - + GBA BIOS file: GBA BIOS 文件: - + GBC BIOS file: GBC BIOS 文件: - + SGB BIOS file: SGB BIOS 文件: - + Save games 游æˆå­˜æ¡£ - - - - - + + + + + Same directory as the ROM 与 ROM æ‰€åœ¨ç›®å½•ç›¸åŒ - + Save states å³æ—¶å­˜æ¡£ - + Screenshots 截图 - + Patches è¡¥ä¸ - + Cheats ä½œå¼Šç  - + Log to file 记录日志到文件 - + Log to console è®°å½•æ—¥å¿—åˆ°æŽ§åˆ¶å° - + Select Log File 选择日志文件 - + Default BG colors: 默认背景色: - + Default sprite colors 1: 默认精çµå›¾é¢œè‰² 1: - + Default sprite colors 2: 默认精çµå›¾é¢œè‰² 2: - + Super Game Boy borders Super Game Boy 边框 @@ -5785,13 +5867,11 @@ Download size: %3 - WebM WebM - MP4 MP4 @@ -5830,82 +5910,6 @@ Download size: %3 Format æ ¼å¼ - - - MKV - MKV - - - - AVI - AVI - - - - HEVC - HEVC - - - - HEVC (NVENC) - HEVC (NVENC) - - - - VP8 - VP8 - - - - VP9 - VP9 - - - - FFV1 - FFV1 - - - - - None - æ—  - - - - FLAC - FLAC - - - - WavPack - WavPack - - - - Opus - Opus - - - - Vorbis - Vorbis - - - - MP3 - MP3 - - - - AAC - AAC - - - - Uncompressed - 未压缩 - Bitrate (kbps) @@ -5916,16 +5920,6 @@ Download size: %3 ABR ABR - - - H.264 - H.264 - - - - H.264 (NVENC) - H.264 (NVENC) - VBR @@ -5955,80 +5949,80 @@ Download size: %3 QGBA::Window - + Archives (%1) 压缩文件 (%1) - - + + Select ROM 选择 ROM - + Select folder 选择文件夹 - - + + Select save 选择存档 - + Select patch é€‰æ‹©è¡¥ä¸ - + Patches (*.ips *.ups *.bps) è¡¥ä¸ (*.ips *.ups *.bps) - + Select e-Reader dotcode 选择 e-Reader ç‚¹ç  - + e-Reader card (*.raw *.bin *.bmp) e-Reader å¡ (*.raw *.bin *.bmp) - + Select image 选择图片 - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) 图åƒæ–‡ä»¶ (*.png *.gif *.jpg *.jpeg);;所有文件 (*) - + GameShark saves (*.sps *.xps) GameShark 存档 (*.sps *.xps) - + Select video log 选择视频日志 - + Video logs (*.mvl) 视频日志文件 (*.mvl) - + Crash 崩溃 - + The game has crashed with the following error: %1 @@ -6037,699 +6031,709 @@ Download size: %3 %1 - + Couldn't Start 无法å¯åŠ¨ - + Could not start game. 无法å¯åŠ¨æ¸¸æˆã€‚ - + Unimplemented BIOS call 未实现的 BIOS 调用 - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. 此游æˆä½¿ç”¨å°šæœªå®žçŽ°çš„ BIOS 调用。请使用官方 BIOS 以获得最佳体验。 - + Failed to create an appropriate display device, falling back to software display. Games may run slowly, especially with larger windows. 无法创建适åˆçš„显示设备,正在回滚到软件显示。游æˆçš„è¿è¡Œé€Ÿåº¦ï¼ˆç‰¹åˆ«åœ¨å¤§çª—å£çš„情况下)å¯èƒ½ä¼šå˜æ…¢ã€‚ - + Really make portable? 确定进行程åºä¾¿æºåŒ–? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? 进行此æ“作åŽï¼Œæ¨¡æ‹Ÿå™¨å°†ä»Žå…¶å¯æ‰§è¡Œæ–‡ä»¶æ‰€åœ¨ç›®å½•ä¸­è½½å…¥æ¨¡æ‹Ÿå™¨é…置。您想继续å—? - + Restart needed 需è¦é‡æ–°å¯åŠ¨ - + Some changes will not take effect until the emulator is restarted. 更改将在模拟器下次é‡æ–°å¯åŠ¨æ—¶ç”Ÿæ•ˆã€‚ - + - Player %1 of %2 - 玩家 %1 å…± %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File 文件(&F) - + Load &ROM... 载入 ROM(&R)... - + Load ROM in archive... 从压缩文件中载入 ROM... - + Add folder to library... 将文件夹添加到库中... - + Save games (%1) ä¿å­˜æ¸¸æˆ (%1) - + Select save game 选择ä¿å­˜æ¸¸æˆ - + mGBA save state files (%1) mGBA å³æ—¶å­˜æ¡£æ–‡ä»¶ (%1) - - + + Select save state 选择å³æ—¶å­˜æ¡£ - + Select e-Reader card images 选择 e-Reader å¡ç‰‡å›¾åƒ - + Image file (*.png *.jpg *.jpeg) 图åƒæ–‡ä»¶ï¼ˆ*.png *.jpg *.jpeg) - + Conversion finished 转æ¢å®Œæˆ - + %1 of %2 e-Reader cards converted successfully. æˆåŠŸè½¬æ¢äº† %1 张(共 %2 张)e-Reader å¡ç‰‡ã€‚ - + Load alternate save game... 加载备用ä¿å­˜æ¸¸æˆ... - + Load temporary save game... 加载临时ä¿å­˜æ¸¸æˆ... - + Load &patch... 载入补ä¸(&P)... - + Boot BIOS 引导 BIOS - + Replace ROM... æ›¿æ¢ ROM... - + Scan e-Reader dotcodes... 扫æ e-Reader 点ç ... - + Convert e-Reader card image to raw... å°† e-Reader å¡ç‰‡å›¾åƒè½¬æ¢ä¸ºåŽŸå§‹æ•°æ®... - + ROM &info... ROM ä¿¡æ¯(&I)... - + Recent 最近打开 - + Make portable 程åºä¾¿æºåŒ– - + &Load state 载入å³æ—¶å­˜æ¡£(&L) - + Load state file... 载入å³æ—¶å­˜æ¡£æ–‡ä»¶... - + &Save state ä¿å­˜å³æ—¶å­˜æ¡£(&S) - + Save state file... ä¿å­˜å³æ—¶å­˜æ¡£æ–‡ä»¶... - + Quick load 快速读档 - + Quick save 快速存档 - + Load recent 载入最近存档 - + Save recent ä¿å­˜æœ€è¿‘存档 - + Undo load state 撤消读档 - + Undo save state 撤消存档 - - + + State &%1 å³æ—¶å­˜æ¡£ (&%1) - + Load camera image... 载入相机图片... - + Convert save game... 转æ¢ä¿å­˜æ¸¸æˆ... - + GameShark saves (*.gsv *.sps *.xps) GameShark 存档 (*.gsv *.sps *.xps) - + Reset needed 需è¦é‡å¯ - + Some changes will not take effect until the game is reset. æŸäº›æ”¹åŠ¨éœ€è¦é‡æ–°å¯åŠ¨æ‰ä¼šç”Ÿæ•ˆã€‚ - + Save games 游æˆå­˜æ¡£ - + Import GameShark Save... 导入 GameShark 存档... - + Export GameShark Save... 导出 GameShark 存档... - + Automatically determine 自动终止 - + Use player %0 save game 使用玩家 %0 存档 - + New multiplayer window 新建多人游æˆçª—å£ - + Connect to Dolphin... 连接到 Dolphin... - + Report bug... 报告错误... - + About... 关于... - + E&xit 退出(&X) - + &Emulation 模拟(&E) - + &Reset é‡ç½®(&R) - + Sh&utdown 关机(&U) - + Yank game pak 快速抽出游æˆå¡å¸¦ - + &Pause æš‚åœ(&P) - + &Next frame 下一帧(&N) - + Fast forward (held) å¿«è¿› (长按) - + &Fast forward å¿«è¿›(&F) - + Fast forward speed 快进速度 - + Unbounded ä¸é™åˆ¶ - + %0x %0x - + Increase fast forward speed 加快快进速度 - + Decrease fast forward speed é™ä½Žå¿«è¿›é€Ÿåº¦ - + Rewind (held) 倒带 (长按) - + Re&wind 倒带(&W) - + Step backwards 步退 - + Solar sensor 太阳光传感器 - + Increase solar level 增加太阳光等级 - + Decrease solar level é™ä½Žå¤ªé˜³å…‰ç­‰çº§ - + Brightest solar level 太阳光等级为最亮 - + Darkest solar level 太阳光等级为最暗 - + Brightness %1 亮度 %1 - + Game Boy Printer... Game Boy 打å°æœº... - + BattleChip Gate... BattleChip Gate... - + Audio/&Video 音频/视频(&V) - + Frame size ç”»é¢å¤§å° - + %1× %1× - + Toggle fullscreen 切æ¢å…¨å± - + + &Lock frame size + + + + Lock aspect ratio é”定纵横比 - + Force integer scaling 强制整数缩放 - + Interframe blending å¸§é—´æ··åˆ - + Bilinear filtering åŒçº¿æ€§è¿‡æ»¤ - + Frame&skip 跳帧(&S) - + Mute é™éŸ³ - + FPS target 目标 FPS - + Native (59.7275) 原生 (59.7275) - + Take &screenshot 截图(&S) - + F12 F12 - + Record A/V... 录制音频/视频... - + Record GIF/WebP/APNG... 录制 GIF/WebP/APNG... - + Video layers 视频图层 - + Audio channels éŸ³é¢‘å£°é“ - + Adjust layer placement... 调整图层布局... - + &Tools 工具(&T) - + View &logs... 查看日志(&L)... - + Game &overrides... 覆写游æˆ(&O)... - + Game Pak sensors... 游æˆå¡å¸¦ä¼ æ„Ÿå™¨... - + &Cheats... 作弊ç (&C)... - + Create forwarder... 创建转å‘器... - + Settings... 设置... - + Open debugger console... 打开调试器控制å°... - + Start &GDB server... 打开 GDB æœåŠ¡å™¨(&G)... - + Scripting... 脚本... - + Game state views 游æˆçŠ¶æ€è§†å›¾ - + View &palette... 查看调色æ¿(&P)... - + View &sprites... 查看精çµå›¾(&S)... - + View &tiles... 查看图å—(&T)... - + View &map... 查看映射(&M)... - + &Frame inspector... 帧检查器(&F)... - + View memory... 查看内存... - + Search memory... æœç´¢å†…å­˜... - + View &I/O registers... 查看 I/O 寄存器(&I)... - + + Log memory &accesses... + + + + Record debug video log... 记录调试视频日志... - + Stop debug video log åœæ­¢è®°å½•è°ƒè¯•è§†é¢‘日志 - + Exit fullscreen é€€å‡ºå…¨å± - + GameShark Button (held) GameShark é”® (长按) - + Autofire è¿žå‘ - + Autofire A è¿žå‘ A - + Autofire B è¿žå‘ B - + Autofire L è¿žå‘ L - + Autofire R è¿žå‘ R - + Autofire Start è¿žå‘ Start - + Autofire Select è¿žå‘ Select - + Autofire Up è¿žå‘ ä¸Š - + Autofire Right è¿žå‘ å³ - + Autofire Down è¿žå‘ ä¸‹ - + Autofire Left è¿žå‘ å·¦ - + Clear 清除 @@ -6767,17 +6771,17 @@ Download size: %3 ? - + Super (L) Super (L) - + Super (R) Super (R) - + Menu èœå• @@ -6785,22 +6789,22 @@ Download size: %3 QShortcut - + Shift Shift - + Control Control - + Alt Alt - + Meta Meta From 271c6dc1298f07eb34338f886fe2dbdcfdc04ceb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 16 Sep 2024 03:51:08 -0700 Subject: [PATCH 268/336] Res: Update gba-colors shader (closes #2976) --- res/shaders/gba-color.shader/gba-color.fs | 35 +++++++---------------- res/shaders/gba-color.shader/gba-color.vs | 34 ++++++++++++++++++++++ res/shaders/gba-color.shader/manifest.ini | 8 ++++++ 3 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 res/shaders/gba-color.shader/gba-color.vs diff --git a/res/shaders/gba-color.shader/gba-color.fs b/res/shaders/gba-color.shader/gba-color.fs index 09177ddfe..461228c20 100644 --- a/res/shaders/gba-color.shader/gba-color.fs +++ b/res/shaders/gba-color.shader/gba-color.fs @@ -1,34 +1,21 @@ +// Shader that replicates the LCD Colorspace from Gameboy Advance -- varying vec2 texCoord; +varying mat4 profile; uniform sampler2D tex; uniform vec2 texSize; uniform float darken_screen; -const float target_gamma = 2.2; -const float display_gamma = 2.5; -const float sat = 1.0; -const float lum = 0.99; -const float contrast = 1.0; -const vec3 bl = vec3(0.0, 0.0, 0.0); -const vec3 r = vec3(0.84, 0.09, 0.15); -const vec3 g = vec3(0.18, 0.67, 0.10); -const vec3 b = vec3(0.0, 0.26, 0.73); +const float target_gamma = 2.0; +const float display_gamma = 2.0; void main() { + // bring out our stored luminance value + float lum = profile[3].w; + + // our adjustments need to happen in linear gamma vec4 screen = pow(texture2D(tex, texCoord), vec4(target_gamma + darken_screen)).rgba; - vec4 avglum = vec4(0.5); - screen = mix(screen, avglum, (1.0 - contrast)); - - mat4 color = mat4( r.r, r.g, r.b, 0.0, - g.r, g.g, g.b, 0.0, - b.r, b.g, b.b, 0.0, - bl.r, bl.g, bl.b, 1.0); - - mat4 adjust = mat4( (1.0 - sat) * 0.3086 + sat, (1.0 - sat) * 0.3086, (1.0 - sat) * 0.3086, 1.0, - (1.0 - sat) * 0.6094, (1.0 - sat) * 0.6094 + sat, (1.0 - sat) * 0.6094, 1.0, - (1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820 + sat, 1.0, - 0.0, 0.0, 0.0, 1.0); - color *= adjust; + screen = clamp(screen * lum, 0.0, 1.0); - screen = color * screen; - gl_FragColor = pow(screen, vec4(1.0 / display_gamma + (darken_screen * 0.125))); + screen = profile * screen; + gl_FragColor = pow(screen, vec4(1.0 / display_gamma)); } diff --git a/res/shaders/gba-color.shader/gba-color.vs b/res/shaders/gba-color.shader/gba-color.vs new file mode 100644 index 000000000..bbf406278 --- /dev/null +++ b/res/shaders/gba-color.shader/gba-color.vs @@ -0,0 +1,34 @@ +uniform int color_mode; +attribute vec4 position; +varying vec2 texCoord; +varying mat4 profile; + +const mat4 GBA_sRGB = mat4( + 0.80, 0.135, 0.195, 0.0, //red channel + 0.275, 0.64, 0.155, 0.0, //green channel + -0.075, 0.225, 0.65, 0.0, //blue channel + 0.0, 0.0, 0.0, 0.93 //alpha channel +); + +const mat4 GBA_DCI = mat4( + 0.685, 0.16, 0.20, 0.0, //red channel + 0.34, 0.629, 0.19, 0.0, //green channel + -0.025, 0.211, 0.61, 0.0, //blue channel + 0.0, 0.0, 0.0, 0.975 //alpha channel +); + +const mat4 GBA_Rec2020 = mat4( + 0.555, 0.1825, 0.20, 0.0, //red channel + 0.395, 0.61, 0.195, 0.0, //green channel + 0.05, 0.2075, 0.605, 0.0, //blue channel + 0.0, 0.0, 0.0, 1.0 //alpha channel +); + +void main() { + if (color_mode == 1) profile = GBA_sRGB; + else if (color_mode == 2) profile = GBA_DCI; + else if (color_mode == 3) profile = GBA_Rec2020; + + gl_Position = position; + texCoord = (position.st + vec2(1.0, 1.0)) * vec2(0.5, 0.5); +} diff --git a/res/shaders/gba-color.shader/manifest.ini b/res/shaders/gba-color.shader/manifest.ini index 8f9735aa3..ed16900cd 100644 --- a/res/shaders/gba-color.shader/manifest.ini +++ b/res/shaders/gba-color.shader/manifest.ini @@ -6,6 +6,7 @@ passes=1 [pass.0] fragmentShader=gba-color.fs +vertexShader=gba-color.vs blend=1 width=-1 height=-1 @@ -14,3 +15,10 @@ height=-1 type=float default=0.5 readableName=Darken Screen + +[pass.0.uniform.color_mode] +type=int +default=1 +min=1 +max=3 +readableName=Color Profile (1=sRGB, 2=DCI, 3=Rec2020) From 11787df6cd48e93ef4552b1b61393d5a734fe3c0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 16 Sep 2024 03:58:39 -0700 Subject: [PATCH 269/336] Res: Port NSO-gba-colors shader (closes #2834) --- CHANGES | 1 + res/shaders/nso-gba-color.shader/manifest.ini | 24 +++++++++++++ .../nso-gba-color.shader/nso-gba-color.fs | 21 ++++++++++++ .../nso-gba-color.shader/nso-gba-color.vs | 34 +++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 res/shaders/nso-gba-color.shader/manifest.ini create mode 100644 res/shaders/nso-gba-color.shader/nso-gba-color.fs create mode 100644 res/shaders/nso-gba-color.shader/nso-gba-color.vs diff --git a/CHANGES b/CHANGES index 3aef9e246..ef075bd9c 100644 --- a/CHANGES +++ b/CHANGES @@ -52,6 +52,7 @@ Misc: - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Qt: Pass logging context through to video proxy thread (fixes mgba.io/i/3095) - Qt: Show maker code and game version in ROM info + - Res: Port NSO-gba-colors shader (closes mgba.io/i/2834) - Scripting: Add `callbacks:oneshot` for single-call callbacks - Switch: Add bilinear filtering option (closes mgba.io/i/3111) - Vita: Add imc0 and xmc0 mount point support diff --git a/res/shaders/nso-gba-color.shader/manifest.ini b/res/shaders/nso-gba-color.shader/manifest.ini new file mode 100644 index 000000000..42faa25bd --- /dev/null +++ b/res/shaders/nso-gba-color.shader/manifest.ini @@ -0,0 +1,24 @@ +[shader] +name=NSO GBA Color +author=Pokefan531 and hunterk +description=Shader that replicates the Nintendo Switch Online's GBA color filter. +passes=1 + +[pass.0] +fragmentShader=nso-gba-color.fs +vertexShader=nso-gba-color.vs +blend=1 +width=-1 +height=-1 + +[pass.0.uniform.darken_screen] +type=float +default=0.8 +readableName=Darken Screen + +[pass.0.uniform.color_mode] +type=int +default=1 +min=1 +max=3 +readableName=Color Profile (1=sRGB, 2=DCI, 3=Rec2020) diff --git a/res/shaders/nso-gba-color.shader/nso-gba-color.fs b/res/shaders/nso-gba-color.shader/nso-gba-color.fs new file mode 100644 index 000000000..8d8a0ec92 --- /dev/null +++ b/res/shaders/nso-gba-color.shader/nso-gba-color.fs @@ -0,0 +1,21 @@ +// Shader that replicates the LCD Colorspace from Gameboy Advance -- +varying vec2 texCoord; +varying mat4 profile; +uniform sampler2D tex; +uniform vec2 texSize; + +uniform float darken_screen; +const float target_gamma = 2.2; +const float display_gamma = 2.2; + +void main() { + // bring out our stored luminance value + float lum = profile[3].w; + + // our adjustments need to happen in linear gamma + vec4 screen = pow(texture2D(tex, texCoord), vec4(target_gamma + darken_screen)).rgba; + + screen = clamp(screen * lum, 0.0, 1.0); + screen = profile * screen; + gl_FragColor = pow(screen, vec4(1.0 / display_gamma)); +} diff --git a/res/shaders/nso-gba-color.shader/nso-gba-color.vs b/res/shaders/nso-gba-color.shader/nso-gba-color.vs new file mode 100644 index 000000000..c9c89181b --- /dev/null +++ b/res/shaders/nso-gba-color.shader/nso-gba-color.vs @@ -0,0 +1,34 @@ +uniform int color_mode; +attribute vec4 position; +varying vec2 texCoord; +varying mat4 profile; + +const mat4 GBA_sRGB = mat4( + 0.865, 0.0575, 0.0575, 0.0, //red channel + 0.1225, 0.925, 0.1225, 0.0, //green channel + 0.0125, 0.0125, 0.82, 0.0, //blue channel + 0.0, 0.0, 0.0, 1.0 //alpha channel +); + +const mat4 GBA_DCI = mat4( + 0.72, 0.0875, 0.0725, 0.0, //red channel + 0.2675, 0.9, 0.185, 0.0, //green channel + 0.0125, 0.0125, 0.7425, 0.0, //blue channel + 0.0, 0.0, 0.0, 1.0 //alpha channel +); + +const mat4 GBA_Rec2020 = mat4( + 0.57, 0.115, 0.0725, 0.0, //red channel + 0.3825, 0.8625, 0.195, 0.0, //green channel + 0.0475, 0.0225, 0.7325, 0.0, //blue channel + 0.0, 0.0, 0.0, 1.0 //alpha channel +); + +void main() { + if (color_mode == 1) profile = GBA_sRGB; + else if (color_mode == 2) profile = GBA_DCI; + else if (color_mode == 3) profile = GBA_Rec2020; + + gl_Position = position; + texCoord = (position.st + vec2(1.0, 1.0)) * vec2(0.5, 0.5); +} From c64dbd6631d0eed88b6ef1cbceddc47cde3000ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 19 Sep 2024 00:05:58 -0700 Subject: [PATCH 270/336] Qt: Make window corners square on Windows 11 (fixes #3285) --- CHANGES | 1 + src/platform/qt/Window.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index ef075bd9c..f225b8b15 100644 --- a/CHANGES +++ b/CHANGES @@ -52,6 +52,7 @@ Misc: - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Qt: Pass logging context through to video proxy thread (fixes mgba.io/i/3095) - Qt: Show maker code and game version in ROM info + - Qt: Make window corners square on Windows 11 (fixes mgba.io/i/3285) - Res: Port NSO-gba-colors shader (closes mgba.io/i/2834) - Scripting: Add `callbacks:oneshot` for single-call callbacks - Switch: Add bilinear filtering option (closes mgba.io/i/3111) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 010dde782..0e3d73b00 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -14,6 +14,10 @@ #include #include +#ifdef Q_OS_WIN +#include +#endif + #ifdef USE_SQLITE3 #include "ArchiveInspector.h" #include "library/LibraryController.h" @@ -717,6 +721,11 @@ void Window::showEvent(QShowEvent* event) { return; } m_wasOpened = true; +#ifdef Q_OS_WIN + HWND hwnd = reinterpret_cast(winId()); + DWM_WINDOW_CORNER_PREFERENCE cornerPref = DWMWCP_DONOTROUND; + DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof(cornerPref)); +#endif if (m_initialSize.isValid()) { resizeFrame(m_initialSize); } From f75f9fd5fdf0868a01732a60aa5b971e828ebecd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 19 Sep 2024 01:01:35 -0700 Subject: [PATCH 271/336] Appveyor: Use Windows 11 SDK --- .appveyor.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 552fdbd2f..586eb059e 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,7 +12,11 @@ install: - vcpkg --no-dry-run upgrade - rd /Q /S C:\Tools\vcpkg\buildtrees before_build: -- cmake . -DCMAKE_PREFIX_PATH=C:\Qt\5.15\msvc2019_64 -DCMAKE_TOOLCHAIN_FILE=C:\Tools\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-release -DCMAKE_CONFIGURATION_TYPES=Release +- cmake . -DCMAKE_PREFIX_PATH=C:\Qt\5.15\msvc2019_64 \ + -DCMAKE_TOOLCHAIN_FILE=C:\Tools\vcpkg\scripts\buildsystems\vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-windows-release \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DCMAKE_SYSTEM_VERSION=10.0.22000.1 build: parallel: true project: mGBA.sln From 49fa1a30c581cd868365c76d6136885a1bdcf238 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 19 Sep 2024 02:09:20 -0700 Subject: [PATCH 272/336] Qt: Fix Windows shared build --- src/platform/qt/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 041ad0830..51aa22401 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -427,6 +427,7 @@ set_target_properties(${BINARY_NAME}-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PR if(WIN32) set_target_properties(${BINARY_NAME}-qt PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") + target_link_libraries(${BINARY_NAME}-qt dwmapi) if(NOT MSVC) target_link_libraries(${BINARY_NAME}-qt -municode) endif() @@ -445,7 +446,7 @@ if(QT_STATIC) if(CMAKE_CROSSCOMPILING) set(QWINDOWS_DEPS ${QT}EventDispatcherSupport ${QT}FontDatabaseSupport ${QT}ThemeSupport ${QT}WindowsUIAutomationSupport) endif() - list(APPEND QT_LIBRARIES ${QT}::QWindowsIntegrationPlugin ${QWINDOWS_DEPS} amstrmid dwmapi uxtheme imm32 -static-libgcc -static-libstdc++) + list(APPEND QT_LIBRARIES ${QT}::QWindowsIntegrationPlugin ${QWINDOWS_DEPS} amstrmid uxtheme imm32 -static-libgcc -static-libstdc++) set_target_properties(${QT}::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ssl;crypto;ws2_32;iphlpapi;crypt32;userenv;netapi32;wtsapi32") set_target_properties(${QT}::Gui PROPERTIES INTERFACE_LINK_LIBRARIES ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY}) elseif(APPLE) From 1636078b34195b9801748eed68a7641771b7ef96 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 20 Sep 2024 03:12:06 -0700 Subject: [PATCH 273/336] GBA I/O: Fix audio register 8-bit write behavior (fixes #3086) --- CHANGES | 1 + src/gba/io.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index f225b8b15..9a1694d69 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Emulation fixes: - GBA: Add baseline CP0 (Wii U VC) and CP1 (DCC) implementations - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) + - GBA I/O: Fix audio register 8-bit write behavior (fixes mgba.io/i/3086) - GBA Serialize: Fix some minor save state edge cases - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) diff --git a/src/gba/io.c b/src/gba/io.c index 397eb9253..8853e4d6f 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -326,17 +326,19 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { break; case GBA_REG_SOUND1CNT_HI: GBAAudioWriteSOUND1CNT_HI(&gba->audio, value); + value &= 0xFFC0; break; case GBA_REG_SOUND1CNT_X: GBAAudioWriteSOUND1CNT_X(&gba->audio, value); - value &= 0x47FF; + value &= 0x4000; break; case GBA_REG_SOUND2CNT_LO: GBAAudioWriteSOUND2CNT_LO(&gba->audio, value); + value &= 0xFFC0; break; case GBA_REG_SOUND2CNT_HI: GBAAudioWriteSOUND2CNT_HI(&gba->audio, value); - value &= 0x47FF; + value &= 0x4000; break; case GBA_REG_SOUND3CNT_LO: GBAAudioWriteSOUND3CNT_LO(&gba->audio, value); @@ -344,16 +346,15 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { break; case GBA_REG_SOUND3CNT_HI: GBAAudioWriteSOUND3CNT_HI(&gba->audio, value); - value &= 0xE03F; + value &= 0xE000; break; case GBA_REG_SOUND3CNT_X: GBAAudioWriteSOUND3CNT_X(&gba->audio, value); - // TODO: The low bits need to not be readable, but still 8-bit writable - value &= 0x47FF; + value &= 0x4000; break; case GBA_REG_SOUND4CNT_LO: GBAAudioWriteSOUND4CNT_LO(&gba->audio, value); - value &= 0xFF3F; + value &= 0xFF00; break; case GBA_REG_SOUND4CNT_HI: GBAAudioWriteSOUND4CNT_HI(&gba->audio, value); @@ -585,9 +586,96 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) { if (address > GBA_SIZE_IO) { return; } - uint16_t value16 = value << (8 * (address & 1)); - value16 |= (gba->memory.io[(address & (GBA_SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1))); - GBAIOWrite(gba, address & 0xFFFFFFFE, value16); + uint16_t value16; + + switch (address) { + case GBA_REG_SOUND1CNT_HI: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR11(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND1CNT_HI)] &= 0xFF00; + gba->memory.io[GBA_REG(SOUND1CNT_HI)] |= value & 0xC0; + break; + case GBA_REG_SOUND1CNT_HI + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR12(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND1CNT_HI)] &= 0x00C0; + gba->memory.io[GBA_REG(SOUND1CNT_HI)] |= value << 8; + break; + case GBA_REG_SOUND1CNT_X: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR13(&gba->audio.psg, value); + break; + case GBA_REG_SOUND1CNT_X + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR14(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND1CNT_X)] = (value & 0x40) << 8; + break; + case GBA_REG_SOUND2CNT_LO: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR21(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND2CNT_LO)] &= 0xFF00; + gba->memory.io[GBA_REG(SOUND2CNT_LO)] |= value & 0xC0; + break; + case GBA_REG_SOUND2CNT_LO + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR22(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND2CNT_LO)] &= 0x00C0; + gba->memory.io[GBA_REG(SOUND2CNT_LO)] |= value << 8; + break; + case GBA_REG_SOUND2CNT_HI: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR23(&gba->audio.psg, value); + break; + case GBA_REG_SOUND2CNT_HI + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR24(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND2CNT_HI)] = (value & 0x40) << 8; + break; + case GBA_REG_SOUND3CNT_HI: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR31(&gba->audio.psg, value); + break; + case GBA_REG_SOUND3CNT_HI + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + gba->audio.psg.ch3.volume = GBAudioRegisterBankVolumeGetVolumeGBA(value); + gba->memory.io[GBA_REG(SOUND3CNT_HI)] = (value & 0xE0) << 8; + break; + case GBA_REG_SOUND3CNT_X: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR33(&gba->audio.psg, value); + break; + case GBA_REG_SOUND3CNT_X + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR34(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND3CNT_X)] = (value & 0x40) << 8; + break; + case GBA_REG_SOUND4CNT_LO: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR41(&gba->audio.psg, value); + break; + case GBA_REG_SOUND4CNT_LO + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR42(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND4CNT_LO)] = value << 8; + break; + case GBA_REG_SOUND4CNT_HI: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR43(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND4CNT_HI)] &= 0x4000; + gba->memory.io[GBA_REG(SOUND4CNT_HI)] |= value; + break; + case GBA_REG_SOUND4CNT_HI + 1: + GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); + GBAudioWriteNR44(&gba->audio.psg, value); + gba->memory.io[GBA_REG(SOUND4CNT_HI)] &= 0x00FF; + gba->memory.io[GBA_REG(SOUND4CNT_HI)] = (value & 0x40) << 8; + break; + default: + value16 = value << (8 * (address & 1)); + value16 |= (gba->memory.io[(address & (GBA_SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1))); + GBAIOWrite(gba, address & 0xFFFFFFFE, value16); + break; + } } void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) { From c564a20970312ab463f5fcee7f8b72f78380b7c0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 20 Sep 2024 23:21:14 -0700 Subject: [PATCH 274/336] GBA I/O: Fix 8-bit NR44 write --- src/gba/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/io.c b/src/gba/io.c index 8853e4d6f..ea9d8d8b0 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -668,7 +668,7 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) { GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing)); GBAudioWriteNR44(&gba->audio.psg, value); gba->memory.io[GBA_REG(SOUND4CNT_HI)] &= 0x00FF; - gba->memory.io[GBA_REG(SOUND4CNT_HI)] = (value & 0x40) << 8; + gba->memory.io[GBA_REG(SOUND4CNT_HI)] |= (value & 0x40) << 8; break; default: value16 = value << (8 * (address & 1)); From 4b0b6b5d37406f1bb8a4d58ec4a378d756082569 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 26 Sep 2024 21:22:08 -0700 Subject: [PATCH 275/336] Scripting: Fix readRegister return type --- src/core/scripting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/scripting.c b/src/core/scripting.c index a00d5cbdc..dc56c1783 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -520,7 +520,7 @@ mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite16, 2, U32, address, U16, va mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mCore, busWrite32, 2, U32, address, U32, value); // Register functions -mSCRIPT_DECLARE_STRUCT_METHOD(mCore, WSTR, readRegister, _mScriptCoreReadRegister, 1, CHARP, regName); +mSCRIPT_DECLARE_STRUCT_METHOD(mCore, WRAPPER, readRegister, _mScriptCoreReadRegister, 1, CHARP, regName); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mCore, writeRegister, _mScriptCoreWriteRegister, 2, CHARP, regName, S32, value); // Savestate functions From 4cfa9c65457e92ffce0a49985e9f6d4a319482d1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 12 Sep 2024 02:40:03 -0700 Subject: [PATCH 276/336] Python: Remove SIO API pending revamp --- src/platform/python/mgba/gba.py | 66 ------------------------- src/platform/python/sio.c | 88 --------------------------------- src/platform/python/sio.h | 42 ---------------- 3 files changed, 196 deletions(-) delete mode 100644 src/platform/python/sio.c delete mode 100644 src/platform/python/sio.h diff --git a/src/platform/python/mgba/gba.py b/src/platform/python/mgba/gba.py index 109de4d50..0c249cec5 100644 --- a/src/platform/python/mgba/gba.py +++ b/src/platform/python/mgba/gba.py @@ -52,72 +52,6 @@ class GBA(Core): super(GBA, self)._load() self.memory = GBAMemory(self._core, self._native.memory.romSize) - def attach_sio(self, link, mode=lib.GBA_SIO_MULTI): - self._sio.add(mode) - lib.GBASIOSetDriver(ffi.addressof(self._native.sio), link._native, mode) - - def __del__(self): - for mode in self._sio: - lib.GBASIOSetDriver(ffi.addressof(self._native.sio), ffi.NULL, mode) - - -create_callback("GBASIOPythonDriver", "init") -create_callback("GBASIOPythonDriver", "deinit") -create_callback("GBASIOPythonDriver", "load") -create_callback("GBASIOPythonDriver", "unload") -create_callback("GBASIOPythonDriver", "writeRegister") - - -class GBASIODriver(object): - def __init__(self): - super(GBASIODriver, self).__init__() - - self._handle = ffi.new_handle(self) - self._native = ffi.gc(lib.GBASIOPythonDriverCreate(self._handle), lib.free) - - def init(self): - return True - - def deinit(self): - pass - - def load(self): - return True - - def unload(self): - return True - - def write_register(self, address, value): - return value - - -class GBASIOJOYDriver(GBASIODriver): - RESET = lib.JOY_RESET - POLL = lib.JOY_POLL - TRANS = lib.JOY_TRANS - RECV = lib.JOY_RECV - - def __init__(self): - super(GBASIOJOYDriver, self).__init__() - - self._native = ffi.gc(lib.GBASIOJOYPythonDriverCreate(self._handle), lib.free) - - def send_command(self, cmd, data): - buffer = ffi.new('uint8_t[5]') - try: - buffer[0] = data[0] - buffer[1] = data[1] - buffer[2] = data[2] - buffer[3] = data[3] - buffer[4] = data[4] - except IndexError: - pass - - outlen = lib.GBASIOJOYSendCommand(self._native, cmd, buffer) - if outlen > 0 and outlen <= 5: - return bytes(buffer[0:outlen]) - return None - class GBAMemory(Memory): def __init__(self, core, romSize=lib.SIZE_CART0): diff --git a/src/platform/python/sio.c b/src/platform/python/sio.c deleted file mode 100644 index fbb407831..000000000 --- a/src/platform/python/sio.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2013-2017 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include - -#define CREATE_SHIM(PLAT, NAME, RETURN) \ - RETURN _py ## PLAT ## SIOPythonDriver ## NAME (void* driver); \ - static RETURN _py ## PLAT ## SIOPythonDriver ## NAME ## Shim(struct PLAT ## SIODriver* driver) { \ - struct PLAT ## SIODriver* py = (struct PLAT ## SIODriver*) driver; \ - return _py ## PLAT ## SIOPythonDriver ## NAME(py); \ - } - -#define CREATE_SHIM_ARGS(PLAT, NAME, RETURN, TYPES, ...) \ - RETURN _py ## PLAT ## SIOPythonDriver ## NAME TYPES; \ - static RETURN _py ## PLAT ## SIOPythonDriver ## NAME ## Shim TYPES { \ - struct PLAT ## SIODriver* py = (struct PLAT ## SIODriver*) driver; \ - return _py ## PLAT ## SIOPythonDriver ## NAME(py, __VA_ARGS__); \ - } - -#ifdef M_CORE_GBA - -#include - -struct GBASIOPythonDriver { - struct GBASIODriver d; - void* pyobj; -}; - -CREATE_SHIM(GBA, Init, bool); -CREATE_SHIM(GBA, Deinit, void); -CREATE_SHIM(GBA, Load, bool); -CREATE_SHIM(GBA, Unload, bool); -CREATE_SHIM_ARGS(GBA, WriteRegister, uint16_t, (struct GBASIODriver* driver, uint32_t address, uint16_t value), address, value); - -struct GBASIODriver* GBASIOPythonDriverCreate(void* pyobj) { - struct GBASIOPythonDriver* driver = malloc(sizeof(*driver)); - driver->d.init = _pyGBASIOPythonDriverInitShim; - driver->d.deinit = _pyGBASIOPythonDriverDeinitShim; - driver->d.load = _pyGBASIOPythonDriverLoadShim; - driver->d.unload = _pyGBASIOPythonDriverUnloadShim; - driver->d.writeRegister = _pyGBASIOPythonDriverWriteRegisterShim; - - driver->pyobj = pyobj; - return &driver->d; -} - -struct GBASIODriver* GBASIOJOYPythonDriverCreate(void* pyobj) { - struct GBASIOPythonDriver* driver = malloc(sizeof(*driver)); - GBASIOJOYCreate(&driver->d); - driver->d.init = _pyGBASIOPythonDriverInitShim; - driver->d.deinit = _pyGBASIOPythonDriverDeinitShim; - driver->d.load = _pyGBASIOPythonDriverLoadShim; - driver->d.unload = _pyGBASIOPythonDriverUnloadShim; - - driver->pyobj = pyobj; - return &driver->d; -} - -#endif - -#ifdef M_CORE_GB - -#include - -struct GBSIOPythonDriver { - struct GBSIODriver d; - void* pyobj; -}; - -CREATE_SHIM(GB, Init, bool); -CREATE_SHIM(GB, Deinit, void); -CREATE_SHIM_ARGS(GB, WriteSB, void, (struct GBSIODriver* driver, uint8_t value), value); -CREATE_SHIM_ARGS(GB, WriteSC, uint8_t, (struct GBSIODriver* driver, uint8_t value), value); - -struct GBSIODriver* GBSIOPythonDriverCreate(void* pyobj) { - struct GBSIOPythonDriver* driver = malloc(sizeof(*driver)); - driver->d.init = _pyGBSIOPythonDriverInitShim; - driver->d.deinit = _pyGBSIOPythonDriverDeinitShim; - driver->d.writeSB = _pyGBSIOPythonDriverWriteSBShim; - driver->d.writeSC = _pyGBSIOPythonDriverWriteSCShim; - - driver->pyobj = pyobj; - return &driver->d; -} - -#endif diff --git a/src/platform/python/sio.h b/src/platform/python/sio.h deleted file mode 100644 index 23b059427..000000000 --- a/src/platform/python/sio.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2013-2017 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifdef M_CORE_GBA - -#include - -struct GBASIOPythonDriver { - struct GBASIODriver d; - void* pyobj; -}; - -struct GBASIODriver* GBASIOPythonDriverCreate(void* pyobj); -struct GBASIODriver* GBASIOJOYPythonDriverCreate(void* pyobj); - -PYEXPORT bool _pyGBASIOPythonDriverInit(void* driver); -PYEXPORT void _pyGBASIOPythonDriverDeinit(void* driver); -PYEXPORT bool _pyGBASIOPythonDriverLoad(void* driver); -PYEXPORT bool _pyGBASIOPythonDriverUnload(void* driver); -PYEXPORT uint16_t _pyGBASIOPythonDriverWriteRegister(void* driver, uint32_t address, uint16_t value); - -#endif - -#ifdef M_CORE_GB - -#include - -struct GBSIOPythonDriver { - struct GBSIODriver d; - void* pyobj; -}; - -struct GBSIODriver* GBSIOPythonDriverCreate(void* pyobj); - -PYEXPORT bool _pyGBSIOPythonDriverInit(void* driver); -PYEXPORT void _pyGBSIOPythonDriverDeinit(void* driver); -PYEXPORT void _pyGBSIOPythonDriverWriteSB(void* driver, uint8_t value); -PYEXPORT uint8_t _pyGBSIOPythonDriverWriteSC(void* driver, uint8_t value); - -#endif From 451da0f8a4d486987192e1c34348ad1fa3ab08fe Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 16 May 2024 15:11:19 -0700 Subject: [PATCH 277/336] GBA SIO: Start adding new SIO callbacks for revamped API --- include/mgba/gba/interface.h | 5 ++++ src/gba/extra/battlechip.c | 22 +++++++++++++++ src/gba/sio.c | 9 +++++++ src/gba/sio/gbp.c | 24 ++++++++++++++--- src/gba/sio/joybus.c | 16 +++++++++++ src/gba/sio/lockstep.c | 52 +++++++++++++++++++++++++++++++++++- 6 files changed, 123 insertions(+), 5 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 97e0a5b9c..6b663b4a7 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -110,8 +110,13 @@ struct GBASIODriver { bool (*init)(struct GBASIODriver* driver); void (*deinit)(struct GBASIODriver* driver); + void (*reset)(struct GBASIODriver* driver); bool (*load)(struct GBASIODriver* driver); bool (*unload)(struct GBASIODriver* driver); + void (*setMode)(struct GBASIODriver* driver, enum GBASIOMode mode); + bool (*handlesMode)(struct GBASIODriver* driver, enum GBASIOMode mode); + int (*connectedDevices)(struct GBASIODriver* driver); + int (*deviceId)(struct GBASIODriver* driver); uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value); }; diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 3ab9f1403..841981fb7 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -35,6 +35,8 @@ enum { static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver); static uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); +static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver); static void _battlechipTransfer(struct GBASIOBattlechipGate* gate); static void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate); @@ -45,6 +47,10 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { gate->d.load = GBASIOBattlechipGateLoad; gate->d.unload = NULL; gate->d.writeRegister = GBASIOBattlechipGateWriteRegister; + gate->d.setMode = NULL; + gate->d.handlesMode = GBASIOBattlechipGateHandlesMode; + gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices; + gate->d.deviceId = NULL; gate->event.context = gate; gate->event.callback = _battlechipTransferEvent; @@ -82,6 +88,22 @@ uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t return value; } +static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + UNUSED(driver); + switch (mode) { + case GBA_SIO_NORMAL_32: + case GBA_SIO_MULTI: + return true; + default: + return false; + } +} + +static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver) { + UNUSED(driver); + return 1; +} + void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { int32_t cycles; if (gate->d.p->mode == GBA_SIO_NORMAL_32) { diff --git a/src/gba/sio.c b/src/gba/sio.c index 4ffeb6388..ae1132dfe 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -103,6 +103,15 @@ void GBASIOReset(struct GBASIO* sio) { if (sio->activeDriver && sio->activeDriver->unload) { sio->activeDriver->unload(sio->activeDriver); } + if (sio->drivers.multiplayer && sio->drivers.multiplayer->reset) { + sio->drivers.multiplayer->reset(sio->drivers.multiplayer); + } + if (sio->drivers.joybus && sio->drivers.joybus->reset) { + sio->drivers.joybus->reset(sio->drivers.joybus); + } + if (sio->drivers.normal && sio->drivers.normal->reset) { + sio->drivers.normal->reset(sio->drivers.normal); + } sio->rcnt = RCNT_INITIAL; sio->siocnt = 0; sio->mode = -1; diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index d992ebe2e..e1f008274 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -14,6 +14,8 @@ static uint16_t _gbpRead(struct mKeyCallback*); static uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); +static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static int _gbpSioConnectedDevices(struct GBASIODriver* driver); static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate); static const uint8_t _logoPalette[] = { @@ -43,11 +45,15 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { gbp->callback.d.readKeys = _gbpRead; gbp->callback.d.requireOpposingDirections = true; gbp->callback.p = gbp; - gbp->d.init = 0; - gbp->d.deinit = 0; - gbp->d.load = 0; - gbp->d.unload = 0; + gbp->d.init = NULL; + gbp->d.deinit = NULL; + gbp->d.load = NULL; + gbp->d.unload = NULL; gbp->d.writeRegister = _gbpSioWriteRegister; + gbp->d.setMode = NULL; + gbp->d.handlesMode = _gbpSioHandlesMode; + gbp->d.connectedDevices = _gbpSioConnectedDevices; + gbp->d.deviceId = NULL; gbp->event.context = gbp; gbp->event.name = "GBA SIO Game Boy Player"; gbp->event.callback = _gbpSioProcessEvents; @@ -125,6 +131,16 @@ uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uin return value; } +static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + UNUSED(driver); + return mode == GBA_SIO_NORMAL_32; +} + +static int _gbpSioConnectedDevices(struct GBASIODriver* driver) { + UNUSED(driver); + return 1; +} + void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { UNUSED(timing); UNUSED(cyclesLate); diff --git a/src/gba/sio/joybus.c b/src/gba/sio/joybus.c index 941527439..f1e86d6ed 100644 --- a/src/gba/sio/joybus.c +++ b/src/gba/sio/joybus.c @@ -9,6 +9,8 @@ #include static uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint16_t value); +static bool GBASIOJOYHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static int GBASIOJOYConnectedDevices(struct GBASIODriver* driver); void GBASIOJOYCreate(struct GBASIODriver* sio) { sio->init = NULL; @@ -16,6 +18,10 @@ void GBASIOJOYCreate(struct GBASIODriver* sio) { sio->load = NULL; sio->unload = NULL; sio->writeRegister = GBASIOJOYWriteRegister; + sio->setMode = NULL; + sio->handlesMode = GBASIOJOYHandlesMode; + sio->connectedDevices = GBASIOJOYConnectedDevices; + sio->deviceId = NULL; } uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint16_t value) { @@ -41,6 +47,16 @@ uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint return value; } +static bool GBASIOJOYHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + UNUSED(driver); + return mode == GBA_SIO_JOYBUS; +} + +static int GBASIOJOYConnectedDevices(struct GBASIODriver* driver) { + UNUSED(driver); + return 1; +} + int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) { switch (command) { case JOY_RESET: diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index ba620911e..9ac1e7174 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -15,6 +15,10 @@ static bool GBASIOLockstepNodeInit(struct GBASIODriver* driver); static void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver); static bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver); static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver); +static void GBASIOLockstepNodeSetMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver); +static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver); static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate); @@ -38,7 +42,11 @@ void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { node->d.deinit = GBASIOLockstepNodeDeinit; node->d.load = GBASIOLockstepNodeLoad; node->d.unload = GBASIOLockstepNodeUnload; - node->d.writeRegister = 0; + node->d.setMode = GBASIOLockstepNodeSetMode; + node->d.handlesMode = GBASIOLockstepNodeHandlesMode; + node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices; + node->d.deviceId = GBASIOLockstepNodeDeviceId; + node->d.writeRegister = NULL; } bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { @@ -186,6 +194,48 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { return true; } +static void GBASIOLockstepNodeSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; + mLockstepLock(&node->p->d); + node->mode = mode; + mLockstepUnlock(&node->p->d); +} + +static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + UNUSED(driver); + switch (mode) { + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: + case GBA_SIO_MULTI: + return true; + default: + return false; + } +} + +static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver) { + struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; + int attached = 0; + + switch (node->mode) { + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: + ATOMIC_LOAD(attached, node->p->attachedNormal); + break; + case GBA_SIO_MULTI: + ATOMIC_LOAD(attached, node->p->attachedMulti); + break; + default: + break; + } + return attached - 1; +} + +static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver) { + struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; + return node->id; +} + static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; From 09a69a32c0da1bbb21b725786449e1b5cfd7a199 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 16 May 2024 23:06:18 -0700 Subject: [PATCH 278/336] GBA SIO: Start moving common SIO logic out of drivers --- include/mgba/gba/interface.h | 2 - src/gba/CMakeLists.txt | 1 - src/gba/sio.c | 100 ++++++++++++++++++++++++++++++-- src/gba/sio/dolphin.c | 18 +++++- src/gba/sio/joybus.c | 108 ----------------------------------- src/gba/sio/lockstep.c | 2 +- 6 files changed, 114 insertions(+), 117 deletions(-) delete mode 100644 src/gba/sio/joybus.c diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 6b663b4a7..c2a4fb5d2 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -120,8 +120,6 @@ struct GBASIODriver { uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value); }; -void GBASIOJOYCreate(struct GBASIODriver* sio); - enum GBASIOBattleChipGateFlavor { GBA_FLAVOR_BATTLECHIP_GATE = 4, GBA_FLAVOR_PROGRESS_GATE = 5, diff --git a/src/gba/CMakeLists.txt b/src/gba/CMakeLists.txt index 933ba3fac..01a968a41 100644 --- a/src/gba/CMakeLists.txt +++ b/src/gba/CMakeLists.txt @@ -31,7 +31,6 @@ set(SOURCE_FILES sharkport.c sio.c sio/gbp.c - sio/joybus.c timer.c video.c) diff --git a/src/gba/sio.c b/src/gba/sio.c index ae1132dfe..27702dfbf 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -186,7 +186,32 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { sio->siocnt = value & 0x3000; _switchMode(sio); } - if (sio->activeDriver && sio->activeDriver->writeRegister) { + int id = 0; + int connected = 0; + bool handled = false; + if (sio->activeDriver) { + handled = sio->activeDriver->handlesMode(sio->activeDriver, sio->mode); + if (handled) { + if (sio->activeDriver->deviceId) { + id = sio->activeDriver->deviceId(sio->activeDriver); + } + connected = sio->activeDriver->connectedDevices(sio->activeDriver); + handled = !!sio->activeDriver->writeRegister; + } + } + + switch (sio->mode) { + case GBA_SIO_MULTI: + value &= 0xFF83; + value = GBASIOMultiplayerSetSlave(value, id || !connected); + value = GBASIOMultiplayerSetId(value, id); + value |= sio->siocnt & 0x00FC; + break; + default: + // TODO + break; + } + if (handled) { value = sio->activeDriver->writeRegister(sio->activeDriver, GBA_REG_SIOCNT, value); } else { // Dummy drivers @@ -203,8 +228,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { } break; case GBA_SIO_MULTI: - value &= 0xFF83; - value |= 0xC; + value = GBASIOMultiplayerFillReady(value); break; default: // TODO @@ -215,7 +239,12 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { } uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value) { - if (sio->activeDriver && sio->activeDriver->writeRegister) { + bool handled = false; + if (sio->activeDriver) { + handled = sio->activeDriver->writeRegister && sio->activeDriver->handlesMode(sio->activeDriver, sio->mode); + } + + if (handled) { return sio->activeDriver->writeRegister(sio->activeDriver, address, value); } // Dummy drivers @@ -223,9 +252,22 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu case GBA_SIO_JOYBUS: switch (address) { case GBA_REG_JOYCNT: + mLOG(GBA_SIO, DEBUG, "JOY write: CNT <- %04X", value); return (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); case GBA_REG_JOYSTAT: + mLOG(GBA_SIO, DEBUG, "JOY write: STAT <- %04X", value); return (value & 0x0030) | (sio->p->memory.io[GBA_REG(JOYSTAT)] & ~0x30); + case GBA_REG_JOY_TRANS_LO: + mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_LO <- %04X", value); + break; + case GBA_REG_JOY_TRANS_HI: + mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_HI <- %04X", value); + break; + default: + mLOG(GBA_SIO, DEBUG, "JOY write: Unknown reg %03X <- %04X", address, value); + break; + case GBA_REG_RCNT: + break; } break; default: @@ -234,3 +276,53 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu } return value; } + +int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) { + switch (command) { + case JOY_RESET: + sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_RESET; + if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) { + GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0); + } + // Fall through + case JOY_POLL: + data[0] = 0x00; + data[1] = 0x04; + data[2] = sio->p->p->memory.io[GBA_REG(JOYSTAT)]; + + mLOG(GBA_SIO, DEBUG, "JOY %s: %02X (%02X)", command == JOY_POLL ? "poll" : "reset", data[2], sio->p->p->memory.io[GBA_REG(JOYCNT)]); + return 3; + case JOY_RECV: + sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_RECV; + sio->p->p->memory.io[GBA_REG(JOYSTAT)] |= JOYSTAT_RECV; + + sio->p->p->memory.io[GBA_REG(JOY_RECV_LO)] = data[0] | (data[1] << 8); + sio->p->p->memory.io[GBA_REG(JOY_RECV_HI)] = data[2] | (data[3] << 8); + + data[0] = sio->p->p->memory.io[GBA_REG(JOYSTAT)]; + + mLOG(GBA_SIO, DEBUG, "JOY recv: %02X (%02X)", data[0], sio->p->p->memory.io[GBA_REG(JOYCNT)]); + + if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) { + GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0); + } + return 1; + case JOY_TRANS: + data[0] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_LO)]; + data[1] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_LO)] >> 8; + data[2] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_HI)]; + data[3] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_HI)] >> 8; + data[4] = sio->p->p->memory.io[GBA_REG(JOYSTAT)]; + + sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_TRANS; + sio->p->p->memory.io[GBA_REG(JOYSTAT)] &= ~JOYSTAT_TRANS; + + mLOG(GBA_SIO, DEBUG, "JOY trans: %02X%02X%02X%02X:%02X (%02X)", data[0], data[1], data[2], data[3], data[4], sio->p->p->memory.io[GBA_REG(JOYCNT)]); + + if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) { + GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0); + } + return 5; + } + return 0; +} diff --git a/src/gba/sio/dolphin.c b/src/gba/sio/dolphin.c index 896d17d3e..badbd05f7 100644 --- a/src/gba/sio/dolphin.c +++ b/src/gba/sio/dolphin.c @@ -25,16 +25,22 @@ enum { static bool GBASIODolphinInit(struct GBASIODriver* driver); static bool GBASIODolphinLoad(struct GBASIODriver* driver); static bool GBASIODolphinUnload(struct GBASIODriver* driver); +static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static int GBASIODolphinConnectedDevices(struct GBASIODriver* driver); static void GBASIODolphinProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate); static int32_t _processCommand(struct GBASIODolphin* dol, uint32_t cyclesLate); static void _flush(struct GBASIODolphin* dol); void GBASIODolphinCreate(struct GBASIODolphin* dol) { - GBASIOJOYCreate(&dol->d); dol->d.init = GBASIODolphinInit; dol->d.load = GBASIODolphinLoad; dol->d.unload = GBASIODolphinUnload; + dol->d.writeRegister = NULL; + dol->d.setMode = NULL; + dol->d.handlesMode = GBASIODolphinHandlesMode; + dol->d.connectedDevices = GBASIODolphinConnectedDevices; + dol->d.deviceId = NULL; dol->event.context = dol; dol->event.name = "GB SIO Lockstep"; dol->event.callback = GBASIODolphinProcessEvents; @@ -116,6 +122,16 @@ static bool GBASIODolphinUnload(struct GBASIODriver* driver) { return true; } +static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + UNUSED(driver); + return mode == GBA_SIO_JOYBUS; +} + +static int GBASIODolphinConnectedDevices(struct GBASIODriver* driver) { + UNUSED(driver); + return 1; +} + void GBASIODolphinProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate) { struct GBASIODolphin* dol = context; if (SOCKET_FAILED(dol->data)) { diff --git a/src/gba/sio/joybus.c b/src/gba/sio/joybus.c deleted file mode 100644 index f1e86d6ed..000000000 --- a/src/gba/sio/joybus.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (c) 2013-2017 Jeffrey Pfau - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include - -#include -#include - -static uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint16_t value); -static bool GBASIOJOYHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); -static int GBASIOJOYConnectedDevices(struct GBASIODriver* driver); - -void GBASIOJOYCreate(struct GBASIODriver* sio) { - sio->init = NULL; - sio->deinit = NULL; - sio->load = NULL; - sio->unload = NULL; - sio->writeRegister = GBASIOJOYWriteRegister; - sio->setMode = NULL; - sio->handlesMode = GBASIOJOYHandlesMode; - sio->connectedDevices = GBASIOJOYConnectedDevices; - sio->deviceId = NULL; -} - -uint16_t GBASIOJOYWriteRegister(struct GBASIODriver* sio, uint32_t address, uint16_t value) { - switch (address) { - case GBA_REG_JOYCNT: - mLOG(GBA_SIO, DEBUG, "JOY write: CNT <- %04X", value); - return (value & 0x0040) | (sio->p->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); - case GBA_REG_JOYSTAT: - mLOG(GBA_SIO, DEBUG, "JOY write: STAT <- %04X", value); - return (value & 0x0030) | (sio->p->p->memory.io[GBA_REG(JOYSTAT)] & ~0x30); - case GBA_REG_JOY_TRANS_LO: - mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_LO <- %04X", value); - break; - case GBA_REG_JOY_TRANS_HI: - mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_HI <- %04X", value); - break; - default: - mLOG(GBA_SIO, DEBUG, "JOY write: Unknown reg %03X <- %04X", address, value); - // Fall through - case GBA_REG_RCNT: - break; - } - return value; -} - -static bool GBASIOJOYHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { - UNUSED(driver); - return mode == GBA_SIO_JOYBUS; -} - -static int GBASIOJOYConnectedDevices(struct GBASIODriver* driver) { - UNUSED(driver); - return 1; -} - -int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) { - switch (command) { - case JOY_RESET: - sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_RESET; - if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) { - GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0); - } - // Fall through - case JOY_POLL: - data[0] = 0x00; - data[1] = 0x04; - data[2] = sio->p->p->memory.io[GBA_REG(JOYSTAT)]; - - mLOG(GBA_SIO, DEBUG, "JOY %s: %02X (%02X)", command == JOY_POLL ? "poll" : "reset", data[2], sio->p->p->memory.io[GBA_REG(JOYCNT)]); - return 3; - case JOY_RECV: - sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_RECV; - sio->p->p->memory.io[GBA_REG(JOYSTAT)] |= JOYSTAT_RECV; - - sio->p->p->memory.io[GBA_REG(JOY_RECV_LO)] = data[0] | (data[1] << 8); - sio->p->p->memory.io[GBA_REG(JOY_RECV_HI)] = data[2] | (data[3] << 8); - - data[0] = sio->p->p->memory.io[GBA_REG(JOYSTAT)]; - - mLOG(GBA_SIO, DEBUG, "JOY recv: %02X (%02X)", data[0], sio->p->p->memory.io[GBA_REG(JOYCNT)]); - - if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) { - GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0); - } - return 1; - case JOY_TRANS: - data[0] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_LO)]; - data[1] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_LO)] >> 8; - data[2] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_HI)]; - data[3] = sio->p->p->memory.io[GBA_REG(JOY_TRANS_HI)] >> 8; - data[4] = sio->p->p->memory.io[GBA_REG(JOYSTAT)]; - - sio->p->p->memory.io[GBA_REG(JOYCNT)] |= JOYCNT_TRANS; - sio->p->p->memory.io[GBA_REG(JOYSTAT)] &= ~JOYSTAT_TRANS; - - mLOG(GBA_SIO, DEBUG, "JOY trans: %02X%02X%02X%02X:%02X (%02X)", data[0], data[1], data[2], data[3], data[4], sio->p->p->memory.io[GBA_REG(JOYCNT)]); - - if (sio->p->p->memory.io[GBA_REG(JOYCNT)] & 0x40) { - GBARaiseIRQ(sio->p->p, GBA_IRQ_SIO, 0); - } - return 5; - } - return 0; -} diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 9ac1e7174..edd170748 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -215,7 +215,7 @@ static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBAS static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - int attached = 0; + int attached = 1; switch (node->mode) { case GBA_SIO_NORMAL_8: From f9e15c53d953b8a23611fb125870513a816fc27b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2024 16:26:33 -0700 Subject: [PATCH 279/336] GBA SIO: Move more SIO logic out of drivers --- src/gba/sio.c | 63 ++++++++++++++++++++++++++++++++++-------- src/gba/sio/lockstep.c | 5 ---- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/gba/sio.c b/src/gba/sio.c index 27702dfbf..4eb9cfa3c 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -69,6 +69,23 @@ static void _switchMode(struct GBASIO* sio) { if (sio->activeDriver && sio->activeDriver->load) { sio->activeDriver->load(sio->activeDriver); } + + int id = 0; + switch (newMode) { + case GBA_SIO_MULTI: + if (sio->activeDriver && sio->activeDriver->deviceId) { + id = sio->activeDriver->deviceId(sio->activeDriver); + } + if (id) { + sio->rcnt |= 4; + } else { + sio->rcnt &= ~4; + } + break; + default: + // TODO + break; + } } } @@ -239,24 +256,17 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { } uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value) { - bool handled = false; - if (sio->activeDriver) { - handled = sio->activeDriver->writeRegister && sio->activeDriver->handlesMode(sio->activeDriver, sio->mode); - } - - if (handled) { - return sio->activeDriver->writeRegister(sio->activeDriver, address, value); - } - // Dummy drivers switch (sio->mode) { case GBA_SIO_JOYBUS: switch (address) { case GBA_REG_JOYCNT: mLOG(GBA_SIO, DEBUG, "JOY write: CNT <- %04X", value); - return (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); + value = (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); + break; case GBA_REG_JOYSTAT: mLOG(GBA_SIO, DEBUG, "JOY write: STAT <- %04X", value); - return (value & 0x0030) | (sio->p->memory.io[GBA_REG(JOYSTAT)] & ~0x30); + value = (value & 0x0030) | (sio->p->memory.io[GBA_REG(JOYSTAT)] & ~0x30); + break; case GBA_REG_JOY_TRANS_LO: mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_LO <- %04X", value); break; @@ -270,10 +280,41 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu break; } break; + case GBA_SIO_NORMAL_8: + switch (address) { + case GBA_REG_SIODATA8: + mLOG(GBA_SIO, DEBUG, "NORMAL8 write: SIODATA8 <- %02X", value); + break; + default: + mLOG(GBA_SIO, DEBUG, "NORMAL8 write: Unknown reg %03X <- %04X", address, value); + break; + case GBA_REG_RCNT: + break; + } + break; + case GBA_SIO_NORMAL_32: + switch (address) { + case GBA_REG_SIODATA32_LO: + mLOG(GBA_SIO, DEBUG, "NORMAL32 write: SIODATA32_LO <- %04X", value); + break; + case GBA_REG_SIODATA32_HI: + mLOG(GBA_SIO, DEBUG, "NORMAL32 write: SIODATA32_HI <- %04X", value); + break; + default: + mLOG(GBA_SIO, DEBUG, "NORMAL32 write: Unknown reg %03X <- %04X", address, value); + break; + case GBA_REG_RCNT: + break; + } + break; default: // TODO break; } + + if (sio->activeDriver && sio->activeDriver->writeRegister && sio->activeDriver->handlesMode(sio->activeDriver, sio->mode)) { + sio->activeDriver->writeRegister(sio->activeDriver, address, value); + } return value; } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index edd170748..9709f633b 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -117,8 +117,6 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, node->p->attachedMulti == node->p->d.attached); if (node->id) { node->d.p->rcnt |= 4; - node->d.p->siocnt = GBASIOMultiplayerFillSlave(node->d.p->siocnt); - int try; for (try = 0; try < 3; ++try) { uint16_t masterSiocnt; @@ -127,9 +125,6 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { break; } } - } else { - node->d.p->rcnt &= ~4; - node->d.p->siocnt = GBASIOMultiplayerClearSlave(node->d.p->siocnt); } break; case GBA_SIO_NORMAL_8: From cd4132fba3c94ea303264bfc1f2d0231c997a749 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2024 16:42:20 -0700 Subject: [PATCH 280/336] GBA SIO: Move MULTI finishing logic out of drivers --- include/mgba/internal/gba/sio.h | 2 ++ src/gba/extra/battlechip.c | 16 +++++----------- src/gba/sio.c | 17 +++++++++++++++++ src/gba/sio/lockstep.c | 11 +---------- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index 260772f55..a546017dc 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -85,6 +85,8 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value); void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value); uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value); +void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate); + int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data); CXX_GUARD_END diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 841981fb7..12750f67b 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -131,11 +131,6 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle uint16_t cmd = gate->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; uint16_t reply = 0xFFFF; - gate->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = cmd; - gate->d.p->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF; - gate->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF; - gate->d.p->siocnt = GBASIOMultiplayerClearBusy(gate->d.p->siocnt); - gate->d.p->siocnt = GBASIOMultiplayerSetId(gate->d.p->siocnt, 0); mLOG(GBA_BATTLECHIP, DEBUG, "Game: %04X (%i)", cmd, gate->state); @@ -168,7 +163,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xA3D0: // EXE 4 case 0xA6C0: - mLOG(GBA_BATTLECHIP, DEBUG, "Resync detected"); + mLOG(GBA_BATTLECHIP, DEBUG, "Resync detected"); gate->state = BATTLECHIP_STATE_SYNC; break; } @@ -213,9 +208,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle mLOG(GBA_BATTLECHIP, DEBUG, "Gate: %04X (%i)", reply, gate->state); ++gate->state; - gate->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = reply; - - if (GBASIOMultiplayerIsIrq(gate->d.p->siocnt)) { - GBARaiseIRQ(gate->d.p->p, GBA_IRQ_SIO, cyclesLate); - } + uint16_t data[4] = { + cmd, reply, 0xFFFF, 0xFFFF + }; + GBASIOMultiplayerFinishTransfer(gate->d.p, data, cyclesLate); } diff --git a/src/gba/sio.c b/src/gba/sio.c index 4eb9cfa3c..cdccf1ea3 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -318,6 +318,23 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu return value; } +void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) { + int id = 0; + if (sio->activeDriver && sio->activeDriver->deviceId) { + id = sio->activeDriver->deviceId(sio->activeDriver); + } + sio->p->memory.io[GBA_REG(SIOMULTI0)] = data[0]; + sio->p->memory.io[GBA_REG(SIOMULTI1)] = data[1]; + sio->p->memory.io[GBA_REG(SIOMULTI2)] = data[2]; + sio->p->memory.io[GBA_REG(SIOMULTI3)] = data[3]; + sio->rcnt |= 1; + sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt); + sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, id); + if (GBASIOMultiplayerIsIrq(sio->siocnt)) { + GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate); + } +} + int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) { switch (command) { case JOY_RESET: diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 9709f633b..b7f5752b4 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -280,16 +280,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { struct GBASIO* sio = node->d.p; switch (node->mode) { case GBA_SIO_MULTI: - sio->p->memory.io[GBA_REG(SIOMULTI0)] = node->p->multiRecv[0]; - sio->p->memory.io[GBA_REG(SIOMULTI1)] = node->p->multiRecv[1]; - sio->p->memory.io[GBA_REG(SIOMULTI2)] = node->p->multiRecv[2]; - sio->p->memory.io[GBA_REG(SIOMULTI3)] = node->p->multiRecv[3]; - sio->rcnt |= 1; - sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt); - sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, node->id); - if (GBASIOMultiplayerIsIrq(sio->siocnt)) { - GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); - } + GBASIOMultiplayerFinishTransfer(sio, node->p->multiRecv, 0); break; case GBA_SIO_NORMAL_8: // TODO From 1b0b540de6743d306e1e53583b1ed24215a25334 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2024 23:24:06 -0700 Subject: [PATCH 281/336] GBA SIO: Move cycle estimation values into core --- include/mgba/internal/gba/sio.h | 4 ++-- src/gba/extra/battlechip.c | 7 +------ src/gba/sio.c | 27 ++++++++++++++++++++++++++- src/gba/sio/lockstep.c | 14 +++----------- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index a546017dc..2576dfffe 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -16,8 +16,6 @@ CXX_GUARD_START #define MAX_GBAS 4 -extern const int GBASIOCyclesPerTransfer[4][MAX_GBAS]; - mLOG_DECLARE_CATEGORY(GBA_SIO); enum { @@ -85,6 +83,8 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value); void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value); uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value); +int32_t GBASIOTransferCycles(struct GBASIO* sio); + void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate); int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data); diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 12750f67b..3314ff02c 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -105,12 +105,7 @@ static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver) { } void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { - int32_t cycles; - if (gate->d.p->mode == GBA_SIO_NORMAL_32) { - cycles = GBA_ARM7TDMI_FREQUENCY / 0x40000; - } else { - cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(gate->d.p->siocnt)][1]; - } + int32_t cycles = GBASIOTransferCycles(gate->d.p); mTimingDeschedule(&gate->d.p->p->timing, &gate->event); mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles); } diff --git a/src/gba/sio.c b/src/gba/sio.c index cdccf1ea3..76d2ea144 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -11,7 +11,7 @@ mLOG_DEFINE_CATEGORY(GBA_SIO, "GBA Serial I/O", "gba.sio"); -const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { +static const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { { 31976, 63427, 94884, 125829 }, { 8378, 16241, 24104, 31457 }, { 5750, 10998, 16241, 20972 }, @@ -318,6 +318,31 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu return value; } +int32_t GBASIOTransferCycles(struct GBASIO* sio) { + int connected = 0; + if (sio->activeDriver) { + connected = sio->activeDriver->connectedDevices(sio->activeDriver); + } + + if (connected < 0 || connected >= MAX_GBAS) { + mLOG(GBA_SIO, ERROR, "SIO driver returned invalid device count %i", connected); + return 0; + } + + switch (sio->mode) { + case GBA_SIO_MULTI: + return GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(sio->siocnt)][connected]; + case GBA_SIO_NORMAL_8: + return 8 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024); + case GBA_SIO_NORMAL_32: + return 32 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024); + default: + mLOG(GBA_SIO, STUB, "No cycle count implemented for mode %s", _modeName(sio->mode)); + break; + } + return 0; +} + void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) { int id = 0; if (sio->activeDriver && sio->activeDriver->deviceId) { diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index b7f5752b4..08c586ae5 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -250,7 +250,7 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][node->p->d.attached - 1]); + ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p)); if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); @@ -502,7 +502,7 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, if (node->p->d.attached < 2) { switch (node->mode) { case GBA_SIO_MULTI: - cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][0]; + cycles = GBASIOTransferCycles(node->d.p); break; case GBA_SIO_NORMAL_8: case GBA_SIO_NORMAL_32: @@ -568,15 +568,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive if ((value & 0x0081) == 0x0081) { if (!node->id) { // Frequency - int32_t cycles; - if (value & 2) { - cycles = 8 * 8; - } else { - cycles = 64 * 8; - } - if (value & 0x1000) { - cycles *= 4; - } + int32_t cycles = GBASIOTransferCycles(node->d.p); if (transferActive == TRANSFER_IDLE) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); From 54c9e9d411bbc03a27ab9ae418227162c3855aef Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2024 23:39:15 -0700 Subject: [PATCH 282/336] GBA SIO: Move NORMAL finishing logic out of drivers --- include/mgba/internal/gba/sio.h | 2 ++ src/gba/extra/battlechip.c | 7 +------ src/gba/sio.c | 17 +++++++++++++++++ src/gba/sio/gbp.c | 9 +-------- src/gba/sio/lockstep.c | 20 ++++---------------- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index 2576dfffe..43acaa7b8 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -86,6 +86,8 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu int32_t GBASIOTransferCycles(struct GBASIO* sio); void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate); +void GBASIONormal8FinishTransfer(struct GBASIO* sio, uint8_t data, uint32_t cyclesLate); +void GBASIONormal32FinishTransfer(struct GBASIO* sio, uint32_t data, uint32_t cyclesLate); int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data); diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 3314ff02c..040ec80b8 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -115,12 +115,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle struct GBASIOBattlechipGate* gate = user; if (gate->d.p->mode == GBA_SIO_NORMAL_32) { - gate->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0; - gate->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0; - gate->d.p->siocnt = GBASIONormalClearStart(gate->d.p->siocnt); - if (GBASIONormalIsIrq(gate->d.p->siocnt)) { - GBARaiseIRQ(gate->d.p->p, GBA_IRQ_SIO, cyclesLate); - } + GBASIONormal32FinishTransfer(gate->d.p, 0, cyclesLate); return; } diff --git a/src/gba/sio.c b/src/gba/sio.c index 76d2ea144..56dc55a9f 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -360,6 +360,23 @@ void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint3 } } +void GBASIONormal8FinishTransfer(struct GBASIO* sio, uint8_t data, uint32_t cyclesLate) { + sio->siocnt = GBASIONormalClearStart(sio->siocnt); + sio->p->memory.io[GBA_REG(SIODATA8)] = data; + if (GBASIONormalIsIrq(sio->siocnt)) { + GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate); + } +} + +void GBASIONormal32FinishTransfer(struct GBASIO* sio, uint32_t data, uint32_t cyclesLate) { + sio->siocnt = GBASIONormalClearStart(sio->siocnt); + sio->p->memory.io[GBA_REG(SIODATA32_LO)] = data; + sio->p->memory.io[GBA_REG(SIODATA32_HI)] = data >> 16; + if (GBASIONormalIsIrq(sio->siocnt)) { + GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate); + } +} + int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) { switch (command) { case JOY_RESET: diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index e1f008274..37944d596 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -143,7 +143,6 @@ static int _gbpSioConnectedDevices(struct GBASIODriver* driver) { void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { UNUSED(timing); - UNUSED(cyclesLate); struct GBASIOPlayer* gbp = user; uint32_t tx = 0; int txPosition = gbp->txPosition; @@ -155,11 +154,5 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat } tx = _gbpTxData[txPosition]; ++gbp->txPosition; - gbp->p->memory.io[GBA_REG(SIODATA32_LO)] = tx; - gbp->p->memory.io[GBA_REG(SIODATA32_HI)] = tx >> 16; - if (GBASIONormalIsIrq(gbp->d.p->siocnt)) { - GBARaiseIRQ(gbp->p, GBA_IRQ_SIO, cyclesLate); - } - gbp->d.p->siocnt = GBASIONormalClearStart(gbp->d.p->siocnt); - gbp->p->memory.io[GBA_REG(SIOCNT)] = gbp->d.p->siocnt & ~0x0080; + GBASIONormal32FinishTransfer(gbp->d.p, tx, cyclesLate); } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 08c586ae5..67b359234 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -283,31 +283,19 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { GBASIOMultiplayerFinishTransfer(sio, node->p->multiRecv, 0); break; case GBA_SIO_NORMAL_8: - // TODO - sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - node->d.p->p->memory.io[GBA_REG(SIODATA8)] = node->p->normalRecv[node->id - 1] & 0xFF; + GBASIONormal8FinishTransfer(sio, node->p->normalRecv[node->id - 1], 0); } else { - node->d.p->p->memory.io[GBA_REG(SIODATA8)] = 0xFFFF; - } - if (GBASIONormalIsIrq(sio->siocnt)) { - GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); + GBASIONormal8FinishTransfer(sio, 0xFF, 0); } break; case GBA_SIO_NORMAL_32: - // TODO - sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = node->p->normalRecv[node->id - 1]; - node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = node->p->normalRecv[node->id - 1] >> 16; + GBASIONormal32FinishTransfer(sio, node->p->normalRecv[node->id - 1], 0); } else { - node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0xFFFF; - } - if (GBASIONormalIsIrq(sio->siocnt)) { - GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); + GBASIONormal32FinishTransfer(sio, 0xFFFFFFFF, 0); } break; default: From 9998de48803887633ff052fe12ef11a46c5ef3ff Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2024 23:52:55 -0700 Subject: [PATCH 283/336] GBA SIO: Move more write logging out of drivers --- src/gba/sio.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/gba/sio.c b/src/gba/sio.c index 56dc55a9f..e0b0a6d1d 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -256,6 +256,11 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { } uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value) { + int id = 0; + if (sio->activeDriver && sio->activeDriver->deviceId) { + id = sio->activeDriver->deviceId(sio->activeDriver); + } + switch (sio->mode) { case GBA_SIO_JOYBUS: switch (address) { @@ -283,10 +288,10 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu case GBA_SIO_NORMAL_8: switch (address) { case GBA_REG_SIODATA8: - mLOG(GBA_SIO, DEBUG, "NORMAL8 write: SIODATA8 <- %02X", value); + mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: SIODATA8 <- %02X", id, value); break; default: - mLOG(GBA_SIO, DEBUG, "NORMAL8 write: Unknown reg %03X <- %04X", address, value); + mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: Unknown reg %03X <- %04X", id, address, value); break; case GBA_REG_RCNT: break; @@ -295,13 +300,25 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu case GBA_SIO_NORMAL_32: switch (address) { case GBA_REG_SIODATA32_LO: - mLOG(GBA_SIO, DEBUG, "NORMAL32 write: SIODATA32_LO <- %04X", value); + mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: SIODATA32_LO <- %04X", id, value); break; case GBA_REG_SIODATA32_HI: - mLOG(GBA_SIO, DEBUG, "NORMAL32 write: SIODATA32_HI <- %04X", value); + mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: SIODATA32_HI <- %04X", id, value); break; default: - mLOG(GBA_SIO, DEBUG, "NORMAL32 write: Unknown reg %03X <- %04X", address, value); + mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: Unknown reg %03X <- %04X", id, address, value); + break; + case GBA_REG_RCNT: + break; + } + break; + case GBA_SIO_MULTI: + switch (address) { + case GBA_REG_SIOMLT_SEND: + mLOG(GBA_SIO, DEBUG, "MULTI %i write: SIOMLT_SEND <- %04X", id, value); + break; + default: + mLOG(GBA_SIO, DEBUG, "MULTI %i write: Unknown reg %03X <- %04X", id, address, value); break; case GBA_REG_RCNT: break; From 5da4b1fc4d61888564894d5b7f6662428b4647e5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2024 01:40:01 -0700 Subject: [PATCH 284/336] GBA SIO: Replace writeRegister with writeSIOCNT --- include/mgba/gba/interface.h | 2 +- src/gba/extra/battlechip.c | 24 ++----- src/gba/sio.c | 11 +-- src/gba/sio/dolphin.c | 2 +- src/gba/sio/gbp.c | 39 +++++------ src/gba/sio/lockstep.c | 130 ++++++++++++++++------------------- 6 files changed, 88 insertions(+), 120 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index c2a4fb5d2..b698f4030 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -117,7 +117,7 @@ struct GBASIODriver { bool (*handlesMode)(struct GBASIODriver* driver, enum GBASIOMode mode); int (*connectedDevices)(struct GBASIODriver* driver); int (*deviceId)(struct GBASIODriver* driver); - uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value); + uint16_t (*writeSIOCNT)(struct GBASIODriver* driver, uint16_t value); }; enum GBASIOBattleChipGateFlavor { diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 040ec80b8..b71b4e33e 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -34,7 +34,7 @@ enum { }; static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver); -static uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); +static uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver); @@ -46,7 +46,7 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { gate->d.deinit = NULL; gate->d.load = GBASIOBattlechipGateLoad; gate->d.unload = NULL; - gate->d.writeRegister = GBASIOBattlechipGateWriteRegister; + gate->d.writeSIOCNT = GBASIOBattlechipGateWriteSIOCNT; gate->d.setMode = NULL; gate->d.handlesMode = GBASIOBattlechipGateHandlesMode; gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices; @@ -68,22 +68,12 @@ bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) { return true; } -uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { +uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; - switch (address) { - case GBA_REG_SIOCNT: - value &= ~0xC; - value |= 0x8; - if (value & 0x80) { - _battlechipTransfer(gate); - } - break; - case GBA_REG_SIOMLT_SEND: - break; - case GBA_REG_RCNT: - break; - default: - break; + value &= ~0xC; + value |= 0x8; + if (value & 0x80) { + _battlechipTransfer(gate); } return value; } diff --git a/src/gba/sio.c b/src/gba/sio.c index e0b0a6d1d..68b8fcb48 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -193,9 +193,6 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) { sio->rcnt &= 0xF; sio->rcnt |= value & ~0xF; _switchMode(sio); - if (sio->activeDriver && sio->activeDriver->writeRegister) { - sio->activeDriver->writeRegister(sio->activeDriver, GBA_REG_RCNT, value); - } } void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { @@ -213,7 +210,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { id = sio->activeDriver->deviceId(sio->activeDriver); } connected = sio->activeDriver->connectedDevices(sio->activeDriver); - handled = !!sio->activeDriver->writeRegister; + handled = !!sio->activeDriver->writeSIOCNT; } } @@ -229,7 +226,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { break; } if (handled) { - value = sio->activeDriver->writeRegister(sio->activeDriver, GBA_REG_SIOCNT, value); + value = sio->activeDriver->writeSIOCNT(sio->activeDriver, value); } else { // Dummy drivers switch (sio->mode) { @@ -328,10 +325,6 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu // TODO break; } - - if (sio->activeDriver && sio->activeDriver->writeRegister && sio->activeDriver->handlesMode(sio->activeDriver, sio->mode)) { - sio->activeDriver->writeRegister(sio->activeDriver, address, value); - } return value; } diff --git a/src/gba/sio/dolphin.c b/src/gba/sio/dolphin.c index badbd05f7..039f9b528 100644 --- a/src/gba/sio/dolphin.c +++ b/src/gba/sio/dolphin.c @@ -36,7 +36,7 @@ void GBASIODolphinCreate(struct GBASIODolphin* dol) { dol->d.init = GBASIODolphinInit; dol->d.load = GBASIODolphinLoad; dol->d.unload = GBASIODolphinUnload; - dol->d.writeRegister = NULL; + dol->d.writeSIOCNT = NULL; dol->d.setMode = NULL; dol->d.handlesMode = GBASIODolphinHandlesMode; dol->d.connectedDevices = GBASIODolphinConnectedDevices; diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index 37944d596..7aeef1b0b 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -13,7 +13,7 @@ #include static uint16_t _gbpRead(struct mKeyCallback*); -static uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); +static uint16_t _gbpSioWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int _gbpSioConnectedDevices(struct GBASIODriver* driver); static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate); @@ -49,7 +49,7 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { gbp->d.deinit = NULL; gbp->d.load = NULL; gbp->d.unload = NULL; - gbp->d.writeRegister = _gbpSioWriteRegister; + gbp->d.writeSIOCNT = _gbpSioWriteSIOCNT; gbp->d.setMode = NULL; gbp->d.handlesMode = _gbpSioHandlesMode; gbp->d.connectedDevices = _gbpSioConnectedDevices; @@ -106,28 +106,27 @@ uint16_t _gbpRead(struct mKeyCallback* callback) { return 0; } -uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { +uint16_t _gbpSioWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { struct GBASIOPlayer* gbp = (struct GBASIOPlayer*) driver; - if (address == GBA_REG_SIOCNT) { - if (value & 0x0080) { - uint32_t rx = gbp->p->memory.io[GBA_REG(SIODATA32_LO)] | (gbp->p->memory.io[GBA_REG(SIODATA32_HI)] << 16); - if (gbp->txPosition < 12 && gbp->txPosition > 0) { - // TODO: Check expected - } else if (gbp->txPosition >= 12) { - // 0x00 = Stop - // 0x11 = Hard Stop - // 0x22 = Start - if (gbp->p->rumble) { - int32_t currentTime = mTimingCurrentTime(&gbp->p->timing); - gbp->p->rumble->setRumble(gbp->p->rumble, (rx & 0x33) == 0x22, currentTime - gbp->p->lastRumble); - gbp->p->lastRumble = currentTime; - } + if (value & 0x0080) { + uint32_t rx = gbp->p->memory.io[GBA_REG(SIODATA32_LO)] | (gbp->p->memory.io[GBA_REG(SIODATA32_HI)] << 16); + if (gbp->txPosition < 12 && gbp->txPosition > 0) { + // TODO: Check expected + } else if (gbp->txPosition >= 12) { + uint32_t mask = 0x33; + // 0x00 = Stop + // 0x11 = Hard Stop + // 0x22 = Start + if (gbp->p->rumble) { + int32_t currentTime = mTimingCurrentTime(&gbp->p->timing); + gbp->p->rumble->setRumble(gbp->p->rumble, (rx & 0x33) == 0x22, currentTime - gbp->p->lastRumble); + gbp->p->lastRumble = currentTime; } - mTimingDeschedule(&gbp->p->timing, &gbp->event); - mTimingSchedule(&gbp->p->timing, &gbp->event, 2048); } - value &= 0x78FB; + mTimingDeschedule(&gbp->p->timing, &gbp->event); + mTimingSchedule(&gbp->p->timing, &gbp->event, 2048); } + value &= 0x78FB; return value; } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 67b359234..526d83575 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -19,8 +19,8 @@ static void GBASIOLockstepNodeSetMode(struct GBASIODriver* driver, enum GBASIOMo static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver); static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver); -static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); -static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); +static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); +static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate); static void _finishTransfer(struct GBASIOLockstepNode* node); @@ -46,7 +46,7 @@ void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { node->d.handlesMode = GBASIOLockstepNodeHandlesMode; node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices; node->d.deviceId = GBASIOLockstepNodeDeviceId; - node->d.writeRegister = NULL; + node->d.writeSIOCNT = NULL; } bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { @@ -112,7 +112,7 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { switch (node->mode) { case GBA_SIO_MULTI: - node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; + node->d.writeSIOCNT = GBASIOLockstepNodeMultiWriteSIOCNT; ATOMIC_ADD(node->p->attachedMulti, 1); node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, node->p->attachedMulti == node->p->d.attached); if (node->id) { @@ -134,7 +134,7 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { } else { node->d.p->siocnt = GBASIONormalClearSi(node->d.p->siocnt); } - node->d.writeRegister = GBASIOLockstepNodeNormalWriteRegister; + node->d.writeSIOCNT = GBASIOLockstepNodeNormalWriteSIOCNT; break; default: break; @@ -231,41 +231,35 @@ static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver) { return node->id; } -static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { +static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; mLockstepLock(&node->p->d); - if (address == GBA_REG_SIOCNT) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value); + mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value); - enum mLockstepPhase transferActive; - int attached; - ATOMIC_LOAD(transferActive, node->p->d.transferActive); - ATOMIC_LOAD(attached, node->p->d.attached); + enum mLockstepPhase transferActive; + int attached; + ATOMIC_LOAD(transferActive, node->p->d.transferActive); + ATOMIC_LOAD(attached, node->p->d.attached); - driver->p->siocnt = GBASIOMultiplayerSetSlave(driver->p->siocnt, node->id || attached < 2); + driver->p->siocnt = GBASIOMultiplayerSetSlave(driver->p->siocnt, node->id || attached < 2); - if (value & 0x0080 && transferActive == TRANSFER_IDLE) { - if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p)); + if (value & 0x0080 && transferActive == TRANSFER_IDLE) { + if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) { + mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); + ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); + ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p)); - if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { - node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); - mTimingDeschedule(&driver->p->p->timing, &node->event); - } - mTimingSchedule(&driver->p->p->timing, &node->event, 0); + if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { + node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); + mTimingDeschedule(&driver->p->p->timing, &node->event); } + mTimingSchedule(&driver->p->p->timing, &node->event, 0); } - value &= 0xFF83; - value |= driver->p->siocnt & 0x00FC; - } else if (address == GBA_REG_SIOMLT_SEND) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOMLT_SEND <- %04X", node->id, value); - } else { - mLOG(GBA_SIO, STUB, "Lockstep %i: Unknown reg %03X <- %04X", node->id, address, value); } + value &= 0xFF83; + value |= driver->p->siocnt & 0x00FC; mLockstepUnlock(&node->p->d); @@ -525,62 +519,54 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, mLockstepUnlock(&node->p->d); } -static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { +static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; mLockstepLock(&node->p->d); - if (address == GBA_REG_SIOCNT) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value); - int attached; - ATOMIC_LOAD(attached, node->p->attachedNormal); - value &= 0xFF8B; - if (node->id > 0) { - value = GBASIONormalSetSi(value, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - } else { - value = GBASIONormalClearSi(value); - } + mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value); + int attached; + ATOMIC_LOAD(attached, node->p->attachedNormal); + value &= 0xFF8B; + if (node->id > 0) { + value = GBASIONormalSetSi(value, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); + } else { + value = GBASIONormalClearSi(value); + } - enum mLockstepPhase transferActive; - ATOMIC_LOAD(transferActive, node->p->d.transferActive); - if (node->id < 3 && attached > node->id + 1 && transferActive == TRANSFER_IDLE) { - int try; - for (try = 0; try < 3; ++try) { - GBASIONormal nextSiocnct; - ATOMIC_LOAD(nextSiocnct, node->p->players[node->id + 1]->d.p->siocnt); - if (ATOMIC_CMPXCHG(node->p->players[node->id + 1]->d.p->siocnt, nextSiocnct, GBASIONormalSetSi(nextSiocnct, GBASIONormalGetIdleSo(value)))) { - break; - } + enum mLockstepPhase transferActive; + ATOMIC_LOAD(transferActive, node->p->d.transferActive); + if (node->id < 3 && attached > node->id + 1 && transferActive == TRANSFER_IDLE) { + int try; + for (try = 0; try < 3; ++try) { + GBASIONormal nextSiocnct; + ATOMIC_LOAD(nextSiocnct, node->p->players[node->id + 1]->d.p->siocnt); + if (ATOMIC_CMPXCHG(node->p->players[node->id + 1]->d.p->siocnt, nextSiocnct, GBASIONormalSetSi(nextSiocnct, GBASIONormalGetIdleSo(value)))) { + break; } } - if ((value & 0x0081) == 0x0081) { - if (!node->id) { - // Frequency - int32_t cycles = GBASIOTransferCycles(node->d.p); + } + if ((value & 0x0081) == 0x0081) { + if (!node->id) { + // Frequency + int32_t cycles = GBASIOTransferCycles(node->d.p); - if (transferActive == TRANSFER_IDLE) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, cycles); + if (transferActive == TRANSFER_IDLE) { + mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); + ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); + ATOMIC_STORE(node->p->d.transferCycles, cycles); - if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { - node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); - mTimingDeschedule(&driver->p->p->timing, &node->event); - } - mTimingSchedule(&driver->p->p->timing, &node->event, 0); - } else { - value &= ~0x0080; + if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { + node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); + mTimingDeschedule(&driver->p->p->timing, &node->event); } + mTimingSchedule(&driver->p->p->timing, &node->event, 0); } else { - // TODO + value &= ~0x0080; } + } else { + // TODO } - } else if (address == GBA_REG_SIODATA32_LO) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04X", node->id, value); - } else if (address == GBA_REG_SIODATA32_HI) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04X", node->id, value); - } else if (address == GBA_REG_SIODATA8) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA8 <- %02X", node->id, value); } mLockstepUnlock(&node->p->d); From aad552ff47deb92b929f6146fd6d795125c869af Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2024 22:42:58 -0700 Subject: [PATCH 285/336] GBA SIO: Add writeRCNT callback, mostly for GPIO mode --- include/mgba/gba/interface.h | 1 + src/gba/extra/battlechip.c | 1 + src/gba/sio.c | 12 ++++-------- src/gba/sio/dolphin.c | 1 + src/gba/sio/gbp.c | 1 + src/gba/sio/lockstep.c | 1 + 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index b698f4030..f83f9e717 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -118,6 +118,7 @@ struct GBASIODriver { int (*connectedDevices)(struct GBASIODriver* driver); int (*deviceId)(struct GBASIODriver* driver); uint16_t (*writeSIOCNT)(struct GBASIODriver* driver, uint16_t value); + uint16_t (*writeRCNT)(struct GBASIODriver* driver, uint16_t value); }; enum GBASIOBattleChipGateFlavor { diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index b71b4e33e..4070626d8 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -51,6 +51,7 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { gate->d.handlesMode = GBASIOBattlechipGateHandlesMode; gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices; gate->d.deviceId = NULL; + gate->d.writeRCNT = NULL; gate->event.context = gate; gate->event.callback = _battlechipTransferEvent; diff --git a/src/gba/sio.c b/src/gba/sio.c index 68b8fcb48..14edd7b7a 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -193,6 +193,10 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) { sio->rcnt &= 0xF; sio->rcnt |= value & ~0xF; _switchMode(sio); + if (sio->activeDriver && sio->activeDriver->writeRCNT) { + sio->rcnt &= 0xC000; + sio->rcnt |= sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01FF; + } } void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { @@ -278,8 +282,6 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu default: mLOG(GBA_SIO, DEBUG, "JOY write: Unknown reg %03X <- %04X", address, value); break; - case GBA_REG_RCNT: - break; } break; case GBA_SIO_NORMAL_8: @@ -290,8 +292,6 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu default: mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: Unknown reg %03X <- %04X", id, address, value); break; - case GBA_REG_RCNT: - break; } break; case GBA_SIO_NORMAL_32: @@ -305,8 +305,6 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu default: mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: Unknown reg %03X <- %04X", id, address, value); break; - case GBA_REG_RCNT: - break; } break; case GBA_SIO_MULTI: @@ -317,8 +315,6 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu default: mLOG(GBA_SIO, DEBUG, "MULTI %i write: Unknown reg %03X <- %04X", id, address, value); break; - case GBA_REG_RCNT: - break; } break; default: diff --git a/src/gba/sio/dolphin.c b/src/gba/sio/dolphin.c index 039f9b528..f7aad747b 100644 --- a/src/gba/sio/dolphin.c +++ b/src/gba/sio/dolphin.c @@ -41,6 +41,7 @@ void GBASIODolphinCreate(struct GBASIODolphin* dol) { dol->d.handlesMode = GBASIODolphinHandlesMode; dol->d.connectedDevices = GBASIODolphinConnectedDevices; dol->d.deviceId = NULL; + dol->d.writeSIOCNT = NULL; dol->event.context = dol; dol->event.name = "GB SIO Lockstep"; dol->event.callback = GBASIODolphinProcessEvents; diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index 7aeef1b0b..f7b3747a1 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -54,6 +54,7 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { gbp->d.handlesMode = _gbpSioHandlesMode; gbp->d.connectedDevices = _gbpSioConnectedDevices; gbp->d.deviceId = NULL; + gbp->d.writeRCNT = NULL; gbp->event.context = gbp; gbp->event.name = "GBA SIO Game Boy Player"; gbp->event.callback = _gbpSioProcessEvents; diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 526d83575..30092c3ec 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -47,6 +47,7 @@ void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices; node->d.deviceId = GBASIOLockstepNodeDeviceId; node->d.writeSIOCNT = NULL; + node->d.writeRCNT = NULL; } bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { From aeb547e3dc621a6ba4f14cbcb3b04941049e54c6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2024 23:04:44 -0700 Subject: [PATCH 286/336] GBA SIO: Finish up GBASIOWriteRegister logging --- src/gba/sio.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/gba/sio.c b/src/gba/sio.c index 14edd7b7a..ec29a62a5 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -280,7 +280,7 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_HI <- %04X", value); break; default: - mLOG(GBA_SIO, DEBUG, "JOY write: Unknown reg %03X <- %04X", address, value); + mLOG(GBA_SIO, GAME_ERROR, "JOY write: Unknown reg %03X <- %04X", address, value); break; } break; @@ -290,7 +290,7 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: SIODATA8 <- %02X", id, value); break; default: - mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: Unknown reg %03X <- %04X", id, address, value); + mLOG(GBA_SIO, GAME_ERROR, "NORMAL8 %i write: Unknown reg %03X <- %04X", id, address, value); break; } break; @@ -303,7 +303,7 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: SIODATA32_HI <- %04X", id, value); break; default: - mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: Unknown reg %03X <- %04X", id, address, value); + mLOG(GBA_SIO, GAME_ERROR, "NORMAL32 %i write: Unknown reg %03X <- %04X", id, address, value); break; } break; @@ -313,12 +313,22 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu mLOG(GBA_SIO, DEBUG, "MULTI %i write: SIOMLT_SEND <- %04X", id, value); break; default: - mLOG(GBA_SIO, DEBUG, "MULTI %i write: Unknown reg %03X <- %04X", id, address, value); + mLOG(GBA_SIO, GAME_ERROR, "MULTI %i write: Unknown reg %03X <- %04X", id, address, value); break; } break; - default: - // TODO + case GBA_SIO_UART: + switch (address) { + case GBA_REG_SIODATA8: + mLOG(GBA_SIO, DEBUG, "UART write: SIODATA8 <- %02X", value); + break; + default: + mLOG(GBA_SIO, GAME_ERROR, "UART write: Unknown reg %03X <- %04X", address, value); + break; + } + break; + case GBA_SIO_GPIO: + mLOG(GBA_SIO, GAME_ERROR, "GPIO %i write: Unknown reg %03X <- %04X", id, address, value); break; } return value; From b572e8b09fbe6ac6052da30d730601d89425b17b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 26 Sep 2024 02:52:25 -0700 Subject: [PATCH 287/336] GBA SIO: Fix SIO register writing per mode --- src/gba/io.c | 1 + src/gba/sio.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/gba/io.c b/src/gba/io.c index ea9d8d8b0..d29fb8a4b 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -483,6 +483,7 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { // SIO case GBA_REG_SIOCNT: + value &= 0x7FFF; GBASIOWriteSIOCNT(&gba->sio, value); break; case GBA_REG_RCNT: diff --git a/src/gba/sio.c b/src/gba/sio.c index ec29a62a5..62ce0adb7 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -262,9 +262,13 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu id = sio->activeDriver->deviceId(sio->activeDriver); } + bool handled = true; switch (sio->mode) { case GBA_SIO_JOYBUS: switch (address) { + case GBA_REG_SIODATA8: + mLOG(GBA_SIO, DEBUG, "JOY write: SIODATA8 (?) <- %04X", value); + break; case GBA_REG_JOYCNT: mLOG(GBA_SIO, DEBUG, "JOY write: CNT <- %04X", value); value = (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); @@ -280,17 +284,23 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu mLOG(GBA_SIO, DEBUG, "JOY write: TRANS_HI <- %04X", value); break; default: - mLOG(GBA_SIO, GAME_ERROR, "JOY write: Unknown reg %03X <- %04X", address, value); + mLOG(GBA_SIO, GAME_ERROR, "JOY write: Unhandled %s <- %04X", GBAIORegisterNames[address >> 1], value); + handled = false; break; } break; case GBA_SIO_NORMAL_8: switch (address) { case GBA_REG_SIODATA8: - mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: SIODATA8 <- %02X", id, value); + mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: SIODATA8 <- %04X", id, value); + break; + case GBA_REG_JOYCNT: + mLOG(GBA_SIO, DEBUG, "NORMAL8 %i write: JOYCNT (?) <- %04X", id, value); + value = (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); break; default: - mLOG(GBA_SIO, GAME_ERROR, "NORMAL8 %i write: Unknown reg %03X <- %04X", id, address, value); + mLOG(GBA_SIO, GAME_ERROR, "NORMAL8 %i write: Unhandled %s <- %04X", id, GBAIORegisterNames[address >> 1], value); + handled = false; break; } break; @@ -302,8 +312,16 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu case GBA_REG_SIODATA32_HI: mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: SIODATA32_HI <- %04X", id, value); break; + case GBA_REG_SIODATA8: + mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: SIODATA8 (?) <- %04X", id, value); + break; + case GBA_REG_JOYCNT: + mLOG(GBA_SIO, DEBUG, "NORMAL32 %i write: JOYCNT (?) <- %04X", id, value); + value = (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); + break; default: - mLOG(GBA_SIO, GAME_ERROR, "NORMAL32 %i write: Unknown reg %03X <- %04X", id, address, value); + mLOG(GBA_SIO, GAME_ERROR, "NORMAL32 %i write: Unhandled %s <- %04X", id, GBAIORegisterNames[address >> 1], value); + handled = false; break; } break; @@ -312,25 +330,39 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu case GBA_REG_SIOMLT_SEND: mLOG(GBA_SIO, DEBUG, "MULTI %i write: SIOMLT_SEND <- %04X", id, value); break; + case GBA_REG_JOYCNT: + mLOG(GBA_SIO, DEBUG, "MULTI %i write: JOYCNT (?) <- %04X", id, value); + value = (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); + break; default: - mLOG(GBA_SIO, GAME_ERROR, "MULTI %i write: Unknown reg %03X <- %04X", id, address, value); + mLOG(GBA_SIO, GAME_ERROR, "MULTI %i write: Unhandled %s <- %04X", id, GBAIORegisterNames[address >> 1], value); + handled = false; break; } break; case GBA_SIO_UART: switch (address) { case GBA_REG_SIODATA8: - mLOG(GBA_SIO, DEBUG, "UART write: SIODATA8 <- %02X", value); + mLOG(GBA_SIO, DEBUG, "UART write: SIODATA8 <- %04X", value); + break; + case GBA_REG_JOYCNT: + mLOG(GBA_SIO, DEBUG, "UART write: JOYCNT (?) <- %04X", value); + value = (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); break; default: - mLOG(GBA_SIO, GAME_ERROR, "UART write: Unknown reg %03X <- %04X", address, value); + mLOG(GBA_SIO, GAME_ERROR, "UART write: Unhandled %s <- %04X", GBAIORegisterNames[address >> 1], value); + handled = false; break; } break; case GBA_SIO_GPIO: - mLOG(GBA_SIO, GAME_ERROR, "GPIO %i write: Unknown reg %03X <- %04X", id, address, value); + mLOG(GBA_SIO, STUB, "GPIO write: Unhandled %s <- %04X", GBAIORegisterNames[address >> 1], value); + handled = false; break; } + if (!handled) { + value = sio->p->memory.io[address >> 1]; + } return value; } From ab655db3f8b6a72d167fbd60e4963dd0c6805666 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2024 01:32:55 -0700 Subject: [PATCH 288/336] GBA SIO: Fix NORMAL timing out --- include/mgba/internal/gba/sio.h | 1 + src/gba/sio.c | 42 ++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index 43acaa7b8..804f0f52a 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -70,6 +70,7 @@ struct GBASIO { uint16_t siocnt; struct GBASIOPlayer gbp; + struct mTimingEvent completeEvent; }; void GBASIOInit(struct GBASIO* sio); diff --git a/src/gba/sio.c b/src/gba/sio.c index 62ce0adb7..710cd9d45 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -18,6 +18,8 @@ static const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { { 3140, 5755, 8376, 10486 } }; +static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate); + static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) { switch (mode) { case GBA_SIO_NORMAL_8: @@ -90,10 +92,15 @@ static void _switchMode(struct GBASIO* sio) { } void GBASIOInit(struct GBASIO* sio) { - sio->drivers.normal = 0; - sio->drivers.multiplayer = 0; - sio->drivers.joybus = 0; - sio->activeDriver = 0; + sio->drivers.normal = NULL; + sio->drivers.multiplayer = NULL; + sio->drivers.joybus = NULL; + sio->activeDriver = NULL; + + sio->completeEvent.context = sio; + sio->completeEvent.name = "GBA SIO Complete"; + sio->completeEvent.callback = _sioFinish; + sio->completeEvent.priority = 0x80; sio->gbp.p = sio->p; GBASIOPlayerInit(&sio->gbp); @@ -239,10 +246,12 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { value = GBASIONormalFillSi(value); if ((value & 0x0081) == 0x0081) { if (GBASIONormalIsIrq(value)) { + mTimingDeschedule(&sio->p->timing, &sio->completeEvent); + mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio)); + } else { // TODO: Test this on hardware to see if this is correct - GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); + value = GBASIONormalClearStart(value); } - value = GBASIONormalClearStart(value); } break; case GBA_SIO_MULTI: @@ -425,6 +434,27 @@ void GBASIONormal32FinishTransfer(struct GBASIO* sio, uint32_t data, uint32_t cy } } +static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate) { + UNUSED(timing); + struct GBASIO* sio = user; + uint16_t data[4] = {0, 0, 0, 0}; + switch (sio->mode) { + case GBA_SIO_MULTI: + GBASIOMultiplayerFinishTransfer(sio, data, cyclesLate); + break; + case GBA_SIO_NORMAL_8: + GBASIONormal8FinishTransfer(sio, 0, cyclesLate); + break; + case GBA_SIO_NORMAL_32: + GBASIONormal32FinishTransfer(sio, 0, cyclesLate); + break; + default: + // TODO + mLOG(GBA_SIO, STUB, "No dummy finish implemented for mode %s", _modeName(sio->mode)); + break; + } +} + int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) { switch (command) { case JOY_RESET: From 914d8798116c4f713c19ad050394d195417c047d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2024 03:01:44 -0700 Subject: [PATCH 289/336] GBA SIO: Allow seamless mode switching if driver supports it --- src/gba/sio.c | 22 +++++++++++++++------- src/gba/sio/lockstep.c | 10 +--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gba/sio.c b/src/gba/sio.c index 710cd9d45..54fff7ea1 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -60,16 +60,24 @@ static void _switchMode(struct GBASIO* sio) { newMode = (enum GBASIOMode) (mode & 0xC); } if (newMode != sio->mode) { - if (sio->activeDriver && sio->activeDriver->unload) { - sio->activeDriver->unload(sio->activeDriver); - } + struct GBASIODriver* driver = _lookupDriver(sio, newMode); if (sio->mode != (enum GBASIOMode) -1) { mLOG(GBA_SIO, DEBUG, "Switching mode from %s to %s", _modeName(sio->mode), _modeName(newMode)); } - sio->mode = newMode; - sio->activeDriver = _lookupDriver(sio, sio->mode); - if (sio->activeDriver && sio->activeDriver->load) { - sio->activeDriver->load(sio->activeDriver); + if (driver != sio->activeDriver || (driver && !driver->setMode)) { + if (sio->activeDriver && sio->activeDriver->unload) { + sio->activeDriver->unload(sio->activeDriver); + } + sio->mode = newMode; + sio->activeDriver = driver; + if (sio->activeDriver && sio->activeDriver->load) { + sio->activeDriver->load(sio->activeDriver); + } + } else { + sio->mode = newMode; + if (sio->activeDriver && sio->activeDriver->setMode) { + sio->activeDriver->setMode(sio->activeDriver, newMode); + } } int id = 0; diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 30092c3ec..f7b82f089 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -15,7 +15,6 @@ static bool GBASIOLockstepNodeInit(struct GBASIODriver* driver); static void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver); static bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver); static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver); -static void GBASIOLockstepNodeSetMode(struct GBASIODriver* driver, enum GBASIOMode mode); static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver); static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver); @@ -42,7 +41,7 @@ void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { node->d.deinit = GBASIOLockstepNodeDeinit; node->d.load = GBASIOLockstepNodeLoad; node->d.unload = GBASIOLockstepNodeUnload; - node->d.setMode = GBASIOLockstepNodeSetMode; + node->d.setMode = NULL; node->d.handlesMode = GBASIOLockstepNodeHandlesMode; node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices; node->d.deviceId = GBASIOLockstepNodeDeviceId; @@ -190,13 +189,6 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { return true; } -static void GBASIOLockstepNodeSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - mLockstepLock(&node->p->d); - node->mode = mode; - mLockstepUnlock(&node->p->d); -} - static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { UNUSED(driver); switch (mode) { From 0425dadee9bdb1eebaae80f523037fd62c39e004 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2024 00:46:00 -0700 Subject: [PATCH 290/336] GBA SIO: Add RCNT bitfield --- include/mgba/internal/gba/sio.h | 9 +++++++++ src/gba/sio.c | 16 ++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index 804f0f52a..bb7b2a78c 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -52,6 +52,15 @@ DECL_BITS(GBASIOMultiplayer, Id, 4, 2); DECL_BIT(GBASIOMultiplayer, Error, 6); DECL_BIT(GBASIOMultiplayer, Busy, 7); DECL_BIT(GBASIOMultiplayer, Irq, 14); +DECL_BITFIELD(GBASIORegisterRCNT, uint16_t); +DECL_BIT(GBASIORegisterRCNT, Sc, 0); +DECL_BIT(GBASIORegisterRCNT, Sd, 1); +DECL_BIT(GBASIORegisterRCNT, Si, 2); +DECL_BIT(GBASIORegisterRCNT, So, 3); +DECL_BIT(GBASIORegisterRCNT, ScDirection, 4); +DECL_BIT(GBASIORegisterRCNT, SdDirection, 5); +DECL_BIT(GBASIORegisterRCNT, SiDirection, 6); +DECL_BIT(GBASIORegisterRCNT, SoDirection, 7); struct GBASIODriverSet { struct GBASIODriver* normal; diff --git a/src/gba/sio.c b/src/gba/sio.c index 54fff7ea1..b10d2c257 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -86,11 +86,7 @@ static void _switchMode(struct GBASIO* sio) { if (sio->activeDriver && sio->activeDriver->deviceId) { id = sio->activeDriver->deviceId(sio->activeDriver); } - if (id) { - sio->rcnt |= 4; - } else { - sio->rcnt &= ~4; - } + sio->rcnt = GBASIORegisterRCNTSetSi(sio->rcnt, !!id); break; default: // TODO @@ -417,9 +413,17 @@ void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint3 sio->p->memory.io[GBA_REG(SIOMULTI1)] = data[1]; sio->p->memory.io[GBA_REG(SIOMULTI2)] = data[2]; sio->p->memory.io[GBA_REG(SIOMULTI3)] = data[3]; - sio->rcnt |= 1; + sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt); sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, id); + + // This SC level is actually a transient pulse, and probably a hardware glitch. + // Based on analog sampling it seems to just be a spike when the other lines deassert. + // It rapidly falls down to GND but it's high enough that it's read out as a 1 for + // several microseconds, likely around 300-500 cycles. I have not measured if and when + // it returns to 0 afterwards. + sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt); + if (GBASIOMultiplayerIsIrq(sio->siocnt)) { GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate); } From 435c4aa2436addc27e7d0f8439a3aa0281b820bb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 15 Sep 2024 23:26:58 -0700 Subject: [PATCH 291/336] GBA SIO: Improve RCNT emulation --- src/gba/sio.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/gba/sio.c b/src/gba/sio.c index b10d2c257..acc45e607 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -201,12 +201,23 @@ void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASI } void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) { - sio->rcnt &= 0xF; - sio->rcnt |= value & ~0xF; + sio->rcnt &= 0x1FF; + sio->rcnt |= value & 0xC000; _switchMode(sio); if (sio->activeDriver && sio->activeDriver->writeRCNT) { + switch (sio->mode) { + case GBA_SIO_GPIO: + sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01FF) | (sio->rcnt & 0xC000); + break; + default: + sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01F0) | (sio->rcnt & 0xC00F); + } + } else if (sio->mode == GBA_SIO_GPIO) { sio->rcnt &= 0xC000; - sio->rcnt |= sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01FF; + sio->rcnt |= value & 0x1FF; + } else { + sio->rcnt &= 0xC00F; + sio->rcnt |= value & 0x1F0; } } @@ -235,6 +246,24 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { value = GBASIOMultiplayerSetSlave(value, id || !connected); value = GBASIOMultiplayerSetId(value, id); value |= sio->siocnt & 0x00FC; + + // SC appears to float in multi mode when not doing a transfer. While + // it does spike at the end of a transfer, it appears to die down after + // around 20-30 microseconds. However, the docs on akkit.org + // (http://www.akkit.org/info/gba_comms.html) say this is high until + // a transfer starts and low while active. Further, the Mario Bros. + // multiplayer expects SC to be high in multi mode. This needs better + // investigation than I managed, apparently. + sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt); + + break; + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: + // This line is pulled up by the clock owner while the clock is idle. + // If there is no clock owner it's just hi-Z. + if (GBASIONormalGetSc(value)) { + sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt); + } break; default: // TODO @@ -417,11 +446,6 @@ void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint3 sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt); sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, id); - // This SC level is actually a transient pulse, and probably a hardware glitch. - // Based on analog sampling it seems to just be a spike when the other lines deassert. - // It rapidly falls down to GND but it's high enough that it's read out as a 1 for - // several microseconds, likely around 300-500 cycles. I have not measured if and when - // it returns to 0 afterwards. sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt); if (GBASIOMultiplayerIsIrq(sio->siocnt)) { From 621eb4d4257ce2fc1894812bc6278e6404dc094b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2024 23:11:22 -0700 Subject: [PATCH 292/336] GBA SIO: Move starting/end timing logic out of drivers --- include/mgba/gba/interface.h | 5 ++- include/mgba/internal/gba/serialize.h | 4 +- include/mgba/internal/gba/sio/gbp.h | 1 - src/gba/cart/gpio.c | 14 +++---- src/gba/extra/battlechip.c | 45 +++++--------------- src/gba/sio.c | 60 +++++++++++++++++++++------ src/gba/sio/dolphin.c | 5 +-- src/gba/sio/gbp.c | 59 +++++++++++--------------- src/gba/sio/lockstep.c | 14 ++++--- 9 files changed, 104 insertions(+), 103 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index f83f9e717..3d52e7743 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -119,6 +119,10 @@ struct GBASIODriver { int (*deviceId)(struct GBASIODriver* driver); uint16_t (*writeSIOCNT)(struct GBASIODriver* driver, uint16_t value); uint16_t (*writeRCNT)(struct GBASIODriver* driver, uint16_t value); + bool (*start)(struct GBASIODriver* driver); + void (*finishMultiplayer)(struct GBASIODriver* driver, uint16_t data[4]); + uint8_t (*finishNormal8)(struct GBASIODriver* driver); + uint32_t (*finishNormal32)(struct GBASIODriver* driver); }; enum GBASIOBattleChipGateFlavor { @@ -130,7 +134,6 @@ enum GBASIOBattleChipGateFlavor { struct GBASIOBattlechipGate { struct GBASIODriver d; - struct mTimingEvent event; uint16_t chipId; uint16_t data[2]; int state; diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index 9bd21821a..c824e85aa 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -191,7 +191,7 @@ mLOG_DECLARE_CATEGORY(GBA_STATE); * | bits 2 - 3: GB Player inputs posted * | bits 4 - 8: GB Player transmit position * | bits 9 - 23: Reserved - * 0x002C4 - 0x002C7: Game Boy Player next event + * 0x002C4 - 0x002C7: SIO next event * 0x002C8 - 0x002CB: Current DMA transfer word * 0x002CC - 0x002CF: Last DMA transfer PC * 0x002D0 - 0x002DF: Matrix memory command buffer @@ -370,7 +370,7 @@ struct GBASerializedState { uint8_t lightSample; GBASerializedHWFlags2 flags2; GBASerializedHWFlags3 flags3; - uint32_t gbpNextEvent; + uint32_t sioNextEvent; } hw; uint32_t dmaTransferRegister; diff --git a/include/mgba/internal/gba/sio/gbp.h b/include/mgba/internal/gba/sio/gbp.h index 6713cdcaf..fe32cd8c1 100644 --- a/include/mgba/internal/gba/sio/gbp.h +++ b/include/mgba/internal/gba/sio/gbp.h @@ -21,7 +21,6 @@ struct GBASIOPlayer { struct GBA* p; unsigned inputsPosted; int txPosition; - struct mTimingEvent event; struct GBASIOPlayerKeyCallback callback; bool oldOpposingDirections; struct mKeyCallback* oldCallback; diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index fde4e3714..a04a5f6b3 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -486,10 +486,10 @@ void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASeria flags2 = GBASerializedHWFlags2SetTiltState(flags2, hw->tiltState); flags2 = GBASerializedHWFlags1SetLightCounter(flags2, hw->lightCounter); - // GBP stuff is only here for legacy reasons + // GBP/SIO stuff is only here for legacy reasons flags2 = GBASerializedHWFlags2SetGbpInputsPosted(flags2, hw->p->sio.gbp.inputsPosted); flags2 = GBASerializedHWFlags2SetGbpTxPosition(flags2, hw->p->sio.gbp.txPosition); - STORE_32(hw->p->sio.gbp.event.when - mTimingCurrentTime(&hw->p->timing), 0, &state->hw.gbpNextEvent); + STORE_32(hw->p->sio.completeEvent.when - mTimingCurrentTime(&hw->p->timing), 0, &state->hw.sioNextEvent); state->hw.flags2 = flags2; } @@ -520,16 +520,16 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer hw->lightSample = state->hw.lightSample; hw->lightEdge = GBASerializedHWFlags1GetLightEdge(flags1); - // GBP stuff is only here for legacy reasons + // GBP/SIO stuff is only here for legacy reasons hw->p->sio.gbp.inputsPosted = GBASerializedHWFlags2GetGbpInputsPosted(state->hw.flags2); hw->p->sio.gbp.txPosition = GBASerializedHWFlags2GetGbpTxPosition(state->hw.flags2); uint32_t when; - LOAD_32(when, 0, &state->hw.gbpNextEvent); + LOAD_32(when, 0, &state->hw.sioNextEvent); if (hw->devices & HW_GB_PLAYER) { GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, GBA_SIO_NORMAL_32); - if (hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) { - mTimingSchedule(&hw->p->timing, &hw->p->sio.gbp.event, when); - } + } + if ((hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) && when < 0x20000) { + mTimingSchedule(&hw->p->timing, &hw->p->sio.completeEvent, when); } } diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 4070626d8..a6eda3bdf 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -37,25 +37,15 @@ static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver); static uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver); - -static void _battlechipTransfer(struct GBASIOBattlechipGate* gate); -static void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate); +static void GBASIOBattlechipGateFinishMultiplayer(struct GBASIODriver* driver, uint16_t data[4]); void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { - gate->d.init = NULL; - gate->d.deinit = NULL; + memset(&gate->d, 0, sizeof(gate->d)); gate->d.load = GBASIOBattlechipGateLoad; - gate->d.unload = NULL; gate->d.writeSIOCNT = GBASIOBattlechipGateWriteSIOCNT; - gate->d.setMode = NULL; gate->d.handlesMode = GBASIOBattlechipGateHandlesMode; gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices; - gate->d.deviceId = NULL; - gate->d.writeRCNT = NULL; - - gate->event.context = gate; - gate->event.callback = _battlechipTransferEvent; - gate->event.priority = 0x80; + gate->d.finishMultiplayer = GBASIOBattlechipGateFinishMultiplayer; gate->chipId = 0; gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE; @@ -70,12 +60,9 @@ bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) { } uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { - struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; + UNUSED(driver); value &= ~0xC; value |= 0x8; - if (value & 0x80) { - _battlechipTransfer(gate); - } return value; } @@ -95,20 +82,8 @@ static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver) { return 1; } -void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { - int32_t cycles = GBASIOTransferCycles(gate->d.p); - mTimingDeschedule(&gate->d.p->p->timing, &gate->event); - mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles); -} - -void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate) { - UNUSED(timing); - struct GBASIOBattlechipGate* gate = user; - - if (gate->d.p->mode == GBA_SIO_NORMAL_32) { - GBASIONormal32FinishTransfer(gate->d.p, 0, cyclesLate); - return; - } +static void GBASIOBattlechipGateFinishMultiplayer(struct GBASIODriver* driver, uint16_t data[4]) { + struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; uint16_t cmd = gate->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; uint16_t reply = 0xFFFF; @@ -189,8 +164,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle mLOG(GBA_BATTLECHIP, DEBUG, "Gate: %04X (%i)", reply, gate->state); ++gate->state; - uint16_t data[4] = { - cmd, reply, 0xFFFF, 0xFFFF - }; - GBASIOMultiplayerFinishTransfer(gate->d.p, data, cyclesLate); + data[0] = cmd; + data[1] = reply; + data[2] = 0xFFFF; + data[3] = 0xFFFF; } diff --git a/src/gba/sio.c b/src/gba/sio.c index acc45e607..971eb9502 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -221,6 +221,17 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) { } } +static void _startTransfer(struct GBASIO* sio) { + if (sio->activeDriver && sio->activeDriver->start) { + if (!sio->activeDriver->start(sio->activeDriver)) { + // Transfer completion is handled internally to the driver + return; + } + } + mTimingDeschedule(&sio->p->timing, &sio->completeEvent); + mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio)); +} + void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { if ((value ^ sio->siocnt) & 0x3000) { sio->siocnt = value & 0x3000; @@ -256,6 +267,18 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { // investigation than I managed, apparently. sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt); + if (GBASIOMultiplayerIsBusy(value) && !GBASIOMultiplayerIsBusy(sio->siocnt)) { + if (!id) { + sio->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF; + sio->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF; + sio->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF; + sio->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF; + sio->rcnt = GBASIORegisterRCNTClearSc(sio->rcnt); + _startTransfer(sio); + } else { + // TODO + } + } break; case GBA_SIO_NORMAL_8: case GBA_SIO_NORMAL_32: @@ -264,6 +287,13 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { if (GBASIONormalGetSc(value)) { sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt); } + if (GBASIONormalIsStart(value) && !GBASIONormalIsStart(sio->siocnt)) { + if (GBASIONormalIsSc(value)) { + _startTransfer(sio); + } else { + // TODO + } + } break; default: // TODO @@ -277,15 +307,6 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { case GBA_SIO_NORMAL_8: case GBA_SIO_NORMAL_32: value = GBASIONormalFillSi(value); - if ((value & 0x0081) == 0x0081) { - if (GBASIONormalIsIrq(value)) { - mTimingDeschedule(&sio->p->timing, &sio->completeEvent); - mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio)); - } else { - // TODO: Test this on hardware to see if this is correct - value = GBASIONormalClearStart(value); - } - } break; case GBA_SIO_MULTI: value = GBASIOMultiplayerFillReady(value); @@ -473,16 +494,29 @@ void GBASIONormal32FinishTransfer(struct GBASIO* sio, uint32_t data, uint32_t cy static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate) { UNUSED(timing); struct GBASIO* sio = user; - uint16_t data[4] = {0, 0, 0, 0}; + union { + uint16_t multi[4]; + uint8_t normal8; + uint32_t normal32; + } data = {0}; switch (sio->mode) { case GBA_SIO_MULTI: - GBASIOMultiplayerFinishTransfer(sio, data, cyclesLate); + if (sio->activeDriver && sio->activeDriver->finishMultiplayer) { + sio->activeDriver->finishMultiplayer(sio->activeDriver, data.multi); + } + GBASIOMultiplayerFinishTransfer(sio, data.multi, cyclesLate); break; case GBA_SIO_NORMAL_8: - GBASIONormal8FinishTransfer(sio, 0, cyclesLate); + if (sio->activeDriver && sio->activeDriver->finishNormal8) { + data.normal8 = sio->activeDriver->finishNormal8(sio->activeDriver); + } + GBASIONormal8FinishTransfer(sio, data.normal8, cyclesLate); break; case GBA_SIO_NORMAL_32: - GBASIONormal32FinishTransfer(sio, 0, cyclesLate); + if (sio->activeDriver && sio->activeDriver->finishNormal32) { + data.normal32 = sio->activeDriver->finishNormal32(sio->activeDriver); + } + GBASIONormal32FinishTransfer(sio, data.normal32, cyclesLate); break; default: // TODO diff --git a/src/gba/sio/dolphin.c b/src/gba/sio/dolphin.c index f7aad747b..e36dfb8a5 100644 --- a/src/gba/sio/dolphin.c +++ b/src/gba/sio/dolphin.c @@ -33,15 +33,12 @@ static int32_t _processCommand(struct GBASIODolphin* dol, uint32_t cyclesLate); static void _flush(struct GBASIODolphin* dol); void GBASIODolphinCreate(struct GBASIODolphin* dol) { + memset(&dol->d, 0, sizeof(dol->d)); dol->d.init = GBASIODolphinInit; dol->d.load = GBASIODolphinLoad; dol->d.unload = GBASIODolphinUnload; - dol->d.writeSIOCNT = NULL; - dol->d.setMode = NULL; dol->d.handlesMode = GBASIODolphinHandlesMode; dol->d.connectedDevices = GBASIODolphinConnectedDevices; - dol->d.deviceId = NULL; - dol->d.writeSIOCNT = NULL; dol->event.context = dol; dol->event.name = "GB SIO Lockstep"; dol->event.callback = GBASIODolphinProcessEvents; diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index f7b3747a1..3335905a1 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -16,7 +16,8 @@ static uint16_t _gbpRead(struct mKeyCallback*); static uint16_t _gbpSioWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int _gbpSioConnectedDevices(struct GBASIODriver* driver); -static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate); +static bool _gbpSioStart(struct GBASIODriver* driver); +static uint32_t _gbpSioFinishNormal32(struct GBASIODriver* driver); static const uint8_t _logoPalette[] = { 0xDF, 0xFF, 0x0C, 0x64, 0x0C, 0xE4, 0x2D, 0xE4, 0x4E, 0x64, 0x4E, 0xE4, 0x6E, 0xE4, 0xAF, 0x68, @@ -45,20 +46,12 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { gbp->callback.d.readKeys = _gbpRead; gbp->callback.d.requireOpposingDirections = true; gbp->callback.p = gbp; - gbp->d.init = NULL; - gbp->d.deinit = NULL; - gbp->d.load = NULL; - gbp->d.unload = NULL; + memset(&gbp->d, 0, sizeof(gbp->d)); gbp->d.writeSIOCNT = _gbpSioWriteSIOCNT; - gbp->d.setMode = NULL; gbp->d.handlesMode = _gbpSioHandlesMode; gbp->d.connectedDevices = _gbpSioConnectedDevices; - gbp->d.deviceId = NULL; - gbp->d.writeRCNT = NULL; - gbp->event.context = gbp; - gbp->event.name = "GBA SIO Game Boy Player"; - gbp->event.callback = _gbpSioProcessEvents; - gbp->event.priority = 0x80; + gbp->d.start = _gbpSioStart; + gbp->d.finishNormal32 = _gbpSioFinishNormal32; } void GBASIOPlayerReset(struct GBASIOPlayer* gbp) { @@ -108,27 +101,26 @@ uint16_t _gbpRead(struct mKeyCallback* callback) { } uint16_t _gbpSioWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { + UNUSED(driver); + return value & 0x78FB; +} + +bool _gbpSioStart(struct GBASIODriver* driver) { struct GBASIOPlayer* gbp = (struct GBASIOPlayer*) driver; - if (value & 0x0080) { - uint32_t rx = gbp->p->memory.io[GBA_REG(SIODATA32_LO)] | (gbp->p->memory.io[GBA_REG(SIODATA32_HI)] << 16); - if (gbp->txPosition < 12 && gbp->txPosition > 0) { - // TODO: Check expected - } else if (gbp->txPosition >= 12) { - uint32_t mask = 0x33; - // 0x00 = Stop - // 0x11 = Hard Stop - // 0x22 = Start - if (gbp->p->rumble) { - int32_t currentTime = mTimingCurrentTime(&gbp->p->timing); - gbp->p->rumble->setRumble(gbp->p->rumble, (rx & 0x33) == 0x22, currentTime - gbp->p->lastRumble); - gbp->p->lastRumble = currentTime; - } + uint32_t rx = gbp->p->memory.io[GBA_REG(SIODATA32_LO)] | (gbp->p->memory.io[GBA_REG(SIODATA32_HI)] << 16); + if (gbp->txPosition < 12 && gbp->txPosition > 0) { + // TODO: Check expected + } else if (gbp->txPosition >= 12) { + // 0x00 = Stop + // 0x11 = Hard Stop + // 0x22 = Start + if (gbp->p->rumble) { + int32_t currentTime = mTimingCurrentTime(&gbp->p->timing); + gbp->p->rumble->setRumble(gbp->p->rumble, (rx & 0x33) == 0x22, currentTime - gbp->p->lastRumble); + gbp->p->lastRumble = currentTime; } - mTimingDeschedule(&gbp->p->timing, &gbp->event); - mTimingSchedule(&gbp->p->timing, &gbp->event, 2048); } - value &= 0x78FB; - return value; + return true; } static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { @@ -141,9 +133,8 @@ static int _gbpSioConnectedDevices(struct GBASIODriver* driver) { return 1; } -void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { - UNUSED(timing); - struct GBASIOPlayer* gbp = user; +uint32_t _gbpSioFinishNormal32(struct GBASIODriver* driver) { + struct GBASIOPlayer* gbp = (struct GBASIOPlayer*) driver; uint32_t tx = 0; int txPosition = gbp->txPosition; if (txPosition > 16) { @@ -154,5 +145,5 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat } tx = _gbpTxData[txPosition]; ++gbp->txPosition; - GBASIONormal32FinishTransfer(gbp->d.p, tx, cyclesLate); + return tx; } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index f7b82f089..ed74ed6d4 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -18,6 +18,7 @@ static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver); static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver); static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver); +static bool GBASIOLockstepNodeStart(struct GBASIODriver* driver); static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate); @@ -37,16 +38,16 @@ void GBASIOLockstepInit(struct GBASIOLockstep* lockstep) { } void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { + memset(&node->d, 0, sizeof(node->d)); node->d.init = GBASIOLockstepNodeInit; node->d.deinit = GBASIOLockstepNodeDeinit; node->d.load = GBASIOLockstepNodeLoad; node->d.unload = GBASIOLockstepNodeUnload; - node->d.setMode = NULL; node->d.handlesMode = GBASIOLockstepNodeHandlesMode; node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices; node->d.deviceId = GBASIOLockstepNodeDeviceId; + node->d.start = GBASIOLockstepNodeStart; node->d.writeSIOCNT = NULL; - node->d.writeRCNT = NULL; } bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { @@ -224,6 +225,11 @@ static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver) { return node->id; } +static bool GBASIOLockstepNodeStart(struct GBASIODriver* driver) { + UNUSED(driver); + return false; +} + static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; @@ -319,10 +325,6 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { switch (node->mode) { case GBA_SIO_MULTI: node->p->multiRecv[0] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; - node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF; node->p->multiRecv[1] = 0xFFFF; node->p->multiRecv[2] = 0xFFFF; node->p->multiRecv[3] = 0xFFFF; From 0b9cf1270cd1779d489ad276527aab973adebeee Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 5 Sep 2024 03:33:35 -0700 Subject: [PATCH 293/336] GBA SIO: Modify GBASIOTransferCycles to not require SIO struct --- include/mgba/internal/gba/sio.h | 2 +- src/gba/sio.c | 25 ++++++++++++------------- src/gba/sio/lockstep.c | 6 +++--- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index bb7b2a78c..ca271abc4 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -93,7 +93,7 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value); void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value); uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value); -int32_t GBASIOTransferCycles(struct GBASIO* sio); +int32_t GBASIOTransferCycles(enum GBASIOMode mode, uint16_t siocnt, int connected); void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate); void GBASIONormal8FinishTransfer(struct GBASIO* sio, uint8_t data, uint32_t cyclesLate); diff --git a/src/gba/sio.c b/src/gba/sio.c index 971eb9502..4b635db18 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -228,8 +228,12 @@ static void _startTransfer(struct GBASIO* sio) { return; } } + int connected = 0; + if (sio->activeDriver && sio->activeDriver->connectedDevices) { + connected = sio->activeDriver->connectedDevices(sio->activeDriver); + } mTimingDeschedule(&sio->p->timing, &sio->completeEvent); - mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio)); + mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio->mode, sio->siocnt, connected)); } void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { @@ -429,26 +433,21 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu return value; } -int32_t GBASIOTransferCycles(struct GBASIO* sio) { - int connected = 0; - if (sio->activeDriver) { - connected = sio->activeDriver->connectedDevices(sio->activeDriver); - } - +int32_t GBASIOTransferCycles(enum GBASIOMode mode, uint16_t siocnt, int connected) { if (connected < 0 || connected >= MAX_GBAS) { - mLOG(GBA_SIO, ERROR, "SIO driver returned invalid device count %i", connected); + mLOG(GBA_SIO, ERROR, "Invalid device count %i", connected); return 0; } - switch (sio->mode) { + switch (mode) { case GBA_SIO_MULTI: - return GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(sio->siocnt)][connected]; + return GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(siocnt)][connected]; case GBA_SIO_NORMAL_8: - return 8 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024); + return 8 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(siocnt) ? 2048 : 256) * 1024); case GBA_SIO_NORMAL_32: - return 32 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024); + return 32 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(siocnt) ? 2048 : 256) * 1024); default: - mLOG(GBA_SIO, STUB, "No cycle count implemented for mode %s", _modeName(sio->mode)); + mLOG(GBA_SIO, STUB, "No cycle count implemented for mode %s", _modeName(mode)); break; } return 0; diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index ed74ed6d4..2008638bd 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -248,7 +248,7 @@ static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p)); + ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p->mode, node->d.p->siocnt, attached)); if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); @@ -479,7 +479,7 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, if (node->p->d.attached < 2) { switch (node->mode) { case GBA_SIO_MULTI: - cycles = GBASIOTransferCycles(node->d.p); + cycles = GBASIOTransferCycles(node->d.p->mode, node->d.p->siocnt, node->p->d.attached); break; case GBA_SIO_NORMAL_8: case GBA_SIO_NORMAL_32: @@ -544,7 +544,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, if ((value & 0x0081) == 0x0081) { if (!node->id) { // Frequency - int32_t cycles = GBASIOTransferCycles(node->d.p); + int32_t cycles = GBASIOTransferCycles(node->d.p->mode, node->d.p->siocnt, attached); if (transferActive == TRANSFER_IDLE) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); From 3180d432e5b1352b5605b5eb9f46aaee439137d1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 21 Aug 2024 23:59:56 -0700 Subject: [PATCH 294/336] Core: Add new mLockstepUser API for upcoming lockstep rewrite --- include/mgba/core/lockstep.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/mgba/core/lockstep.h b/include/mgba/core/lockstep.h index ac6cb3f84..8936d263e 100644 --- a/include/mgba/core/lockstep.h +++ b/include/mgba/core/lockstep.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016 Jeffrey Pfau +/* Copyright (c) 2013-2024 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -53,6 +53,14 @@ static inline void mLockstepUnlock(struct mLockstep* lockstep) { } } +struct mLockstepUser { + void (*sleep)(struct mLockstepUser*); + void (*wake)(struct mLockstepUser*); + + int (*requestedId)(struct mLockstepUser*); + void (*playerIdChanged)(struct mLockstepUser*, int id); +}; + CXX_GUARD_END #endif From 36c1a8cfbc759eae52958dd5e927a6ab4dd8a5ed Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 22 Aug 2024 22:23:27 -0700 Subject: [PATCH 295/336] Core: Implement mLockstepUser for mCoreThread --- include/mgba/core/lockstep.h | 11 +++++++++++ src/core/lockstep.c | 25 +++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/mgba/core/lockstep.h b/include/mgba/core/lockstep.h index 8936d263e..b83d17657 100644 --- a/include/mgba/core/lockstep.h +++ b/include/mgba/core/lockstep.h @@ -61,6 +61,17 @@ struct mLockstepUser { void (*playerIdChanged)(struct mLockstepUser*, int id); }; +#ifndef DISABLE_THREADING +struct mCoreThread; +struct mLockstepThreadUser { + struct mLockstepUser d; + + struct mCoreThread* thread; +}; + +void mLockstepThreadUserInit(struct mLockstepThreadUser* lockstep, struct mCoreThread* thread); +#endif + CXX_GUARD_END #endif diff --git a/src/core/lockstep.c b/src/core/lockstep.c index 587cff2b5..c058a80fc 100644 --- a/src/core/lockstep.c +++ b/src/core/lockstep.c @@ -1,10 +1,14 @@ -/* Copyright (c) 2013-2016 Jeffrey Pfau +/* Copyright (c) 2013-2024 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#ifndef DISABLE_THREADING +#include +#endif + void mLockstepInit(struct mLockstep* lockstep) { lockstep->attached = 0; lockstep->transferActive = 0; @@ -19,4 +23,21 @@ void mLockstepDeinit(struct mLockstep* lockstep) { UNUSED(lockstep); } -// TODO: Migrate nodes +#ifndef DISABLE_THREADING +static void mLockstepThreadUserSleep(struct mLockstepUser* user) { + struct mLockstepThreadUser* lockstep = (struct mLockstepThreadUser*) user; + mCoreThreadWaitFromThread(lockstep->thread); +} + +static void mLockstepThreadUserWake(struct mLockstepUser* user) { + struct mLockstepThreadUser* lockstep = (struct mLockstepThreadUser*) user; + mCoreThreadStopWaiting(lockstep->thread); +} + +void mLockstepThreadUserInit(struct mLockstepThreadUser* lockstep, struct mCoreThread* thread) { + memset(lockstep, 0, sizeof(*lockstep)); + lockstep->d.sleep = mLockstepThreadUserSleep; + lockstep->d.wake = mLockstepThreadUserWake; + lockstep->thread = thread; +} +#endif From 0955b9446624d63743b74dd1cb18cb71500e1ebc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 22 Aug 2024 00:00:10 -0700 Subject: [PATCH 296/336] GBA SIO: Bring up new lockstep driver --- include/mgba/internal/gba/sio/lockstep.h | 77 ++- src/gba/sio/lockstep.c | 769 ++++++++++++++++++++++- 2 files changed, 844 insertions(+), 2 deletions(-) diff --git a/include/mgba/internal/gba/sio/lockstep.h b/include/mgba/internal/gba/sio/lockstep.h index 13c181039..313285a44 100644 --- a/include/mgba/internal/gba/sio/lockstep.h +++ b/include/mgba/internal/gba/sio/lockstep.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau +/* Copyright (c) 2013-2024 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -13,6 +13,9 @@ CXX_GUARD_START #include #include #include +#include +#include +#include struct GBASIOLockstep { struct mLockstep d; @@ -48,6 +51,78 @@ void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode*); bool GBASIOLockstepAttachNode(struct GBASIOLockstep*, struct GBASIOLockstepNode*); void GBASIOLockstepDetachNode(struct GBASIOLockstep*, struct GBASIOLockstepNode*); +#define MAX_LOCKSTEP_EVENTS 8 + +enum GBASIOLockstepEventType { + SIO_EV_ATTACH, + SIO_EV_DETACH, + SIO_EV_HARD_SYNC, + SIO_EV_MODE_SET, + SIO_EV_TRANSFER_START, +}; + +struct GBASIOLockstepCoordinator { + struct Table players; + Mutex mutex; + + unsigned nextId; + + unsigned attachedPlayers[MAX_GBAS]; + int nAttached; + uint32_t waiting; + + bool transferActive; + enum GBASIOMode transferMode; + + int32_t cycle; + + uint16_t multiData[4]; + uint32_t normalData[4]; +}; + +struct GBASIOLockstepEvent { + enum GBASIOLockstepEventType type; + int32_t timestamp; + struct GBASIOLockstepEvent* next; + int playerId; + union { + enum GBASIOMode mode; + int32_t finishCycle; + }; +}; + +struct GBASIOLockstepPlayer { + struct GBASIOLockstepDriver* driver; + int playerId; + enum GBASIOMode mode; + enum GBASIOMode otherModes[MAX_GBAS]; + bool asleep; + int32_t cycleOffset; + struct GBASIOLockstepEvent* queue; + bool dataReceived; + + struct GBASIOLockstepEvent buffer[MAX_LOCKSTEP_EVENTS]; + struct GBASIOLockstepEvent* freeList; +}; + +struct GBASIOLockstepDriver { + struct GBASIODriver d; + struct GBASIOLockstepCoordinator* coordinator; + struct mTimingEvent event; + unsigned lockstepId; + + struct mLockstepUser* user; +}; + +void GBASIOLockstepCoordinatorInit(struct GBASIOLockstepCoordinator*); +void GBASIOLockstepCoordinatorDeinit(struct GBASIOLockstepCoordinator*); + +void GBASIOLockstepCoordinatorAttach(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepDriver*); +void GBASIOLockstepCoordinatorDetach(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepDriver*); +size_t GBASIOLockstepCoordinatorAttached(struct GBASIOLockstepCoordinator*); + +void GBASIOLockstepDriverCreate(struct GBASIOLockstepDriver*, struct mLockstepUser*); + CXX_GUARD_END #endif diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 2008638bd..18603e054 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau +/* Copyright (c) 2013-2024 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,6 +10,7 @@ #define LOCKSTEP_INCREMENT 2000 #define LOCKSTEP_TRANSFER 512 +#define QUEUE_SIZE 16 static bool GBASIOLockstepNodeInit(struct GBASIODriver* driver); static void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver); @@ -568,3 +569,769 @@ static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, return value; } + +#define TARGET(P) (1 << (P)) +#define TARGET_ALL 0xF +#define TARGET_PRIMARY 0x1 +#define TARGET_SECONDARY ((TARGET_ALL) & ~(TARGET_PRIMARY)) + +static bool GBASIOLockstepDriverInit(struct GBASIODriver* driver); +static void GBASIOLockstepDriverDeinit(struct GBASIODriver* driver); +static void GBASIOLockstepDriverReset(struct GBASIODriver* driver); +static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver); +static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver); +static void GBASIOLockstepDriverSetMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static bool GBASIOLockstepDriverHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); +static int GBASIOLockstepDriverConnectedDevices(struct GBASIODriver* driver); +static int GBASIOLockstepDriverDeviceId(struct GBASIODriver* driver); +static uint16_t GBASIOLockstepDriverWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); +static uint16_t GBASIOLockstepDriverWriteRCNT(struct GBASIODriver* driver, uint16_t value); +static bool GBASIOLockstepDriverStart(struct GBASIODriver* driver); +static void GBASIOLockstepDriverFinishMultiplayer(struct GBASIODriver* driver, uint16_t data[4]); +static uint8_t GBASIOLockstepDriverFinishNormal8(struct GBASIODriver* driver); +static uint32_t GBASIOLockstepDriverFinishNormal32(struct GBASIODriver* driver); + +static void GBASIOLockstepCoordinatorWaitOnPlayers(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPlayer*); +static void GBASIOLockstepCoordinatorAckPlayer(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPlayer*); +static void GBASIOLockstepCoordinatorWakePlayers(struct GBASIOLockstepCoordinator*); + +static int32_t GBASIOLockstepTime(struct GBASIOLockstepPlayer*); +static void GBASIOLockstepPlayerWake(struct GBASIOLockstepPlayer*); +static void GBASIOLockstepPlayerSleep(struct GBASIOLockstepPlayer*); + +static void _advanceCycle(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPlayer*); +static void _removePlayer(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPlayer*); +static void _reconfigPlayers(struct GBASIOLockstepCoordinator*); +static int32_t _untilNextSync(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPlayer*); +static void _enqueueEvent(struct GBASIOLockstepCoordinator*, const struct GBASIOLockstepEvent*, uint32_t target); +static void _setData(struct GBASIOLockstepCoordinator*, uint32_t id, struct GBASIO* sio); +static void _setReady(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPlayer* activePlayer, int playerId, enum GBASIOMode mode); +static void _hardSync(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPlayer*); + +static void _lockstepEvent(struct mTiming*, void* context, uint32_t cyclesLate); + +void GBASIOLockstepDriverCreate(struct GBASIOLockstepDriver* driver, struct mLockstepUser* user) { + memset(driver, 0, sizeof(*driver)); + driver->d.init = GBASIOLockstepDriverInit; + driver->d.deinit = GBASIOLockstepDriverDeinit; + driver->d.reset = GBASIOLockstepDriverReset; + driver->d.load = GBASIOLockstepDriverLoad; + driver->d.unload = GBASIOLockstepDriverUnload; + driver->d.setMode = GBASIOLockstepDriverSetMode; + driver->d.handlesMode = GBASIOLockstepDriverHandlesMode; + driver->d.deviceId = GBASIOLockstepDriverDeviceId; + driver->d.connectedDevices = GBASIOLockstepDriverConnectedDevices; + driver->d.writeSIOCNT = GBASIOLockstepDriverWriteSIOCNT; + driver->d.writeRCNT = GBASIOLockstepDriverWriteRCNT; + driver->d.start = GBASIOLockstepDriverStart; + driver->d.finishMultiplayer = GBASIOLockstepDriverFinishMultiplayer; + driver->d.finishNormal8 = GBASIOLockstepDriverFinishNormal8; + driver->d.finishNormal32 = GBASIOLockstepDriverFinishNormal32; + driver->event.context = driver; + driver->event.callback = _lockstepEvent; + driver->event.name = "GBA SIO Lockstep"; + driver->event.priority = 0x80; + driver->user = user; +} + +static bool GBASIOLockstepDriverInit(struct GBASIODriver* driver) { + GBASIOLockstepDriverReset(driver); + return true; +} + +static void GBASIOLockstepDriverDeinit(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (player) { + _removePlayer(coordinator, player); + } + MutexUnlock(&coordinator->mutex); + mTimingDeschedule(&lockstep->d.p->p->timing, &lockstep->event); + lockstep->lockstepId = 0; +} + +static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + if (!lockstep->lockstepId) { + struct GBASIOLockstepPlayer* player = calloc(1, sizeof(*player)); + unsigned id; + player->driver = lockstep; + player->mode = driver->p->mode; + player->playerId = -1; + + int i; + for (i = 0; i < MAX_LOCKSTEP_EVENTS - 1; ++i) { + player->buffer[i].next = &player->buffer[i + 1]; + } + player->freeList = &player->buffer[0]; + + MutexLock(&coordinator->mutex); + while (true) { + if (coordinator->nextId == UINT_MAX) { + coordinator->nextId = 0; + } + ++coordinator->nextId; + id = coordinator->nextId; + if (!TableLookup(&coordinator->players, id)) { + TableInsert(&coordinator->players, id, player); + lockstep->lockstepId = id; + break; + } + } + _reconfigPlayers(coordinator); + if (player->playerId != 0) { + player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle + LOCKSTEP_INCREMENT; + struct GBASIOLockstepEvent event = { + .type = SIO_EV_ATTACH, + .playerId = player->playerId, + .timestamp = GBASIOLockstepTime(player), + }; + _enqueueEvent(coordinator, &event, TARGET_ALL & ~TARGET(player->playerId)); + } + MutexUnlock(&coordinator->mutex); + } + + if (mTimingIsScheduled(&lockstep->d.p->p->timing, &lockstep->event)) { + return; + } + + int32_t nextEvent; + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + _setReady(coordinator, player, player->playerId, player->mode); + if (TableSize(&coordinator->players) == 1) { + coordinator->cycle = mTimingCurrentTime(&lockstep->d.p->p->timing); + nextEvent = LOCKSTEP_INCREMENT; + } else { + _setReady(coordinator, player, 0, coordinator->transferMode); + nextEvent = _untilNextSync(lockstep->coordinator, player); + } + MutexUnlock(&coordinator->mutex); + mTimingSchedule(&lockstep->d.p->p->timing, &lockstep->event, nextEvent); +} + +static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + if (lockstep->lockstepId) { + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + _setReady(coordinator, player, 0, coordinator->transferMode); + MutexUnlock(&coordinator->mutex); + GBASIOLockstepDriverSetMode(driver, driver->p->mode); + } + return true; +} + +static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + if (lockstep->lockstepId) { + GBASIOLockstepDriverSetMode(driver, -1); + } + return true; +} + +static void GBASIOLockstepDriverSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (mode != player->mode) { + player->mode = mode; + struct GBASIOLockstepEvent event = { + .type = SIO_EV_MODE_SET, + .playerId = player->playerId, + .timestamp = GBASIOLockstepTime(player), + .mode = mode, + }; + if (player->playerId == 0) { + mASSERT(!coordinator->transferActive); // TODO + coordinator->transferMode = mode; + GBASIOLockstepCoordinatorWaitOnPlayers(coordinator, player); + } + _setReady(coordinator, player, player->playerId, mode); + _enqueueEvent(coordinator, &event, TARGET_ALL & ~TARGET(player->playerId)); + } + MutexUnlock(&coordinator->mutex); +} + +static bool GBASIOLockstepDriverHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { + UNUSED(driver); + UNUSED(mode); + return true; +} + +static int GBASIOLockstepDriverConnectedDevices(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + if (!lockstep->lockstepId) { + return 0; + } + MutexLock(&coordinator->mutex); + int attached = coordinator->nAttached - 1; + MutexUnlock(&coordinator->mutex); + return attached; +} + +static int GBASIOLockstepDriverDeviceId(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + int playerId = 0; + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (player && player->playerId >= 0) { + playerId = player->playerId; + } + MutexUnlock(&coordinator->mutex); + return playerId; +} + +static uint16_t GBASIOLockstepDriverWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { + UNUSED(driver); + mLOG(GBA_SIO, DEBUG, "Lockstep: SIOCNT <- %04X", value); + return value; +} + +static uint16_t GBASIOLockstepDriverWriteRCNT(struct GBASIODriver* driver, uint16_t value) { + UNUSED(driver); + mLOG(GBA_SIO, DEBUG, "Lockstep: RCNT <- %04X", value); + return value; +} + +static bool GBASIOLockstepDriverStart(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + bool ret = false; + MutexLock(&coordinator->mutex); + if (coordinator->transferActive) { + mLOG(GBA_SIO, ERROR, "Transfer restarted unexpectedly"); + goto out; + } + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (player->playerId != 0) { + mLOG(GBA_SIO, DEBUG, "Secondary player attempted to start transfer"); + goto out; + } + mLOG(GBA_SIO, DEBUG, "Transfer starting at %08X", coordinator->cycle); + memset(coordinator->multiData, 0xFF, sizeof(coordinator->multiData)); + _setData(coordinator, 0, player->driver->d.p); + + int32_t timestamp = GBASIOLockstepTime(player); + struct GBASIOLockstepEvent event = { + .type = SIO_EV_TRANSFER_START, + .timestamp = timestamp, + .finishCycle = timestamp + GBASIOTransferCycles(player->mode, player->driver->d.p->siocnt, coordinator->nAttached - 1), + }; + _enqueueEvent(coordinator, &event, TARGET_SECONDARY); + GBASIOLockstepCoordinatorWaitOnPlayers(coordinator, player); + coordinator->transferActive = true; + ret = true; +out: + MutexUnlock(&coordinator->mutex); + return ret; +} + +static void GBASIOLockstepDriverFinishMultiplayer(struct GBASIODriver* driver, uint16_t data[4]) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + MutexLock(&coordinator->mutex); + if (coordinator->transferMode == GBA_SIO_MULTI) { + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (!player->dataReceived) { + mLOG(GBA_SIO, WARN, "MULTI did not receive data. Are we running behind?"); + memset(data, 0xFF, sizeof(uint16_t) * 4); + } else { + mLOG(GBA_SIO, INFO, "MULTI transfer finished: %04X %04X %04X %04X", + coordinator->multiData[0], + coordinator->multiData[1], + coordinator->multiData[2], + coordinator->multiData[3]); + memcpy(data, coordinator->multiData, sizeof(uint16_t) * 4); + } + player->dataReceived = false; + if (player->playerId == 0) { + _hardSync(coordinator, player); + } + } + MutexUnlock(&coordinator->mutex); +} + +static uint8_t GBASIOLockstepDriverFinishNormal8(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + uint8_t data = 0xFF; + MutexLock(&coordinator->mutex); + if (coordinator->transferMode == GBA_SIO_NORMAL_8) { + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (player->playerId > 0) { + if (!player->dataReceived) { + mLOG(GBA_SIO, WARN, "NORMAL did not receive data. Are we running behind?"); + } else { + data = coordinator->normalData[player->playerId - 1]; + mLOG(GBA_SIO, INFO, "NORMAL8 transfer finished: %02X", data); + } + } + player->dataReceived = false; + if (player->playerId == 0) { + _hardSync(coordinator, player); + } + } + MutexUnlock(&coordinator->mutex); + return data; +} + +static uint32_t GBASIOLockstepDriverFinishNormal32(struct GBASIODriver* driver) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + uint32_t data = 0xFFFFFFFF; + MutexLock(&coordinator->mutex); + if (coordinator->transferMode == GBA_SIO_NORMAL_32) { + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (player->playerId > 0) { + if (!player->dataReceived) { + mLOG(GBA_SIO, WARN, "Did not receive data. Are we running behind?"); + } else { + data = coordinator->normalData[player->playerId - 1]; + mLOG(GBA_SIO, INFO, "NORMAL32 transfer finished: %08X", data); + } + } + player->dataReceived = false; + if (player->playerId == 0) { + _hardSync(coordinator, player); + } + } + MutexUnlock(&coordinator->mutex); + return data; +} + +void GBASIOLockstepCoordinatorInit(struct GBASIOLockstepCoordinator* coordinator) { + memset(coordinator, 0, sizeof(*coordinator)); + MutexInit(&coordinator->mutex); + TableInit(&coordinator->players, 8, free); +} + +void GBASIOLockstepCoordinatorDeinit(struct GBASIOLockstepCoordinator* coordinator) { + MutexDeinit(&coordinator->mutex); + TableDeinit(&coordinator->players); +} + +void GBASIOLockstepCoordinatorAttach(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepDriver* driver) { + if (driver->coordinator && driver->coordinator != coordinator) { + // TODO + abort(); + } + driver->coordinator = coordinator; +} + +void GBASIOLockstepCoordinatorDetach(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepDriver* driver) { + if (driver->coordinator != coordinator) { + // TODO + abort(); + return; + } + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, driver->lockstepId); + if (player) { + _removePlayer(coordinator, player); + } + MutexUnlock(&coordinator->mutex); + driver->coordinator = NULL; +} + +int32_t _untilNextSync(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { + int32_t cycle = coordinator->cycle - GBASIOLockstepTime(player); + if (player->playerId == 0) { + cycle += LOCKSTEP_INCREMENT; + } + return cycle; +} + +void _advanceCycle(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { + int32_t newCycle = GBASIOLockstepTime(player); + mASSERT(newCycle - coordinator->cycle >= 0); + //mLOG(GBA_SIO, DEBUG, "Advancing from cycle %08X to %08X (%i cycles)", coordinator->cycle, newCycle, newCycle - coordinator->cycle); + coordinator->cycle = newCycle; +} + +void _removePlayer(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { + struct GBASIOLockstepEvent event = { + .type = SIO_EV_DETACH, + .playerId = player->playerId, + .timestamp = GBASIOLockstepTime(player), + }; + _enqueueEvent(coordinator, &event, TARGET_ALL & ~TARGET(player->playerId)); + GBASIOLockstepCoordinatorWakePlayers(coordinator); + if (player->playerId != 0) { + GBASIOLockstepCoordinatorAckPlayer(coordinator, player); + } + TableRemove(&coordinator->players, player->driver->lockstepId); + _reconfigPlayers(coordinator); +} + +void _reconfigPlayers(struct GBASIOLockstepCoordinator* coordinator) { + size_t players = TableSize(&coordinator->players); + memset(coordinator->attachedPlayers, 0, sizeof(coordinator->attachedPlayers)); + if (players == 0) { + mLOG(GBA_SIO, WARN, "Reconfiguring player IDs with no players attached somehow?"); + } else if (players == 1) { + struct TableIterator iter; + mASSERT(TableIteratorStart(&coordinator->players, &iter)); + unsigned p0 = TableIteratorGetKey(&coordinator->players, &iter); + coordinator->attachedPlayers[0] = p0; + + struct GBASIOLockstepPlayer* player = TableIteratorGetValue(&coordinator->players, &iter); + coordinator->cycle = mTimingCurrentTime(&player->driver->d.p->p->timing); + + if (player->playerId != 0) { + player->playerId = 0; + if (player->driver->user->playerIdChanged) { + player->driver->user->playerIdChanged(player->driver->user, player->playerId); + } + } + + if (!coordinator->transferActive) { + coordinator->transferMode = player->mode; + } + } else { + struct UIntList playerPreferences[MAX_GBAS]; + + int i; + for (i = 0; i < MAX_GBAS; ++i) { + UIntListInit(&playerPreferences[i], 4); + } + + // Collect the first four players' requested player IDs so we can sort through them later + int seen = 0; + struct TableIterator iter; + mASSERT(TableIteratorStart(&coordinator->players, &iter)); + do { + unsigned pid = TableIteratorGetKey(&coordinator->players, &iter); + struct GBASIOLockstepPlayer* player = TableIteratorGetValue(&coordinator->players, &iter); + int requested = MAX_GBAS - 1; + if (player->driver->user->requestedId) { + requested = player->driver->user->requestedId(player->driver->user); + } + if (requested < 0) { + continue; + } + if (requested >= MAX_GBAS) { + requested = MAX_GBAS - 1; + } + + *UIntListAppend(&playerPreferences[requested]) = pid; + ++seen; + } while (TableIteratorNext(&coordinator->players, &iter) && seen < MAX_GBAS); + + // Now sort each requested player ID to figure out who gets which ID + seen = 0; + for (i = 0; i < MAX_GBAS; ++i) { + int j; + for (j = 0; j <= i; ++j) { + while (UIntListSize(&playerPreferences[j]) && seen < MAX_GBAS) { + unsigned pid = *UIntListGetPointer(&playerPreferences[j], 0); + UIntListShift(&playerPreferences[j], 0, 1); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, pid); + if (!player) { + mLOG(GBA_SIO, ERROR, "Player list appears to have changed unexpectedly. PID %u missing.", pid); + continue; + } + coordinator->attachedPlayers[seen] = pid; + if (player->playerId != seen) { + player->playerId = seen; + if (player->driver->user->playerIdChanged) { + player->driver->user->playerIdChanged(player->driver->user, player->playerId); + } + } + ++seen; + } + } + } + + for (i = 0; i < MAX_GBAS; ++i) { + UIntListDeinit(&playerPreferences[i]); + } + } + + int nAttached = 0; + size_t i; + for (i = 0; i < MAX_GBAS; ++i) { + unsigned pid = coordinator->attachedPlayers[i]; + if (!pid) { + continue; + } + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, pid); + if (!player) { + coordinator->attachedPlayers[i] = 0; + } else { + ++nAttached; + } + } + coordinator->nAttached = nAttached; +} + +static void _setData(struct GBASIOLockstepCoordinator* coordinator, uint32_t id, struct GBASIO* sio) { + switch (coordinator->transferMode) { + case GBA_SIO_MULTI: + coordinator->multiData[id] = sio->p->memory.io[GBA_REG(SIOMLT_SEND)]; + break; + case GBA_SIO_NORMAL_8: + coordinator->normalData[id] = sio->p->memory.io[GBA_REG(SIODATA8)]; + break; + case GBA_SIO_NORMAL_32: + coordinator->normalData[id] = sio->p->memory.io[GBA_REG(SIODATA32_LO)]; + coordinator->normalData[id] |= sio->p->memory.io[GBA_REG(SIODATA32_HI)] << 16; + break; + case GBA_SIO_UART: + case GBA_SIO_GPIO: + case GBA_SIO_JOYBUS: + mLOG(GBA_SIO, ERROR, "Unsupported mode %i in lockstep", coordinator->transferMode); + // TODO: Should we handle this or just abort? + abort(); + break; + } +} + +void _setReady(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* activePlayer, int playerId, enum GBASIOMode mode) { + activePlayer->otherModes[playerId] = mode; + bool ready = true; + int i; + for (i = 0; ready && i < coordinator->nAttached; ++i) { + ready = activePlayer->otherModes[i] == activePlayer->mode; + } + if (activePlayer->mode == GBA_SIO_MULTI) { + struct GBASIO* sio = activePlayer->driver->d.p; + sio->siocnt = GBASIOMultiplayerSetReady(sio->siocnt, ready); + sio->rcnt = GBASIORegisterRCNTSetSd(sio->rcnt, ready); + } +} + +void _hardSync(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { + mASSERT_DEBUG(player->playerId == 0); + struct GBASIOLockstepEvent event = { + .type = SIO_EV_HARD_SYNC, + .playerId = 0, + .timestamp = GBASIOLockstepTime(player), + }; + _enqueueEvent(coordinator, &event, TARGET_SECONDARY); + GBASIOLockstepCoordinatorWaitOnPlayers(coordinator, player); +} + +void _enqueueEvent(struct GBASIOLockstepCoordinator* coordinator, const struct GBASIOLockstepEvent* event, uint32_t target) { + mLOG(GBA_SIO, DEBUG, "Enqueuing event of type %X from %i for target %X at timestamp %X", + event->type, event->playerId, target, event->timestamp); + + int i; + for (i = 0; i < coordinator->nAttached; ++i) { + if (!(target & TARGET(i))) { + continue; + } + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, coordinator->attachedPlayers[i]); + mASSERT_LOG(GBA_SIO, player->freeList, "No free events"); + struct GBASIOLockstepEvent* newEvent = player->freeList; + player->freeList = newEvent->next; + + memcpy(newEvent, event, sizeof(*event)); + struct GBASIOLockstepEvent** previous = &player->queue; + struct GBASIOLockstepEvent* next = player->queue; + while (next) { + int32_t until = newEvent->timestamp - next->timestamp; + if (until < 0) { + break; + } + previous = &next->next; + next = next->next; + } + newEvent->next = next; + *previous = newEvent; + } +} + +void _lockstepEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) { + struct GBASIOLockstepDriver* lockstep = context; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + struct GBASIO* sio = player->driver->d.p; + mASSERT(player->playerId >= 0 && player->playerId < 4); + + bool wasDetach = false; + if (player->queue && player->queue->type == SIO_EV_DETACH) { + mLOG(GBA_SIO, DEBUG, "Player %i detached at timestamp %X, picking up the pieces", + player->queue->playerId, player->queue->timestamp); + wasDetach = true; + } + if (player->playerId == 0) { + // We are the clock owner; advance the shared clock + _advanceCycle(coordinator, player); + if (!coordinator->transferActive) { + GBASIOLockstepCoordinatorWakePlayers(coordinator); + } + } + + int32_t nextEvent = _untilNextSync(coordinator, player); + //mASSERT_DEBUG(nextEvent + cyclesLate > 0); + while (true) { + struct GBASIOLockstepEvent* event = player->queue; + if (!event) { + break; + } + if (event->timestamp > GBASIOLockstepTime(player)) { + break; + } + player->queue = event->next; + struct GBASIOLockstepEvent reply = { + .playerId = player->playerId, + .timestamp = GBASIOLockstepTime(player), + }; + mLOG(GBA_SIO, DEBUG, "Got event of type %X from %i at timestamp %X", + event->type, event->playerId, event->timestamp); + switch (event->type) { + case SIO_EV_ATTACH: + _setReady(coordinator, player, event->playerId, -1); + if (player->playerId == 0) { + struct GBASIO* sio = player->driver->d.p; + sio->siocnt = GBASIOMultiplayerClearSlave(sio->siocnt); + } + reply.mode = player->mode; + reply.type = SIO_EV_MODE_SET; + _enqueueEvent(coordinator, &reply, TARGET(event->playerId)); + break; + case SIO_EV_HARD_SYNC: + GBASIOLockstepCoordinatorAckPlayer(coordinator, player); + break; + case SIO_EV_TRANSFER_START: + _setData(coordinator, player->playerId, sio); + nextEvent = event->finishCycle - GBASIOLockstepTime(player) - cyclesLate; + player->driver->d.p->siocnt |= 0x80; + mTimingDeschedule(&sio->p->timing, &sio->completeEvent); + mTimingSchedule(&sio->p->timing, &sio->completeEvent, nextEvent); + GBASIOLockstepCoordinatorAckPlayer(coordinator, player); + break; + case SIO_EV_MODE_SET: + _setReady(coordinator, player, event->playerId, event->mode); + if (event->playerId == 0) { + GBASIOLockstepCoordinatorAckPlayer(coordinator, player); + } + break; + case SIO_EV_DETACH: + _setReady(coordinator, player, event->playerId, -1); + _setReady(coordinator, player, player->playerId, player->mode); + reply.mode = player->mode; + reply.type = SIO_EV_MODE_SET; + _enqueueEvent(coordinator, &reply, ~TARGET(event->playerId)); + if (player->mode == GBA_SIO_MULTI) { + sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, player->playerId); + sio->siocnt = GBASIOMultiplayerSetSlave(sio->siocnt, player->playerId || coordinator->nAttached < 2); + } + wasDetach = true; + break; + } + event->next = player->freeList; + player->freeList = event; + } + if (player->queue && player->queue->timestamp - GBASIOLockstepTime(player) < nextEvent) { + nextEvent = player->queue->timestamp - GBASIOLockstepTime(player); + } + + if (player->playerId != 0 && nextEvent <= LOCKSTEP_INCREMENT) { + if (!player->queue || wasDetach) { + GBASIOLockstepPlayerSleep(player); + // XXX: Is there a better way to gain sync lock at the beginning? + if (nextEvent < 4) { + nextEvent = 4; + } + } + } + MutexUnlock(&coordinator->mutex); + + mASSERT_DEBUG(nextEvent > 0); + mTimingSchedule(timing, &lockstep->event, nextEvent); +} + +int32_t GBASIOLockstepTime(struct GBASIOLockstepPlayer* player) { + return mTimingCurrentTime(&player->driver->d.p->p->timing) - player->cycleOffset; +} + +void GBASIOLockstepCoordinatorWaitOnPlayers(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { + mASSERT(!coordinator->waiting); + mASSERT(!player->asleep); + mASSERT(player->playerId == 0); + if (coordinator->nAttached < 2) { + return; + } + + _advanceCycle(coordinator, player); + mLOG(GBA_SIO, DEBUG, "Primary waiting for players to ack"); + coordinator->waiting = ((1 << coordinator->nAttached) - 1) & ~TARGET(player->playerId); + GBASIOLockstepPlayerSleep(player); + GBASIOLockstepCoordinatorWakePlayers(coordinator); +} + +void GBASIOLockstepCoordinatorWakePlayers(struct GBASIOLockstepCoordinator* coordinator) { + //mLOG(GBA_SIO, DEBUG, "Waking all secondary players"); + int i; + for (i = 1; i < coordinator->nAttached; ++i) { + if (!coordinator->attachedPlayers[i]) { + continue; + } + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, coordinator->attachedPlayers[i]); + GBASIOLockstepPlayerWake(player); + } +} + +void GBASIOLockstepPlayerWake(struct GBASIOLockstepPlayer* player) { + if (!player->asleep) { + return; + } + player->asleep = false; + player->driver->user->wake(player->driver->user); +} + +void GBASIOLockstepCoordinatorAckPlayer(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { + if (player->playerId == 0) { + return; + } + mLOG(GBA_SIO, DEBUG, "Player %i acking primary", player->playerId); + coordinator->waiting &= ~TARGET(player->playerId); + if (!coordinator->waiting) { + mLOG(GBA_SIO, DEBUG, "All players acked, waking primary"); + if (coordinator->transferActive) { + int i; + for (i = 0; i < coordinator->nAttached; ++i) { + if (!coordinator->attachedPlayers[i]) { + continue; + } + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, coordinator->attachedPlayers[i]); + player->dataReceived = true; + } + + coordinator->transferActive = false; + } + + struct GBASIOLockstepPlayer* runner = TableLookup(&coordinator->players, coordinator->attachedPlayers[0]); + GBASIOLockstepPlayerWake(runner); + } + GBASIOLockstepPlayerSleep(player); +} + +void GBASIOLockstepPlayerSleep(struct GBASIOLockstepPlayer* player) { + if (player->asleep) { + return; + } + //mLOG(GBA_SIO, DEBUG, "Player %i going to sleep with %i cycles until sync", player->playerId, _untilNextSync(coordinator, player)); + player->asleep = true; + player->driver->user->sleep(player->driver->user); + player->driver->d.p->p->cpu->nextEvent = 0; + player->driver->d.p->p->earlyExit = true; +} + +size_t GBASIOLockstepCoordinatorAttached(struct GBASIOLockstepCoordinator* coordinator) { + size_t count; + MutexLock(&coordinator->mutex); + count = TableSize(&coordinator->players); + MutexUnlock(&coordinator->mutex); + return count; +} From cd8933415cfcc25452ecfcb95292faa8ea9c74b3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 25 Aug 2024 02:48:50 -0700 Subject: [PATCH 297/336] Qt: Switch to new GBA lockstep driver --- src/platform/qt/MultiplayerController.cpp | 120 ++++++++++++++-------- src/platform/qt/MultiplayerController.h | 17 ++- 2 files changed, 88 insertions(+), 49 deletions(-) diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index 149df2386..c142fe126 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -7,6 +7,7 @@ #include "CoreController.h" #include "LogController.h" +#include "utils.h" #ifdef M_CORE_GBA #include @@ -27,8 +28,14 @@ MultiplayerController::Player::Player(CoreController* coreController) int MultiplayerController::Player::id() const { switch (controller->platform()) { #ifdef M_CORE_GBA - case mPLATFORM_GBA: - return node.gba->id; + case mPLATFORM_GBA: { + int id = node.gba->d.deviceId(&node.gba->d); + if (id >= 0) { + return id; + } else { + return preferredId; + } + } #endif #ifdef M_CORE_GB case mPLATFORM_GB: @@ -89,25 +96,7 @@ MultiplayerController::MultiplayerController() { switch (player->controller->platform()) { #ifdef M_CORE_GBA case mPLATFORM_GBA: - if (!id) { - for (int i = 1; i < controller->m_players.count(); ++i) { - player = controller->player(i); - if (player->node.gba->d.p->mode > GBA_SIO_MULTI) { - player->controller->setSync(true); - continue; - } - player->controller->setSync(false); - player->cyclesPosted += cycles; - if (player->awake < 1) { - player->node.gba->nextEvent += player->cyclesPosted; - } - mCoreThreadStopWaiting(player->controller->thread()); - player->awake = 1; - } - } else { - player->controller->setSync(true); - player->cyclesPosted += cycles; - } + abort(); break; #endif #ifdef M_CORE_GB @@ -169,7 +158,6 @@ MultiplayerController::MultiplayerController() { switch (player->controller->platform()) { #ifdef M_CORE_GBA case mPLATFORM_GBA: - player->cyclesPosted += reinterpret_cast(lockstep)->players[0]->eventDiff; break; #endif #ifdef M_CORE_GB @@ -184,7 +172,6 @@ MultiplayerController::MultiplayerController() { switch (player->controller->platform()) { #ifdef M_CORE_GBA case mPLATFORM_GBA: - player->node.gba->nextEvent += player->cyclesPosted; break; #endif #ifdef M_CORE_GB @@ -214,11 +201,11 @@ bool MultiplayerController::attachGame(CoreController* controller) { interrupters.append(p.controller); } - if (m_lockstep.attached == 0) { + if (attached() == 0) { switch (controller->platform()) { #ifdef M_CORE_GBA case mPLATFORM_GBA: - GBASIOLockstepInit(&m_gbaLockstep); + GBASIOLockstepCoordinatorInit(&m_gbaCoordinator); break; #endif #ifdef M_CORE_GB @@ -240,28 +227,53 @@ bool MultiplayerController::attachGame(CoreController* controller) { } Player player{controller}; + for (int i = 0; i < MAX_GBAS; ++i) { + if (m_claimedIds & (1 << i)) { + continue; + } + player.preferredId = i; + m_claimedIds |= 1 << i; + break; + } switch (controller->platform()) { #ifdef M_CORE_GBA case mPLATFORM_GBA: { - if (m_lockstep.attached >= MAX_GBAS) { + if (attached() >= MAX_GBAS) { return false; } GBA* gba = static_cast(thread->core->board); - GBASIOLockstepNode* node = new GBASIOLockstepNode; - GBASIOLockstepNodeCreate(node); - GBASIOLockstepAttachNode(&m_gbaLockstep, node); + GBASIOLockstepDriver* node = new GBASIOLockstepDriver; + LockstepUser* user = new LockstepUser; + mLockstepThreadUserInit(user, thread); + user->controller = this; + user->pid = m_nextPid; + user->d.requestedId = [](mLockstepUser* ctx) { + mLockstepThreadUser* tctx = reinterpret_cast(ctx); + LockstepUser* user = static_cast(tctx); + MultiplayerController* controller = user->controller; + const auto iter = controller->m_pids.find(user->pid); + if (iter == controller->m_pids.end()) { + return -1; + } + const Player& p = iter.value(); + return p.preferredId; + }; + + GBASIOLockstepDriverCreate(node, &user->d); + GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, node); player.node.gba = node; GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_8); GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_32); break; } #endif #ifdef M_CORE_GB case mPLATFORM_GB: { - if (m_lockstep.attached >= 2) { + if (attached() >= 2) { return false; } @@ -281,7 +293,7 @@ bool MultiplayerController::attachGame(CoreController* controller) { } QPair path(controller->path(), controller->baseDirectory()); - int claimed = m_claimed[path]; + int claimed = m_claimedSaves[path]; int saveId = 0; mCoreConfigGetIntValue(&controller->thread()->core->config, "savePlayerId", &saveId); @@ -304,7 +316,7 @@ bool MultiplayerController::attachGame(CoreController* controller) { } else { player.saveId = 1; } - m_claimed[path] |= 1 << (player.saveId - 1); + m_claimedSaves[path] |= 1 << (player.saveId - 1); m_pids.insert(m_nextPid, player); ++m_nextPid; @@ -328,8 +340,7 @@ void MultiplayerController::detachGame(CoreController* controller) { for (int i = 0; i < m_players.count(); ++i) { Player* p = player(i); if (!p) { - LOG(QT, ERROR) << tr("Trying to detach a multiplayer player that's not attached"); - return; + continue; } CoreController* playerController = p->controller; if (playerController == controller) { @@ -337,15 +348,21 @@ void MultiplayerController::detachGame(CoreController* controller) { } interrupters.append(playerController); } + if (pid < 0) { + LOG(QT, WARN) << tr("Trying to detach a multiplayer player that's not attached"); + return; + } switch (controller->platform()) { #ifdef M_CORE_GBA case mPLATFORM_GBA: { GBA* gba = static_cast(thread->core->board); - GBASIOLockstepNode* node = reinterpret_cast(gba->sio.drivers.multiplayer); + GBASIOLockstepDriver* node = reinterpret_cast(gba->sio.drivers.multiplayer); GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_8); GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_32); if (node) { - GBASIOLockstepDetachNode(&m_gbaLockstep, node); + GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, node); + delete node->user; delete node; } break; @@ -371,14 +388,20 @@ void MultiplayerController::detachGame(CoreController* controller) { QPair path(controller->path(), controller->baseDirectory()); Player& p = m_pids.find(pid).value(); if (!p.saveId) { - LOG(QT, ERROR) << "Clearing invalid save ID"; + LOG(QT, WARN) << "Clearing invalid save ID"; } else { - m_claimed[path] &= ~(1 << (p.saveId - 1)); - if (!m_claimed[path]) { - m_claimed.remove(path); + m_claimedSaves[path] &= ~(1 << (p.saveId - 1)); + if (!m_claimedSaves[path]) { + m_claimedSaves.remove(path); } } + if (p.preferredId < 0) { + LOG(QT, WARN) << "Clearing invalid preferred ID"; + } else { + m_claimedIds &= ~(1 << p.preferredId); + } + m_pids.remove(pid); if (m_pids.size() == 0) { m_platform = mPLATFORM_NONE; @@ -417,8 +440,17 @@ int MultiplayerController::saveId(CoreController* controller) const { } int MultiplayerController::attached() { - int num; - num = m_lockstep.attached; + int num = 0; + switch (m_platform) { + case mPLATFORM_GB: + num = m_lockstep.attached; + break; + case mPLATFORM_GBA: + num = saturateCast(GBASIOLockstepCoordinatorAttached(&m_gbaCoordinator)); + break; + default: + break; + } return num; } @@ -456,8 +488,8 @@ void MultiplayerController::fixOrder() { for (int pid : m_pids.keys()) { Player& p = m_pids.find(pid).value(); GBA* gba = static_cast(p.controller->thread()->core->board); - GBASIOLockstepNode* node = reinterpret_cast(gba->sio.drivers.multiplayer); - m_players[node->id] = pid; + GBASIOLockstepDriver* node = reinterpret_cast(gba->sio.drivers.multiplayer); + m_players[node->d.deviceId(&node->d)] = pid; } break; #endif diff --git a/src/platform/qt/MultiplayerController.h b/src/platform/qt/MultiplayerController.h index b5582319f..9eaf20b16 100644 --- a/src/platform/qt/MultiplayerController.h +++ b/src/platform/qt/MultiplayerController.h @@ -49,7 +49,7 @@ signals: private: union Node { GBSIOLockstepNode* gb; - GBASIOLockstepNode* gba; + GBASIOLockstepDriver* gba; }; struct Player { Player(CoreController* controller); @@ -63,6 +63,11 @@ private: int32_t cyclesPosted = 0; unsigned waitMask = 0; int saveId = 1; + int preferredId = 0; + }; + struct LockstepUser : mLockstepThreadUser { + MultiplayerController* controller; + int pid; }; Player* player(int id); @@ -73,18 +78,20 @@ private: mLockstep m_lockstep; #ifdef M_CORE_GB GBSIOLockstep m_gbLockstep; -#endif -#ifdef M_CORE_GBA - GBASIOLockstep m_gbaLockstep; #endif }; +#ifdef M_CORE_GBA + GBASIOLockstepCoordinator m_gbaCoordinator; +#endif + mPlatform m_platform = mPLATFORM_NONE; int m_nextPid = 0; + int m_claimedIds = 0; QHash m_pids; QList m_players; QMutex m_lock; - QHash, int> m_claimed; + QHash, int> m_claimedSaves; }; } From 26e20ca8461f76eefacc2a3906b74ec53dc39741 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 30 Aug 2024 23:26:29 -0700 Subject: [PATCH 298/336] GBA SIO: Remove old lockstep driver --- include/mgba/internal/gba/sio/lockstep.h | 34 -- src/gba/sio/lockstep.c | 561 ----------------------- 2 files changed, 595 deletions(-) diff --git a/include/mgba/internal/gba/sio/lockstep.h b/include/mgba/internal/gba/sio/lockstep.h index 313285a44..7baed0693 100644 --- a/include/mgba/internal/gba/sio/lockstep.h +++ b/include/mgba/internal/gba/sio/lockstep.h @@ -17,40 +17,6 @@ CXX_GUARD_START #include #include -struct GBASIOLockstep { - struct mLockstep d; - struct GBASIOLockstepNode* players[MAX_GBAS]; - int attachedMulti; - int attachedNormal; - - uint16_t multiRecv[MAX_GBAS]; - uint32_t normalRecv[MAX_GBAS]; -}; - -struct GBASIOLockstepNode { - struct GBASIODriver d; - struct GBASIOLockstep* p; - struct mTimingEvent event; - - volatile int32_t nextEvent; - int32_t eventDiff; - bool normalSO; - int id; - enum GBASIOMode mode; - bool transferFinished; -#ifndef NDEBUG - int transferId; - enum mLockstepPhase phase; -#endif -}; - -void GBASIOLockstepInit(struct GBASIOLockstep*); - -void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode*); - -bool GBASIOLockstepAttachNode(struct GBASIOLockstep*, struct GBASIOLockstepNode*); -void GBASIOLockstepDetachNode(struct GBASIOLockstep*, struct GBASIOLockstepNode*); - #define MAX_LOCKSTEP_EVENTS 8 enum GBASIOLockstepEventType { diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 18603e054..1493ca9f6 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -9,567 +9,6 @@ #include #define LOCKSTEP_INCREMENT 2000 -#define LOCKSTEP_TRANSFER 512 -#define QUEUE_SIZE 16 - -static bool GBASIOLockstepNodeInit(struct GBASIODriver* driver); -static void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver); -static bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver); -static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver); -static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); -static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver); -static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver); -static bool GBASIOLockstepNodeStart(struct GBASIODriver* driver); -static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); -static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); -static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate); -static void _finishTransfer(struct GBASIOLockstepNode* node); - -void GBASIOLockstepInit(struct GBASIOLockstep* lockstep) { - lockstep->players[0] = 0; - lockstep->players[1] = 0; - lockstep->players[2] = 0; - lockstep->players[3] = 0; - lockstep->multiRecv[0] = 0xFFFF; - lockstep->multiRecv[1] = 0xFFFF; - lockstep->multiRecv[2] = 0xFFFF; - lockstep->multiRecv[3] = 0xFFFF; - lockstep->attachedMulti = 0; - lockstep->attachedNormal = 0; -} - -void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { - memset(&node->d, 0, sizeof(node->d)); - node->d.init = GBASIOLockstepNodeInit; - node->d.deinit = GBASIOLockstepNodeDeinit; - node->d.load = GBASIOLockstepNodeLoad; - node->d.unload = GBASIOLockstepNodeUnload; - node->d.handlesMode = GBASIOLockstepNodeHandlesMode; - node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices; - node->d.deviceId = GBASIOLockstepNodeDeviceId; - node->d.start = GBASIOLockstepNodeStart; - node->d.writeSIOCNT = NULL; -} - -bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { - if (lockstep->d.attached == MAX_GBAS) { - return false; - } - mLockstepLock(&lockstep->d); - lockstep->players[lockstep->d.attached] = node; - node->p = lockstep; - node->id = lockstep->d.attached; - node->normalSO = true; - node->transferFinished = true; - ++lockstep->d.attached; - mLockstepUnlock(&lockstep->d); - return true; -} - -void GBASIOLockstepDetachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { - if (lockstep->d.attached == 0) { - return; - } - mLockstepLock(&lockstep->d); - int i; - for (i = 0; i < lockstep->d.attached; ++i) { - if (lockstep->players[i] != node) { - continue; - } - for (++i; i < lockstep->d.attached; ++i) { - lockstep->players[i - 1] = lockstep->players[i]; - lockstep->players[i - 1]->id = i - 1; - } - --lockstep->d.attached; - lockstep->players[lockstep->d.attached] = NULL; - break; - } - mLockstepUnlock(&lockstep->d); -} - -bool GBASIOLockstepNodeInit(struct GBASIODriver* driver) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - node->d.p->siocnt = GBASIOMultiplayerSetSlave(node->d.p->siocnt, node->id > 0); - mLOG(GBA_SIO, DEBUG, "Lockstep %i: Node init", node->id); - node->event.context = node; - node->event.name = "GBA SIO Lockstep"; - node->event.callback = _GBASIOLockstepNodeProcessEvents; - node->event.priority = 0x80; - return true; -} - -void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver) { - UNUSED(driver); -} - -bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - node->nextEvent = 0; - node->eventDiff = 0; - mTimingSchedule(&driver->p->p->timing, &node->event, 0); - - mLockstepLock(&node->p->d); - - node->mode = driver->p->mode; - - switch (node->mode) { - case GBA_SIO_MULTI: - node->d.writeSIOCNT = GBASIOLockstepNodeMultiWriteSIOCNT; - ATOMIC_ADD(node->p->attachedMulti, 1); - node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, node->p->attachedMulti == node->p->d.attached); - if (node->id) { - node->d.p->rcnt |= 4; - int try; - for (try = 0; try < 3; ++try) { - uint16_t masterSiocnt; - ATOMIC_LOAD(masterSiocnt, node->p->players[0]->d.p->siocnt); - if (ATOMIC_CMPXCHG(node->p->players[0]->d.p->siocnt, masterSiocnt, GBASIOMultiplayerClearSlave(masterSiocnt))) { - break; - } - } - } - break; - case GBA_SIO_NORMAL_8: - case GBA_SIO_NORMAL_32: - if (ATOMIC_ADD(node->p->attachedNormal, 1) > node->id + 1 && node->id > 0) { - node->d.p->siocnt = GBASIONormalSetSi(node->d.p->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - } else { - node->d.p->siocnt = GBASIONormalClearSi(node->d.p->siocnt); - } - node->d.writeSIOCNT = GBASIOLockstepNodeNormalWriteSIOCNT; - break; - default: - break; - } -#ifndef NDEBUG - node->phase = node->p->d.transferActive; - node->transferId = node->p->d.transferId; -#endif - - mLockstepUnlock(&node->p->d); - - return true; -} - -bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - - mLockstepLock(&node->p->d); - - node->mode = driver->p->mode; - switch (node->mode) { - case GBA_SIO_MULTI: - ATOMIC_SUB(node->p->attachedMulti, 1); - break; - case GBA_SIO_NORMAL_8: - case GBA_SIO_NORMAL_32: - ATOMIC_SUB(node->p->attachedNormal, 1); - break; - default: - break; - } - - // Flush ongoing transfer - if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { - node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); - mTimingDeschedule(&driver->p->p->timing, &node->event); - } - - node->p->d.unload(&node->p->d, node->id); - - _finishTransfer(node); - - if (!node->id) { - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_IDLE); - } - - // Invalidate SIO mode - node->mode = GBA_SIO_GPIO; - - mLockstepUnlock(&node->p->d); - - return true; -} - -static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { - UNUSED(driver); - switch (mode) { - case GBA_SIO_NORMAL_8: - case GBA_SIO_NORMAL_32: - case GBA_SIO_MULTI: - return true; - default: - return false; - } -} - -static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - int attached = 1; - - switch (node->mode) { - case GBA_SIO_NORMAL_8: - case GBA_SIO_NORMAL_32: - ATOMIC_LOAD(attached, node->p->attachedNormal); - break; - case GBA_SIO_MULTI: - ATOMIC_LOAD(attached, node->p->attachedMulti); - break; - default: - break; - } - return attached - 1; -} - -static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - return node->id; -} - -static bool GBASIOLockstepNodeStart(struct GBASIODriver* driver) { - UNUSED(driver); - return false; -} - -static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - - mLockstepLock(&node->p->d); - - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value); - - enum mLockstepPhase transferActive; - int attached; - ATOMIC_LOAD(transferActive, node->p->d.transferActive); - ATOMIC_LOAD(attached, node->p->d.attached); - - driver->p->siocnt = GBASIOMultiplayerSetSlave(driver->p->siocnt, node->id || attached < 2); - - if (value & 0x0080 && transferActive == TRANSFER_IDLE) { - if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p->mode, node->d.p->siocnt, attached)); - - if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { - node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); - mTimingDeschedule(&driver->p->p->timing, &node->event); - } - mTimingSchedule(&driver->p->p->timing, &node->event, 0); - } - } - value &= 0xFF83; - value |= driver->p->siocnt & 0x00FC; - - mLockstepUnlock(&node->p->d); - - return value; -} - -static void _finishTransfer(struct GBASIOLockstepNode* node) { - if (node->transferFinished) { - return; - } - - struct GBASIO* sio = node->d.p; - switch (node->mode) { - case GBA_SIO_MULTI: - GBASIOMultiplayerFinishTransfer(sio, node->p->multiRecv, 0); - break; - case GBA_SIO_NORMAL_8: - if (node->id) { - sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - GBASIONormal8FinishTransfer(sio, node->p->normalRecv[node->id - 1], 0); - } else { - GBASIONormal8FinishTransfer(sio, 0xFF, 0); - } - break; - case GBA_SIO_NORMAL_32: - if (node->id) { - sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - GBASIONormal32FinishTransfer(sio, node->p->normalRecv[node->id - 1], 0); - } else { - GBASIONormal32FinishTransfer(sio, 0xFFFFFFFF, 0); - } - break; - default: - break; - } - node->transferFinished = true; -#ifndef NDEBUG - ++node->transferId; -#endif -} - -static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { - bool needsToWait = false; - int i; - - enum mLockstepPhase transferActive; - int attachedMulti, attached; - - ATOMIC_LOAD(transferActive, node->p->d.transferActive); - ATOMIC_LOAD(attachedMulti, node->p->attachedMulti); - ATOMIC_LOAD(attached, node->p->d.attached); - - switch (transferActive) { - case TRANSFER_IDLE: - // If the master hasn't initiated a transfer, it can keep going. - node->nextEvent += LOCKSTEP_INCREMENT; - if (node->mode == GBA_SIO_MULTI) { - node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached); - } - break; - case TRANSFER_STARTING: - // Start the transfer, but wait for the other GBAs to catch up - node->transferFinished = false; - switch (node->mode) { - case GBA_SIO_MULTI: - node->p->multiRecv[0] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; - node->p->multiRecv[1] = 0xFFFF; - node->p->multiRecv[2] = 0xFFFF; - node->p->multiRecv[3] = 0xFFFF; - break; - case GBA_SIO_NORMAL_8: - node->p->multiRecv[0] = 0xFFFF; - node->p->normalRecv[0] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF; - break; - case GBA_SIO_NORMAL_32: - node->p->multiRecv[0] = 0xFFFF; - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]); - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)]); - node->p->normalRecv[0] = node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]; - node->p->normalRecv[0] |= node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] << 16; - break; - default: - node->p->multiRecv[0] = 0xFFFF; - break; - } - needsToWait = true; - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTED); - node->nextEvent += LOCKSTEP_TRANSFER; - break; - case TRANSFER_STARTED: - // All the other GBAs have caught up and are sleeping, we can all continue now - node->nextEvent += LOCKSTEP_TRANSFER; - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_FINISHING); - break; - case TRANSFER_FINISHING: - // Finish the transfer - // We need to make sure the other GBAs catch up so they don't get behind - node->nextEvent += node->p->d.transferCycles - 1024; // Split the cycles to avoid waiting too long -#ifndef NDEBUG - ATOMIC_ADD(node->p->d.transferId, 1); -#endif - needsToWait = true; - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_FINISHED); - break; - case TRANSFER_FINISHED: - // Everything's settled. We're done. - _finishTransfer(node); - node->nextEvent += LOCKSTEP_INCREMENT; - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_IDLE); - break; - } - int mask = 0; - for (i = 1; i < node->p->d.attached; ++i) { - if (node->p->players[i]->mode == node->mode) { - mask |= 1 << i; - } - } - if (mask) { - if (needsToWait) { - if (!node->p->d.wait(&node->p->d, mask)) { - abort(); - } - } else { - node->p->d.signal(&node->p->d, mask); - } - } - // Tell the other GBAs they can continue up to where we were - node->p->d.addCycles(&node->p->d, 0, node->eventDiff); -#ifndef NDEBUG - node->phase = node->p->d.transferActive; -#endif - - if (needsToWait) { - return 0; - } - return node->nextEvent; -} - -static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { - enum mLockstepPhase transferActive; - int attached; - int attachedMode; - - ATOMIC_LOAD(transferActive, node->p->d.transferActive); - ATOMIC_LOAD(attached, node->p->d.attached); - - if (node->mode == GBA_SIO_MULTI) { - ATOMIC_LOAD(attachedMode, node->p->attachedMulti); - node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMode == attached); - } else { - ATOMIC_LOAD(attachedMode, node->p->attachedNormal); - } - bool signal = false; - switch (transferActive) { - case TRANSFER_IDLE: - if (attachedMode != attached) { - node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT); - } - break; - case TRANSFER_STARTING: - case TRANSFER_FINISHING: - break; - case TRANSFER_STARTED: - if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) { - break; - } - node->transferFinished = false; - switch (node->mode) { - case GBA_SIO_MULTI: - node->d.p->rcnt &= ~1; - node->p->multiRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; - node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF; - node->d.p->siocnt = GBASIOMultiplayerFillBusy(node->d.p->siocnt); - break; - case GBA_SIO_NORMAL_8: - node->p->multiRecv[node->id] = 0xFFFF; - node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF; - break; - case GBA_SIO_NORMAL_32: - node->p->multiRecv[node->id] = 0xFFFF; - node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]; - node->p->normalRecv[node->id] |= node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] << 16; - break; - default: - node->p->multiRecv[node->id] = 0xFFFF; - break; - } - signal = true; - break; - case TRANSFER_FINISHED: - if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) { - break; - } - _finishTransfer(node); - signal = true; - break; - } -#ifndef NDEBUG - node->phase = node->p->d.transferActive; -#endif - if (signal) { - node->p->d.signal(&node->p->d, 1 << node->id); - } - - return 0; -} - -static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { - struct GBASIOLockstepNode* node = user; - mLockstepLock(&node->p->d); - - int32_t cycles = node->nextEvent; - node->nextEvent -= cyclesLate; - node->eventDiff += cyclesLate; - if (node->p->d.attached < 2) { - switch (node->mode) { - case GBA_SIO_MULTI: - cycles = GBASIOTransferCycles(node->d.p->mode, node->d.p->siocnt, node->p->d.attached); - break; - case GBA_SIO_NORMAL_8: - case GBA_SIO_NORMAL_32: - if (node->nextEvent <= 0) { - cycles = _masterUpdate(node); - node->eventDiff = 0; - } - break; - default: - break; - } - } else if (node->nextEvent <= 0) { - if (!node->id) { - cycles = _masterUpdate(node); - } else { - cycles = _slaveUpdate(node); - cycles += node->p->d.useCycles(&node->p->d, node->id, node->eventDiff); - } - node->eventDiff = 0; - } - if (cycles > 0) { - node->nextEvent = 0; - node->eventDiff += cycles; - mTimingDeschedule(timing, &node->event); - mTimingSchedule(timing, &node->event, cycles); - } else { - node->d.p->p->earlyExit = true; - node->eventDiff += 1; - mTimingSchedule(timing, &node->event, 1); - } - - mLockstepUnlock(&node->p->d); -} - -static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - - mLockstepLock(&node->p->d); - - mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04X", node->id, value); - int attached; - ATOMIC_LOAD(attached, node->p->attachedNormal); - value &= 0xFF8B; - if (node->id > 0) { - value = GBASIONormalSetSi(value, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - } else { - value = GBASIONormalClearSi(value); - } - - enum mLockstepPhase transferActive; - ATOMIC_LOAD(transferActive, node->p->d.transferActive); - if (node->id < 3 && attached > node->id + 1 && transferActive == TRANSFER_IDLE) { - int try; - for (try = 0; try < 3; ++try) { - GBASIONormal nextSiocnct; - ATOMIC_LOAD(nextSiocnct, node->p->players[node->id + 1]->d.p->siocnt); - if (ATOMIC_CMPXCHG(node->p->players[node->id + 1]->d.p->siocnt, nextSiocnct, GBASIONormalSetSi(nextSiocnct, GBASIONormalGetIdleSo(value)))) { - break; - } - } - } - if ((value & 0x0081) == 0x0081) { - if (!node->id) { - // Frequency - int32_t cycles = GBASIOTransferCycles(node->d.p->mode, node->d.p->siocnt, attached); - - if (transferActive == TRANSFER_IDLE) { - mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); - ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, cycles); - - if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { - node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); - mTimingDeschedule(&driver->p->p->timing, &node->event); - } - mTimingSchedule(&driver->p->p->timing, &node->event, 0); - } else { - value &= ~0x0080; - } - } else { - // TODO - } - } - - mLockstepUnlock(&node->p->d); - - return value; -} - #define TARGET(P) (1 << (P)) #define TARGET_ALL 0xF #define TARGET_PRIMARY 0x1 From 630e3a591a89b24a268be772a209de33d8a07824 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 7 Sep 2024 21:12:19 -0700 Subject: [PATCH 299/336] GBA SIO: Add support for side data in save states --- include/mgba/gba/interface.h | 3 +++ include/mgba/internal/gba/serialize.h | 1 + src/gba/core.c | 37 ++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 3d52e7743..cba586632 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -113,6 +113,9 @@ struct GBASIODriver { void (*reset)(struct GBASIODriver* driver); bool (*load)(struct GBASIODriver* driver); bool (*unload)(struct GBASIODriver* driver); + uint32_t (*driverId)(const struct GBASIODriver* renderer); + bool (*loadState)(struct GBASIODriver* renderer, const void* state, size_t size); + void (*saveState)(struct GBASIODriver* renderer, void** state, size_t* size); void (*setMode)(struct GBASIODriver* driver, enum GBASIOMode mode); bool (*handlesMode)(struct GBASIODriver* driver, enum GBASIOMode mode); int (*connectedDevices)(struct GBASIODriver* driver); diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index c824e85aa..8b1823a17 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -287,6 +287,7 @@ DECL_BITS(GBASerializedMiscFlags, KeyIRQKeys, 4, 11); enum { GBA_SUBSYSTEM_VIDEO_RENDERER = 0, + GBA_SUBSYSTEM_SIO_DRIVER = 1, GBA_SUBSYSTEM_MAX, }; diff --git a/src/gba/core.c b/src/gba/core.c index a6939406e..00f5ccf97 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -842,7 +842,21 @@ static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdat if (type == gba->video.renderer->rendererId(gba->video.renderer)) { ok = gba->video.renderer->loadState(gba->video.renderer, (void*) ((uintptr_t) item.data + sizeof(uint32_t)), - item.size - sizeof(type)); + item.size - sizeof(type)) && ok; + } + } else if (item.data) { + ok = false; + } + } + if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->loadState && + mStateExtdataGet(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item)) { + if ((uint32_t) item.size > sizeof(uint32_t)) { + uint32_t type; + LOAD_32(type, 0, item.data); + if (type == gba->sio.activeDriver->driverId(gba->sio.activeDriver)) { + ok = gba->sio.activeDriver->loadState(gba->sio.activeDriver, + (void*) ((uintptr_t) item.data + sizeof(uint32_t)), + item.size - sizeof(type)) && ok; } } else if (item.data) { ok = false; @@ -868,6 +882,27 @@ static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* ext } if (buffer) { free(buffer); + buffer = NULL; + } + size = 0; + + if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->saveState) { + gba->sio.activeDriver->saveState(gba->sio.activeDriver, &buffer, &size); + if (size > 0 && buffer) { + struct mStateExtdataItem item; + item.size = size + sizeof(uint32_t); + item.data = malloc(item.size); + item.clean = free; + uint32_t type = gba->sio.activeDriver->driverId(gba->sio.activeDriver); + STORE_32(type, 0, item.data); + memcpy((void*) ((uintptr_t) item.data + sizeof(uint32_t)), buffer, size); + mStateExtdataPut(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item); + } + if (buffer) { + free(buffer); + buffer = NULL; + } + size = 0; } return true; From f2bbf8e66c0dfcd1166939a5701a278f104199ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 8 Sep 2024 04:17:41 -0700 Subject: [PATCH 300/336] GBA SIO: Support save states in lockstep driver --- src/gba/sio/lockstep.c | 271 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 1493ca9f6..074b7d0e8 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -8,17 +8,82 @@ #include #include +#define DRIVER_ID 0x6B636F4C +#define DRIVER_STATE_VERSION 1 #define LOCKSTEP_INCREMENT 2000 #define TARGET(P) (1 << (P)) #define TARGET_ALL 0xF #define TARGET_PRIMARY 0x1 #define TARGET_SECONDARY ((TARGET_ALL) & ~(TARGET_PRIMARY)) +DECL_BITFIELD(GBASIOLockstepSerializedFlags, uint32_t); +DECL_BITS(GBASIOLockstepSerializedFlags, DriverMode, 0, 3); +DECL_BITS(GBASIOLockstepSerializedFlags, NumEvents, 3, 4); +DECL_BIT(GBASIOLockstepSerializedFlags, Asleep, 7); +DECL_BIT(GBASIOLockstepSerializedFlags, DataReceived, 8); +DECL_BIT(GBASIOLockstepSerializedFlags, EventScheduled, 9); +DECL_BITS(GBASIOLockstepSerializedFlags, Player0Mode, 10, 3); +DECL_BITS(GBASIOLockstepSerializedFlags, Player1Mode, 13, 3); +DECL_BITS(GBASIOLockstepSerializedFlags, Player2Mode, 16, 3); +DECL_BITS(GBASIOLockstepSerializedFlags, Player3Mode, 19, 3); +DECL_BITS(GBASIOLockstepSerializedFlags, TransferMode, 28, 3); +DECL_BIT(GBASIOLockstepSerializedFlags, TransferActive, 31); + +DECL_BITFIELD(GBASIOLockstepSerializedEventFlags, uint32_t); +DECL_BITS(GBASIOLockstepSerializedEventFlags, Type, 0, 3); + +struct GBASIOLockstepSerializedEvent { + int32_t timestamp; + int32_t playerId; + GBASIOLockstepSerializedEventFlags flags; + int32_t reserved[5]; + union { + int32_t mode; + int32_t finishCycle; + int32_t padding[4]; + }; +}; +static_assert(sizeof(struct GBASIOLockstepSerializedEvent) == 0x30, "GBA lockstep event savestate struct sized wrong"); + +struct GBASIOLockstepSerializedState { + uint32_t version; + GBASIOLockstepSerializedFlags flags; + uint32_t reserved[2]; + + struct { + int32_t nextEvent; + uint32_t reservedDriver[7]; + } driver; + + struct { + int32_t playerId; + int32_t cycleOffset; + uint32_t reservedPlayer[2]; + struct GBASIOLockstepSerializedEvent events[MAX_LOCKSTEP_EVENTS]; + } player; + + // playerId 0 only + struct { + int32_t cycle; + uint32_t waiting; + uint32_t reservedCoordinator[4]; + uint16_t multiData[4]; + uint32_t normalData[4]; + } coordinator; +}; +static_assert(offsetof(struct GBASIOLockstepSerializedState, driver) == 0x10, "GBA lockstep savestate driver offset wrong"); +static_assert(offsetof(struct GBASIOLockstepSerializedState, player) == 0x30, "GBA lockstep savestate player offset wrong"); +static_assert(offsetof(struct GBASIOLockstepSerializedState, coordinator) == 0x1C0, "GBA lockstep savestate coordinator offset wrong"); +static_assert(sizeof(struct GBASIOLockstepSerializedState) == 0x1F0, "GBA lockstep savestate struct sized wrong"); + static bool GBASIOLockstepDriverInit(struct GBASIODriver* driver); static void GBASIOLockstepDriverDeinit(struct GBASIODriver* driver); static void GBASIOLockstepDriverReset(struct GBASIODriver* driver); static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver); static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver); +static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver); +static bool GBASIOLockstepDriverLoadState(struct GBASIODriver* driver, const void* state, size_t size); +static void GBASIOLockstepDriverSaveState(struct GBASIODriver* driver, void** state, size_t* size); static void GBASIOLockstepDriverSetMode(struct GBASIODriver* driver, enum GBASIOMode mode); static bool GBASIOLockstepDriverHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIOLockstepDriverConnectedDevices(struct GBASIODriver* driver); @@ -56,6 +121,9 @@ void GBASIOLockstepDriverCreate(struct GBASIOLockstepDriver* driver, struct mLoc driver->d.reset = GBASIOLockstepDriverReset; driver->d.load = GBASIOLockstepDriverLoad; driver->d.unload = GBASIOLockstepDriverUnload; + driver->d.driverId = GBASIOLockstepDriverId; + driver->d.loadState = GBASIOLockstepDriverLoadState; + driver->d.saveState = GBASIOLockstepDriverSaveState; driver->d.setMode = GBASIOLockstepDriverSetMode; driver->d.handlesMode = GBASIOLockstepDriverHandlesMode; driver->d.deviceId = GBASIOLockstepDriverDeviceId; @@ -173,6 +241,209 @@ static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver) { return true; } +static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver) { + UNUSED(driver); + return DRIVER_ID; +} + +static unsigned _modeEnumToInt(enum GBASIOMode mode) { + switch ((int) mode) { + case -1: + default: + return 0; + case GBA_SIO_MULTI: + return 1; + case GBA_SIO_NORMAL_8: + return 2; + case GBA_SIO_NORMAL_32: + return 3; + case GBA_SIO_GPIO: + return 4; + case GBA_SIO_UART: + return 5; + case GBA_SIO_JOYBUS: + return 6; + } +} + +static enum GBASIOMode _modeIntToEnum(unsigned mode) { + const enum GBASIOMode modes[8] = { + -1, GBA_SIO_MULTI, GBA_SIO_NORMAL_8, GBA_SIO_NORMAL_32, GBA_SIO_GPIO, GBA_SIO_UART, GBA_SIO_JOYBUS, -1 + }; + return modes[mode & 7]; +} + +static bool GBASIOLockstepDriverLoadState(struct GBASIODriver* driver, const void* data, size_t size) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + if (size != sizeof(struct GBASIOLockstepSerializedState)) { + mLOG(GBA_SIO, WARN, "Incorrect state size: expected %" PRIz "X, got %" PRIz "X", sizeof(struct GBASIOLockstepSerializedState), size); + return false; + } + const struct GBASIOLockstepSerializedState* state = data; + bool error = false; + uint32_t ucheck; + int32_t check; + LOAD_32LE(ucheck, 0, &state->version); + if (ucheck > DRIVER_STATE_VERSION) { + mLOG(GBA_SIO, WARN, "Invalid or too new save state: expected %u, got %u", DRIVER_STATE_VERSION, ucheck); + return false; + } + + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + LOAD_32LE(check, 0, &state->player.playerId); + if (check != player->playerId) { + mLOG(GBA_SIO, WARN, "State is for different player: expected %d, got %d", player->playerId, check); + error = true; + goto out; + } + + GBASIOLockstepSerializedFlags flags = 0; + LOAD_32LE(flags, 0, &state->flags); + LOAD_32LE(player->cycleOffset, 0, &state->player.cycleOffset); + player->dataReceived = GBASIOLockstepSerializedFlagsGetDataReceived(flags); + player->mode = _modeIntToEnum(GBASIOLockstepSerializedFlagsGetDriverMode(flags)); + + player->otherModes[0] = _modeIntToEnum(GBASIOLockstepSerializedFlagsGetPlayer0Mode(flags)); + player->otherModes[1] = _modeIntToEnum(GBASIOLockstepSerializedFlagsGetPlayer1Mode(flags)); + player->otherModes[2] = _modeIntToEnum(GBASIOLockstepSerializedFlagsGetPlayer2Mode(flags)); + player->otherModes[3] = _modeIntToEnum(GBASIOLockstepSerializedFlagsGetPlayer3Mode(flags)); + + if (GBASIOLockstepSerializedFlagsGetEventScheduled(flags)) { + int32_t when; + LOAD_32LE(when, 0, &state->driver.nextEvent); + mTimingSchedule(&driver->p->p->timing, &lockstep->event, when); + } + + if (GBASIOLockstepSerializedFlagsGetAsleep(flags)) { + if (!player->asleep && player->driver->user->sleep) { + player->driver->user->sleep(player->driver->user); + } + player->asleep = true; + } else { + if (player->asleep && player->driver->user->wake) { + player->driver->user->wake(player->driver->user); + } + player->asleep = false; + } + + unsigned i; + for (i = 0; i < MAX_LOCKSTEP_EVENTS - 1; ++i) { + player->buffer[i].next = &player->buffer[i + 1]; + } + player->freeList = &player->buffer[0]; + player->queue = NULL; + + struct GBASIOLockstepEvent** lastEvent = &player->queue; + for (i = 0; i < GBASIOLockstepSerializedFlagsGetNumEvents(flags) && i < MAX_LOCKSTEP_EVENTS; ++i) { + struct GBASIOLockstepEvent* event = player->freeList; + const struct GBASIOLockstepSerializedEvent* stateEvent = &state->player.events[i]; + player->freeList = player->freeList->next; + *lastEvent = event; + lastEvent = &event->next; + + GBASIOLockstepSerializedEventFlags flags; + LOAD_32LE(flags, 0, &stateEvent->flags); + LOAD_32LE(event->timestamp, 0, &stateEvent->timestamp); + LOAD_32LE(event->playerId, 0, &stateEvent->playerId); + event->type = GBASIOLockstepSerializedEventFlagsGetType(flags); + switch (event->type) { + case SIO_EV_ATTACH: + case SIO_EV_DETACH: + case SIO_EV_HARD_SYNC: + break; + case SIO_EV_MODE_SET: + LOAD_32LE(event->mode, 0, &stateEvent->mode); + break; + case SIO_EV_TRANSFER_START: + LOAD_32LE(event->finishCycle, 0, &stateEvent->finishCycle); + break; + } + } + + if (player->playerId == 0) { + LOAD_32LE(coordinator->cycle, 0, &state->coordinator.cycle); + LOAD_32LE(coordinator->waiting, 0, &state->coordinator.waiting); + for (i = 0; i < 4; ++i) { + LOAD_16LE(coordinator->multiData[i], 0, &state->coordinator.multiData[i]); + LOAD_32LE(coordinator->normalData[i], 0, &state->coordinator.normalData[i]); + } + coordinator->transferMode = _modeIntToEnum(GBASIOLockstepSerializedFlagsGetTransferMode(flags)); + coordinator->transferActive = GBASIOLockstepSerializedFlagsGetTransferActive(flags); + } +out: + MutexUnlock(&coordinator->mutex); + if (!error) { + mTimingInterrupt(&driver->p->p->timing); + } + return !error; +} + +static void GBASIOLockstepDriverSaveState(struct GBASIODriver* driver, void** stateOut, size_t* size) { + struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; + struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + struct GBASIOLockstepSerializedState* state = calloc(1, sizeof(*state)); + + STORE_32LE(DRIVER_STATE_VERSION, 0, &state->version); + + STORE_32LE(lockstep->event.when - mTimingCurrentTime(&driver->p->p->timing), 0, &state->driver.nextEvent); + + MutexLock(&coordinator->mutex); + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); + GBASIOLockstepSerializedFlags flags = 0; + STORE_32LE(player->playerId, 0, &state->player.playerId); + STORE_32LE(player->cycleOffset, 0, &state->player.cycleOffset); + flags = GBASIOLockstepSerializedFlagsSetAsleep(flags, player->asleep); + flags = GBASIOLockstepSerializedFlagsSetDataReceived(flags, player->dataReceived); + flags = GBASIOLockstepSerializedFlagsSetDriverMode(flags, _modeEnumToInt(player->mode)); + flags = GBASIOLockstepSerializedFlagsSetEventScheduled(flags, mTimingIsScheduled(&driver->p->p->timing, &lockstep->event)); + + flags = GBASIOLockstepSerializedFlagsSetPlayer0Mode(flags, _modeEnumToInt(player->otherModes[0])); + flags = GBASIOLockstepSerializedFlagsSetPlayer1Mode(flags, _modeEnumToInt(player->otherModes[1])); + flags = GBASIOLockstepSerializedFlagsSetPlayer2Mode(flags, _modeEnumToInt(player->otherModes[2])); + flags = GBASIOLockstepSerializedFlagsSetPlayer3Mode(flags, _modeEnumToInt(player->otherModes[3])); + + struct GBASIOLockstepEvent* event = player->queue; + size_t i; + for (i = 0; i < MAX_LOCKSTEP_EVENTS && event; ++i, event = event->next) { + struct GBASIOLockstepSerializedEvent* stateEvent = &state->player.events[i]; + GBASIOLockstepSerializedEventFlags flags = GBASIOLockstepSerializedEventFlagsSetType(0, event->type); + STORE_32LE(event->timestamp, 0, &stateEvent->timestamp); + STORE_32LE(event->playerId, 0, &stateEvent->playerId); + switch (event->type) { + case SIO_EV_ATTACH: + case SIO_EV_DETACH: + case SIO_EV_HARD_SYNC: + break; + case SIO_EV_MODE_SET: + STORE_32LE(event->mode, 0, &stateEvent->mode); + break; + case SIO_EV_TRANSFER_START: + STORE_32LE(event->finishCycle, 0, &stateEvent->finishCycle); + break; + } + STORE_32LE(flags, 0, &stateEvent->flags); + } + flags = GBASIOLockstepSerializedFlagsSetNumEvents(flags, i); + + if (player->playerId == 0) { + STORE_32LE(coordinator->cycle, 0, &state->coordinator.cycle); + STORE_32LE(coordinator->waiting, 0, &state->coordinator.waiting); + for (i = 0; i < 4; ++i) { + STORE_16LE(coordinator->multiData[i], 0, &state->coordinator.multiData[i]); + STORE_32LE(coordinator->normalData[i], 0, &state->coordinator.normalData[i]); + } + flags = GBASIOLockstepSerializedFlagsSetTransferMode(flags, _modeEnumToInt(coordinator->transferMode)); + flags = GBASIOLockstepSerializedFlagsSetTransferActive(flags, coordinator->transferActive); + } + MutexUnlock(&lockstep->coordinator->mutex); + + STORE_32LE(flags, 0, &state->flags); + *stateOut = state; + *size = sizeof(*state); +} + static void GBASIOLockstepDriverSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) { struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; From 0823797671d678206f4bf1cf042a15e1299782d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 10 Sep 2024 03:19:02 -0700 Subject: [PATCH 301/336] GBA SIO: Remove driver sets and driver load/unload concepts --- include/mgba/gba/interface.h | 2 - include/mgba/internal/gba/sio.h | 12 +- src/gba/cart/gpio.c | 2 +- src/gba/core.c | 19 ++- src/gba/extra/battlechip.c | 6 +- src/gba/gba.c | 4 +- src/gba/sio.c | 157 ++++++---------------- src/gba/sio/dolphin.c | 21 ++- src/gba/sio/gbp.c | 6 +- src/gba/sio/lockstep.c | 25 ---- src/platform/qt/CoreController.cpp | 5 +- src/platform/qt/MultiplayerController.cpp | 17 +-- 12 files changed, 77 insertions(+), 199 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index cba586632..9b8f6e001 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -111,8 +111,6 @@ struct GBASIODriver { bool (*init)(struct GBASIODriver* driver); void (*deinit)(struct GBASIODriver* driver); void (*reset)(struct GBASIODriver* driver); - bool (*load)(struct GBASIODriver* driver); - bool (*unload)(struct GBASIODriver* driver); uint32_t (*driverId)(const struct GBASIODriver* renderer); bool (*loadState)(struct GBASIODriver* renderer, const void* state, size_t size); void (*saveState)(struct GBASIODriver* renderer, void** state, size_t* size); diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index ca271abc4..14a2136b8 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -62,18 +62,11 @@ DECL_BIT(GBASIORegisterRCNT, SdDirection, 5); DECL_BIT(GBASIORegisterRCNT, SiDirection, 6); DECL_BIT(GBASIORegisterRCNT, SoDirection, 7); -struct GBASIODriverSet { - struct GBASIODriver* normal; - struct GBASIODriver* multiplayer; - struct GBASIODriver* joybus; -}; - struct GBASIO { struct GBA* p; enum GBASIOMode mode; - struct GBASIODriverSet drivers; - struct GBASIODriver* activeDriver; + struct GBASIODriver* driver; uint16_t rcnt; uint16_t siocnt; @@ -86,8 +79,7 @@ void GBASIOInit(struct GBASIO* sio); void GBASIODeinit(struct GBASIO* sio); void GBASIOReset(struct GBASIO* sio); -void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers); -void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode); +void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver); void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value); void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value); diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index a04a5f6b3..3386ac3c6 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -527,7 +527,7 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer uint32_t when; LOAD_32(when, 0, &state->hw.sioNextEvent); if (hw->devices & HW_GB_PLAYER) { - GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, GBA_SIO_NORMAL_32); + GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d); } if ((hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) && when < 0x20000) { mTimingSchedule(&hw->p->timing, &hw->p->sio.completeEvent, when); diff --git a/src/gba/core.c b/src/gba/core.c index 00f5ccf97..898745e9e 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -848,15 +848,15 @@ static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdat ok = false; } } - if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->loadState && + if (gba->sio.driver && gba->sio.driver->driverId && gba->sio.driver->loadState && mStateExtdataGet(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item)) { if ((uint32_t) item.size > sizeof(uint32_t)) { uint32_t type; LOAD_32(type, 0, item.data); - if (type == gba->sio.activeDriver->driverId(gba->sio.activeDriver)) { - ok = gba->sio.activeDriver->loadState(gba->sio.activeDriver, - (void*) ((uintptr_t) item.data + sizeof(uint32_t)), - item.size - sizeof(type)) && ok; + if (type == gba->sio.driver->driverId(gba->sio.driver)) { + ok = gba->sio.driver->loadState(gba->sio.driver, + (void*) ((uintptr_t) item.data + sizeof(uint32_t)), + item.size - sizeof(type)) && ok; } } else if (item.data) { ok = false; @@ -886,14 +886,14 @@ static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* ext } size = 0; - if (gba->sio.activeDriver && gba->sio.activeDriver->driverId && gba->sio.activeDriver->saveState) { - gba->sio.activeDriver->saveState(gba->sio.activeDriver, &buffer, &size); + if (gba->sio.driver && gba->sio.driver->driverId && gba->sio.driver->saveState) { + gba->sio.driver->saveState(gba->sio.driver, &buffer, &size); if (size > 0 && buffer) { struct mStateExtdataItem item; item.size = size + sizeof(uint32_t); item.data = malloc(item.size); item.clean = free; - uint32_t type = gba->sio.activeDriver->driverId(gba->sio.activeDriver); + uint32_t type = gba->sio.driver->driverId(gba->sio.driver); STORE_32(type, 0, item.data); memcpy((void*) ((uintptr_t) item.data + sizeof(uint32_t)), buffer, size); mStateExtdataPut(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_SIO_DRIVER, &item); @@ -963,8 +963,7 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { gba->luminanceSource = periph; break; case mPERIPH_GBA_BATTLECHIP_GATE: - GBASIOSetDriver(&gba->sio, periph, GBA_SIO_MULTI); - GBASIOSetDriver(&gba->sio, periph, GBA_SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, periph); break; default: return; diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index a6eda3bdf..d7bf35cce 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -33,7 +33,7 @@ enum { BATTLECHIP_CONTINUE = 0xFFFF, }; -static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver); +static bool GBASIOBattlechipGateInit(struct GBASIODriver* driver); static uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value); static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver); @@ -41,7 +41,7 @@ static void GBASIOBattlechipGateFinishMultiplayer(struct GBASIODriver* driver, u void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { memset(&gate->d, 0, sizeof(gate->d)); - gate->d.load = GBASIOBattlechipGateLoad; + gate->d.init = GBASIOBattlechipGateInit; gate->d.writeSIOCNT = GBASIOBattlechipGateWriteSIOCNT; gate->d.handlesMode = GBASIOBattlechipGateHandlesMode; gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices; @@ -51,7 +51,7 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE; } -bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) { +bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) { struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; gate->state = BATTLECHIP_STATE_SYNC; gate->data[0] = 0x00FE; diff --git a/src/gba/gba.c b/src/gba/gba.c index aab2cd3ec..187d83373 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -263,8 +263,8 @@ void GBAReset(struct ARMCore* cpu) { // GB Player SIO control should not be engaged before detection, even if we already know it's GBP gba->memory.hw.devices &= ~HW_GB_PLAYER; - if (gba->sio.drivers.normal == &gba->sio.gbp.d) { - GBASIOSetDriver(&gba->sio, NULL, GBA_SIO_NORMAL_32); + if (gba->sio.driver == &gba->sio.gbp.d) { + GBASIOSetDriver(&gba->sio, NULL); } bool isELF = false; diff --git a/src/gba/sio.c b/src/gba/sio.c index 4b635db18..60c7c2286 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -20,20 +20,6 @@ static const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate); -static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) { - switch (mode) { - case GBA_SIO_NORMAL_8: - case GBA_SIO_NORMAL_32: - return sio->drivers.normal; - case GBA_SIO_MULTI: - return sio->drivers.multiplayer; - case GBA_SIO_JOYBUS: - return sio->drivers.joybus; - default: - return 0; - } -} - static const char* _modeName(enum GBASIOMode mode) { switch (mode) { case GBA_SIO_NORMAL_8: @@ -60,31 +46,19 @@ static void _switchMode(struct GBASIO* sio) { newMode = (enum GBASIOMode) (mode & 0xC); } if (newMode != sio->mode) { - struct GBASIODriver* driver = _lookupDriver(sio, newMode); if (sio->mode != (enum GBASIOMode) -1) { mLOG(GBA_SIO, DEBUG, "Switching mode from %s to %s", _modeName(sio->mode), _modeName(newMode)); } - if (driver != sio->activeDriver || (driver && !driver->setMode)) { - if (sio->activeDriver && sio->activeDriver->unload) { - sio->activeDriver->unload(sio->activeDriver); - } - sio->mode = newMode; - sio->activeDriver = driver; - if (sio->activeDriver && sio->activeDriver->load) { - sio->activeDriver->load(sio->activeDriver); - } - } else { - sio->mode = newMode; - if (sio->activeDriver && sio->activeDriver->setMode) { - sio->activeDriver->setMode(sio->activeDriver, newMode); - } + sio->mode = newMode; + if (sio->driver && sio->driver->setMode) { + sio->driver->setMode(sio->driver, newMode); } int id = 0; switch (newMode) { case GBA_SIO_MULTI: - if (sio->activeDriver && sio->activeDriver->deviceId) { - id = sio->activeDriver->deviceId(sio->activeDriver); + if (sio->driver && sio->driver->deviceId) { + id = sio->driver->deviceId(sio->driver); } sio->rcnt = GBASIORegisterRCNTSetSi(sio->rcnt, !!id); break; @@ -96,10 +70,7 @@ static void _switchMode(struct GBASIO* sio) { } void GBASIOInit(struct GBASIO* sio) { - sio->drivers.normal = NULL; - sio->drivers.multiplayer = NULL; - sio->drivers.joybus = NULL; - sio->activeDriver = NULL; + sio->driver = NULL; sio->completeEvent.context = sio; sio->completeEvent.name = "GBA SIO Complete"; @@ -113,73 +84,28 @@ void GBASIOInit(struct GBASIO* sio) { } void GBASIODeinit(struct GBASIO* sio) { - if (sio->activeDriver && sio->activeDriver->unload) { - sio->activeDriver->unload(sio->activeDriver); - } - if (sio->drivers.multiplayer && sio->drivers.multiplayer->deinit) { - sio->drivers.multiplayer->deinit(sio->drivers.multiplayer); - } - if (sio->drivers.joybus && sio->drivers.joybus->deinit) { - sio->drivers.joybus->deinit(sio->drivers.joybus); - } - if (sio->drivers.normal && sio->drivers.normal->deinit) { - sio->drivers.normal->deinit(sio->drivers.normal); + if (sio->driver && sio->driver->deinit) { + sio->driver->deinit(sio->driver); } } void GBASIOReset(struct GBASIO* sio) { - if (sio->activeDriver && sio->activeDriver->unload) { - sio->activeDriver->unload(sio->activeDriver); - } - if (sio->drivers.multiplayer && sio->drivers.multiplayer->reset) { - sio->drivers.multiplayer->reset(sio->drivers.multiplayer); - } - if (sio->drivers.joybus && sio->drivers.joybus->reset) { - sio->drivers.joybus->reset(sio->drivers.joybus); - } - if (sio->drivers.normal && sio->drivers.normal->reset) { - sio->drivers.normal->reset(sio->drivers.normal); + if (sio->driver && sio->driver->reset) { + sio->driver->reset(sio->driver); } sio->rcnt = RCNT_INITIAL; sio->siocnt = 0; sio->mode = -1; - sio->activeDriver = NULL; _switchMode(sio); GBASIOPlayerReset(&sio->gbp); } -void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers) { - GBASIOSetDriver(sio, drivers->normal, GBA_SIO_NORMAL_8); - GBASIOSetDriver(sio, drivers->multiplayer, GBA_SIO_MULTI); - GBASIOSetDriver(sio, drivers->joybus, GBA_SIO_JOYBUS); -} - -void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode) { - struct GBASIODriver** driverLoc; - switch (mode) { - case GBA_SIO_NORMAL_8: - case GBA_SIO_NORMAL_32: - driverLoc = &sio->drivers.normal; - break; - case GBA_SIO_MULTI: - driverLoc = &sio->drivers.multiplayer; - break; - case GBA_SIO_JOYBUS: - driverLoc = &sio->drivers.joybus; - break; - default: - mLOG(GBA_SIO, ERROR, "Setting an unsupported SIO driver: %x", mode); - return; - } - if (*driverLoc) { - if ((*driverLoc)->unload) { - (*driverLoc)->unload(*driverLoc); - } - if ((*driverLoc)->deinit) { - (*driverLoc)->deinit(*driverLoc); - } +void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver) { + if (sio->driver && sio->driver->deinit) { + sio->driver->deinit(sio->driver); } + sio->driver = driver; if (driver) { driver->p = sio; @@ -191,26 +117,19 @@ void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASI } } } - if (sio->activeDriver == *driverLoc) { - sio->activeDriver = driver; - if (driver && driver->load) { - driver->load(driver); - } - } - *driverLoc = driver; } void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) { sio->rcnt &= 0x1FF; sio->rcnt |= value & 0xC000; _switchMode(sio); - if (sio->activeDriver && sio->activeDriver->writeRCNT) { + if (sio->driver && sio->driver->writeRCNT) { switch (sio->mode) { case GBA_SIO_GPIO: - sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01FF) | (sio->rcnt & 0xC000); + sio->rcnt = (sio->driver->writeRCNT(sio->driver, value) & 0x01FF) | (sio->rcnt & 0xC000); break; default: - sio->rcnt = (sio->activeDriver->writeRCNT(sio->activeDriver, value) & 0x01F0) | (sio->rcnt & 0xC00F); + sio->rcnt = (sio->driver->writeRCNT(sio->driver, value) & 0x01F0) | (sio->rcnt & 0xC00F); } } else if (sio->mode == GBA_SIO_GPIO) { sio->rcnt &= 0xC000; @@ -222,15 +141,15 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) { } static void _startTransfer(struct GBASIO* sio) { - if (sio->activeDriver && sio->activeDriver->start) { - if (!sio->activeDriver->start(sio->activeDriver)) { + if (sio->driver && sio->driver->start) { + if (!sio->driver->start(sio->driver)) { // Transfer completion is handled internally to the driver return; } } int connected = 0; - if (sio->activeDriver && sio->activeDriver->connectedDevices) { - connected = sio->activeDriver->connectedDevices(sio->activeDriver); + if (sio->driver && sio->driver->connectedDevices) { + connected = sio->driver->connectedDevices(sio->driver); } mTimingDeschedule(&sio->p->timing, &sio->completeEvent); mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio->mode, sio->siocnt, connected)); @@ -244,14 +163,14 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { int id = 0; int connected = 0; bool handled = false; - if (sio->activeDriver) { - handled = sio->activeDriver->handlesMode(sio->activeDriver, sio->mode); + if (sio->driver) { + handled = sio->driver->handlesMode(sio->driver, sio->mode); if (handled) { - if (sio->activeDriver->deviceId) { - id = sio->activeDriver->deviceId(sio->activeDriver); + if (sio->driver->deviceId) { + id = sio->driver->deviceId(sio->driver); } - connected = sio->activeDriver->connectedDevices(sio->activeDriver); - handled = !!sio->activeDriver->writeSIOCNT; + connected = sio->driver->connectedDevices(sio->driver); + handled = !!sio->driver->writeSIOCNT; } } @@ -304,7 +223,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { break; } if (handled) { - value = sio->activeDriver->writeSIOCNT(sio->activeDriver, value); + value = sio->driver->writeSIOCNT(sio->driver, value); } else { // Dummy drivers switch (sio->mode) { @@ -325,8 +244,8 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value) { int id = 0; - if (sio->activeDriver && sio->activeDriver->deviceId) { - id = sio->activeDriver->deviceId(sio->activeDriver); + if (sio->driver && sio->driver->deviceId) { + id = sio->driver->deviceId(sio->driver); } bool handled = true; @@ -455,8 +374,8 @@ int32_t GBASIOTransferCycles(enum GBASIOMode mode, uint16_t siocnt, int connecte void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) { int id = 0; - if (sio->activeDriver && sio->activeDriver->deviceId) { - id = sio->activeDriver->deviceId(sio->activeDriver); + if (sio->driver && sio->driver->deviceId) { + id = sio->driver->deviceId(sio->driver); } sio->p->memory.io[GBA_REG(SIOMULTI0)] = data[0]; sio->p->memory.io[GBA_REG(SIOMULTI1)] = data[1]; @@ -500,20 +419,20 @@ static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate) } data = {0}; switch (sio->mode) { case GBA_SIO_MULTI: - if (sio->activeDriver && sio->activeDriver->finishMultiplayer) { - sio->activeDriver->finishMultiplayer(sio->activeDriver, data.multi); + if (sio->driver && sio->driver->finishMultiplayer) { + sio->driver->finishMultiplayer(sio->driver, data.multi); } GBASIOMultiplayerFinishTransfer(sio, data.multi, cyclesLate); break; case GBA_SIO_NORMAL_8: - if (sio->activeDriver && sio->activeDriver->finishNormal8) { - data.normal8 = sio->activeDriver->finishNormal8(sio->activeDriver); + if (sio->driver && sio->driver->finishNormal8) { + data.normal8 = sio->driver->finishNormal8(sio->driver); } GBASIONormal8FinishTransfer(sio, data.normal8, cyclesLate); break; case GBA_SIO_NORMAL_32: - if (sio->activeDriver && sio->activeDriver->finishNormal32) { - data.normal32 = sio->activeDriver->finishNormal32(sio->activeDriver); + if (sio->driver && sio->driver->finishNormal32) { + data.normal32 = sio->driver->finishNormal32(sio->driver); } GBASIONormal32FinishTransfer(sio, data.normal32, cyclesLate); break; diff --git a/src/gba/sio/dolphin.c b/src/gba/sio/dolphin.c index e36dfb8a5..0bb783e76 100644 --- a/src/gba/sio/dolphin.c +++ b/src/gba/sio/dolphin.c @@ -23,8 +23,8 @@ enum { }; static bool GBASIODolphinInit(struct GBASIODriver* driver); -static bool GBASIODolphinLoad(struct GBASIODriver* driver); -static bool GBASIODolphinUnload(struct GBASIODriver* driver); +static void GBASIODolphinReset(struct GBASIODriver* driver); +static void GBASIODolphinSetMode(struct GBASIODriver* driver, enum GBASIOMode mode); static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode); static int GBASIODolphinConnectedDevices(struct GBASIODriver* driver); static void GBASIODolphinProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate); @@ -35,8 +35,8 @@ static void _flush(struct GBASIODolphin* dol); void GBASIODolphinCreate(struct GBASIODolphin* dol) { memset(&dol->d, 0, sizeof(dol->d)); dol->d.init = GBASIODolphinInit; - dol->d.load = GBASIODolphinLoad; - dol->d.unload = GBASIODolphinUnload; + dol->d.reset = GBASIODolphinReset; + dol->d.setMode = GBASIODolphinSetMode; dol->d.handlesMode = GBASIODolphinHandlesMode; dol->d.connectedDevices = GBASIODolphinConnectedDevices; dol->event.context = dol; @@ -98,26 +98,23 @@ bool GBASIODolphinConnect(struct GBASIODolphin* dol, const struct Address* addre static bool GBASIODolphinInit(struct GBASIODriver* driver) { struct GBASIODolphin* dol = (struct GBASIODolphin*) driver; - dol->active = false; dol->clockSlice = 0; dol->state = WAIT_FOR_FIRST_CLOCK; - _flush(dol); + GBASIODolphinReset(driver); return true; } -static bool GBASIODolphinLoad(struct GBASIODriver* driver) { +static void GBASIODolphinReset(struct GBASIODriver* driver) { struct GBASIODolphin* dol = (struct GBASIODolphin*) driver; - dol->active = true; + dol->active = false; _flush(dol); mTimingDeschedule(&dol->d.p->p->timing, &dol->event); mTimingSchedule(&dol->d.p->p->timing, &dol->event, 0); - return true; } -static bool GBASIODolphinUnload(struct GBASIODriver* driver) { +static void GBASIODolphinSetMode(struct GBASIODriver* driver, enum GBASIOMode mode) { struct GBASIODolphin* dol = (struct GBASIODolphin*) driver; - dol->active = false; - return true; + dol->active = mode == GBA_SIO_JOYBUS; } static bool GBASIODolphinHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) { diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index 3335905a1..8edd92388 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -55,8 +55,8 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { } void GBASIOPlayerReset(struct GBASIOPlayer* gbp) { - if (gbp->p->sio.drivers.normal == &gbp->d) { - GBASIOSetDriver(&gbp->p->sio, NULL, GBA_SIO_NORMAL_32); + if (gbp->p->sio.driver == &gbp->d) { + GBASIOSetDriver(&gbp->p->sio, NULL); } } @@ -88,7 +88,7 @@ void GBASIOPlayerUpdate(struct GBA* gba) { gba->sio.gbp.oldCallback = gba->keyCallback; gba->keyCallback = &gba->sio.gbp.callback.d; // TODO: Check if the SIO driver is actually used first - GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, GBA_SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d); } } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 074b7d0e8..f71f9b323 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -79,8 +79,6 @@ static_assert(sizeof(struct GBASIOLockstepSerializedState) == 0x1F0, "GBA lockst static bool GBASIOLockstepDriverInit(struct GBASIODriver* driver); static void GBASIOLockstepDriverDeinit(struct GBASIODriver* driver); static void GBASIOLockstepDriverReset(struct GBASIODriver* driver); -static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver); -static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver); static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver); static bool GBASIOLockstepDriverLoadState(struct GBASIODriver* driver, const void* state, size_t size); static void GBASIOLockstepDriverSaveState(struct GBASIODriver* driver, void** state, size_t* size); @@ -119,8 +117,6 @@ void GBASIOLockstepDriverCreate(struct GBASIOLockstepDriver* driver, struct mLoc driver->d.init = GBASIOLockstepDriverInit; driver->d.deinit = GBASIOLockstepDriverDeinit; driver->d.reset = GBASIOLockstepDriverReset; - driver->d.load = GBASIOLockstepDriverLoad; - driver->d.unload = GBASIOLockstepDriverUnload; driver->d.driverId = GBASIOLockstepDriverId; driver->d.loadState = GBASIOLockstepDriverLoadState; driver->d.saveState = GBASIOLockstepDriverSaveState; @@ -220,27 +216,6 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { mTimingSchedule(&lockstep->d.p->p->timing, &lockstep->event, nextEvent); } -static bool GBASIOLockstepDriverLoad(struct GBASIODriver* driver) { - struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; - if (lockstep->lockstepId) { - struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; - MutexLock(&coordinator->mutex); - struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); - _setReady(coordinator, player, 0, coordinator->transferMode); - MutexUnlock(&coordinator->mutex); - GBASIOLockstepDriverSetMode(driver, driver->p->mode); - } - return true; -} - -static bool GBASIOLockstepDriverUnload(struct GBASIODriver* driver) { - struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; - if (lockstep->lockstepId) { - GBASIOLockstepDriverSetMode(driver, -1); - } - return true; -} - static uint32_t GBASIOLockstepDriverId(const struct GBASIODriver* driver) { UNUSED(driver); return DRIVER_ID; diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 08b96bd81..032bdbc4f 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -424,7 +424,7 @@ bool CoreController::attachDolphin(const Address& address) { } if (GBASIODolphinConnect(&m_dolphin, &address, 0, 0)) { GBA* gba = static_cast(m_threadContext.core->board); - GBASIOSetDriver(&gba->sio, &m_dolphin.d, GBA_SIO_JOYBUS); + GBASIOSetDriver(&gba->sio, &m_dolphin.d); return true; } return false; @@ -433,7 +433,8 @@ bool CoreController::attachDolphin(const Address& address) { void CoreController::detachDolphin() { if (platform() == mPLATFORM_GBA) { GBA* gba = static_cast(m_threadContext.core->board); - GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_JOYBUS); + // TODO: Reattach to multiplayer controller + GBASIOSetDriver(&gba->sio, nullptr); } GBASIODolphinDestroy(&m_dolphin); } diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index c142fe126..616a252b5 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -265,9 +265,7 @@ bool MultiplayerController::attachGame(CoreController* controller) { GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, node); player.node.gba = node; - GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_MULTI); - GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_8); - GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, &node->d); break; } #endif @@ -356,10 +354,8 @@ void MultiplayerController::detachGame(CoreController* controller) { #ifdef M_CORE_GBA case mPLATFORM_GBA: { GBA* gba = static_cast(thread->core->board); - GBASIOLockstepDriver* node = reinterpret_cast(gba->sio.drivers.multiplayer); - GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_MULTI); - GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_8); - GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_32); + GBASIOLockstepDriver* node = reinterpret_cast(gba->sio.driver); + GBASIOSetDriver(&gba->sio, nullptr); if (node) { GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, node); delete node->user; @@ -485,12 +481,13 @@ void MultiplayerController::fixOrder() { switch (m_platform) { #ifdef M_CORE_GBA case mPLATFORM_GBA: - for (int pid : m_pids.keys()) { + // TODO: fix + /*for (int pid : m_pids.keys()) { Player& p = m_pids.find(pid).value(); GBA* gba = static_cast(p.controller->thread()->core->board); - GBASIOLockstepDriver* node = reinterpret_cast(gba->sio.drivers.multiplayer); + GBASIOLockstepDriver* node = reinterpret_cast(gba->sio.driver); m_players[node->d.deviceId(&node->d)] = pid; - } + }*/ break; #endif #ifdef M_CORE_GB From 7fa572e3ff39164c64a453646a0a74d43f21720c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 11 Sep 2024 02:02:38 -0700 Subject: [PATCH 302/336] GBA SIO: Split lockstep interval for linked and unlinked times --- src/gba/sio/lockstep.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index f71f9b323..7d6f921d9 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -10,7 +10,8 @@ #define DRIVER_ID 0x6B636F4C #define DRIVER_STATE_VERSION 1 -#define LOCKSTEP_INCREMENT 2000 +#define LOCKSTEP_INTERVAL 2048 +#define UNLOCKED_INTERVAL 4096 #define TARGET(P) (1 << (P)) #define TARGET_ALL 0xF #define TARGET_PRIMARY 0x1 @@ -186,7 +187,7 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { } _reconfigPlayers(coordinator); if (player->playerId != 0) { - player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle + LOCKSTEP_INCREMENT; + player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle + LOCKSTEP_INTERVAL; struct GBASIOLockstepEvent event = { .type = SIO_EV_ATTACH, .playerId = player->playerId, @@ -207,7 +208,7 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { _setReady(coordinator, player, player->playerId, player->mode); if (TableSize(&coordinator->players) == 1) { coordinator->cycle = mTimingCurrentTime(&lockstep->d.p->p->timing); - nextEvent = LOCKSTEP_INCREMENT; + nextEvent = LOCKSTEP_INTERVAL; } else { _setReady(coordinator, player, 0, coordinator->transferMode); nextEvent = _untilNextSync(lockstep->coordinator, player); @@ -629,7 +630,11 @@ void GBASIOLockstepCoordinatorDetach(struct GBASIOLockstepCoordinator* coordinat int32_t _untilNextSync(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { int32_t cycle = coordinator->cycle - GBASIOLockstepTime(player); if (player->playerId == 0) { - cycle += LOCKSTEP_INCREMENT; + if (coordinator->nAttached < 2) { + cycle += UNLOCKED_INTERVAL; + } else { + cycle += LOCKSTEP_INTERVAL; + } } return cycle; } @@ -921,7 +926,7 @@ void _lockstepEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) nextEvent = player->queue->timestamp - GBASIOLockstepTime(player); } - if (player->playerId != 0 && nextEvent <= LOCKSTEP_INCREMENT) { + if (player->playerId != 0 && nextEvent <= LOCKSTEP_INTERVAL) { if (!player->queue || wasDetach) { GBASIOLockstepPlayerSleep(player); // XXX: Is there a better way to gain sync lock at the beginning? From 5db42e83c97d705a0a1d564148458bf29082c4bc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 12 Sep 2024 02:13:38 -0700 Subject: [PATCH 303/336] Qt: Delay attaching SIO driver until a second player is connected --- src/platform/qt/MultiplayerController.cpp | 39 ++++++++++++++++------- src/platform/qt/MultiplayerController.h | 1 + 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index 616a252b5..0d12359bb 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -201,7 +201,8 @@ bool MultiplayerController::attachGame(CoreController* controller) { interrupters.append(p.controller); } - if (attached() == 0) { + bool doDelayedAttach = false; + if (m_platform == mPLATFORM_NONE) { switch (controller->platform()) { #ifdef M_CORE_GBA case mPLATFORM_GBA: @@ -242,8 +243,6 @@ bool MultiplayerController::attachGame(CoreController* controller) { return false; } - GBA* gba = static_cast(thread->core->board); - GBASIOLockstepDriver* node = new GBASIOLockstepDriver; LockstepUser* user = new LockstepUser; mLockstepThreadUserInit(user, thread); @@ -262,10 +261,11 @@ bool MultiplayerController::attachGame(CoreController* controller) { }; GBASIOLockstepDriverCreate(node, &user->d); - GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, node); player.node.gba = node; - GBASIOSetDriver(&gba->sio, &node->d); + if (m_pids.size()) { + doDelayedAttach = true; + } break; } #endif @@ -281,6 +281,7 @@ bool MultiplayerController::attachGame(CoreController* controller) { GBSIOLockstepNodeCreate(node); GBSIOLockstepAttachNode(&m_gbLockstep, node); player.node.gb = node; + player.attached = true; GBSIOSetDriver(&gb->sio, &node->d); break; @@ -320,6 +321,19 @@ bool MultiplayerController::attachGame(CoreController* controller) { ++m_nextPid; fixOrder(); + if (doDelayedAttach) { + for (auto pid: m_players) { + Player& player = m_pids.find(pid).value(); + if (player.attached) { + continue; + } + GBA* gba = static_cast(player.controller->thread()->core->board); + GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, player.node.gba); + GBASIOSetDriver(&gba->sio, &player.node.gba->d); + player.attached = true; + } + } + emit gameAttached(); return true; } @@ -354,13 +368,16 @@ void MultiplayerController::detachGame(CoreController* controller) { #ifdef M_CORE_GBA case mPLATFORM_GBA: { GBA* gba = static_cast(thread->core->board); - GBASIOLockstepDriver* node = reinterpret_cast(gba->sio.driver); - GBASIOSetDriver(&gba->sio, nullptr); - if (node) { - GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, node); - delete node->user; - delete node; + Player& p = m_pids.find(pid).value(); + GBASIODriver* node = gba->sio.driver; + if (node == &p.node.gba->d) { + GBASIOSetDriver(&gba->sio, nullptr); } + if (p.attached) { + GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, p.node.gba); + } + delete p.node.gba->user; + delete p.node.gba; break; } #endif diff --git a/src/platform/qt/MultiplayerController.h b/src/platform/qt/MultiplayerController.h index 9eaf20b16..666cb390b 100644 --- a/src/platform/qt/MultiplayerController.h +++ b/src/platform/qt/MultiplayerController.h @@ -64,6 +64,7 @@ private: unsigned waitMask = 0; int saveId = 1; int preferredId = 0; + bool attached = false; }; struct LockstepUser : mLockstepThreadUser { MultiplayerController* controller; From 1d584edb77db9693e050d0b00dda2b06d9582c1c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 12 Sep 2024 02:44:26 -0700 Subject: [PATCH 304/336] GBA: Expose setting the link port device as a peripheral --- include/mgba/gba/interface.h | 2 +- src/gba/core.c | 2 +- src/platform/qt/CoreController.cpp | 11 +++++------ src/platform/qt/MultiplayerController.cpp | 6 +++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 9b8f6e001..cbbb4d23a 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -81,7 +81,7 @@ extern MGBA_EXPORT const int GBA_LUX_LEVELS[10]; enum { mPERIPH_GBA_LUMINANCE = 0x1000, - mPERIPH_GBA_BATTLECHIP_GATE, + mPERIPH_GBA_LINK_PORT, }; struct GBACartridgeOverride { diff --git a/src/gba/core.c b/src/gba/core.c index 898745e9e..67550bd7a 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -962,7 +962,7 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { case mPERIPH_GBA_LUMINANCE: gba->luminanceSource = periph; break; - case mPERIPH_GBA_BATTLECHIP_GATE: + case mPERIPH_GBA_LINK_PORT: GBASIOSetDriver(&gba->sio, periph); break; default: diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 032bdbc4f..807a86685 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -423,8 +423,8 @@ bool CoreController::attachDolphin(const Address& address) { return false; } if (GBASIODolphinConnect(&m_dolphin, &address, 0, 0)) { - GBA* gba = static_cast(m_threadContext.core->board); - GBASIOSetDriver(&gba->sio, &m_dolphin.d); + clearMultiplayerController(); + m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_LINK_PORT, &m_dolphin.d); return true; } return false; @@ -432,9 +432,8 @@ bool CoreController::attachDolphin(const Address& address) { void CoreController::detachDolphin() { if (platform() == mPLATFORM_GBA) { - GBA* gba = static_cast(m_threadContext.core->board); // TODO: Reattach to multiplayer controller - GBASIOSetDriver(&gba->sio, nullptr); + m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_LINK_PORT, NULL); } GBASIODolphinDestroy(&m_dolphin); } @@ -1095,7 +1094,7 @@ void CoreController::attachBattleChipGate() { Interrupter interrupter(this); clearMultiplayerController(); GBASIOBattlechipGateCreate(&m_battlechip); - m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_BATTLECHIP_GATE, &m_battlechip); + m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_LINK_PORT, &m_battlechip); } void CoreController::detachBattleChipGate() { @@ -1103,7 +1102,7 @@ void CoreController::detachBattleChipGate() { return; } Interrupter interrupter(this); - m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_BATTLECHIP_GATE, nullptr); + m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_LINK_PORT, nullptr); } void CoreController::setBattleChipId(uint16_t id) { diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index 0d12359bb..5839b0f84 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -327,9 +327,9 @@ bool MultiplayerController::attachGame(CoreController* controller) { if (player.attached) { continue; } - GBA* gba = static_cast(player.controller->thread()->core->board); + struct mCore* core = player.controller->thread()->core; GBASIOLockstepCoordinatorAttach(&m_gbaCoordinator, player.node.gba); - GBASIOSetDriver(&gba->sio, &player.node.gba->d); + core->setPeripheral(core, mPERIPH_GBA_LINK_PORT, &player.node.gba->d); player.attached = true; } } @@ -371,7 +371,7 @@ void MultiplayerController::detachGame(CoreController* controller) { Player& p = m_pids.find(pid).value(); GBASIODriver* node = gba->sio.driver; if (node == &p.node.gba->d) { - GBASIOSetDriver(&gba->sio, nullptr); + thread->core->setPeripheral(thread->core, mPERIPH_GBA_LINK_PORT, NULL); } if (p.attached) { GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, p.node.gba); From 39d90e5e443cd41c68b4562b66d08fc40ff1fe57 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 13 Sep 2024 01:13:48 -0700 Subject: [PATCH 305/336] GBA SIO: Only set up GBP driver if no other driver is loaded --- src/gba/sio/gbp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index 8edd92388..977e67de4 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -87,8 +87,9 @@ void GBASIOPlayerUpdate(struct GBA* gba) { gba->sio.gbp.inputsPosted = 0; gba->sio.gbp.oldCallback = gba->keyCallback; gba->keyCallback = &gba->sio.gbp.callback.d; - // TODO: Check if the SIO driver is actually used first - GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d); + if (!gba->sio.driver) { + GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d); + } } } From 79ed790a4e397451d810824f86c50e322fb1ec08 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 15 Sep 2024 04:43:18 -0700 Subject: [PATCH 306/336] GBA IO: Fix SIOCNT/RCNT serialization --- src/gba/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gba/io.c b/src/gba/io.c index d29fb8a4b..8a4ea7fc2 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -214,8 +214,8 @@ static const int _isRSpecialRegister[GBA_REG(INTERNAL_MAX)] = { /* 10 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 11 */ 0, 0, 0, 0, 0, 0, 0, 0, /* SIO */ - /* 12 */ 1, 1, 1, 1, 1, 0, 0, 0, - /* 13 */ 1, 1, 1, 0, 0, 0, 0, 0, + /* 12 */ 1, 1, 1, 1, 0, 0, 0, 0, + /* 13 */ 1, 1, 0, 0, 0, 0, 0, 0, /* 14 */ 1, 0, 0, 0, 0, 0, 0, 0, /* 15 */ 1, 1, 1, 1, 1, 0, 0, 0, /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, From 2c1fcf96915523fa527fb97df672c1b70f43962b Mon Sep 17 00:00:00 2001 From: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Sat, 28 Sep 2024 08:55:21 -0700 Subject: [PATCH 307/336] Fix savestates not writing back GPIO variables to gpioBase Resolves #3294 Also see https://github.com/TASEmulators/BizHawk/issues/4060 (this is fixed with this patch). --- src/gba/cart/gpio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index fde4e3714..15f082849 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -465,6 +465,18 @@ void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASeria STORE_16(hw->direction, 0, &state->hw.pinDirection); state->hw.devices = hw->devices; + if (hw->gpioBase) { + if (hw->readWrite) { + STORE_16(hw->pinState, 0, hw->gpioBase); + STORE_16(hw->direction, 2, hw->gpioBase); + STORE_16(hw->readWrite, 4, hw->gpioBase); + } else { + hw->gpioBase[0] = 0; + hw->gpioBase[1] = 0; + hw->gpioBase[2] = 0; + } + } + STORE_32(hw->rtc.bytesRemaining, 0, &state->hw.rtcBytesRemaining); STORE_32(hw->rtc.transferStep, 0, &state->hw.rtcTransferStep); STORE_32(hw->rtc.bitsRead, 0, &state->hw.rtcBitsRead); From a26971cdc7fe564a572a06e7320e115cc959895d Mon Sep 17 00:00:00 2001 From: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:39:19 -0700 Subject: [PATCH 308/336] This should be in Deserialize not Serialize --- src/gba/cart/gpio.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index 15f082849..562a42b63 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -465,18 +465,6 @@ void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASeria STORE_16(hw->direction, 0, &state->hw.pinDirection); state->hw.devices = hw->devices; - if (hw->gpioBase) { - if (hw->readWrite) { - STORE_16(hw->pinState, 0, hw->gpioBase); - STORE_16(hw->direction, 2, hw->gpioBase); - STORE_16(hw->readWrite, 4, hw->gpioBase); - } else { - hw->gpioBase[0] = 0; - hw->gpioBase[1] = 0; - hw->gpioBase[2] = 0; - } - } - STORE_32(hw->rtc.bytesRemaining, 0, &state->hw.rtcBytesRemaining); STORE_32(hw->rtc.transferStep, 0, &state->hw.rtcTransferStep); STORE_32(hw->rtc.bitsRead, 0, &state->hw.rtcBitsRead); @@ -514,6 +502,18 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer LOAD_16(hw->direction, 0, &state->hw.pinDirection); hw->devices = state->hw.devices; + if (hw->gpioBase) { + if (hw->readWrite) { + STORE_16(hw->pinState, 0, hw->gpioBase); + STORE_16(hw->direction, 2, hw->gpioBase); + STORE_16(hw->readWrite, 4, hw->gpioBase); + } else { + hw->gpioBase[0] = 0; + hw->gpioBase[1] = 0; + hw->gpioBase[2] = 0; + } + } + LOAD_32(hw->rtc.bytesRemaining, 0, &state->hw.rtcBytesRemaining); LOAD_32(hw->rtc.transferStep, 0, &state->hw.rtcTransferStep); LOAD_32(hw->rtc.bitsRead, 0, &state->hw.rtcBitsRead); From 4008ccea3d1fcdfee476fcdc0a3511f3206a9a21 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 29 Sep 2024 01:00:32 -0700 Subject: [PATCH 309/336] CHANGES: Update --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 9a1694d69..b30f3c95f 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,7 @@ Emulation fixes: - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA I/O: Fix audio register 8-bit write behavior (fixes mgba.io/i/3086) - GBA Serialize: Fix some minor save state edge cases + - GBA Serialize: Properly restore GPIO register state (fixes mgba.io/i/3294) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) - GBA Video: Improve emulation of window start/end conditions (fixes mgba.io/i/1945) From 7089a5572b21e9ba82448538b40cd31e9a538f19 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 17 Sep 2024 00:35:31 -0700 Subject: [PATCH 310/336] GBA SIO: Add periodic hard sync so the runner doesn't get too ahead --- include/mgba/internal/gba/sio/lockstep.h | 1 + src/gba/sio/lockstep.c | 26 +++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/mgba/internal/gba/sio/lockstep.h b/include/mgba/internal/gba/sio/lockstep.h index 7baed0693..0053e6b94 100644 --- a/include/mgba/internal/gba/sio/lockstep.h +++ b/include/mgba/internal/gba/sio/lockstep.h @@ -41,6 +41,7 @@ struct GBASIOLockstepCoordinator { enum GBASIOMode transferMode; int32_t cycle; + int32_t nextHardSync; uint16_t multiData[4]; uint32_t normalData[4]; diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 7d6f921d9..d1375c8a0 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -12,6 +12,7 @@ #define DRIVER_STATE_VERSION 1 #define LOCKSTEP_INTERVAL 2048 #define UNLOCKED_INTERVAL 4096 +#define HARD_SYNC_INTERVAL 0x80000 #define TARGET(P) (1 << (P)) #define TARGET_ALL 0xF #define TARGET_PRIMARY 0x1 @@ -67,7 +68,8 @@ struct GBASIOLockstepSerializedState { struct { int32_t cycle; uint32_t waiting; - uint32_t reservedCoordinator[4]; + int32_t nextHardSync; + uint32_t reservedCoordinator[3]; uint16_t multiData[4]; uint32_t normalData[4]; } coordinator; @@ -159,9 +161,10 @@ static void GBASIOLockstepDriverDeinit(struct GBASIODriver* driver) { static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { struct GBASIOLockstepDriver* lockstep = (struct GBASIOLockstepDriver*) driver; struct GBASIOLockstepCoordinator* coordinator = lockstep->coordinator; + struct GBASIOLockstepPlayer* player; if (!lockstep->lockstepId) { - struct GBASIOLockstepPlayer* player = calloc(1, sizeof(*player)); unsigned id; + player = calloc(1, sizeof(*player)); player->driver = lockstep; player->mode = driver->p->mode; player->playerId = -1; @@ -195,16 +198,19 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { }; _enqueueEvent(coordinator, &event, TARGET_ALL & ~TARGET(player->playerId)); } - MutexUnlock(&coordinator->mutex); + } else { + player = TableLookup(&coordinator->players, lockstep->lockstepId); + if (player->playerId != 0) { + player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle + LOCKSTEP_INTERVAL; + } } if (mTimingIsScheduled(&lockstep->d.p->p->timing, &lockstep->event)) { + MutexUnlock(&coordinator->mutex); return; } int32_t nextEvent; - MutexLock(&coordinator->mutex); - struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, lockstep->lockstepId); _setReady(coordinator, player, player->playerId, player->mode); if (TableSize(&coordinator->players) == 1) { coordinator->cycle = mTimingCurrentTime(&lockstep->d.p->p->timing); @@ -341,6 +347,7 @@ static bool GBASIOLockstepDriverLoadState(struct GBASIODriver* driver, const voi if (player->playerId == 0) { LOAD_32LE(coordinator->cycle, 0, &state->coordinator.cycle); LOAD_32LE(coordinator->waiting, 0, &state->coordinator.waiting); + LOAD_32LE(coordinator->nextHardSync, 0, &state->coordinator.nextHardSync); for (i = 0; i < 4; ++i) { LOAD_16LE(coordinator->multiData[i], 0, &state->coordinator.multiData[i]); LOAD_32LE(coordinator->normalData[i], 0, &state->coordinator.normalData[i]); @@ -406,6 +413,7 @@ static void GBASIOLockstepDriverSaveState(struct GBASIODriver* driver, void** st if (player->playerId == 0) { STORE_32LE(coordinator->cycle, 0, &state->coordinator.cycle); STORE_32LE(coordinator->waiting, 0, &state->coordinator.waiting); + STORE_32LE(coordinator->nextHardSync, 0, &state->coordinator.nextHardSync); for (i = 0; i < 4; ++i) { STORE_16LE(coordinator->multiData[i], 0, &state->coordinator.multiData[i]); STORE_32LE(coordinator->normalData[i], 0, &state->coordinator.normalData[i]); @@ -643,6 +651,7 @@ void _advanceCycle(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOL int32_t newCycle = GBASIOLockstepTime(player); mASSERT(newCycle - coordinator->cycle >= 0); //mLOG(GBA_SIO, DEBUG, "Advancing from cycle %08X to %08X (%i cycles)", coordinator->cycle, newCycle, newCycle - coordinator->cycle); + coordinator->nextHardSync -= newCycle - coordinator->cycle; coordinator->cycle = newCycle; } @@ -674,6 +683,7 @@ void _reconfigPlayers(struct GBASIOLockstepCoordinator* coordinator) { struct GBASIOLockstepPlayer* player = TableIteratorGetValue(&coordinator->players, &iter); coordinator->cycle = mTimingCurrentTime(&player->driver->d.p->p->timing); + coordinator->nextHardSync = HARD_SYNC_INTERVAL; if (player->playerId != 0) { player->playerId = 0; @@ -859,6 +869,12 @@ void _lockstepEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) if (!coordinator->transferActive) { GBASIOLockstepCoordinatorWakePlayers(coordinator); } + if (coordinator->nextHardSync < 0) { + if (!coordinator->waiting) { + _hardSync(coordinator, player); + } + coordinator->nextHardSync += HARD_SYNC_INTERVAL; + } } int32_t nextEvent = _untilNextSync(coordinator, player); From 3f7cfb3e32775919c803c105c08b23a3dd33093f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Sep 2024 01:47:16 -0700 Subject: [PATCH 311/336] GBA SIO: Attempt to clean up resyncing on disconnects --- src/gba/sio/lockstep.c | 46 +++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index d1375c8a0..e73dcbb09 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -115,6 +115,23 @@ static void _hardSync(struct GBASIOLockstepCoordinator*, struct GBASIOLockstepPl static void _lockstepEvent(struct mTiming*, void* context, uint32_t cyclesLate); +static void _verifyAwake(struct GBASIOLockstepCoordinator* coordinator) { +#ifdef NDEBUG + UNUSED(coordinator); +#else + int i; + int asleep = 0; + for (i = 0; i < coordinator->nAttached; ++i) { + if (!coordinator->attachedPlayers[i]) { + continue; + } + struct GBASIOLockstepPlayer* player = TableLookup(&coordinator->players, coordinator->attachedPlayers[i]); + asleep += player->asleep; + } + mASSERT_DEBUG(!asleep || asleep < coordinator->nAttached); +#endif +} + void GBASIOLockstepDriverCreate(struct GBASIOLockstepDriver* driver, struct mLockstepUser* user) { memset(driver, 0, sizeof(*driver)); driver->d.init = GBASIOLockstepDriverInit; @@ -189,8 +206,8 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { } } _reconfigPlayers(coordinator); + player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle; if (player->playerId != 0) { - player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle + LOCKSTEP_INTERVAL; struct GBASIOLockstepEvent event = { .type = SIO_EV_ATTACH, .playerId = player->playerId, @@ -200,9 +217,7 @@ static void GBASIOLockstepDriverReset(struct GBASIODriver* driver) { } } else { player = TableLookup(&coordinator->players, lockstep->lockstepId); - if (player->playerId != 0) { - player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle + LOCKSTEP_INTERVAL; - } + player->cycleOffset = mTimingCurrentTime(&driver->p->p->timing) - coordinator->cycle; } if (mTimingIsScheduled(&lockstep->d.p->p->timing, &lockstep->event)) { @@ -662,12 +677,18 @@ void _removePlayer(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOL .timestamp = GBASIOLockstepTime(player), }; _enqueueEvent(coordinator, &event, TARGET_ALL & ~TARGET(player->playerId)); - GBASIOLockstepCoordinatorWakePlayers(coordinator); - if (player->playerId != 0) { - GBASIOLockstepCoordinatorAckPlayer(coordinator, player); - } + + coordinator->waiting = 0; + coordinator->transferActive = false; + TableRemove(&coordinator->players, player->driver->lockstepId); _reconfigPlayers(coordinator); + + struct GBASIOLockstepPlayer* runner = TableLookup(&coordinator->players, coordinator->attachedPlayers[0]); + if (runner) { + GBASIOLockstepPlayerWake(runner); + } + _verifyAwake(coordinator); } void _reconfigPlayers(struct GBASIOLockstepCoordinator* coordinator) { @@ -863,8 +884,10 @@ void _lockstepEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) player->queue->playerId, player->queue->timestamp); wasDetach = true; } - if (player->playerId == 0) { - // We are the clock owner; advance the shared clock + if (player->playerId == 0 && GBASIOLockstepTime(player) - coordinator->cycle >= 0) { + // We are the clock owner; advance the shared clock. However, if we just became + // the clock owner (by the previous one disconnecting) we might be slightly + // behind the shared clock. We should wait a bit if needed in that case. _advanceCycle(coordinator, player); if (!coordinator->transferActive) { GBASIOLockstepCoordinatorWakePlayers(coordinator); @@ -949,6 +972,7 @@ void _lockstepEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) if (nextEvent < 4) { nextEvent = 4; } + _verifyAwake(coordinator); } } MutexUnlock(&coordinator->mutex); @@ -974,6 +998,8 @@ void GBASIOLockstepCoordinatorWaitOnPlayers(struct GBASIOLockstepCoordinator* co coordinator->waiting = ((1 << coordinator->nAttached) - 1) & ~TARGET(player->playerId); GBASIOLockstepPlayerSleep(player); GBASIOLockstepCoordinatorWakePlayers(coordinator); + + _verifyAwake(coordinator); } void GBASIOLockstepCoordinatorWakePlayers(struct GBASIOLockstepCoordinator* coordinator) { From f0d65b73e81a39208e6305127185a0792b844460 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 17 Sep 2024 00:18:58 -0700 Subject: [PATCH 312/336] GBA SIO: Late cleanup --- src/gba/sio/lockstep.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index e73dcbb09..a429a31e2 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -10,7 +10,7 @@ #define DRIVER_ID 0x6B636F4C #define DRIVER_STATE_VERSION 1 -#define LOCKSTEP_INTERVAL 2048 +#define LOCKSTEP_INTERVAL 4096 #define UNLOCKED_INTERVAL 4096 #define HARD_SYNC_INTERVAL 0x80000 #define TARGET(P) (1 << (P)) @@ -457,7 +457,7 @@ static void GBASIOLockstepDriverSetMode(struct GBASIODriver* driver, enum GBASIO .mode = mode, }; if (player->playerId == 0) { - mASSERT(!coordinator->transferActive); // TODO + mASSERT_DEBUG(!coordinator->transferActive); // TODO coordinator->transferMode = mode; GBASIOLockstepCoordinatorWaitOnPlayers(coordinator, player); } @@ -664,8 +664,7 @@ int32_t _untilNextSync(struct GBASIOLockstepCoordinator* coordinator, struct GBA void _advanceCycle(struct GBASIOLockstepCoordinator* coordinator, struct GBASIOLockstepPlayer* player) { int32_t newCycle = GBASIOLockstepTime(player); - mASSERT(newCycle - coordinator->cycle >= 0); - //mLOG(GBA_SIO, DEBUG, "Advancing from cycle %08X to %08X (%i cycles)", coordinator->cycle, newCycle, newCycle - coordinator->cycle); + mASSERT_DEBUG(newCycle - coordinator->cycle >= 0); coordinator->nextHardSync -= newCycle - coordinator->cycle; coordinator->cycle = newCycle; } @@ -810,7 +809,6 @@ static void _setData(struct GBASIOLockstepCoordinator* coordinator, uint32_t id, case GBA_SIO_JOYBUS: mLOG(GBA_SIO, ERROR, "Unsupported mode %i in lockstep", coordinator->transferMode); // TODO: Should we handle this or just abort? - abort(); break; } } @@ -901,7 +899,6 @@ void _lockstepEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) } int32_t nextEvent = _untilNextSync(coordinator, player); - //mASSERT_DEBUG(nextEvent + cyclesLate > 0); while (true) { struct GBASIOLockstepEvent* event = player->queue; if (!event) { @@ -1003,7 +1000,6 @@ void GBASIOLockstepCoordinatorWaitOnPlayers(struct GBASIOLockstepCoordinator* co } void GBASIOLockstepCoordinatorWakePlayers(struct GBASIOLockstepCoordinator* coordinator) { - //mLOG(GBA_SIO, DEBUG, "Waking all secondary players"); int i; for (i = 1; i < coordinator->nAttached; ++i) { if (!coordinator->attachedPlayers[i]) { @@ -1026,7 +1022,6 @@ void GBASIOLockstepCoordinatorAckPlayer(struct GBASIOLockstepCoordinator* coordi if (player->playerId == 0) { return; } - mLOG(GBA_SIO, DEBUG, "Player %i acking primary", player->playerId); coordinator->waiting &= ~TARGET(player->playerId); if (!coordinator->waiting) { mLOG(GBA_SIO, DEBUG, "All players acked, waking primary"); @@ -1053,7 +1048,6 @@ void GBASIOLockstepPlayerSleep(struct GBASIOLockstepPlayer* player) { if (player->asleep) { return; } - //mLOG(GBA_SIO, DEBUG, "Player %i going to sleep with %i cycles until sync", player->playerId, _untilNextSync(coordinator, player)); player->asleep = true; player->driver->user->sleep(player->driver->user); player->driver->d.p->p->cpu->nextEvent = 0; From ed0a63d1b812611fa3832e5af1722037a9916e3d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 29 Sep 2024 20:09:48 -0700 Subject: [PATCH 313/336] Python: Attempt to fix build --- src/platform/python/_builder.h | 1 - src/platform/python/_builder.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index 0b51eb19d..ad12c107e 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -46,7 +46,6 @@ void free(void*); #define PYEXPORT extern "Python+C" #include "platform/python/core.h" #include "platform/python/log.h" -#include "platform/python/sio.h" #include "platform/python/vfs-py.h" #undef PYEXPORT diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index 1defca537..e144b6a51 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -45,7 +45,6 @@ ffi.set_source("mgba._pylib", """ #define PYEXPORT #include "platform/python/core.h" #include "platform/python/log.h" -#include "platform/python/sio.h" #include "platform/python/vfs-py.h" #undef PYEXPORT """, include_dirs=[incdir, srcdir], From 36f321f84889bc69b48541e0519401c091eeaeca Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 29 Sep 2024 20:27:00 -0700 Subject: [PATCH 314/336] Python: Actually fix build --- src/platform/python/_builder.h | 3 +-- src/platform/python/_builder.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index ad12c107e..c39fcf143 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -22,8 +22,7 @@ #define CXX_GUARD_END #define PYCPARSE -#define va_list void* - +typedef ... va_list; typedef int... time_t; typedef int... off_t; typedef ...* png_structp; diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index e144b6a51..f18a3c95e 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -52,7 +52,7 @@ ffi.set_source("mgba._pylib", """ libraries=["mgba"], library_dirs=[bindir], runtime_library_dirs=[libdir], - sources=[os.path.join(pydir, path) for path in ["vfs-py.c", "core.c", "log.c", "sio.c"]]) + sources=[os.path.join(pydir, path) for path in ["vfs-py.c", "core.c", "log.c"]]) preprocessed = subprocess.check_output(cpp + ["-fno-inline", "-P"] + cppflags + [os.path.join(pydir, "_builder.h")], universal_newlines=True) From 8941f742927226c822ab0879347558aea6aa9b6e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 29 Sep 2024 20:13:11 -0700 Subject: [PATCH 315/336] Qt: Add missing tr()s --- src/platform/qt/MultiplayerController.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index 5839b0f84..3b2146f7a 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -401,7 +401,7 @@ void MultiplayerController::detachGame(CoreController* controller) { QPair path(controller->path(), controller->baseDirectory()); Player& p = m_pids.find(pid).value(); if (!p.saveId) { - LOG(QT, WARN) << "Clearing invalid save ID"; + LOG(QT, WARN) << tr("Clearing invalid save ID"); } else { m_claimedSaves[path] &= ~(1 << (p.saveId - 1)); if (!m_claimedSaves[path]) { @@ -410,7 +410,7 @@ void MultiplayerController::detachGame(CoreController* controller) { } if (p.preferredId < 0) { - LOG(QT, WARN) << "Clearing invalid preferred ID"; + LOG(QT, WARN) << tr("Clearing invalid preferred ID"); } else { m_claimedIds &= ~(1 << p.preferredId); } From bfc52cd2f0156d82add7d634e107b68552cac538 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 30 Sep 2024 17:24:04 -0700 Subject: [PATCH 316/336] All: Fix whitespace errors --- include/mgba-util/geometry.h | 12 +++++----- include/mgba/feature/proxy-backend.h | 2 +- include/mgba/internal/defines.h | 24 +++++++++---------- src/arm/isa-thumb.c | 2 +- src/core/cheats.c | 2 +- src/core/thread.c | 2 +- src/feature/ffmpeg/ffmpeg-decoder.c | 2 +- src/feature/ffmpeg/ffmpeg-encoder.c | 2 +- src/feature/gui/gui-config.c | 2 +- src/feature/updater.c | 2 +- src/feature/video-logger.c | 6 ++--- src/gb/core.c | 2 +- src/gb/extra/proxy.c | 2 +- src/gb/gb.c | 4 ++-- src/gb/mbc.c | 2 +- src/gb/mbc/tama5.c | 2 +- src/gb/mbc/unlicensed.c | 10 ++++---- src/gb/video.c | 2 +- src/gba/extra/proxy.c | 2 +- src/gba/serialize.c | 2 +- src/platform/3ds/ctr-gpu.c | 2 +- src/platform/example/client-server/server.c | 2 +- src/platform/opengl/gl.c | 4 ++-- src/platform/opengl/gles2.c | 4 ++-- src/platform/psp2/psp2-common.h | 2 +- src/platform/qt/BattleChipView.cpp | 2 +- src/platform/qt/ConfigController.h | 2 +- src/platform/qt/DebuggerConsoleController.cpp | 2 +- src/platform/qt/Display.h | 2 +- src/platform/qt/DisplayGL.cpp | 2 +- src/platform/qt/ForwarderController.cpp | 4 ++-- src/platform/qt/ForwarderView.cpp | 6 ++--- src/platform/qt/MemorySearch.cpp | 2 +- src/platform/qt/SaveConverter.cpp | 16 ++++++------- src/platform/qt/TilePainter.cpp | 2 +- src/platform/qt/TileView.cpp | 4 ++-- src/platform/qt/Window.cpp | 6 ++--- src/platform/qt/library/LibraryTree.cpp | 2 +- .../qt/scripting/ScriptingTextBuffer.cpp | 2 +- src/script/engines/lua.c | 2 +- src/script/types.c | 2 +- src/tools/font-sdf.c | 2 +- src/util/audio-resampler.c | 2 +- src/util/crc32.c | 2 +- src/util/hash.c | 6 ++--- src/util/sfo.c | 2 +- 46 files changed, 86 insertions(+), 86 deletions(-) diff --git a/include/mgba-util/geometry.h b/include/mgba-util/geometry.h index aa7d65e94..5164b0b8d 100644 --- a/include/mgba-util/geometry.h +++ b/include/mgba-util/geometry.h @@ -11,15 +11,15 @@ CXX_GUARD_START struct mSize { - int width; - int height; + int width; + int height; }; struct mRectangle { - int x; - int y; - int width; - int height; + int x; + int y; + int width; + int height; }; void mRectangleUnion(struct mRectangle* dst, const struct mRectangle* add); diff --git a/include/mgba/feature/proxy-backend.h b/include/mgba/feature/proxy-backend.h index ffd38eb47..0851b3a68 100644 --- a/include/mgba/feature/proxy-backend.h +++ b/include/mgba/feature/proxy-backend.h @@ -57,7 +57,7 @@ struct mVideoBackendCommand { struct mVideoProxyBackend { struct VideoBackend d; struct VideoBackend* backend; - + struct RingFIFO in; struct RingFIFO out; diff --git a/include/mgba/internal/defines.h b/include/mgba/internal/defines.h index 8af603736..67b8ec8fd 100644 --- a/include/mgba/internal/defines.h +++ b/include/mgba/internal/defines.h @@ -9,23 +9,23 @@ #define mSAVEDATA_CLEANUP_THRESHOLD 15 enum { - mSAVEDATA_DIRT_NONE = 0, + mSAVEDATA_DIRT_NONE = 0, mSAVEDATA_DIRT_NEW = 1, mSAVEDATA_DIRT_SEEN = 2, }; static inline bool mSavedataClean(int* dirty, uint32_t* dirtAge, uint32_t frameCount) { - if (*dirty & mSAVEDATA_DIRT_NEW) { - *dirtAge = frameCount; - *dirty &= ~mSAVEDATA_DIRT_NEW; - if (!(*dirty & mSAVEDATA_DIRT_SEEN)) { - *dirty |= mSAVEDATA_DIRT_SEEN; - } - } else if ((*dirty & mSAVEDATA_DIRT_SEEN) && frameCount - *dirtAge > mSAVEDATA_CLEANUP_THRESHOLD) { - *dirty = 0; - return true; - } - return false; + if (*dirty & mSAVEDATA_DIRT_NEW) { + *dirtAge = frameCount; + *dirty &= ~mSAVEDATA_DIRT_NEW; + if (!(*dirty & mSAVEDATA_DIRT_SEEN)) { + *dirty |= mSAVEDATA_DIRT_SEEN; + } + } else if ((*dirty & mSAVEDATA_DIRT_SEEN) && frameCount - *dirtAge > mSAVEDATA_CLEANUP_THRESHOLD) { + *dirty = 0; + return true; + } + return false; } #endif diff --git a/src/arm/isa-thumb.c b/src/arm/isa-thumb.c index 0bc8fcb12..30fcfde9d 100644 --- a/src/arm/isa-thumb.c +++ b/src/arm/isa-thumb.c @@ -88,7 +88,7 @@ DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSR1, } THUMB_NEUTRAL_S( , , cpu->gprs[rd]);) -DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(ASR1, +DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(ASR1, if (!immediate) { cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]); if (cpu->cpsr.c) { diff --git a/src/core/cheats.c b/src/core/cheats.c index 53f71e907..1ffe91adf 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -37,7 +37,7 @@ static uint32_t _patchMakeKey(struct mCheatPatch* patch) { patchKey >>= 2; break; default: - break; + break; } // TODO: More than one segment if (patch->segment > 0) { diff --git a/src/core/thread.c b/src/core/thread.c index 2462407cc..2b16a03c7 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -656,7 +656,7 @@ void mCoreThreadContinue(struct mCoreThread* threadContext) { if (threadContext->impl->requested) { threadContext->impl->state = mTHREAD_REQUEST; } else { - threadContext->impl->state = mTHREAD_RUNNING; + threadContext->impl->state = mTHREAD_RUNNING; } ConditionWake(&threadContext->impl->stateOnThreadCond); } diff --git a/src/feature/ffmpeg/ffmpeg-decoder.c b/src/feature/ffmpeg/ffmpeg-decoder.c index 09539ca61..189fb312f 100644 --- a/src/feature/ffmpeg/ffmpeg-decoder.c +++ b/src/feature/ffmpeg/ffmpeg-decoder.c @@ -71,7 +71,7 @@ bool FFmpegDecoderOpen(struct FFmpegDecoder* decoder, const char* infile) { codec = avcodec_find_decoder(context->codec_id); if (!codec) { FFmpegDecoderClose(decoder); - return false; + return false; } if (avcodec_open2(context, codec, NULL) < 0) { FFmpegDecoderClose(decoder); diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index 5ee54a5e8..6202e0fcd 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -893,7 +893,7 @@ void FFmpegEncoderSetInputFrameRate(struct FFmpegEncoder* encoder, int numerator void FFmpegEncoderSetInputSampleRate(struct FFmpegEncoder* encoder, int sampleRate) { encoder->isampleRate = sampleRate; - if (encoder->resampleContext) { + if (encoder->resampleContext) { av_freep(&encoder->audioBuffer); #ifdef USE_LIBAVRESAMPLE avresample_close(encoder->resampleContext); diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index e110ef768..6214abc15 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -295,7 +295,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t test.v.s = mCoreConfigGetValue(&runner->config, item->data.v.s); if (test.v.s && strcmp(test.v.s, v->v.s) == 0) { item->state = j; - break; + break; } break; case GUI_VARIANT_POINTER: diff --git a/src/feature/updater.c b/src/feature/updater.c index e50ed0fa2..ea9cea3c1 100644 --- a/src/feature/updater.c +++ b/src/feature/updater.c @@ -46,7 +46,7 @@ static void _updateList(const char* key, const char* value, void* user) { if (strncmp("medusa.", key, 7) == 0) { dotLoc = strchr(&key[7], '.'); } else { - dotLoc = strchr(key, '.'); + dotLoc = strchr(key, '.'); } if (!dotLoc) { return; diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index 4044a4928..ac5ef1777 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -339,17 +339,17 @@ bool mVideoLoggerRendererRunInjected(struct mVideoLogger* logger) { channel->injecting = true; bool res = mVideoLoggerRendererRun(logger, false); channel->injecting = false; - return res; + return res; } void mVideoLoggerInjectionPoint(struct mVideoLogger* logger, enum mVideoLoggerInjectionPoint injectionPoint) { struct mVideoLogChannel* channel = logger->dataContext; - channel->injectionPoint = injectionPoint; + channel->injectionPoint = injectionPoint; } void mVideoLoggerIgnoreAfterInjection(struct mVideoLogger* logger, uint32_t mask) { struct mVideoLogChannel* channel = logger->dataContext; - channel->ignorePackets = mask; + channel->ignorePackets = mask; } static bool _writeData(struct mVideoLogger* logger, const void* data, size_t length) { diff --git a/src/gb/core.c b/src/gb/core.c index 2bfea28ef..e67fe4232 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -152,7 +152,7 @@ static bool _GBCoreInit(struct mCore* core) { #ifdef ENABLE_VFS mDirectorySetInit(&core->dirs); #endif - + return true; } diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index ba36c0090..c0c386f4c 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -267,7 +267,7 @@ void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, _copyExtraState(proxyRenderer); proxyRenderer->backend->drawRange(proxyRenderer->backend, startX, endX, y); } - mVideoLoggerRendererDrawRange(proxyRenderer->logger, startX, endX, y); + mVideoLoggerRendererDrawRange(proxyRenderer->logger, startX, endX, y); } void GBVideoProxyRendererFinishScanline(struct GBVideoRenderer* renderer, int y) { diff --git a/src/gb/gb.c b/src/gb/gb.c index 67dea55b8..fa0d6482f 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -152,7 +152,7 @@ bool GBLoadGBX(struct GBXMetadata* metadata, struct VFile* vf) { if (memcmp(footer, "MBC1", 4) == 0) { metadata->mapperVars.u8[0] = 5; } else if (memcmp(footer, "MB1M", 4) == 0) { - metadata->mapperVars.u8[0] = 4; + metadata->mapperVars.u8[0] = 4; } return true; } @@ -894,7 +894,7 @@ int GBValidModels(const uint8_t* bank0) { } else if (cart->cgb == 0xC0) { models = GB_MODEL_CGB; } else { - models = GB_MODEL_MGB; + models = GB_MODEL_MGB; } if (cart->sgb == 0x03 && cart->oldLicensee == 0x33) { models |= GB_MODEL_SGB; diff --git a/src/gb/mbc.c b/src/gb/mbc.c index c9ebed546..397b50088 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -163,7 +163,7 @@ static bool _isMulticart(const uint8_t* mem) { success = GBIsROM(vf); vf->close(vf); } - + return success; } diff --git a/src/gb/mbc/tama5.c b/src/gb/mbc/tama5.c index 505a35ed8..c4f0a1517 100644 --- a/src/gb/mbc/tama5.c +++ b/src/gb/mbc/tama5.c @@ -131,7 +131,7 @@ static void _latchTAMA6Rtc(struct mRTCSource* rtc, struct GBTAMA5State* tama5, t timerRegs[GBTAMA6_RTC_PA0_HOUR_10] = (diff % 24) / 10; } else { timerRegs[GBTAMA6_RTC_PA0_HOUR_1] = (diff % 12) % 10; - timerRegs[GBTAMA6_RTC_PA0_HOUR_10] = (diff % 12) / 10 + (diff / 12) * 2; + timerRegs[GBTAMA6_RTC_PA0_HOUR_10] = (diff % 12) / 10 + (diff / 12) * 2; } t /= 24; t += diff / 24; diff --git a/src/gb/mbc/unlicensed.c b/src/gb/mbc/unlicensed.c index 950ddf074..844c0d0cd 100644 --- a/src/gb/mbc/unlicensed.c +++ b/src/gb/mbc/unlicensed.c @@ -349,7 +349,7 @@ void _GBHitek(struct GB* gb, uint16_t address, uint8_t value) { break; case 0x300: // See hhugboy src/memory/mbc/MbcUnlHitek.cpp for commentary on this return - return; + return; } _GBMBC5(gb, address, value); } @@ -396,10 +396,10 @@ uint8_t _GBGGB81Read(struct GBMemory* memory, uint16_t address) { } void _GBLiCheng(struct GB* gb, uint16_t address, uint8_t value) { - if (address > 0x2100 && address < 0x3000) { - return; - } - _GBMBC5(gb, address, value); + if (address > 0x2100 && address < 0x3000) { + return; + } + _GBMBC5(gb, address, value); } void _GBSachen(struct GB* gb, uint16_t address, uint8_t value) { diff --git a/src/gb/video.c b/src/gb/video.c index 38be72a5a..d52e43dee 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -755,7 +755,7 @@ void GBVideoWriteLCDC(struct GBVideo* video, GBRegisterLCDC value) { video->ly = 0; video->p->memory.io[GB_REG_LY] = 0; video->renderer->writePalette(video->renderer, 0, video->dmgPalette[0]); - + mTimingDeschedule(&video->p->timing, &video->modeEvent); mTimingDeschedule(&video->p->timing, &video->frameEvent); mTimingSchedule(&video->p->timing, &video->frameEvent, GB_VIDEO_TOTAL_LENGTH << 1); diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index ee611247b..e33c7b568 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -324,7 +324,7 @@ void GBAVideoProxyRendererSaveState(struct GBAVideoRenderer* renderer, void** st proxyRenderer->logger->stateSize = 0; } else { proxyRenderer->backend->saveState(proxyRenderer->backend, state, size); - } + } } void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { diff --git a/src/gba/serialize.c b/src/gba/serialize.c index 1669eca3d..5eabaedea 100644 --- a/src/gba/serialize.c +++ b/src/gba/serialize.c @@ -195,7 +195,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) { if (GBASerializedMiscFlagsIsIrqPending(miscFlags)) { int32_t when; LOAD_32(when, 0, &state->nextIrq); - mTimingSchedule(&gba->timing, &gba->irqEvent, when); + mTimingSchedule(&gba->timing, &gba->irqEvent, when); } gba->cpuBlocked = GBASerializedMiscFlagsGetBlocked(miscFlags); gba->keysLast = GBASerializedMiscFlagsGetKeyIRQKeys(miscFlags); diff --git a/src/platform/3ds/ctr-gpu.c b/src/platform/3ds/ctr-gpu.c index 4a95c4640..d153f84a0 100644 --- a/src/platform/3ds/ctr-gpu.c +++ b/src/platform/3ds/ctr-gpu.c @@ -160,7 +160,7 @@ void ctrActivateTexture(const C3D_Tex* texture) { .m = { // Rows are in the order w z y x, because ctrulib 0.0f, 0.0f, 0.0f, 1.0f / activeTexture->width, - 0.0f, 0.0f, 1.0f / activeTexture->height, 0.0f + 0.0f, 0.0f, 1.0f / activeTexture->height, 0.0f } }; C3D_FVUnifMtx2x4(GPU_GEOMETRY_SHADER, GSH_FVEC_textureMtx, &textureMtx); diff --git a/src/platform/example/client-server/server.c b/src/platform/example/client-server/server.c index 0dcec9b15..71472a05c 100644 --- a/src/platform/example/client-server/server.c +++ b/src/platform/example/client-server/server.c @@ -53,7 +53,7 @@ int main(int argc, char** argv) { SocketClose(sock); SocketSubsystemDeinit(); didFail = true; - goto cleanup; + goto cleanup; } // Run the server diff --git a/src/platform/opengl/gl.c b/src/platform/opengl/gl.c index b0cef1f0d..de8354c1c 100644 --- a/src/platform/opengl/gl.c +++ b/src/platform/opengl/gl.c @@ -253,7 +253,7 @@ static void mGLContextImageSize(struct VideoBackend* v, enum VideoLayer layer, i *height = context->layerDims[layer].height; } else { *width = context->imageSizes[layer].width; - *height = context->imageSizes[layer].height; + *height = context->imageSizes[layer].height; } } @@ -266,7 +266,7 @@ void mGLContextPostFrame(struct VideoBackend* v, enum VideoLayer layer, const vo context->activeTex ^= 1; glBindTexture(GL_TEXTURE_2D, context->tex[context->activeTex]); } else { - glBindTexture(GL_TEXTURE_2D, context->layers[layer]); + glBindTexture(GL_TEXTURE_2D, context->layers[layer]); } int width = context->imageSizes[layer].width; diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index fa6716be9..e5ee98767 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -529,7 +529,7 @@ static void mGLES2ContextImageSize(struct VideoBackend* v, enum VideoLayer layer *height = context->layerDims[layer].height; } else { *width = context->imageSizes[layer].width; - *height = context->imageSizes[layer].height; + *height = context->imageSizes[layer].height; } } @@ -617,7 +617,7 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f if (shader->width > 0 && shader->height > 0) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, shader->width, shader->height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shader->tex, 0); diff --git a/src/platform/psp2/psp2-common.h b/src/platform/psp2/psp2-common.h index 7f34d1d10..dcb67b700 100644 --- a/src/platform/psp2/psp2-common.h +++ b/src/platform/psp2/psp2-common.h @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef PSP2_COMMON_H #define PSP2_COMMON_H - + #include #define PSP2_HORIZONTAL_PIXELS 960 diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index f7d6eb4c7..46b24e927 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -216,7 +216,7 @@ void BattleChipView::loadDeck() { error->show(); return; } - + QList newDeck; QStringList deck = ini.value("deck").toString().split(','); for (const auto& item : deck) { diff --git a/src/platform/qt/ConfigController.h b/src/platform/qt/ConfigController.h index 4c71c3943..4325a46ba 100644 --- a/src/platform/qt/ConfigController.h +++ b/src/platform/qt/ConfigController.h @@ -130,7 +130,7 @@ private: mGraphicsOpts m_graphicsOpts{}; std::array m_subparsers; bool m_parsed = false; - + QHash m_argvOptions; QHash m_optionSet; std::unique_ptr m_settings; diff --git a/src/platform/qt/DebuggerConsoleController.cpp b/src/platform/qt/DebuggerConsoleController.cpp index dffd71bcf..716c31639 100644 --- a/src/platform/qt/DebuggerConsoleController.cpp +++ b/src/platform/qt/DebuggerConsoleController.cpp @@ -162,7 +162,7 @@ void DebuggerConsoleController::historyLoad() { if (line.endsWith("\r\n")) { line.chop(2); } else if (line.endsWith("\n")) { - line.chop(1); + line.chop(1); } history.append(QString::fromUtf8(line)); } diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index bb16b268e..3cc2fc61f 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -62,7 +62,7 @@ public: virtual void setVideoProxy(std::shared_ptr proxy) { m_videoProxy = std::move(proxy); } std::shared_ptr videoProxy() { return m_videoProxy; } virtual VideoBackend* videoBackend(); - + signals: void drawingStarted(); void showCursor(); diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 5b60eb46e..ad4969943 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -314,7 +314,7 @@ bool DisplayGL::highestCompatible(QSurfaceFormat& format) { if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { format.setVersion(1, 4); } else { - format.setVersion(1, 1); + format.setVersion(1, 1); } format.setOption(QSurfaceFormat::DeprecatedFunctions); if (DisplayGL::supportsFormat(format)) { diff --git a/src/platform/qt/ForwarderController.cpp b/src/platform/qt/ForwarderController.cpp index 0934f1c69..abf2d27d0 100644 --- a/src/platform/qt/ForwarderController.cpp +++ b/src/platform/qt/ForwarderController.cpp @@ -160,7 +160,7 @@ void ForwarderController::gotManifest(QNetworkReply* reply) { mUpdaterGetUpdateForChannel(&context, platform.toUtf8().constData(), m_channel.toUtf8().constData(), &update); downloadBuild({bucket + update.path}); - mUpdaterDeinit(&context); + mUpdaterDeinit(&context); } void ForwarderController::downloadBuild(const QUrl& url) { @@ -174,7 +174,7 @@ void ForwarderController::downloadBuild(const QUrl& url) { .arg(extension)); if (!m_sourceFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { emit buildFailed(); - return; + return; } QNetworkReply* reply = GBAApp::app()->httpGet(url); diff --git a/src/platform/qt/ForwarderView.cpp b/src/platform/qt/ForwarderView.cpp index 922ef7c16..7261c0941 100644 --- a/src/platform/qt/ForwarderView.cpp +++ b/src/platform/qt/ForwarderView.cpp @@ -97,7 +97,7 @@ void ForwarderView::build() { if (m_ui.baseType->currentIndex() == 2) { m_controller.setBaseFilename(m_ui.baseFilename->text()); } else { - m_controller.clearBaseFilename(); + m_controller.clearBaseFilename(); } m_controller.startBuild(m_ui.outputFilename->text()); m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); @@ -235,14 +235,14 @@ void ForwarderView::updateProgress() { if (m_needsForwarderKit) { m_ui.progressBar->setValue(450 + m_downloadProgress * 50); } else { - m_ui.progressBar->setValue(m_downloadProgress * 100); + m_ui.progressBar->setValue(m_downloadProgress * 100); } break; case ForwarderController::BASE: if (m_needsForwarderKit) { m_ui.progressBar->setValue(500 + m_downloadProgress * 500); } else { - m_ui.progressBar->setValue(100 + m_downloadProgress * 900); + m_ui.progressBar->setValue(100 + m_downloadProgress * 900); } break; } diff --git a/src/platform/qt/MemorySearch.cpp b/src/platform/qt/MemorySearch.cpp index 34f87fe14..7a8446887 100644 --- a/src/platform/qt/MemorySearch.cpp +++ b/src/platform/qt/MemorySearch.cpp @@ -21,7 +21,7 @@ MemorySearch::MemorySearch(std::shared_ptr controller, QWidget* mCoreMemorySearchResultsInit(&m_results, 0); connect(m_ui.search, &QPushButton::clicked, this, &MemorySearch::search); - connect(m_ui.value, &QLineEdit::returnPressed, this, &MemorySearch::search); + connect(m_ui.value, &QLineEdit::returnPressed, this, &MemorySearch::search); connect(m_ui.searchWithin, &QPushButton::clicked, this, &MemorySearch::searchWithin); connect(m_ui.refresh, &QPushButton::clicked, this, &MemorySearch::refresh); connect(m_ui.numHex, &QPushButton::clicked, this, &MemorySearch::refresh); diff --git a/src/platform/qt/SaveConverter.cpp b/src/platform/qt/SaveConverter.cpp index 974f31af0..205a7563d 100644 --- a/src/platform/qt/SaveConverter.cpp +++ b/src/platform/qt/SaveConverter.cpp @@ -86,18 +86,18 @@ void SaveConverter::refreshInputTypes() { m_validSaves.clear(); m_ui.inputType->clear(); if (m_ui.inputFile->text().isEmpty()) { - m_ui.inputType->addItem(tr("No file selected")); + m_ui.inputType->addItem(tr("No file selected")); m_ui.inputType->setEnabled(false); return; } std::shared_ptr vf = std::make_shared(m_ui.inputFile->text(), QIODevice::ReadOnly); if (!vf->isOpen()) { - m_ui.inputType->addItem(tr("Could not open file")); + m_ui.inputType->addItem(tr("Could not open file")); m_ui.inputType->setEnabled(false); return; } - + detectFromSavestate(*vf); detectFromSize(vf); detectFromHeaders(vf); @@ -108,7 +108,7 @@ void SaveConverter::refreshInputTypes() { if (m_validSaves.count()) { m_ui.inputType->setEnabled(true); } else { - m_ui.inputType->addItem(tr("No valid formats found")); + m_ui.inputType->addItem(tr("No valid formats found")); m_ui.inputType->setEnabled(false); } } @@ -127,7 +127,7 @@ void SaveConverter::refreshOutputTypes() { if (m_validOutputs.count()) { m_ui.outputType->setEnabled(true); } else { - m_ui.outputType->addItem(tr("No valid conversions found")); + m_ui.outputType->addItem(tr("No valid conversions found")); m_ui.outputType->setEnabled(false); } checkCanConvert(); @@ -494,21 +494,21 @@ SaveConverter::AnnotatedSave::operator QString() const { if (size & 0xFF) { typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 SRAM + RTC"); } else { - typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 SRAM"); + typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 SRAM"); } break; case GB_MBC2: if (size == 0x100) { typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "packed MBC2"); } else { - typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "unpacked MBC2"); + typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "unpacked MBC2"); } break; case GB_MBC6: if (size == GB_SIZE_MBC6_FLASH) { typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "MBC6 flash"); } else if (size > GB_SIZE_MBC6_FLASH) { - typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "MBC6 combined SRAM + flash"); + typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "MBC6 combined SRAM + flash"); } else { typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "MBC6 SRAM"); } diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp index b8c8075e6..88f7b51b1 100644 --- a/src/platform/qt/TilePainter.cpp +++ b/src/platform/qt/TilePainter.cpp @@ -81,7 +81,7 @@ void TilePainter::setTileCount(int tiles) { int w = width() / m_size; int h = (tiles + w - 1) * m_size / w; setMinimumSize(m_size, h - (h % m_size)); - } else { + } else { int w = minimumSize().width() / m_size; if (!w) { w = 1; diff --git a/src/platform/qt/TileView.cpp b/src/platform/qt/TileView.cpp index dbfc15531..6ba409a0a 100644 --- a/src/platform/qt/TileView.cpp +++ b/src/platform/qt/TileView.cpp @@ -132,7 +132,7 @@ void TileView::updateTilesGBA(bool force) { if (m_ui.tilesBg->isChecked()) { m_ui.tiles->setTileCount(1024); } else if (m_ui.tilesObj->isChecked()) { - m_ui.tiles->setTileCount(512); + m_ui.tiles->setTileCount(512); } else { m_ui.tiles->setTileCount(1536); } @@ -165,7 +165,7 @@ void TileView::updateTilesGBA(bool force) { if (m_ui.tilesBg->isChecked()) { m_ui.tiles->setTileCount(2048); } else if (m_ui.tilesObj->isChecked()) { - m_ui.tiles->setTileCount(1024); + m_ui.tiles->setTileCount(1024); } else { m_ui.tiles->setTileCount(3072); } diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 0e3d73b00..77c7695fb 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -127,7 +127,7 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi if (value.toBool()) { attachWidget(m_libraryView); } else { - attachWidget(m_screenWidget); + attachWidget(m_screenWidget); } } }, this); @@ -136,8 +136,8 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi ConfigOption* showFilenameInLibrary = m_config->addOption("showFilenameInLibrary"); showFilenameInLibrary->connect([this](const QVariant& value) { m_libraryView->setShowFilename(value.toBool()); - }, this); - m_config->updateOption("showFilenameInLibrary"); + }, this); + m_config->updateOption("showFilenameInLibrary"); ConfigOption* libraryStyle = m_config->addOption("libraryStyle"); libraryStyle->connect([this](const QVariant& value) { m_libraryView->setViewStyle(static_cast(value.toInt())); diff --git a/src/platform/qt/library/LibraryTree.cpp b/src/platform/qt/library/LibraryTree.cpp index 37d07e3e7..c9029e963 100644 --- a/src/platform/qt/library/LibraryTree.cpp +++ b/src/platform/qt/library/LibraryTree.cpp @@ -181,7 +181,7 @@ void LibraryTree::rebuildTree() { QHash pathNodes; if (m_currentStyle == LibraryStyle::STYLE_TREE) { - for (const QString& folder : m_pathNodes.keys()) { + for (const QString& folder : m_pathNodes.keys()) { QTreeWidgetItem* i = new LibraryTreeItem; pathNodes.insert(folder, i); i->setText(0, folder.section("/", -1)); diff --git a/src/platform/qt/scripting/ScriptingTextBuffer.cpp b/src/platform/qt/scripting/ScriptingTextBuffer.cpp index fe85eda0e..9a5de818d 100644 --- a/src/platform/qt/scripting/ScriptingTextBuffer.cpp +++ b/src/platform/qt/scripting/ScriptingTextBuffer.cpp @@ -107,7 +107,7 @@ void ScriptingTextBuffer::moveCursor(const QPoint& pos) { m_shim.cursor.insertBlock(); } } else { - m_shim.cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, y); + m_shim.cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, y); } int x = pos.x(); diff --git a/src/script/engines/lua.c b/src/script/engines/lua.c index f6bdabea2..732d54e99 100644 --- a/src/script/engines/lua.c +++ b/src/script/engines/lua.c @@ -1143,7 +1143,7 @@ bool _luaInvoke(struct mScriptEngineContextLua* luaContext, struct mScriptFrame* if (ret == LUA_ERRRUN) { luaContext->lastError = strdup(lua_tostring(luaContext->lua, -1)); lua_pop(luaContext->lua, 1); - + _luaError(luaContext); } mScriptContextDeactivate(luaContext->d.context); diff --git a/src/script/types.c b/src/script/types.c index be58a43bf..00422d20c 100644 --- a/src/script/types.c +++ b/src/script/types.c @@ -1443,7 +1443,7 @@ static struct mScriptClassMember* _findSetter(const struct mScriptTypeClass* cls if (m) { return m; } - + switch (type->base) { case mSCRIPT_TYPE_SINT: if (type->size < 2) { diff --git a/src/tools/font-sdf.c b/src/tools/font-sdf.c index e28c34eaf..0ddcdc645 100644 --- a/src/tools/font-sdf.c +++ b/src/tools/font-sdf.c @@ -24,7 +24,7 @@ void createSdf(const struct mImage* src, struct mImage* dst, int x, int y, int w if (mImageGetPixel(src, i, j) & 0xFFFFFF) { mImageSetPixelRaw(dst, i, j, 0xFF); } else { - mImageSetPixelRaw(dst, i, j, 1); + mImageSetPixelRaw(dst, i, j, 1); } } } diff --git a/src/util/audio-resampler.c b/src/util/audio-resampler.c index 3b1848190..554f4744b 100644 --- a/src/util/audio-resampler.c +++ b/src/util/audio-resampler.c @@ -60,7 +60,7 @@ void mAudioResamplerSetSource(struct mAudioResampler* resampler, struct mAudioBu void mAudioResamplerSetDestination(struct mAudioResampler* resampler, struct mAudioBuffer* destination, double rate) { resampler->destination = destination; - resampler->destRate = rate; + resampler->destRate = rate; } size_t mAudioResamplerProcess(struct mAudioResampler* resampler) { diff --git a/src/util/crc32.c b/src/util/crc32.c index 24f611111..7c1fcda55 100644 --- a/src/util/crc32.c +++ b/src/util/crc32.c @@ -103,7 +103,7 @@ uint32_t doCrc32(const void* buf, size_t size) { #ifndef HAVE_CRC32 uint32_t crc32(uint32_t crc, const void* buf, size_t size) { const uint8_t* p = buf; - + crc = ~crc; for (size_t i = 0; i < size; ++i) { crc = crc32Table[(crc ^ p[i]) & 0xFF] ^ (crc >> 8); diff --git a/src/util/hash.c b/src/util/hash.c index ed070e86c..1ac0b56e2 100644 --- a/src/util/hash.c +++ b/src/util/hash.c @@ -69,9 +69,9 @@ uint32_t hash32(const void* key, size_t len, uint32_t seed) { k1 *= c1; k1 = ROTL32(k1, 15); k1 *= c2; - + h1 ^= k1; - h1 = ROTL32(h1, 13); + h1 = ROTL32(h1, 13); h1 = h1 * 5 + 0xe6546b64; } @@ -105,4 +105,4 @@ uint32_t hash32(const void* key, size_t len, uint32_t seed) { h1 = fmix32(h1); return h1; -} +} diff --git a/src/util/sfo.c b/src/util/sfo.c index 97c4e3853..47d5f2702 100644 --- a/src/util/sfo.c +++ b/src/util/sfo.c @@ -91,7 +91,7 @@ bool SfoAddStrValue(struct Table* sfo, const char* name, const char* value) { HashTableInsert(sfo, name, entry); } entry->type = PSF_TYPE_STR; - entry->data.str = value; + entry->data.str = value; return true; } From c71cd4a81b8ad0d09084d28d56d1ebaadcb7d468 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 1 Oct 2024 02:02:18 -0700 Subject: [PATCH 317/336] Qt: Improve --script help --- src/platform/qt/ConfigController.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index ccec60432..819b2479d 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -154,11 +154,12 @@ ConfigController::ConfigController(QObject* parent) mSubParserGraphicsInit(&m_subparsers[0], &m_graphicsOpts); m_subparsers[1].usage = "Frontend options:\n" - " --ecard FILE Scan an e-Reader card in the first loaded game\n" - " Can be passed multiple times for multiple cards\n" - " --mb FILE Boot a multiboot image with FILE inserted into the ROM slot" + " --ecard FILE Scan an e-Reader card in the first loaded game\n" + " Can be passed multiple times for multiple cards\n" + " --mb FILE Boot a multiboot image with FILE inserted into the ROM slot" #ifdef ENABLE_SCRIPTING - "\n --script FILE Script file to load on start" + "\n --script FILE Script file to load on start\n" + " Can be passed multiple times\n" #endif ; From 541ed9606cc3a53879f81f473f88a8d5b96fe451 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 4 Oct 2024 17:13:43 -0700 Subject: [PATCH 318/336] Core: Check for null when autoloading/saving cheats --- src/core/cheats.c | 3 +++ src/core/core.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/cheats.c b/src/core/cheats.c index 1ffe91adf..2fc97c3ac 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -627,6 +627,9 @@ void mCheatAutosave(struct mCheatDevice* device) { if (!device->autosave) { return; } + if (!device->p->dirs.cheats) { + return; + } struct VFile* vf = mDirectorySetOpenSuffix(&device->p->dirs, device->p->dirs.cheats, ".cheats", O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { return; diff --git a/src/core/core.c b/src/core/core.c index 20f9fdefc..789656ea4 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -245,14 +245,16 @@ bool mCoreAutoloadPatch(struct mCore* core) { } bool mCoreAutoloadCheats(struct mCore* core) { - bool success = true; + bool success = !!core->dirs.cheats; int cheatAuto; - if (!mCoreConfigGetIntValue(&core->config, "cheatAutoload", &cheatAuto) || cheatAuto) { + if (success && (!mCoreConfigGetIntValue(&core->config, "cheatAutoload", &cheatAuto) || cheatAuto)) { struct VFile* vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.cheats, ".cheats", O_RDONLY); if (vf) { struct mCheatDevice* device = core->cheatDevice(core); success = mCheatParseFile(device, vf); vf->close(vf); + } else { + success = false; } } if (!mCoreConfigGetIntValue(&core->config, "cheatAutosave", &cheatAuto) || cheatAuto) { From 5fb7c5e3ee85343c2e9c397a3644fe568b6373f6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 4 Oct 2024 17:17:47 -0700 Subject: [PATCH 319/336] Core: Add sanity check for mDirectorySetOpenSuffix --- src/core/directories.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/directories.c b/src/core/directories.c index c4551b6c7..e0748f829 100644 --- a/src/core/directories.c +++ b/src/core/directories.c @@ -110,6 +110,9 @@ struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path } struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, struct VDir* dir, const char* suffix, int mode) { + if (!dir) { + return NULL; + } char name[PATH_MAX + 1] = ""; snprintf(name, sizeof(name) - 1, "%s%s", dirs->baseName, suffix); return dir->openFile(dir, name, mode); From 7950279a09ce7f41a56a584a8fd1b6231f8074b2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 4 Oct 2024 22:20:21 -0700 Subject: [PATCH 320/336] Core: Split out semantics of rumble integrator init/reset (fixes #3309) --- include/mgba/core/interface.h | 1 + src/core/interface.c | 16 ++++++++++------ src/platform/libretro/libretro.c | 2 +- src/platform/switch/main.c | 6 ++---- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 597387753..033047cac 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -133,6 +133,7 @@ struct mRumbleIntegrator { }; void mRumbleIntegratorInit(struct mRumbleIntegrator*); +void mRumbleIntegratorReset(struct mRumbleIntegrator*); struct mCoreChannelInfo { size_t id; diff --git a/src/core/interface.c b/src/core/interface.c index 10d3433ab..5771d80e1 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -110,14 +110,14 @@ void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core) { rtc->d.deserialize = _rtcGenericDeserialize; } -static void mRumbleIntegratorReset(struct mRumble* rumble, bool enable) { +static void _mRumbleIntegratorReset(struct mRumble* rumble, bool enable) { struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; integrator->state = enable; integrator->timeOn = 0; integrator->totalTime = 0; } -static void mRumbleIntegratorSetRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast) { +static void _mRumbleIntegratorSetRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast) { struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; if (integrator->state) { @@ -127,7 +127,7 @@ static void mRumbleIntegratorSetRumble(struct mRumble* rumble, bool enable, uint integrator->state = enable; } -static void mRumbleIntegratorIntegrate(struct mRumble* rumble, uint32_t period) { +static void _mRumbleIntegratorIntegrate(struct mRumble* rumble, uint32_t period) { if (!period) { return; } @@ -144,7 +144,11 @@ static void mRumbleIntegratorIntegrate(struct mRumble* rumble, uint32_t period) void mRumbleIntegratorInit(struct mRumbleIntegrator* integrator) { memset(integrator, 0, sizeof(*integrator)); - integrator->d.reset = mRumbleIntegratorReset; - integrator->d.setRumble = mRumbleIntegratorSetRumble; - integrator->d.integrate = mRumbleIntegratorIntegrate; + integrator->d.reset = _mRumbleIntegratorReset; + integrator->d.setRumble = _mRumbleIntegratorSetRumble; + integrator->d.integrate = _mRumbleIntegratorIntegrate; +} + +void mRumbleIntegratorReset(struct mRumbleIntegrator* integrator) { + _mRumbleIntegratorReset(&integrator->d, false); } diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 232c4e6eb..d2a871546 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -834,7 +834,7 @@ static void _setupMaps(struct mCore* core) { void retro_reset(void) { core->reset(core); - mRumbleIntegratorInit(&rumble); + mRumbleIntegratorReset(&rumble); _setupMaps(core); } diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 1f61cc279..6cd7bc3b8 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -296,7 +296,7 @@ static void _setup(struct mGUIRunner* runner) { } _updateRenderer(runner, fakeBool); - mRumbleIntegratorInit(&rumble.d); + mRumbleIntegratorReset(&rumble.d); runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d.d); runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation); runner->core->setAVStream(runner->core, &stream); @@ -363,13 +363,10 @@ static void _gameLoaded(struct mGUIRunner* runner) { runner->core->reloadConfigOption(runner->core, "videoScale", &runner->config); } } - - mRumbleIntegratorInit(&rumble.d); } static void _gameUnloaded(struct mGUIRunner* runner) { UNUSED(runner); - mRumbleIntegratorInit(&rumble.d); HidVibrationValue values[4]; memcpy(&values[0], &vibrationStop, sizeof(rumble.value)); memcpy(&values[1], &vibrationStop, sizeof(rumble.value)); @@ -812,6 +809,7 @@ static void hidSetup(void) { padConfigureInput(1, HidNpadStyleSet_NpadStandard); padInitializeDefault(&pad); + mRumbleIntegratorInit(&rumble.d); rumble.d.setRumble = _setRumble; rumble.value.freq_low = 120.0; rumble.value.freq_high = 180.0; From 0e52f7054fae93794706611b71a9190d726052b0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 6 Oct 2024 03:20:49 -0700 Subject: [PATCH 321/336] Res: Add demo input display script --- res/scripts/input-display.lua | 122 ++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 res/scripts/input-display.lua diff --git a/res/scripts/input-display.lua b/res/scripts/input-display.lua new file mode 100644 index 000000000..e3db0340c --- /dev/null +++ b/res/scripts/input-display.lua @@ -0,0 +1,122 @@ +input_display = { + anchor = "top", + offset = { + x = 0, + y = 0, + } +} + +local state = { + drawButton = { + [0] = function(state) -- A + state.painter:drawCircle(27, 6, 4) + end, + [1] = function(state) -- B + state.painter:drawCircle(23, 8, 4) + end, + [2] = function(state) -- Select + state.painter:drawCircle(13, 11, 3) + end, + [3] = function(state) -- Start + state.painter:drawCircle(18, 11, 3) + end, + [4] = function(state) -- Right + state.painter:drawRectangle(9, 7, 4, 3) + end, + [5] = function(state) -- Left + state.painter:drawRectangle(2, 7, 4, 3) + end, + [6] = function(state) -- Up + state.painter:drawRectangle(6, 3, 3, 4) + end, + [7] = function(state) -- Down + state.painter:drawRectangle(6, 10, 3, 4) + end, + [8] = function(state) -- R + state.painter:drawRectangle(28, 0, 4, 3) + end, + [9] = function(state) -- L + state.painter:drawRectangle(0, 0, 4, 3) + end + }, + maxKey = { + [C.PLATFORM.GBA] = 9, + [C.PLATFORM.GB] = 7, + } +} +state.overlay = canvas:newLayer(32, 16) +state.painter = image.newPainter(state.overlay.image) +state.painter:setBlend(false) +state.painter:setFill(true) + +function state.update() + local keys = util.expandBitmask(emu:getKeys()) + local maxKey = state.maxKey[emu:platform()] + + for key = 0, maxKey do + if emu:getKey(key) ~= 0 then + state.painter:setFillColor(0x80FFFFFF) + else + state.painter:setFillColor(0x40404040) + end + state.drawButton[key](state) + end + state.overlay:update() +end + +function state.reset() + local endX = canvas:screenWidth() - 32 + local endY = canvas:screenHeight() - 16 + + local anchors = { + topLeft = { + x = 0, + y = 0 + }, + top = { + x = endX / 2, + y = 0 + }, + topRight = { + x = endX, + y = 0 + }, + left = { + x = 0, + y = endY / 2 + }, + center = { + x = endX / 2, + y = endY / 2 + }, + right = { + x = endX, + y = endY / 2 + }, + bottomLeft = { + x = 0, + y = endY + }, + bottom = { + x = endX / 2, + y = endY + }, + bottomRight = { + x = endX, + y = endY + }, + } + + local pos = anchors[input_display.anchor]; + pos.x = pos.x + input_display.offset.x; + pos.y = pos.y + input_display.offset.y; + + state.overlay:setPosition(pos.x, pos.y); + state.painter:setFillColor(0x40808080) + state.painter:drawRectangle(0, 0, 32, 16) + state.overlay:update() +end + +state.reset() +callbacks:add("frame", state.update) +callbacks:add("start", state.reset) From 58510ca2506679b31618d80dd75fc6f00c043959 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 8 Oct 2024 03:12:51 -0700 Subject: [PATCH 322/336] Util: Add MD5 implementation and consistency tests --- include/mgba-util/md5.h | 34 ++++++ src/util/CMakeLists.txt | 2 + src/util/md5.c | 228 ++++++++++++++++++++++++++++++++++++++++ src/util/test/hash.c | 130 +++++++++++++++++++++++ 4 files changed, 394 insertions(+) create mode 100644 include/mgba-util/md5.h create mode 100644 src/util/md5.c create mode 100644 src/util/test/hash.c diff --git a/include/mgba-util/md5.h b/include/mgba-util/md5.h new file mode 100644 index 000000000..9a2c58145 --- /dev/null +++ b/include/mgba-util/md5.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Based on https://github.com/Zunawe/md5-c + * Originally released under the Unlicense */ +#ifndef MD5_H +#define MD5_H + +#include + +CXX_GUARD_START + +struct MD5Context { + size_t size; // Size of input in bytes + uint32_t buffer[4]; // Current accumulation of hash + uint8_t input[0x40]; // Input to be used in the next step + uint8_t digest[0x10]; // Result of algorithm +}; + +void md5Init(struct MD5Context* ctx); +void md5Update(struct MD5Context* ctx, const void* input, size_t len); +void md5Finalize(struct MD5Context* ctx); + +void md5Buffer(const void* input, size_t len, uint8_t* result); + +struct VFile; +bool md5File(struct VFile* vf, uint8_t* result); + +CXX_GUARD_END + +#endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 66cd6ca47..2f4ba2dcd 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -6,6 +6,7 @@ set(BASE_SOURCE_FILES formatting.c gbk-table.c hash.c + md5.c string.c table.c vector.c @@ -41,6 +42,7 @@ set(TEST_FILES test/circle-buffer.c test/color.c test/geometry.c + test/hash.c test/image.c test/sfo.c test/string-parser.c diff --git a/src/util/md5.c b/src/util/md5.c new file mode 100644 index 000000000..08e06fb1d --- /dev/null +++ b/src/util/md5.c @@ -0,0 +1,228 @@ +/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Based on https://github.com/Zunawe/md5-c + * Originally released under the Unlicense + * + * Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm + */ +#include + +#include + +/* + * Constants defined by the MD5 algorithm + */ +#define A 0x67452301 +#define B 0xEFCDAB89 +#define C 0x98BADCFE +#define D 0x10325476 + +static const uint32_t S[] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }; + +static const uint32_t K[] = { 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, + 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, + 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, + 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, + 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, + 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, + 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, + 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, + 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, + 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, + 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, + 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, + 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, + 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, + 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, + 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 }; + +/* + * Padding used to make the size (in bits) of the input congruent to 448 mod 512 + */ +static const uint8_t PADDING[] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +/* + * Bit-manipulation functions defined by the MD5 algorithm + */ +#define F(X, Y, Z) (((X) & (Y)) | (~(X) & (Z))) +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & ~(Z))) +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z)) +#define I(X, Y, Z) ((Y) ^ ((X) | ~(Z))) + +/* + * Rotates a 32-bit word left by n bits + */ +static uint32_t rotateLeft(uint32_t x, uint32_t n) { + return (x << n) | (x >> (32 - n)); +} + +/* + * Step on 512 bits of input with the main MD5 algorithm. + */ +static void md5Step(uint32_t* buffer, const uint32_t* input) { + uint32_t AA = buffer[0]; + uint32_t BB = buffer[1]; + uint32_t CC = buffer[2]; + uint32_t DD = buffer[3]; + + uint32_t E; + + unsigned j; + + for (unsigned i = 0; i < 64; ++i) { + switch (i / 16) { + case 0: + E = F(BB, CC, DD); + j = i; + break; + case 1: + E = G(BB, CC, DD); + j = ((i * 5) + 1) & 0xF; + break; + case 2: + E = H(BB, CC, DD); + j = ((i * 3) + 5) & 0xF; + break; + default: + E = I(BB, CC, DD); + j = (i * 7) & 0xF; + break; + } + + uint32_t temp = DD; + DD = CC; + CC = BB; + BB += rotateLeft(AA + E + K[i] + input[j], S[i]); + AA = temp; + } + + buffer[0] += AA; + buffer[1] += BB; + buffer[2] += CC; + buffer[3] += DD; +} + +/* + * Initialize a context + */ +void md5Init(struct MD5Context* ctx) { + memset(ctx, 0, sizeof(*ctx)); + + ctx->buffer[0] = A; + ctx->buffer[1] = B; + ctx->buffer[2] = C; + ctx->buffer[3] = D; +} + +/* + * Add some amount of input to the context + * + * If the input fills out a block of 512 bits, apply the algorithm (md5Step) + * and save the result in the buffer. Also updates the overall size. + */ +void md5Update(struct MD5Context* ctx, const void* input, size_t len) { + uint32_t buffer[16]; + unsigned offset = ctx->size & 0x3F; + const uint8_t* inputBuffer = input; + ctx->size += len; + + // Copy each byte in input_buffer into the next space in our context input + unsigned i; + for (i = 0; i < len; ++i) { + ctx->input[offset] = inputBuffer[i]; + + // If we've filled our context input, copy it into our local array input + // then reset the offset to 0 and fill in a new buffer. + // Every time we fill out a chunk, we run it through the algorithm + // to enable some back and forth between cpu and i/o + if (offset < 0x3F) { + ++offset; + continue; + } + + unsigned j; + for (j = 0; j < 16; ++j) { + // Convert to little-endian + // The local variable `input` our 512-bit chunk separated into 32-bit words + // we can use in calculations + LOAD_32LE(buffer[j], j * 4, ctx->input); + } + md5Step(ctx->buffer, buffer); + offset = 0; + } +} + +/* + * Pad the current input to get to 448 bits, append the size in bits to the very end, + * and save the result of the final iteration into digest. + */ +void md5Finalize(struct MD5Context* ctx) { + uint32_t input[16]; + int offset = ctx->size & 0x3F; + unsigned paddingLength = offset < 56 ? 56 - offset : (56 + 64) - offset; + + // Fill in the padding and undo the changes to size that resulted from the update + md5Update(ctx, PADDING, paddingLength); + ctx->size -= paddingLength; + + // Do a final update (internal to this function) + // Last two 32-bit words are the two halves of the size (converted from bytes to bits) + unsigned j; + for (j = 0; j < 14; ++j) { + LOAD_32LE(input[j], j * 4, ctx->input); + } + input[14] = (uint32_t) (ctx->size * 8); + input[15] = (uint32_t) ((ctx->size * 8ULL) >> 32); + + md5Step(ctx->buffer, input); + + // Move the result into digest (convert from little-endian) + unsigned i; + for (i = 0; i < 4; ++i) { + STORE_32LE(ctx->buffer[i], i * 4, ctx->digest); + } +} + +void md5Buffer(const void* input, size_t len, uint8_t* result) { + struct MD5Context ctx; + md5Init(&ctx); + md5Update(&ctx, input, len); + md5Finalize(&ctx); + memcpy(result, ctx.digest, sizeof(ctx.digest)); +} + +bool md5File(struct VFile* vf, uint8_t* result) { + struct MD5Context ctx; + uint8_t buffer[2048]; + md5Init(&ctx); + + ssize_t read; + ssize_t position = vf->seek(vf, 0, SEEK_CUR); + if (vf->seek(vf, 0, SEEK_SET) < 0) { + return false; + } + while ((read = vf->read(vf, buffer, sizeof(buffer))) > 0) { + md5Update(&ctx, buffer, read); + } + vf->seek(vf, position, SEEK_SET); + if (read < 0) { + return false; + } + md5Finalize(&ctx); + memcpy(result, ctx.digest, sizeof(ctx.digest)); + return true; +} diff --git a/src/util/test/hash.c b/src/util/test/hash.c new file mode 100644 index 000000000..6d014435b --- /dev/null +++ b/src/util/test/hash.c @@ -0,0 +1,130 @@ +/* Copyright (c) 2013-2022 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "util/test/suite.h" + +#include +#include + +M_TEST_DEFINE(emptyCrc32) { + uint8_t buffer[1] = {0}; + assert_int_equal(doCrc32(buffer, 0), 0); +} + +M_TEST_DEFINE(newlineCrc32) { +uint8_t buffer[1] = { '\n' }; + assert_int_equal(doCrc32(buffer, 1), 0x32D70693); +} + +M_TEST_DEFINE(helloWorldCrc32) { + const char* buffer = "Hello, world!"; + assert_int_equal(doCrc32(buffer, strlen(buffer)), 0xEBE6C6E6); +} + +#ifndef HAVE_CRC32 +M_TEST_DEFINE(stagedCrc32) { + uint8_t buffer[1] = { '\n\n' }; + assert_int_equal(crc32(0, buffer, 1), 0x32D70693); + assert_int_equal(crc32(0, buffer, 2), 0x09304EBD); + assert_int_equal(crc32(0x32D70693, buffer, 1), 0x09304EBD); +} +#endif + +M_TEST_DEFINE(emptyMd5) { + uint8_t buffer[1] = {0}; + uint8_t digest[0x10] = {0}; + md5Buffer(buffer, 0, digest); + assert_memory_equal(digest, ((uint8_t[]) { + 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E + }), 16); +} + +M_TEST_DEFINE(newlineMd5) { + uint8_t buffer[1] = { '\n' }; + uint8_t digest[0x10] = {0}; + md5Buffer(buffer, 1, digest); + assert_memory_equal(digest, ((uint8_t[]) { + 0x68, 0xB3, 0x29, 0xDA, 0x98, 0x93, 0xE3, 0x40, + 0x99, 0xC7, 0xD8, 0xAD, 0x5C, 0xB9, 0xC9, 0x40 + }), 16); +} + +M_TEST_DEFINE(fullBlockMd5) { + uint8_t buffer[56] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + uint8_t digest[0x10] = {0}; + md5Buffer(buffer, 56, digest); + assert_memory_equal(digest, ((uint8_t[]) { + 0xA3, 0x31, 0x42, 0x53, 0x78, 0x54, 0xFE, 0xE2, + 0xAF, 0xD6, 0xCF, 0xF4, 0xC5, 0xA1, 0xDD, 0x39 + }), 16); +} + +M_TEST_DEFINE(overflowBlockMd5) { + uint8_t buffer[57] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x0a, + }; + uint8_t digest[0x10] = {0}; + md5Buffer(buffer, 57, digest); + assert_memory_equal(digest, ((uint8_t[]) { + 0xBA, 0x49, 0x77, 0x29, 0x15, 0x5B, 0x13, 0x5D, + 0xBA, 0x27, 0xF3, 0xD8, 0x53, 0xCF, 0xD2, 0x1A + }), 16); +} + +M_TEST_DEFINE(twoBlockMd5) { + uint8_t buffer[120] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + uint8_t digest[0x10] = {0}; + md5Buffer(buffer, 120, digest); + assert_memory_equal(digest, ((uint8_t[]) { + 0xB5, 0x68, 0xA7, 0x7E, 0xD4, 0xC2, 0x39, 0xFB, + 0x4B, 0x74, 0xD7, 0x5B, 0xDB, 0xFD, 0x94, 0x93 + }), 16); +} + +M_TEST_SUITE_DEFINE(Hashes, + cmocka_unit_test(emptyCrc32), + cmocka_unit_test(newlineCrc32), + cmocka_unit_test(helloWorldCrc32), +#ifndef HAVE_CRC32 + cmocka_unit_test(stagedCrc32), +#endif + cmocka_unit_test(emptyMd5), + cmocka_unit_test(newlineMd5), + cmocka_unit_test(fullBlockMd5), + cmocka_unit_test(overflowBlockMd5), + cmocka_unit_test(twoBlockMd5), +) From 2ccfde0f33ff372f644d40aa4e8bf6d65fa677f8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 8 Oct 2024 04:09:26 -0700 Subject: [PATCH 323/336] Core: Add MD5 hashing for ROMs --- CHANGES | 1 + include/mgba/core/core.h | 1 + src/gb/core.c | 10 ++ src/gba/core.c | 14 ++ src/platform/qt/ROMInfo.cpp | 6 + src/platform/qt/ROMInfo.ui | 300 ++++++++++++++++++++---------------- 6 files changed, 198 insertions(+), 134 deletions(-) diff --git a/CHANGES b/CHANGES index f0fe0a474..9a538caee 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,7 @@ Other fixes: Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) - Core: Improve rumble emulation by averaging state over entire frame (fixes mgba.io/i/3232) + - Core: Add MD5 hashing for ROMs - GB: Prevent incompatible BIOSes from being used on differing models - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index e8c5df7bc..94dfb1114 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -30,6 +30,7 @@ enum mPlatform { enum mCoreChecksumType { mCHECKSUM_CRC32, + mCHECKSUM_MD5, }; struct mAudioBuffer; diff --git a/src/gb/core.c b/src/gb/core.c index e67fe4232..b97e1ee25 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -529,6 +530,15 @@ static void _GBCoreChecksum(const struct mCore* core, void* data, enum mCoreChec case mCHECKSUM_CRC32: memcpy(data, &gb->romCrc32, sizeof(gb->romCrc32)); break; + case mCHECKSUM_MD5: + if (gb->romVf) { + md5File(gb->romVf, data); + } else if (gb->memory.rom && gb->isPristine) { + md5Buffer(gb->memory.rom, gb->pristineRomSize, data); + } else { + md5Buffer("", 0, data); + } + break; } return; } diff --git a/src/gba/core.c b/src/gba/core.c index 67550bd7a..e81e66dac 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -30,6 +30,7 @@ #ifdef USE_ELF #include #endif +#include #include #include #include @@ -676,6 +677,19 @@ static void _GBACoreChecksum(const struct mCore* core, void* data, enum mCoreChe case mCHECKSUM_CRC32: memcpy(data, &gba->romCrc32, sizeof(gba->romCrc32)); break; + case mCHECKSUM_MD5: + if (gba->romVf) { + md5File(gba->romVf, data); + } else if (gba->mbVf) { + md5File(gba->mbVf, data); + } else if (gba->memory.rom && gba->isPristine) { + md5Buffer(gba->memory.rom, gba->pristineRomSize, data); + } else if (gba->memory.rom) { + md5Buffer(gba->memory.rom, gba->memory.romSize, data); + } else { + md5Buffer("", 0, data); + } + break; } return; } diff --git a/src/platform/qt/ROMInfo.cpp b/src/platform/qt/ROMInfo.cpp index 9f2537439..25aafeda8 100644 --- a/src/platform/qt/ROMInfo.cpp +++ b/src/platform/qt/ROMInfo.cpp @@ -24,6 +24,7 @@ ROMInfo::ROMInfo(std::shared_ptr controller, QWidget* parent) const NoIntroDB* db = GBAApp::app()->gameDB(); #endif uint32_t crc32 = 0; + uint8_t md5[16]{}; CoreController::Interrupter interrupter(controller); mCore* core = controller->thread()->core; @@ -39,6 +40,7 @@ ROMInfo::ROMInfo(std::shared_ptr controller, QWidget* parent) m_ui.version->setText(QString::number(info.version)); core->checksum(core, &crc32, mCHECKSUM_CRC32); + core->checksum(core, &md5, mCHECKSUM_MD5); m_ui.size->setText(QString::number(core->romSize(core)) + tr(" bytes")); @@ -63,6 +65,10 @@ ROMInfo::ROMInfo(std::shared_ptr controller, QWidget* parent) m_ui.name->setText(tr("(unknown)")); } + m_ui.md5->setText(QString::asprintf("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + md5[0x0], md5[0x1], md5[0x2], md5[0x3], md5[0x4], md5[0x5], md5[0x6], md5[0x7], + md5[0x8], md5[0x9], md5[0xA], md5[0xB], md5[0xC], md5[0xD], md5[0xE], md5[0xF])); + QString savePath = controller->savePath(); if (!savePath.isEmpty()) { m_ui.savefile->setText(savePath); diff --git a/src/platform/qt/ROMInfo.ui b/src/platform/qt/ROMInfo.ui index 655d4810f..a4a179ca8 100644 --- a/src/platform/qt/ROMInfo.ui +++ b/src/platform/qt/ROMInfo.ui @@ -6,154 +6,186 @@ 0 0 - 178 - 198 + 180 + 298 ROM Info - + QLayout::SetFixedSize - - QFormLayout::FieldsStayAtSizeHint - - - - Game name: - - - - - - - {NAME} - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + File information + + + + + Game name: + + + + + + + {NAME} + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + File size: + + + + + + + {SIZE} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + CRC32: + + + + + + + {CRC} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + MD5 + + + + + + + {MD5} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Save file: + + + + + + + {SAVEFILE} + + + + - - - Internal name: - - - - - - - {TITLE} - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Game ID: - - - - - - - {ID} - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Maker Code: - - - - - - - {MAKER} - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Revision: - - - - - - - {VERSION} - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - File size: - - - - - - - {SIZE} - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - CRC32: - - - - - - - {CRC} - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Save file: - - - - - - - {SAVEFILE} + + + ROM header + + + + + Internal name: + + + + + + + {TITLE} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Game ID: + + + + + + + {ID} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Maker Code: + + + + + + + {MAKER} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Revision: + + + + + + + {VERSION} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + From 7e474db93a62c148299616bb315e6c65afc8f00f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 8 Oct 2024 04:32:43 -0700 Subject: [PATCH 324/336] Qt: Fix some new SIO cleanup issues --- src/platform/qt/MultiplayerController.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index 3b2146f7a..e95498fad 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -192,6 +192,9 @@ MultiplayerController::MultiplayerController() { MultiplayerController::~MultiplayerController() { mLockstepDeinit(&m_lockstep); + if (m_platform == mPLATFORM_GBA) { + GBASIOLockstepCoordinatorDeinit(&m_gbaCoordinator); + } } bool MultiplayerController::attachGame(CoreController* controller) { @@ -376,7 +379,7 @@ void MultiplayerController::detachGame(CoreController* controller) { if (p.attached) { GBASIOLockstepCoordinatorDetach(&m_gbaCoordinator, p.node.gba); } - delete p.node.gba->user; + delete reinterpret_cast(p.node.gba->user); delete p.node.gba; break; } @@ -417,6 +420,9 @@ void MultiplayerController::detachGame(CoreController* controller) { m_pids.remove(pid); if (m_pids.size() == 0) { + if (m_platform == mPLATFORM_GBA) { + GBASIOLockstepCoordinatorDeinit(&m_gbaCoordinator); + } m_platform = mPLATFORM_NONE; } else { fixOrder(); From eaf45b9ab8d2a5902a80fbea5a9210fcda08a7a9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 8 Oct 2024 04:34:30 -0700 Subject: [PATCH 325/336] GB, GBA: Clean up some corner cases with ROM fd closing --- src/gb/gb.c | 4 +--- src/gb/memory.c | 2 -- src/gba/core.c | 3 +++ src/gba/gba.c | 6 ++---- src/gba/memory.c | 2 -- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index fa0d6482f..875cbf86e 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -483,12 +483,10 @@ void GBApplyPatch(struct GB* gb, struct Patch* patch) { mappedMemoryFree(newRom, GB_SIZE_CART_MAX); return; } - if (gb->romVf) { + if (gb->romVf && gb->isPristine) { #ifndef FIXED_ROM_BUFFER gb->romVf->unmap(gb->romVf, gb->memory.rom, gb->pristineRomSize); #endif - gb->romVf->close(gb->romVf); - gb->romVf = NULL; } gb->isPristine = false; if (gb->memory.romBase == gb->memory.rom) { diff --git a/src/gb/memory.c b/src/gb/memory.c index e41050784..dccd91e08 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -1017,8 +1017,6 @@ void _pristineCow(struct GB* gb) { } if (gb->romVf) { gb->romVf->unmap(gb->romVf, gb->memory.rom, gb->memory.romSize); - gb->romVf->close(gb->romVf); - gb->romVf = NULL; } gb->memory.rom = newRom; GBMBCSwitchBank(gb, gb->memory.currentBank); diff --git a/src/gba/core.c b/src/gba/core.c index e81e66dac..1d3fffb9e 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -668,6 +668,9 @@ static size_t _GBACoreROMSize(const struct mCore* core) { if (gba->romVf) { return gba->romVf->size(gba->romVf); } + if (gba->mbVf) { + return gba->mbVf->size(gba->mbVf); + } return gba->pristineRomSize; } diff --git a/src/gba/gba.c b/src/gba/gba.c index 187d83373..6b833838e 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -557,16 +557,14 @@ void GBAApplyPatch(struct GBA* gba, struct Patch* patch) { mappedMemoryFree(newRom, GBA_SIZE_ROM0); return; } - if (gba->romVf) { + if (gba->memory.rom) { #ifndef FIXED_ROM_BUFFER if (!gba->isPristine) { - mappedMemoryFree(gba->memory.rom, GBA_SIZE_ROM0); + mappedMemoryFree(gba->memory.rom, gba->memory.romSize); } else { gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->pristineRomSize); } #endif - gba->romVf->close(gba->romVf); - gba->romVf = NULL; } gba->isPristine = false; gba->memory.rom = newRom; diff --git a/src/gba/memory.c b/src/gba/memory.c index 09d3e7a74..3243fc5a1 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1894,8 +1894,6 @@ void _pristineCow(struct GBA* gba) { } if (gba->romVf) { gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->memory.romSize); - gba->romVf->close(gba->romVf); - gba->romVf = NULL; } gba->memory.rom = newRom; gba->memory.hw.gpioBase = &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]; From 4ef98c7ddfcec1348a21da6f4a23c5f022f0209b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 8 Oct 2024 04:39:53 -0700 Subject: [PATCH 326/336] Core: Fix patch autoloading leaking the file handle --- CHANGES | 1 + src/core/core.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 9a538caee..a3d67111c 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Emulation fixes: - GBA Video: Improve emulation of window start/end conditions (fixes mgba.io/i/1945) Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) + - Core: Fix patch autoloading leaking the file handle - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves - GB, GBA Core: Fix memory leak if reloading debug symbols diff --git a/src/core/core.c b/src/core/core.c index 789656ea4..ba7ef914c 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -239,9 +239,22 @@ bool mCoreAutoloadPatch(struct mCore* core) { if (!core->dirs.patch) { return false; } - return core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ups", O_RDONLY)) || - core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ips", O_RDONLY)) || - core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".bps", O_RDONLY)); + struct VFile* vf = NULL; + if (!vf) { + vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".bps", O_RDONLY); + } + if (!vf) { + vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ups", O_RDONLY); + } + if (!vf) { + vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ips", O_RDONLY); + } + if (!vf) { + return false; + } + bool result = core->loadPatch(core, vf); + vf->close(vf); + return result; } bool mCoreAutoloadCheats(struct mCore* core) { From 67c3c40989cd5d8e0c6de335ba56c02abc7829d8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 9 Oct 2024 00:26:10 -0700 Subject: [PATCH 327/336] Util: Shut Coverity up about a false positive --- src/util/md5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/md5.c b/src/util/md5.c index 08e06fb1d..9eaa4903b 100644 --- a/src/util/md5.c +++ b/src/util/md5.c @@ -87,7 +87,7 @@ static void md5Step(uint32_t* buffer, const uint32_t* input) { switch (i / 16) { case 0: E = F(BB, CC, DD); - j = i; + j = i & 0xF; break; case 1: E = G(BB, CC, DD); From afff68cfc0731c441ececa83bf43c3d8bebe5c5a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 11 Oct 2024 21:52:48 -0700 Subject: [PATCH 328/336] Qt: Show a dummy shader settings tab if shaders aren't supported --- CHANGES | 1 + src/platform/qt/SettingsView.cpp | 36 +++++++++++++++++++------------- src/platform/qt/SettingsView.h | 4 ++-- src/platform/qt/Window.cpp | 8 ++++++- src/platform/qt/Window.h | 1 + 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index a3d67111c..d6fd60848 100644 --- a/CHANGES +++ b/CHANGES @@ -58,6 +58,7 @@ Misc: - Qt: Pass logging context through to video proxy thread (fixes mgba.io/i/3095) - Qt: Show maker code and game version in ROM info - Qt: Make window corners square on Windows 11 (fixes mgba.io/i/3285) + - Qt: Show a dummy shader settings tab if shaders aren't supported - Res: Port NSO-gba-colors shader (closes mgba.io/i/2834) - Scripting: Add `callbacks:oneshot` for single-call callbacks - Switch: Add bilinear filtering option (closes mgba.io/i/3111) diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 66c125466..c86dcf06e 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -397,29 +397,38 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC shortcutView->setController(shortcutController); shortcutView->setInputController(inputController); addPage(tr("Shortcuts"), shortcutView, Page::SHORTCUTS); + +#if defined(BUILD_GLES2) || defined(USE_EPOXY) + m_dummyShader = new QLabel(tr("Shaders are not supported when the display driver is not OpenGL.\n\n" + "If it is set to OpenGL and you still see this, your graphics card or drivers may be too old.")); + m_dummyShader->setWordWrap(true); + m_dummyShader->setAlignment(Qt::AlignCenter); + addPage(tr("Shaders"), m_dummyShader, Page::SHADERS); +#endif } SettingsView::~SettingsView() { -#if defined(BUILD_GL) || defined(BUILD_GLES2) - setShaderSelector(nullptr); +#if defined(BUILD_GLES2) || defined(USE_EPOXY) + if (m_shader) { + m_shader->setParent(nullptr); + } #endif } void SettingsView::setShaderSelector(ShaderSelector* shaderSelector) { -#if defined(BUILD_GL) || defined(BUILD_GLES2) - if (m_shader) { - auto items = m_ui.tabs->findItems(tr("Shaders"), Qt::MatchFixedString); - for (const auto& item : items) { - m_ui.tabs->removeItemWidget(item); - } - m_ui.stackedWidget->removeWidget(m_shader); - m_shader->setParent(nullptr); +#if defined(BUILD_GLES2) || defined(USE_EPOXY) + auto items = m_ui.tabs->findItems(tr("Shaders"), Qt::MatchFixedString); + for (QListWidgetItem* item : items) { + delete item; + } + if (!m_shader) { + m_ui.stackedWidget->removeWidget(m_dummyShader); } m_shader = shaderSelector; if (shaderSelector) { - m_ui.stackedWidget->addWidget(m_shader); - m_ui.tabs->addItem(tr("Shaders")); - connect(m_ui.buttonBox, &QDialogButtonBox::accepted, m_shader, &ShaderSelector::saved); + addPage(tr("Shaders"), m_shader, Page::SHADERS); + } else { + addPage(tr("Shaders"), m_dummyShader, Page::SHADERS); } #endif } @@ -579,7 +588,6 @@ void SettingsView::updateConfig() { if (displayDriver != m_controller->getQtOption("displayDriver")) { m_controller->setQtOption("displayDriver", displayDriver); Display::setDriver(static_cast(displayDriver.toInt())); - setShaderSelector(nullptr); emit displayDriverChanged(); } diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 010b4ef0d..85cf35a99 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -51,8 +51,6 @@ public: SettingsView(ConfigController* controller, InputController* inputController, ShortcutController* shortcutController, LogController* logController, QWidget* parent = nullptr); ~SettingsView(); - void setShaderSelector(ShaderSelector* shaderSelector); - signals: void biosLoaded(int platform, const QString&); void audioDriverChanged(); @@ -66,6 +64,7 @@ signals: public slots: void selectPage(Page); + void setShaderSelector(ShaderSelector* shaderSelector); private slots: void selectBios(QLineEdit*); @@ -81,6 +80,7 @@ private: ConfigController* m_controller; InputController* m_input; ShaderSelector* m_shader = nullptr; + QLabel* m_dummyShader; LogConfigModel m_logModel; QTimer m_checkTimer; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 77c7695fb..ddf34f4f9 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -550,6 +550,7 @@ void Window::openSettingsWindow(SettingsView::Page page) { #ifdef USE_SQLITE3 connect(settingsWindow, &SettingsView::libraryCleared, m_libraryView, &LibraryController::clear); #endif + connect(this, &Window::shaderSelectorAdded, settingsWindow, &SettingsView::setShaderSelector); openView(settingsWindow); settingsWindow->selectPage(page); } @@ -1050,7 +1051,12 @@ void Window::reloadDisplayDriver() { } #if defined(BUILD_GL) || defined(BUILD_GLES2) m_shaderView.reset(); - m_shaderView = std::make_unique(m_display.get(), m_config); + if (m_display->supportsShaders()) { + m_shaderView = std::make_unique(m_display.get(), m_config); + emit shaderSelectorAdded(m_shaderView.get()); + } else { + emit shaderSelectorAdded(nullptr); + } #endif connect(m_display.get(), &QGBA::Display::hideCursor, [this]() { diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index f91e3ff30..cb467f89d 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -73,6 +73,7 @@ signals: void startDrawing(); void shutdown(); void paused(bool); + void shaderSelectorAdded(ShaderSelector*); public slots: void setController(CoreController* controller, const QString& fname); From 4a5a25e90c5ab0909a283df8a9cb10d9807f6e7a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 18 Oct 2024 02:58:19 -0700 Subject: [PATCH 329/336] GBA DMA: Cache cycle estimation on first DMA --- include/mgba/internal/gba/dma.h | 2 ++ src/gba/audio.c | 1 + src/gba/dma.c | 35 ++++++++++++++++++++++++++++----- src/gba/io.c | 1 + src/gba/memory.c | 4 ++++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/mgba/internal/gba/dma.h b/include/mgba/internal/gba/dma.h index 192b3995a..58d590948 100644 --- a/include/mgba/internal/gba/dma.h +++ b/include/mgba/internal/gba/dma.h @@ -48,6 +48,7 @@ struct GBADMA { uint32_t nextDest; int32_t nextCount; uint32_t when; + int32_t cycles; }; struct GBA; @@ -65,6 +66,7 @@ void GBADMARunHblank(struct GBA* gba, int32_t cycles); void GBADMARunVblank(struct GBA* gba, int32_t cycles); void GBADMARunDisplayStart(struct GBA* gba, int32_t cycles); void GBADMAUpdate(struct GBA* gba); +void GBADMARecalculateCycles(struct GBA* gba); CXX_GUARD_END diff --git a/src/gba/audio.c b/src/gba/audio.c index a6ebafbae..ac394e995 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -309,6 +309,7 @@ void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) { if (GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM) { dma->when = mTimingCurrentTime(&audio->p->timing) - cycles; dma->nextCount = 4; + GBADMARecalculateCycles(audio->p); GBADMASchedule(audio->p, channel->dmaSource, dma); } } diff --git a/src/gba/dma.c b/src/gba/dma.c index 290341361..5971b1b03 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -256,15 +256,21 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { if (info->count == info->nextCount) { if (width == 4) { cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion]; + info->cycles = memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion]; } else { cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion]; + info->cycles = memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion]; } } else { - if (width == 4) { - cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion]; - } else { - cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion]; + // Crossed region boundary; recalculate cached cycles + if (UNLIKELY(!(source & 0x00FFFFFC) || !(dest & 0x00FFFFFC))) { + if (width == 4) { + info->cycles = memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion]; + } else { + info->cycles = memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion]; + } } + cycles += info->cycles; } info->when += cycles; @@ -281,7 +287,7 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { memory->dmaTransferRegister = cpu->memory.load16(cpu, source, 0); memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; } - if (destRegion == GBA_REGION_ROM2_EX) { + if (UNLIKELY(destRegion == GBA_REGION_ROM2_EX)) { if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) { mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); GBASavedataInitEEPROM(&memory->savedata); @@ -327,3 +333,22 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { } GBADMAUpdate(gba); } + +void GBADMARecalculateCycles(struct GBA* gba) { + int i; + for (i = 0; i < 4; ++i) { + struct GBADMA* dma = &gba->memory.dma[i]; + if (!GBADMARegisterIsEnable(dma->reg)) { + continue; + } + + uint32_t width = GBADMARegisterGetWidth(dma->reg); + uint32_t sourceRegion = dma->nextSource >> BASE_OFFSET; + uint32_t destRegion = dma->nextDest >> BASE_OFFSET; + if (width) { + dma->cycles = gba->memory.waitstatesSeq32[sourceRegion] + gba->memory.waitstatesSeq32[destRegion]; + } else { + dma->cycles = gba->memory.waitstatesSeq16[sourceRegion] + gba->memory.waitstatesSeq16[destRegion]; + } + } +} diff --git a/src/gba/io.c b/src/gba/io.c index 8a4ea7fc2..cb6058f7f 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -1079,6 +1079,7 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) { LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC); LOAD_32(gba->bus, 0, &state->bus); + GBADMARecalculateCycles(gba); GBADMAUpdate(gba); GBAHardwareDeserialize(&gba->memory.hw, state); } diff --git a/src/gba/memory.c b/src/gba/memory.c index 3243fc5a1..c818c75c8 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1734,6 +1734,10 @@ void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) { STORE_32(memory->agbPrintFuncBackup, AGB_PRINT_FLUSH_ADDR | base, memory->rom); } } + + if (gba->performingDMA) { + GBADMARecalculateCycles(gba); + } } void GBAAdjustEWRAMWaitstates(struct GBA* gba, uint16_t parameters) { From 1c739e39e71dcbdd776bf0abf0b64761219e755e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 18 Oct 2024 05:08:14 -0700 Subject: [PATCH 330/336] GBA DMA: Minor branch optimization --- src/gba/dma.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gba/dma.c b/src/gba/dma.c index 5971b1b03..e9044d26a 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -319,9 +319,11 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { int i; for (i = 0; i < 4; ++i) { struct GBADMA* dma = &memory->dma[i]; - int32_t time = dma->when - info->when; - if (time < 0 && GBADMARegisterIsEnable(dma->reg) && dma->nextCount) { - dma->when = info->when; + if (GBADMARegisterIsEnable(dma->reg) && dma->nextCount) { + int32_t time = dma->when - info->when; + if (time < 0) { + dma->when = info->when; + } } } From 279485fc3ed54b0dafbbff448e901be47b25ef2f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 20 Oct 2024 18:04:30 -0700 Subject: [PATCH 331/336] Qt: Fix saving named states breaking when screenshot states disabled (fixes #3320) --- CHANGES | 1 + src/platform/qt/CoreController.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d6fd60848..e432bee67 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,7 @@ Other fixes: - Qt: Fix potential crash when configuring shortcuts - Qt: Fix crash when applying changes to GB I/O registers in I/O view - Qt: Fix LCDC background priority/enable bit being mis-mapped in I/O view + - Qt: Fix saving named states breaking when screenshot states disabled (fixes mgba.io/i/3320) - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 807a86685..2496f8039 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -736,7 +736,7 @@ void CoreController::saveState(const QString& path, int flags) { vf->read(vf, controller->m_backupSaveState.data(), controller->m_backupSaveState.size()); vf->close(vf); } - vf = VFileDevice::open(controller->m_statePath, O_WRONLY | O_CREAT | O_TRUNC); + vf = VFileDevice::open(controller->m_statePath, O_RDWR | O_CREAT | O_TRUNC); if (!vf) { return; } From 65b14b4ad984b41dff2e5c9604da3a565dea867e Mon Sep 17 00:00:00 2001 From: oltolm Date: Fri, 25 Oct 2024 19:07:04 +0200 Subject: [PATCH 332/336] fix assignment of modifier keys --- src/platform/qt/KeyEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/KeyEditor.cpp b/src/platform/qt/KeyEditor.cpp index 818b6c703..9ad981ce7 100644 --- a/src/platform/qt/KeyEditor.cpp +++ b/src/platform/qt/KeyEditor.cpp @@ -110,7 +110,7 @@ void KeyEditor::keyPressEvent(QKeyEvent* event) { m_key = Qt::Key_unknown; } m_lastKey.start(KEY_TIME); - setValue(ShortcutController::isModifierKey(event->key()) ? event->modifiers() : event->key() | event->modifiers()); + setValue(ShortcutController::isModifierKey(event->key()) ? event->key() : event->key() | event->modifiers()); } event->accept(); } From 47e5cd2432218d27cf778ee4e57c55c387774aab Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 29 Oct 2024 22:40:23 -0700 Subject: [PATCH 333/336] Qt: Fix "QFSFileEngine::open: No file name specified" warning --- src/platform/qt/Window.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index ddf34f4f9..8dca02078 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1086,7 +1086,12 @@ void Window::reloadDisplayDriver() { m_display->setMinimumSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); #endif - m_display->setBackgroundImage(QImage{m_config->getOption("backgroundImage")}); + QString backgroundImage = m_config->getOption("backgroundImage"); + if (backgroundImage.isEmpty()) { + m_display->setBackgroundImage(QImage{}); + } else { + m_display->setBackgroundImage(QImage{backgroundImage}); + } if (!proxy) { proxy = std::make_shared(); @@ -1978,7 +1983,12 @@ void Window::setupOptions() { ConfigOption* backgroundImage = m_config->addOption("backgroundImage"); backgroundImage->connect([this](const QVariant& value) { if (m_display) { - m_display->setBackgroundImage(QImage{value.toString()}); + QString backgroundImage = value.toString(); + if (backgroundImage.isEmpty()) { + m_display->setBackgroundImage(QImage{}); + } else { + m_display->setBackgroundImage(QImage{backgroundImage}); + } } }, this); m_config->updateOption("backgroundImage"); From 377ddf50810a5cd1889e0cdfd86298c577b8a956 Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Wed, 30 Oct 2024 23:48:25 +0100 Subject: [PATCH 334/336] Qt: Recreate Window to release old surface and create a OpenGL one --- src/platform/qt/DisplayGL.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index ad4969943..e62e9685e 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -192,6 +192,7 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) setAttribute(Qt::WA_NativeWindow); window()->windowHandle()->setFormat(format); windowHandle()->setSurfaceType(QSurface::OpenGLSurface); + windowHandle()->destroy(); windowHandle()->create(); #ifdef USE_SHARE_WIDGET From 26ea53b024717fb74a6023ac7a59d04a196b24ca Mon Sep 17 00:00:00 2001 From: oltolm Date: Wed, 30 Oct 2024 17:54:32 +0100 Subject: [PATCH 335/336] fix numpad shortcuts --- src/platform/qt/KeyEditor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/KeyEditor.cpp b/src/platform/qt/KeyEditor.cpp index 9ad981ce7..6ce94fc55 100644 --- a/src/platform/qt/KeyEditor.cpp +++ b/src/platform/qt/KeyEditor.cpp @@ -110,7 +110,9 @@ void KeyEditor::keyPressEvent(QKeyEvent* event) { m_key = Qt::Key_unknown; } m_lastKey.start(KEY_TIME); - setValue(ShortcutController::isModifierKey(event->key()) ? event->key() : event->key() | event->modifiers()); + setValue(ShortcutController::isModifierKey(event->key()) ? + event->key() : + event->key() | (event->modifiers() & ~Qt::KeypadModifier)); } event->accept(); } From ef5646bbe3aaba0ac72f0ecce319684500852c52 Mon Sep 17 00:00:00 2001 From: Bo He Date: Tue, 15 Oct 2024 23:43:14 +0800 Subject: [PATCH 336/336] associate windows with the owning application --- res/mgba-qt.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/res/mgba-qt.desktop b/res/mgba-qt.desktop index d5d98ab37..2dc96901c 100644 --- a/res/mgba-qt.desktop +++ b/res/mgba-qt.desktop @@ -10,3 +10,4 @@ Comment=Nintendo Game Boy Advance Emulator Categories=Game;Emulator; MimeType=application/x-gameboy-advance-rom;application/x-agb-rom;application/x-gba-rom; Keywords=emulator;Nintendo;advance;gba;Game Boy Advance; +StartupWMClass=mGBA