From 61749a9b6697930b18362ecec473aa0824253333 Mon Sep 17 00:00:00 2001 From: Paul Robson Date: Sat, 13 Apr 2024 09:15:46 +0100 Subject: [PATCH] New Cursor graphics --- basic/test.bsc | 1 + emulator/src/core/sys_debugger.cpp | 5 +- firmware/common/include/common.h | 1 + firmware/common/include/interface/cursor.h | 28 +++++++++ firmware/common/include/interface/mouse.h | 6 +- firmware/common/scripts/cursors.py | 59 +++++++++++------- firmware/common/scripts/cursors/Makefile | 23 +++++++ firmware/common/scripts/cursors/default.png | Bin 195 -> 0 bytes firmware/common/scripts/cursors/graphics.gfx | Bin 0 -> 1664 bytes firmware/common/scripts/cursors/sprite_16.png | Bin 0 -> 5316 bytes firmware/common/scripts/cursors/sprite_32.png | Bin 0 -> 1116 bytes firmware/common/scripts/cursors/tile_16.png | Bin 0 -> 1244 bytes firmware/common/sources/interface/cursor.cpp | 56 +++++++++++++++++ .../common/sources/interface/dispatch.cpp | 1 + firmware/common/sources/interface/mouse.cpp | 3 +- firmware/sources/hardware/dvi_320x240x256.cpp | 21 ++++--- 16 files changed, 167 insertions(+), 37 deletions(-) create mode 100644 firmware/common/include/interface/cursor.h create mode 100644 firmware/common/scripts/cursors/Makefile delete mode 100644 firmware/common/scripts/cursors/default.png create mode 100644 firmware/common/scripts/cursors/graphics.gfx create mode 100644 firmware/common/scripts/cursors/sprite_16.png create mode 100644 firmware/common/scripts/cursors/sprite_32.png create mode 100644 firmware/common/scripts/cursors/tile_16.png create mode 100644 firmware/common/sources/interface/cursor.cpp diff --git a/basic/test.bsc b/basic/test.bsc index 6e8ab1b51..eec06269b 100644 --- a/basic/test.bsc +++ b/basic/test.bsc @@ -2,6 +2,7 @@ ' BASIC Mouse cursor manipulation ' mouse show +cls:line 0,0 ink 3 to 100,100 mouse to 260,180 repeat b = mouse(x,y,s) diff --git a/emulator/src/core/sys_debugger.cpp b/emulator/src/core/sys_debugger.cpp index 7d397ad9f..755e525a7 100644 --- a/emulator/src/core/sys_debugger.cpp +++ b/emulator/src/core/sys_debugger.cpp @@ -158,7 +158,10 @@ void DBGXRender(int *address,int showDisplay) { } const uint8_t *cursorImage; uint16_t cursorX,cursorY; - if (MSEGetCursorDrawInformation(&cursorImage,&cursorX,&cursorY)) { + uint8_t xHit,yHit; + if (MSEGetCursorDrawInformation(&cursorX,&cursorY)) { + cursorImage = CURGetCurrent(&xHit,&yHit); + cursorX -= xHit;cursorY -= yHit; uint8_t w = 16,h = 16; if (cursorX + 16 >= 320) w = 320-cursorX; if (cursorY + 16 >= 240) h = 240-cursorY; diff --git a/firmware/common/include/common.h b/firmware/common/include/common.h index 2bfda39f1..b284f513e 100644 --- a/firmware/common/include/common.h +++ b/firmware/common/include/common.h @@ -48,6 +48,7 @@ #include "interface/graphics.h" #include "interface/console.h" #include "interface/mouse.h" +#include "interface/cursor.h" #include "interface/timer.h" #include "interface/sound.h" #include "interface/memory.h" diff --git a/firmware/common/include/interface/cursor.h b/firmware/common/include/interface/cursor.h new file mode 100644 index 000000000..04318f19e --- /dev/null +++ b/firmware/common/include/interface/cursor.h @@ -0,0 +1,28 @@ +// *************************************************************************************** +// *************************************************************************************** +// +// Name : cursor.h +// Authors : Paul Robson (paul@robsons.org.uk) +// Date : 13th April 2024 +// Reviewed : No +// Purpose : Cursor header +// +// *************************************************************************************** +// *************************************************************************************** + +#ifndef _CURSOR_H +#define _CURSOR_H + +void CURInitialise(void); +const uint8_t *CURGetCurrent(uint8_t *xHit,uint8_t *yHit); +bool CURSetCurrent(uint8_t cursorID); + + +#endif + +// *************************************************************************************** +// +// Date Revision +// ==== ======== +// +// *************************************************************************************** diff --git a/firmware/common/include/interface/mouse.h b/firmware/common/include/interface/mouse.h index bdc34fe88..c4b05d8f0 100644 --- a/firmware/common/include/interface/mouse.h +++ b/firmware/common/include/interface/mouse.h @@ -10,8 +10,8 @@ // *************************************************************************************** // *************************************************************************************** -#ifndef _CURSOR_H -#define _CURSOR_H +#ifndef _MOUSE_H +#define _MOUSE_H void MSEInitialise(void); void MSESetPosition(uint16_t x, uint16_t y); @@ -19,7 +19,7 @@ void MSEOffsetPosition(int8_t dx, int8_t dy); void MSEUpdateScrollWheel(int8_t ds); void MSEUpdateButtonState(uint8_t buttonState); void MSEGetState(uint16_t *pX, uint16_t *pY, uint8_t *pButtonState, uint8_t *pScrollWheelState); -bool MSEGetCursorDrawInformation(const uint8_t **pData, uint16_t *pX, uint16_t *pY); +bool MSEGetCursorDrawInformation(uint16_t *pX, uint16_t *pY); void MSESetVisible(bool isVisible); void MSEEnableMouse(void); bool MSEMousePresent(void); diff --git a/firmware/common/scripts/cursors.py b/firmware/common/scripts/cursors.py index aa1980787..6b4db5938 100644 --- a/firmware/common/scripts/cursors.py +++ b/firmware/common/scripts/cursors.py @@ -3,32 +3,45 @@ # # Name : cursors.py # Authors : Paul Robson (paul@robsons.org.uk) -# Date : 21st March 2024 +# Date : 13th April 2024 # Reviewed : No -# Purpose : Converts cursors to data (monochrome only at present) +# Purpose : Converts cursors to data (2nd version) # # *************************************************************************************** # *************************************************************************************** import re,os,sys -from PIL import Image - - -class Cursor(object): - def __init__(self,imageFile,xClick,yClick): - self.click = (xClick,yClick) - self.image = Image.open("scripts"+os.sep+"cursors"+os.sep+imageFile) - assert self.image.size == (16,16) - self.imageData = [0xFF] * 256 - self.name = imageFile[:-4].lower() - for x in range(0,16): - for y in range(0,16): - p = self.image.getpixel((x,y)) - if p[3] > 128: - self.imageData[x+y*16] = 7 if p[0]+p[1]+p[2] > 512 else 0 - ib = ",".join([str(x) for x in self.imageData]) - print("static const uint8_t {1}_cursor_data[] = {{ {0}}};\n".format(ib,self.name)) - -cursors = [] -print("//\n//\tThis file is automatically generated.\n//") -Cursor("default.png",0,0) + +def convert(n): + n = n & 0x0F + return 0xFF if n == 0 else n + +src = [x for x in open("scripts/cursors/graphics.gfx","rb").read(-1)] +assert src[0] == 1 and src[1] == 0 and src[3] == 0 +cursorCount = src[2] + +print("//\n//\tThis file is automatically generated\n//\n") + +print("#define CURSOR_IMAGE_COUNT ({0})\n".format(cursorCount)) + +cursorData = [] +for c in src[256:]: + cursorData.append(convert(c >> 4)) + cursorData.append(convert(c)) + +print("const uint8_t cursor_data[] = {") +print(",".join([str(x) for x in cursorData])) +print("};\n") + +hitPoint = [] +for i in range(0,cursorCount): + hp = [8,8] + if i == 0: + hp = [4,0] + if i == 4 or i == 9: + hp = [4,4] + hitPoint += hp +print("const uint8_t cursor_hitPoint[] = {") +print(",".join([str(x) for x in hitPoint])) +print("};\n") + diff --git a/firmware/common/scripts/cursors/Makefile b/firmware/common/scripts/cursors/Makefile new file mode 100644 index 000000000..aa0d3b5e2 --- /dev/null +++ b/firmware/common/scripts/cursors/Makefile @@ -0,0 +1,23 @@ +# *************************************************************************************** +# *************************************************************************************** +# +# Name : Makefile +# Author : Paul Robson (paul@robsons.org.uk) +# Date : 20th November 2023 +# Reviewed : No +# Purpose : Main firmware makefile, most of the work is done by CMake. +# +# *************************************************************************************** +# *************************************************************************************** + +ifeq ($(OS),Windows_NT) +#is this really needed? WSL2 is the 2023. +include ..\..\..\..\build_env\common.make +else +include ../../../../build_env/common.make +endif + +all: + + $(PYTHON) $(BINDIR)makeimg.zip + diff --git a/firmware/common/scripts/cursors/default.png b/firmware/common/scripts/cursors/default.png deleted file mode 100644 index 09fac77589e38fc6e9a32be29c634864b8d1f7da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf3`PczN7E(lQC-2~X1Ioh;rKZ> z{Bn=1Bi1j)rKA4XII;osv`794`5P!d_I-Z?!b74@06NTUsFWES(ow}$rPFI{8xd8J zf$!{mnZY;UOZP~M1^EpNHt`eqK@}5xv670va}x1E zK(EF6glCUfx!D3W;kW<3mWAJn{0g|Qy7}Uakj6&L{qm8z=`cF8I5IN z$9@v2sRWQ9p$vnl0?`bsCCFNREEE`n#8Yla1`!fShQ%v)W>c&S0}qO9g!sjK-= zqX0!WE5o^?%KY*b$WnbF-5PnS#I!`7#&$7az!c7;~J-Mus%IK zu{ti6%Zw4ZTAs`MY`C=deu&FSUgCalk9gYV4!Az?cO^Y-$m^39?>_DnpA>&Wwzkh4 z`nR;j-_y7y+TKmLm&ZkP{n2i5Yxgvc*znyoJQ_#WkGtkS#)aGOVqCzkZ#?@rEnL6- E4N-o11^@s6 literal 0 HcmV?d00001 diff --git a/firmware/common/scripts/cursors/sprite_16.png b/firmware/common/scripts/cursors/sprite_16.png new file mode 100644 index 0000000000000000000000000000000000000000..fee2812e344286eb31b9c842d05eed7f490aea41 GIT binary patch literal 5316 zcmeHLcT^ME+a6t66bq}MsDPjZr7R!{Vn9KqgaHJkxzy+iBH+MEDAE!|ih_U)U<4MB zCWIDgg9wIIRJv^FFiNB=ozQE3qwDT*_4}Rg-|vra&Y3&+=H7Rn=Y8JyoSbLw80r(Y z^6cdS0AMSqtziTJ>uzK7j*UNJbsv%6hIIFh5-lyKoG$FPlr$dMF0c_U z8N>fxJPrpzQ5Zq6KoEkk6EKQG2m-<|Hiu9Ydp|Y-Q4||-obT9k5Dp5X2!y~O3}Jj> z4ho?Nh`?AL5C;WO1j`TPpjh6YqW=wsDf2ZRCg4AiSaJVC#i(GwpW(k#4*0in*z)UC zJ{6e*BPawTAOzz;2*9D=XboUQzmgk(5cHb}5Jor>#Zg~!tKNuD?EuyzoRn{3ctx4E~-er&xA2Pd;$(D<}bn)Xa% z<_-rj3(5456omGY65}5oQbgnbw#7sQ{V=XWY#9TNIw;$6X?sX zIh3^G9+$MzXq|WbuKXhPoa^IX*B;(LmP-N`qLlhYD#iu^EA%*KYa?oG)>K2n`SHe+ zYYX}6Q)4dVgPav^GUFcQRnLk@qLPd5ik-6*hwExr!DTwfXS`f-ekGW)@bbkHrvX}| zbCh-%4D+%nzHaj``bZz5NXGki3i~M- zn8Q)pCa}D~vL5Y=Dt9*8u8i#lymXHW`Ev{lJshL+iU+u%`QX>}f8%^ZV&q;~laf=h zuWI~Li`+!&ihZJ&R(LaoyW6e#thK@Kd!ttbUCQ%E+9QPUa9tlobvjJGwBOTbg-tL-be1gV_Jb&F#3)kNsP?tuO0JC5MN{u zR7b9KvybXVRxGH#9C-p?2n_DtO^bGR*Oijg4w{2S=H!F6npr2uOqbGN2Tk{c%YR~$|j1<34ksF4Nnam}w=#0f!KG&z^q-ib0 zN%ePX^IFuwisf4)S;<-x=5_sL7qfSt31r*r*UD>kS9^FR3%GnZqFZ`x_Pk@!&x^@z z^*;{r@l+ZrfSbh{d);2KSH zWX!+-IcA}5N%GsLGqzu|q-oR6x$_=F=Rk2tLEJA>u6EB7pXrQk*763>m4y6@2BezOLO0>4dkH@^wq(AEno|!2Oc57y!#mrH|cZnYsy}}>G z$Z~o%Suf7KsKC!H^EvVwxxErQWUBn+tPM%uJz->IYWFj5>TB}SHcK^r%b(0y4RWzM z$|U7ApVfN#*oJd?bh=Q^2kwZqU-FKo435Tcp2%uUd}FeM;TuD!&GnpVj&cV_pIDWasVhhc`VS53P< za?*{i;6~T77cuIqAL%;0f{$^F^?xtm7xpA?rSYBj^!+xT3a`2V9oW}1%BViXT@x?* zitgYs*GjM>`k82H%?p()%HAatA2Z3@s*W#Z5E4ymW|eD`lLSh|2*--BPR5!%CJ2$* zxIXaW15131DOFCbo4cp(y!pU&g>z=5BjMEpgkS2^^1OrwimdX~R64t^HztNC^)t!0 zbDHgHc1)@h(;ws1W-QZx8YFHLk7;pxLo?YMk?JGE4Z2=6o-U+2u!;rTqbob|JqNZ~ zr?Mya1vaywm{*2Qw(@GzK_@JU?G+2DsjP60$h#k1Wp1YhSCFZr*%8Buw@MyKZI;gV zOZA~jZX%f3&(udAqDEITn9pJfvdq^qThs$Dc1#uPX-Y~H^a;Sai*C_>2~Y3v8_LJTSJ{E1>q?DpwV4V?Ddr9ML1@cQ+5 zMCiqq_l$$%DXC+=J(f+ztaCMYB@UAckkzM>4Kl(920nyjc+@$y?L3~&DAXdT z(ev|DugM#3lknXjf8F!#M{kw78TgQac#Hx)&~JC16&FwMj*w$>b}@ZP6LxWuwV{tH zQz8RY%AuYFa=1aN7$Nb*VsjKb<4~X70`}~;voUicRw^pz75ff8Ti88u>ZX4z2aa;! zX=x5hc2a;;4>qW#{no4nHgPvMX3f35Xzev?xA)m)jV`w&ojJ|eo@|ru6_nllJE{3Z z@pe_-}WHgW0L?sKqXBE>(>K*Jfa8B~`bg6GmoY^&X5fZUJzMSG19OSQ}p8PLo8okjOyv z<;wAFMZ!c)lv2UTeRy1k5nDM#vg@{w7`n4QF@(xD5w*J($tjx0hw2uY7LM(Gu*4E@ zXNs4#6rCp4<%|Sa6&hR0mg|RgwwtUm=?d=ct6gk4R@;ZxvYFSREK`SO8Q0PBAlWi~ z5}%r>xk%=|dRvP;rSf|7+>2zwXjqu=*aM3Y#%qc7w9PN7UvgcTdmAbB)={=K^jMs- z>x_KhL`lT*T11Iu-I}Y9luj-!lWbF;XVq#SUMEw0>~`2kzF6G@UGsk$rlvkgamcZ? zQQ+FS6YL6eGU4Am0X@53acZCVcH!QxxL+N|La&TbC;96Whs$t0@%mk}DorXA!))~^ zZ8b|{lV%j}f{F5eek0ck^{U(HC*!K0 z=DZRVCX%bl*2p?3X|O_5BJ42XIawK)usEfBT;I7_qi)||Tw9qj+n(5LN(d25P*6Z{CFM)J8_SeCle zDYLdqSH0`J*}FJ$2Ma8NHF}4^Qz> z@BiWb?8m4fvc*}>-P+0|<12Uh*B<4t<$~XQeALVgEtnpere~XUrL+G$TX0jZ@4hS1 z!(@j8POeR9_IC(_GV{9 zW}6@WDt@~igJvS7$>IY30DcYG^f%+bMRdB1wTe@*h3saUS@xHT7_Mb;?FWze$-evl lcKJWhE?8Y}OpkEZ?cv=du)J;ki%;KVKuvv(yfYX4{{uTV^8^3@ literal 0 HcmV?d00001 diff --git a/firmware/common/scripts/cursors/sprite_32.png b/firmware/common/scripts/cursors/sprite_32.png new file mode 100644 index 0000000000000000000000000000000000000000..31814a5a8ce3242e008404051157a712934d3c3e GIT binary patch literal 1116 zcmeAS@N?(olHy`uVBq!ia0y~yVDtd8cW^KPNxsRCPBJjCD0{j%hE&XXdv{}(Oew?h zkCGd=ZQLNB<9g(r6L;%Pae+=j9UT_=Ln2KaV!s5MT3ZuDKC*7R;KXgsnWPyJapMP5 zdg1QbE3Da#tE<)H?dCr-oA7Y^lXuc=&*s0e@V(4%#OHs>#%bBHuWv=~|MuYH|7CW4 zk1y?))zj1aCcb~$kM+~K^UJ6I`*-P)_xyi_-(Q`7F81E;=jo@{)8lsR{&MMl-M;#t zkDAlP<9|O~zdL*W|EiZu4>w!?4zK^a@y8?edAt5po%;TL?)JF&s<-L!HJfk${c&#U z{*O1_?fpCd;`8qNpFeziXM4Xs`Q!Pkch{HMhs*E%{_;}x{r^wy-d#O^Urg28507R~ zkKh0MU;EPO`+l7|-T&{?#-q0n{GYc$(c^}IN)CsR84IU$Qwy)-p*Dp?=Lulpk|%3^ z9B#g^{f578{mw51AF5mb9(*s#$G$(@Lgr80!-J0&U+%vl4`fYw|Nh~F@3Zb!pXNU< zzi011TY0{^^&dVw_|EkksQu4tAY*a;Hcs2TqnNfWP-YKlOT3Y{-F(B|n>lZ8ZLNO0 z`*6&S!v;L3|3{xleby&*b8GhZC$ZZf;c_Mp*Apvz;m`Br^R@Th?*!SC^4P?8`(~aw zz0rlpL9*a+|L$$K-}2_q3axzKl(=NAIC_^>FiV!KaNe%8H2L7c zgGZ%*$n3KZoE`D#C)fKAHr`4n`dtojvlrQP@7=qXal)qW%bx1p*qD6$T=kor+7ItT zbj7-7UecX@`s@X9W9#If1-75xY+gCDf8HAV>W?R{T>tzqes#ZmeU*jr=kxR3SNp$< zn|JHyyZ2wuO^r`aJ9fGGY`Xq@f8N+VTYl|WJ%9fCyjsi6pD+Kte=Yv}-sbXuNB{q- z+IREM?|(L5YkP0Me*gN#u`B04KWzSb{`2?v{}!7+zvVB#HvjL((`U}@s4D*Y@#5qA z>1pfg>)w8~kDGCm>4!as@C0Qahdu*F%R?+ruyD?4mOu5=+wFTRrfl}yn{j2cx9ogl zmRWr>_tLjbx0fsr4nG*T86*;JZ-4uA-ei!{U3+K0&jzVDnY!I`Hc;^1E}(*k`)wJs zWS%z2Br+AXaGnrUQ*fUF<5)fw*Eue6{P^+r8@KM?pMShh)_St_<244opZAv*UVH!h z7AQC?%W>#NF$#ra`T2kHt*h0m%HG`ASR5Dkh_wjAi1(*%ZcJXj)p(C~`tiQG5Be6% z;13Uskh(W@bMkS&yyLrz956ILjw5*Uo)dH%HdGtjW3$=mMPah)t#<{2VZ(cgns$#b}A48SLcCwxp= zhZ<+-PDR8fR0bTf>f3=~pn#$IBiPAN)`!9V<9ufUbOHACht1u= 320) wCursor = 320-xCursor; @@ -84,12 +87,14 @@ static void __not_in_flash_func(_scanline_callback)(void) { *scanline++ = palette[*screenPos++]; // convert using palette => buffer. } if (cursorEnabled && lineCounter>=yCursor && lineCounter= 0 && xCursor < 320-16) { // On Screen ? + const uint8_t *cursorData = cursorImage + (lineCounter-yCursor) * 16; + cursline += xCursor; // Position on this line. + for (uint16_t i = 0;i < wCursor;i++) { // Each pixel. + uint8_t pixel = *cursorData++; + if (pixel != 0xFF) *cursline = palette[pixel]; // Check for transparency + cursline++; + } } } }