You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MonochromeLib.c 37KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559
  1. /*************************************************************/
  2. /** MonochromeLib - monochrome graphic library for fx-9860G **/
  3. /** MonochromeLib is free software **/
  4. /** **/
  5. /** @author Pierre "PierrotLL" Le Gall **/
  6. /** @contact legallpierre89@gmail.com **/
  7. /** **/
  8. /** @file MonochromeLib.c **/
  9. /** Code file of MonochromeLib **/
  10. /** **/
  11. /** @date 11-22-2011 **/
  12. /*************************************************************/
  13. #include "MonochromeLib.h"
  14. #include <stdlib.h>
  15. #include "fxlib.h"
  16. #include "mathf.h"
  17. /******************************/
  18. /** Dependencies management **/
  19. /******************************/
  20. #ifdef ML_ALL
  21. #define ML_CLEAR_VRAM
  22. #define ML_CLEAR_SCREEN
  23. #define ML_DISPLAY_VRAM
  24. #define ML_SET_CONTRAST
  25. #define ML_GET_CONTRAST
  26. #define ML_PIXEL
  27. #define ML_POINT
  28. #define ML_PIXEL_TEST
  29. #define ML_LINE
  30. #define ML_HORIZONTAL_LINE
  31. #define ML_VERTICAL_LINE
  32. #define ML_RECTANGLE
  33. #define ML_POLYGON
  34. #define ML_FILLED_POLYGON
  35. #define ML_CIRCLE
  36. #define ML_FILLED_CIRCLE
  37. #define ML_ELLIPSE
  38. #define ML_ELLIPSE_IN_RECT
  39. #define ML_FILLED_ELLIPSE
  40. #define ML_FILLED_ELLIPSE_IN_RECT
  41. #define ML_HORIZONTAL_SCROLL
  42. #define ML_VERTICAL_SCROLL
  43. #define ML_BMP_OR
  44. #define ML_BMP_AND
  45. #define ML_BMP_XOR
  46. #define ML_BMP_OR_CL
  47. #define ML_BMP_AND_CL
  48. #define ML_BMP_XOR_CL
  49. #define ML_BMP_8_OR
  50. #define ML_BMP_8_AND
  51. #define ML_BMP_8_XOR
  52. #define ML_BMP_8_OR_CL
  53. #define ML_BMP_8_AND_CL
  54. #define ML_BMP_8_XOR_CL
  55. #define ML_BMP_16_OR
  56. #define ML_BMP_16_AND
  57. #define ML_BMP_16_XOR
  58. #define ML_BMP_16_OR_CL
  59. #define ML_BMP_16_AND_CL
  60. #define ML_BMP_16_XOR_CL
  61. #define ML_BMP_OR_ZOOM
  62. #define ML_BMP_AND_ZOOM
  63. #define ML_BMP_XOR_ZOOM
  64. #define ML_BMP_OR_ROTATE
  65. #define ML_BMP_AND_ROTATE
  66. #define ML_BMP_XOR_ROTATE
  67. #endif
  68. #ifdef ML_POLYGON
  69. #define ML_LINE
  70. #endif
  71. #ifdef ML_LINE
  72. #define ML_PIXEL
  73. #endif
  74. #ifdef ML_POINT
  75. #define ML_PIXEL
  76. #define ML_RECTANGLE
  77. #endif
  78. #ifdef ML_RECTANGLE
  79. #define ML_HORIZONTAL_LINE
  80. #endif
  81. #ifdef ML_FILLED_POLYGON
  82. #define ML_HORIZONTAL_LINE
  83. #endif
  84. #ifdef ML_CIRCLE
  85. #define ML_PIXEL
  86. #endif
  87. #ifdef ML_FILLED_CIRCLE
  88. #define ML_HORIZONTAL_LINE
  89. #endif
  90. #ifdef ML_ELLIPSE_IN_RECT
  91. #define ML_ELLIPSE
  92. #endif
  93. #ifdef ML_ELLIPSE
  94. #define ML_PIXEL
  95. #endif
  96. #ifdef ML_FILLED_ELLIPSE_IN_RECT
  97. #define ML_FILLED_ELLIPSE
  98. #endif
  99. #ifdef ML_FILLED_ELLIPSE
  100. #define ML_HORIZONTAL_LINE
  101. #endif
  102. /***************/
  103. /** Functions **/
  104. /***************/
  105. #define sgn(x) (x<0?-1:1)
  106. #define rnd(x) ((int)(x+0.5))
  107. //Thanks to Simon Lothar for this function
  108. static int SysCallCode[] = {0xD201422B,0x60F20000,0x80010070};
  109. static int (*SysCall)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
  110. char* ML_vram_adress()
  111. {
  112. return (char*)((*SysCall)(0, 0, 0, 0, 309));
  113. }
  114. #ifdef ML_CLEAR_VRAM
  115. void ML_clear_vram()
  116. {
  117. int i, end, *pointer_long, vram;
  118. char *pointer_byte;
  119. vram = (int)ML_vram_adress();
  120. end = 4-vram&3;
  121. pointer_byte = (char*)vram;
  122. for(i=0 ; i<end ; i++) pointer_byte[i] = 0;
  123. pointer_long = (int*) (vram+end);
  124. for(i=0 ; i<255 ; i++) pointer_long[i] = 0;
  125. pointer_byte += 1020+end;
  126. end = vram&3;
  127. for(i=0 ; i<end ; i++) pointer_byte[i] = 0;
  128. }
  129. #endif
  130. #ifdef ML_CLEAR_SCREEN
  131. void ML_clear_screen()
  132. {
  133. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
  134. int i, j;
  135. for(i=0 ; i<64 ; i++)
  136. {
  137. *LCD_register_selector = 4;
  138. *LCD_data_register = i|192;
  139. *LCD_register_selector = 4;
  140. *LCD_data_register = 0;
  141. *LCD_register_selector = 7;
  142. for(j=0 ; j<16 ; j++) *LCD_data_register = 0;
  143. }
  144. }
  145. #endif
  146. #ifdef ML_DISPLAY_VRAM
  147. void ML_display_vram()
  148. {
  149. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000, *vram;
  150. int i, j;
  151. vram = ML_vram_adress();
  152. for(i=0 ; i<64 ; i++)
  153. {
  154. *LCD_register_selector = 4;
  155. *LCD_data_register = i|192;
  156. *LCD_register_selector = 4;
  157. *LCD_data_register = 0;
  158. *LCD_register_selector = 7;
  159. for(j=0 ; j<16 ; j++) *LCD_data_register = *vram++;
  160. }
  161. }
  162. #endif
  163. #ifdef ML_SET_CONTRAST
  164. void ML_set_contrast(unsigned char contrast)
  165. {
  166. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
  167. *LCD_register_selector = 6;
  168. *LCD_data_register = contrast;
  169. }
  170. #endif
  171. #ifdef ML_GET_CONTRAST
  172. unsigned char ML_get_contrast()
  173. {
  174. char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
  175. *LCD_register_selector = 6;
  176. return *LCD_data_register;
  177. }
  178. #endif
  179. #ifdef ML_PIXEL
  180. void ML_pixel(int x, int y, ML_Color color)
  181. {
  182. char* vram = ML_vram_adress();
  183. if(x&~127 || y&~63) return;
  184. switch(color)
  185. {
  186. case ML_BLACK:
  187. vram[(y<<4)+(x>>3)] |= 128>>(x&7);
  188. break;
  189. case ML_WHITE:
  190. vram[(y<<4)+(x>>3)] &= ~(128>>(x&7));
  191. break;
  192. case ML_XOR:
  193. vram[(y<<4)+(x>>3)] ^= 128>>(x&7);
  194. break;
  195. case ML_CHECKER:
  196. if(y&1^x&1) vram[(y<<4)+(x>>3)] &= ~(128>>(x&7));
  197. else vram[(y<<4)+(x>>3)] |= 128>>(x&7);
  198. break;
  199. }
  200. }
  201. #endif
  202. #ifdef ML_POINT
  203. void ML_point(int x, int y, int width, ML_Color color)
  204. {
  205. if(width < 1) return;
  206. if(width == 1) ML_pixel(x, y, color);
  207. else
  208. {
  209. int padding, pair;
  210. padding = width>>1;
  211. pair = !(width&1);
  212. ML_rectangle(x-padding+pair, y-padding+pair, x+padding, y+padding, 0, 0, color);
  213. }
  214. }
  215. #endif
  216. #ifdef ML_PIXEL_TEST
  217. ML_Color ML_pixel_test(int x, int y)
  218. {
  219. char *vram, byte;
  220. if(x&~127 || y&~63) return ML_TRANSPARENT;
  221. vram = ML_vram_adress();
  222. byte = 1<<(7-(x&7));
  223. return (vram[(y<<4)+(x>>3)] & byte ? ML_BLACK : ML_WHITE);
  224. }
  225. #endif
  226. #ifdef ML_LINE
  227. void ML_line(int x1, int y1, int x2, int y2, ML_Color color)
  228. {
  229. int i, x, y, dx, dy, sx, sy, cumul;
  230. x = x1;
  231. y = y1;
  232. dx = x2 - x1;
  233. dy = y2 - y1;
  234. sx = sgn(dx);
  235. sy = sgn(dy);
  236. dx = abs(dx);
  237. dy = abs(dy);
  238. ML_pixel(x, y, color);
  239. if(dx > dy)
  240. {
  241. cumul = dx / 2;
  242. for(i=1 ; i<dx ; i++)
  243. {
  244. x += sx;
  245. cumul += dy;
  246. if(cumul > dx)
  247. {
  248. cumul -= dx;
  249. y += sy;
  250. }
  251. ML_pixel(x, y, color);
  252. }
  253. }
  254. else
  255. {
  256. cumul = dy / 2;
  257. for(i=1 ; i<dy ; i++)
  258. {
  259. y += sy;
  260. cumul += dx;
  261. if(cumul > dy)
  262. {
  263. cumul -= dy;
  264. x += sx;
  265. }
  266. ML_pixel(x, y, color);
  267. }
  268. }
  269. }
  270. #endif
  271. #ifdef ML_HORIZONTAL_LINE
  272. void ML_horizontal_line(int y, int x1, int x2, ML_Color color)
  273. {
  274. int i;
  275. char checker;
  276. char* vram = ML_vram_adress();
  277. if(y&~63 || (x1<0 && x2<0) || (x1>127 && x2>127)) return;
  278. if(x1 > x2)
  279. {
  280. i = x1;
  281. x1 = x2;
  282. x2 = i;
  283. }
  284. if(x1 < 0) x1 = 0;
  285. if(x2 > 127) x2 = 127;
  286. switch(color)
  287. {
  288. case ML_BLACK:
  289. if(x1>>3 != x2>>3)
  290. {
  291. vram[(y<<4)+(x1>>3)] |= 255 >> (x1&7);
  292. vram[(y<<4)+(x2>>3)] |= 255 << 7-(x2&7);
  293. for(i=(x1>>3)+1 ; i<x2>>3 ; i++)
  294. vram[(y<<4) + i] = 255;
  295. }
  296. else vram[(y<<4)+(x1>>3)] |= (255>>(x1%8 + 7-x2%8))<<(7-(x2&7));
  297. break;
  298. case ML_WHITE:
  299. if(x1>>3 != x2>>3)
  300. {
  301. vram[(y<<4)+(x1>>3)] &= 255 << 8-(x1&7);
  302. vram[(y<<4)+(x2>>3)] &= 255 >> 1+(x2&7);
  303. for(i=(x1>>3)+1 ; i<x2>>3 ; i++)
  304. vram[(y<<4) + i] = 0;
  305. }
  306. else vram[(y<<4)+(x1>>3)] &= (255<<8-(x1&7)) | (255>>1+(x2&7));
  307. break;
  308. case ML_XOR:
  309. if(x1>>3 != x2>>3)
  310. {
  311. vram[(y<<4)+(x1>>3)] ^= 255 >> (x1&7);
  312. vram[(y<<4)+(x2>>3)] ^= 255 << 7-(x2&7);
  313. for(i=(x1>>3)+1 ; i<(x2>>3) ; i++)
  314. vram[(y<<4) + i] ^= 255;
  315. }
  316. else vram[(y<<4)+(x1>>3)] ^= (255>>((x1&7) + 7-(x2&7)))<<(7-(x2&7));
  317. break;
  318. case ML_CHECKER:
  319. checker = (y&1 ? 85 : 170);
  320. if(x1>>3 != x2>>3)
  321. {
  322. vram[(y<<4)+(x1>>3)] &= 255 << 8-(x1&7);
  323. vram[(y<<4)+(x2>>3)] &= 255 >> 1+(x2&7);
  324. vram[(y<<4)+(x1>>3)] |= checker & 255>>(x1&7);
  325. vram[(y<<4)+(x2>>3)] |= checker & 255<<7-(x2&7);
  326. for(i=(x1>>3)+1 ; i<x2>>3 ; i++)
  327. vram[(y<<4) + i] = checker;
  328. }
  329. else
  330. {
  331. vram[(y<<4)+(x1>>3)] &= (255<<8-(x1&7)) | (255>>1+(x2&7));
  332. vram[(y<<4)+(x1>>3)] |= checker & (255>>(x1%8 + 7-x2%8))<<(7-(x2&7));
  333. }
  334. break;
  335. }
  336. }
  337. #endif
  338. #ifdef ML_VERTICAL_LINE
  339. void ML_vertical_line(int x, int y1, int y2, ML_Color color)
  340. {
  341. int i, j;
  342. char checker, byte, *vram = ML_vram_adress();
  343. if(x&~127 || (y1<0 && y2<0) || (y1>63 && y2>63)) return;
  344. if(y1 > y2)
  345. {
  346. int tmp = y1;
  347. y1 = y2;
  348. y2 = tmp;
  349. }
  350. if(y1 < 0) y1 = 0;
  351. if(y2 > 63) y2 = 63;
  352. i = (y1<<4)+(x>>3);
  353. j = (y2<<4)+(x>>3);
  354. switch(color)
  355. {
  356. case ML_BLACK:
  357. byte = 128>>(x&7);
  358. for( ; i<=j ; i+=16)
  359. vram[i] |= byte;
  360. break;
  361. case ML_WHITE:
  362. byte = ~(128>>(x&7));
  363. for( ; i<=j ; i+=16)
  364. vram[i] &= byte;
  365. break;
  366. case ML_XOR:
  367. byte = 128>>(x&7);
  368. for( ; i<=j ; i+=16)
  369. vram[i] ^= byte;
  370. break;
  371. case ML_CHECKER:
  372. byte = 128>>(x&7);
  373. checker = y1&1^x&1;
  374. for( ; i<=j ; i+=16)
  375. {
  376. if(checker) vram[i] &= ~byte;
  377. else vram[i] |= byte;
  378. checker = !checker;
  379. }
  380. break;
  381. }
  382. }
  383. #endif
  384. #ifdef ML_RECTANGLE
  385. void ML_rectangle(int x1, int y1, int x2, int y2, int border_width, ML_Color border_color, ML_Color fill_color)
  386. {
  387. int i;
  388. if(x1 > x2)
  389. {
  390. i = x1;
  391. x1 = x2;
  392. x2 = i;
  393. }
  394. if(y1 > y2)
  395. {
  396. i = y1;
  397. y1 = y2;
  398. y2 = i;
  399. }
  400. if(border_width > (x2-x1)/2+1) border_width = (x2-x1)/2+1;
  401. if(border_width > (y2-y1)/2+1) border_width = (y2-y1)/2+1;
  402. if(border_color != ML_TRANSPARENT && border_width > 0)
  403. {
  404. for(i=0 ; i<border_width ; i++)
  405. {
  406. ML_horizontal_line(y1+i, x1, x2, border_color);
  407. ML_horizontal_line(y2-i, x1, x2, border_color);
  408. }
  409. for(i=y1+border_width ; i<=y2-border_width ; i++)
  410. {
  411. ML_horizontal_line(i, x1, x1+border_width-1, border_color);
  412. ML_horizontal_line(i, x2-border_width+1, x2, border_color);
  413. }
  414. }
  415. if(fill_color != ML_TRANSPARENT)
  416. {
  417. for(i=y1+border_width ; i<=y2-border_width ; i++)
  418. ML_horizontal_line(i, x1+border_width, x2-border_width, fill_color);
  419. }
  420. }
  421. #endif
  422. #ifdef ML_POLYGON
  423. void ML_polygon(const int *x, const int *y, int nb_vertices, ML_Color color)
  424. {
  425. int i;
  426. if(nb_vertices < 1) return;
  427. for(i=0 ; i<nb_vertices-1 ; i++)
  428. ML_line(x[i], y[i], x[i+1], y[i+1], color);
  429. ML_line(x[i], y[i], x[0], y[0], color);
  430. }
  431. #endif
  432. #ifdef ML_FILLED_POLYGON
  433. static int ML_filled_polygon_quicksord_partition(int *t, int p, int r)
  434. {
  435. int i, j, x, tmp;
  436. j = p - 1;
  437. x = t[r];
  438. for(i=p ; i<r ; i++)
  439. {
  440. if(x > t[i])
  441. {
  442. j++;
  443. tmp = t[j];
  444. t[j] = t[i];
  445. t[i] = tmp;
  446. }
  447. }
  448. t[r] = t[j+1];
  449. t[j+1] = x;
  450. return j + 1;
  451. }
  452. static void ML_filled_polygon_quicksord(int* t, int p, int r)
  453. {
  454. int q;
  455. if(p < r)
  456. {
  457. q = ML_filled_polygon_quicksord_partition(t, p, r);
  458. ML_filled_polygon_quicksord(t, p, q-1);
  459. ML_filled_polygon_quicksord(t, q+1, r);
  460. }
  461. }
  462. void ML_filled_polygon(const int *x, const int *y, int nb_vertices, ML_Color color)
  463. {
  464. int i, j, dx, dy, ymin, ymax;
  465. int *cut_in_line, nb_cut;
  466. if(nb_vertices < 3) return;
  467. cut_in_line = malloc(nb_vertices*sizeof(int));
  468. if(!cut_in_line) return;
  469. ymin = ymax = y[0];
  470. for(i=1 ; i<nb_vertices ; i++)
  471. {
  472. if(y[i] < ymin) ymin = y[i];
  473. if(y[i] > ymax) ymax = y[i];
  474. }
  475. for(i=ymin ; i<=ymax ; i++)
  476. {
  477. nb_cut = 0;
  478. for(j=0 ; j<nb_vertices ; j++)
  479. {
  480. if((y[j]<=i && y[(j+1)%nb_vertices]>=i) || (y[j]>=i && y[(j+1)%nb_vertices]<=i))
  481. {
  482. dy = abs(y[j]-y[(j+1)%nb_vertices]);
  483. if(dy)
  484. {
  485. dx = x[(j+1)%nb_vertices]-x[j];
  486. cut_in_line[nb_cut] = x[j] + rnd(abs(i-y[j]+sgn(i-y[j])/2)*dx/dy);
  487. nb_cut++;
  488. }
  489. }
  490. }
  491. ML_filled_polygon_quicksord(cut_in_line, 0, nb_cut-1);
  492. j = 0;
  493. while(j<nb_cut-2 && cut_in_line[j]==cut_in_line[j+1]) j++;
  494. while(j < nb_cut)
  495. {
  496. if(j == nb_cut-1) ML_horizontal_line(i, cut_in_line[j-1]+1, cut_in_line[j], color);
  497. else
  498. {
  499. dx = 1;
  500. while(j+dx<nb_cut-1 && cut_in_line[j+dx]==cut_in_line[j+dx+1]) dx++;
  501. ML_horizontal_line(i, cut_in_line[j], cut_in_line[j+dx], color);
  502. j += dx;
  503. }
  504. j++;
  505. }
  506. }
  507. free(cut_in_line);
  508. }
  509. #endif
  510. #ifdef ML_CIRCLE
  511. void ML_circle(int x, int y, int radius, ML_Color color)
  512. {
  513. int plot_x, plot_y, d;
  514. if(radius < 0) return;
  515. plot_x = 0;
  516. plot_y = radius;
  517. d = 1 - radius;
  518. ML_pixel(x, y+plot_y, color);
  519. if(radius)
  520. {
  521. ML_pixel(x, y-plot_y, color);
  522. ML_pixel(x+plot_y, y, color);
  523. ML_pixel(x-plot_y, y, color);
  524. }
  525. while(plot_y > plot_x)
  526. {
  527. if(d < 0)
  528. d += 2*plot_x+3;
  529. else
  530. {
  531. d += 2*(plot_x-plot_y)+5;
  532. plot_y--;
  533. }
  534. plot_x++;
  535. if(plot_y >= plot_x)
  536. {
  537. ML_pixel(x+plot_x, y+plot_y, color);
  538. ML_pixel(x-plot_x, y+plot_y, color);
  539. ML_pixel(x+plot_x, y-plot_y, color);
  540. ML_pixel(x-plot_x, y-plot_y, color);
  541. }
  542. if(plot_y > plot_x)
  543. {
  544. ML_pixel(x+plot_y, y+plot_x, color);
  545. ML_pixel(x-plot_y, y+plot_x, color);
  546. ML_pixel(x+plot_y, y-plot_x, color);
  547. ML_pixel(x-plot_y, y-plot_x, color);
  548. }
  549. }
  550. }
  551. #endif
  552. #ifdef ML_FILLED_CIRCLE
  553. void ML_filled_circle(int x, int y, int radius, ML_Color color)
  554. {
  555. int plot_x, plot_y, d;
  556. if(radius < 0) return;
  557. plot_x = 0;
  558. plot_y = radius;
  559. d = 1 - radius;
  560. ML_horizontal_line(y, x-plot_y, x+plot_y, color);
  561. while(plot_y > plot_x)
  562. {
  563. if(d < 0)
  564. d += 2*plot_x+3;
  565. else {
  566. d += 2*(plot_x-plot_y)+5;
  567. plot_y--;
  568. ML_horizontal_line(y+plot_y+1, x-plot_x, x+plot_x, color);
  569. ML_horizontal_line(y-plot_y-1, x-plot_x, x+plot_x, color);
  570. }
  571. plot_x++;
  572. if(plot_y >= plot_x)
  573. {
  574. ML_horizontal_line(y+plot_x, x-plot_y, x+plot_y, color);
  575. ML_horizontal_line(y-plot_x, x-plot_y, x+plot_y, color);
  576. }
  577. }
  578. }
  579. #endif
  580. #ifdef ML_ELLIPSE
  581. void ML_ellipse(int x, int y, int radius1, int radius2, ML_Color color)
  582. {
  583. int plot_x, plot_y;
  584. float d1, d2;
  585. if(radius1 < 1 || radius2 < 1) return;
  586. plot_x = 0;
  587. plot_y = radius2;
  588. d1 = radius2*radius2 - radius1*radius1*radius2 + radius1*radius1/4;
  589. ML_pixel(x, y+plot_y, color);
  590. ML_pixel(x, y-plot_y, color);
  591. while(radius1*radius1*(plot_y-.5) > radius2*radius2*(plot_x+1))
  592. {
  593. if(d1 < 0)
  594. {
  595. d1 += radius2*radius2*(2*plot_x+3);
  596. plot_x++;
  597. } else {
  598. d1 += radius2*radius2*(2*plot_x+3) + radius1*radius1*(-2*plot_y+2);
  599. plot_x++;
  600. plot_y--;
  601. }
  602. ML_pixel(x+plot_x, y+plot_y, color);
  603. ML_pixel(x-plot_x, y+plot_y, color);
  604. ML_pixel(x+plot_x, y-plot_y, color);
  605. ML_pixel(x-plot_x, y-plot_y, color);
  606. }
  607. d2 = radius2*radius2*(plot_x+.5)*(plot_x+.5) + radius1*radius1*(plot_y-1)*(plot_y-1) - radius1*radius1*radius2*radius2;
  608. while(plot_y > 0)
  609. {
  610. if(d2 < 0)
  611. {
  612. d2 += radius2*radius2*(2*plot_x+2) + radius1*radius1*(-2*plot_y+3);
  613. plot_y--;
  614. plot_x++;
  615. } else {
  616. d2 += radius1*radius1*(-2*plot_y+3);
  617. plot_y--;
  618. }
  619. ML_pixel(x+plot_x, y+plot_y, color);
  620. ML_pixel(x-plot_x, y+plot_y, color);
  621. if(plot_y > 0)
  622. {
  623. ML_pixel(x+plot_x, y-plot_y, color);
  624. ML_pixel(x-plot_x, y-plot_y, color);
  625. }
  626. }
  627. }
  628. #endif
  629. #ifdef ML_ELLIPSE_IN_RECT
  630. void ML_ellipse_in_rect(int x1, int y1, int x2, int y2, ML_Color color)
  631. {
  632. int radius1, radius2;
  633. if(x1 > x2)
  634. {
  635. int tmp = x1;
  636. x1 = x2;
  637. x2 = tmp;
  638. }
  639. if(y1 > y2)
  640. {
  641. int tmp = y1;
  642. y1 = y2;
  643. y2 = tmp;
  644. }
  645. radius1 = (x2-x1)/2;
  646. radius2 = (y2-y1)/2;
  647. ML_ellipse(x1+radius1, y1+radius2, radius1, radius2, color);
  648. }
  649. #endif
  650. #ifdef ML_FILLED_ELLIPSE
  651. void ML_filled_ellipse(int x, int y, int radius1, int radius2, ML_Color color)
  652. {
  653. int plot_x, plot_y;
  654. float d1, d2;
  655. if(radius1 < 1 || radius2 < 1) return;
  656. plot_x = 0;
  657. plot_y = radius2;
  658. d1 = radius2*radius2 - radius1*radius1*radius2 + radius1*radius1/4;
  659. while(radius1*radius1*(plot_y-.5) > radius2*radius2*(plot_x+1))
  660. {
  661. if(d1 < 0)
  662. {
  663. d1 += radius2*radius2*(2*plot_x+3);
  664. plot_x++;
  665. } else {
  666. d1 += radius2*radius2*(2*plot_x+3) + radius1*radius1*(-2*plot_y+2);
  667. ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color);
  668. ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color);
  669. plot_x++;
  670. plot_y--;
  671. }
  672. }
  673. ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color);
  674. ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color);
  675. d2 = radius2*radius2*(plot_x+.5)*(plot_x+.5) + radius1*radius1*(plot_y-1)*(plot_y-1) - radius1*radius1*radius2*radius2;
  676. while(plot_y > 0)
  677. {
  678. if(d2 < 0)
  679. {
  680. d2 += radius2*radius2*(2*plot_x+2) + radius1*radius1*(-2*plot_y+3);
  681. plot_y--;
  682. plot_x++;
  683. } else {
  684. d2 += radius1*radius1*(-2*plot_y+3);
  685. plot_y--;
  686. }
  687. ML_horizontal_line(y+plot_y, x-plot_x, x+plot_x, color);
  688. if(plot_y > 0)
  689. ML_horizontal_line(y-plot_y, x-plot_x, x+plot_x, color);
  690. }
  691. }
  692. #endif
  693. #ifdef ML_FILLED_ELLIPSE_IN_RECT
  694. void ML_filled_ellipse_in_rect(int x1, int y1, int x2, int y2, ML_Color color)
  695. {
  696. int radius1, radius2;
  697. if(x1 > x2)
  698. {
  699. int tmp = x1;
  700. x1 = x2;
  701. x2 = tmp;
  702. }
  703. if(y1 > y2)
  704. {
  705. int tmp = y1;
  706. y1 = y2;
  707. y2 = tmp;
  708. }
  709. radius1 = (x2-x1)/2;
  710. radius2 = (y2-y1)/2;
  711. ML_filled_ellipse(x1+radius1, y1+radius2, radius1, radius2, color);
  712. }
  713. #endif
  714. #ifdef ML_HORIZONTAL_SCROLL
  715. void ML_horizontal_scroll(int scroll)
  716. {
  717. int i, j;
  718. char line[16], shift, *vram;
  719. unsigned char next;
  720. unsigned short word;
  721. vram = ML_vram_adress();
  722. scroll %= 128;
  723. shift = 8-(scroll&7);
  724. for(i=0 ; i<64 ; i++)
  725. {
  726. for(j=0 ; j<16 ; j++) line[j] = vram[(i<<4)+((j-(scroll>>3)+15)&15)];
  727. next = line[15];
  728. vram[(i<<4)+15] = 0;
  729. for(j=15 ; j>0 ; j--)
  730. {
  731. word = next << shift;
  732. next = line[j-1];
  733. vram[(i<<4)+j] |= *((char*)&word+1);
  734. vram[(i<<4)+j-1] = *((char*)&word);
  735. }
  736. word = next << shift;
  737. vram[(i<<4)] |= *((char*)&word+1);
  738. vram[(i<<4)+15] |= *((char*)&word);
  739. }
  740. }
  741. #endif
  742. #ifdef ML_VERTICAL_SCROLL
  743. void ML_vertical_scroll(int scroll)
  744. {
  745. int i, j;
  746. char column[64], *vram = ML_vram_adress();
  747. scroll %= 64;
  748. for(i=0 ; i<16 ; i++)
  749. {
  750. for(j=0 ; j<64 ; j++) column[j] = vram[(j<<4)+i];
  751. for(j=0 ; j<64 ; j++) vram[(j<<4)+i] = column[(j-scroll+64)&63];
  752. }
  753. }
  754. #endif
  755. #ifdef ML_BMP_OR
  756. void ML_bmp_or(const unsigned char *bmp, int x, int y, int width, int height)
  757. {
  758. unsigned short line;
  759. char shift, *screen, *p=(char*)&line;
  760. int i, j, begin=0, end=height, real_width=(width-1>>3<<3)+8;
  761. if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return;
  762. if(y < 0) begin = -y;
  763. if(y+height > 64) end = 64-y;
  764. shift = 8-(x&7);
  765. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  766. for(i=begin ; i<end ; i++)
  767. {
  768. for(j=0 ; j<width-1>>3 ; j++)
  769. {
  770. line = bmp[i*(real_width>>3)+j]<<shift;
  771. screen[j] |= *p;
  772. if(shift!=8) screen[j+1] |= *(p+1);
  773. }
  774. line = (bmp[i*(real_width>>3)+j] & -1<<(real_width-width))<<shift;
  775. screen[j] |= *p;
  776. if(shift!=8 && x+real_width<129) screen[j+1] |= *(p+1);
  777. screen += 16;
  778. }
  779. }
  780. #endif
  781. #ifdef ML_BMP_AND
  782. void ML_bmp_and(const unsigned char *bmp, int x, int y, int width, int height)
  783. {
  784. unsigned short line;
  785. char shift, *screen, *p=(char*)&line;
  786. int i, j, begin=0, end=height, real_width=(width-1>>3<<3)+8;
  787. if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return;
  788. if(y < 0) begin = -y;
  789. if(y+height > 64) end = 64-y;
  790. shift = 8-(x&7);
  791. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  792. for(i=begin ; i<end ; i++)
  793. {
  794. for(j=0 ; j<width-1>>3 ; j++)
  795. {
  796. line = ~((unsigned char)~bmp[i*(real_width>>3)+j]<<shift);
  797. screen[j] &= *p;
  798. if(shift!=8) screen[j+1] &= *(p+1);
  799. }
  800. line = ~((unsigned char)~(bmp[i*(real_width>>3)+j] | (unsigned char)-1>>8-(width&7))<<shift);
  801. screen[j] &= *p;
  802. if(shift!=8 && x+real_width<129) screen[j+1] &= *(p+1);
  803. screen += 16;
  804. }
  805. }
  806. #endif
  807. #ifdef ML_BMP_XOR
  808. void ML_bmp_xor(const unsigned char *bmp, int x, int y, int width, int height)
  809. {
  810. unsigned short line;
  811. char shift, *screen, *p=(char*)&line;
  812. int i, j, begin=0, end=height, real_width=(width-1>>3<<3)+8;
  813. if(!bmp || x<0 || x>128-width || y<1-height || y>63 || width<1 || height<1) return;
  814. if(y < 0) begin = -y;
  815. if(y+height > 64) end = 64-y;
  816. shift = 8-(x&7);
  817. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  818. for(i=begin ; i<end ; i++)
  819. {
  820. for(j=0 ; j<width-1>>3 ; j++)
  821. {
  822. line = bmp[i*(real_width>>3)+j]<<shift;
  823. screen[j] ^= *p;
  824. if(shift!=8) screen[j+1] ^= *(p+1);
  825. }
  826. line = (bmp[i*(real_width>>3)+j] & -1<<(real_width-width))<<shift;
  827. screen[j] ^= *p;
  828. if(shift!=8 && x+real_width<129) screen[j+1] ^= *(p+1);
  829. screen += 16;
  830. }
  831. }
  832. #endif
  833. #ifdef ML_BMP_OR_CL
  834. void ML_bmp_or_cl(const unsigned char *bmp, int x, int y, int width, int height)
  835. {
  836. unsigned short line;
  837. char shift, *screen, *p;
  838. int i, j, real_width, begin_x, end_x, begin_y, end_y;
  839. char bool1=1, bool2=1, bool3;
  840. if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
  841. p = (char*)&line;
  842. real_width = (width-1>>3<<3)+8;
  843. if(y < 0) begin_y = -y;
  844. else begin_y = 0;
  845. if(y+height > 64) end_y = 64-y;
  846. else end_y = height;
  847. shift = 8-(x&7);
  848. if(x<0)
  849. {
  850. begin_x = -x>>3;
  851. if(shift != 8) bool1 = 0;
  852. } else begin_x = 0;
  853. if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
  854. else end_x = real_width-1>>3;
  855. bool3 = (end_x == real_width-1>>3);
  856. screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
  857. for(i=begin_y ; i<end_y ; i++)
  858. {
  859. if(begin_x < end_x)
  860. {
  861. line = bmp[i*(real_width>>3)+begin_x] << shift;
  862. if(bool1) screen[begin_x] |= *p;
  863. if(shift!=8) screen[begin_x+1] |= *(p+1);
  864. for(j=begin_x+1 ; j<end_x ; j++)
  865. {
  866. line = bmp[i*(real_width>>3)+j] << shift;
  867. screen[j] |= *p;
  868. if(shift!=8) screen[j+1] |= *(p+1);
  869. }
  870. }
  871. line = bmp[i*(real_width>>3)+end_x];
  872. if(bool3) line &= -1<<real_width-width;
  873. line <<= shift;
  874. if(begin_x < end_x || bool1) screen[end_x] |= *p;
  875. if(bool2) screen[end_x+1] |= *(p+1);
  876. screen += 16;
  877. }
  878. }
  879. #endif
  880. #ifdef ML_BMP_AND_CL
  881. void ML_bmp_and_cl(const unsigned char *bmp, int x, int y, int width, int height)
  882. {
  883. unsigned short line;
  884. char shift, *screen, *p;
  885. int i, j, real_width, begin_x, end_x, begin_y, end_y;
  886. char bool1=1, bool2=1, bool3;
  887. if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
  888. p = (char*)&line;
  889. real_width = (width-1>>3<<3)+8;
  890. if(y < 0) begin_y = -y;
  891. else begin_y = 0;
  892. if(y+height > 64) end_y = 64-y;
  893. else end_y = height;
  894. shift = 8-(x&7);
  895. if(x<0)
  896. {
  897. begin_x = -x>>3;
  898. if(shift != 8) bool1 = 0;
  899. } else begin_x = 0;
  900. if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
  901. else end_x = real_width-1>>3;
  902. bool3 = (end_x == real_width-1>>3);
  903. screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
  904. for(i=begin_y ; i<end_y ; i++)
  905. {
  906. if(begin_x < end_x)
  907. {
  908. line = ~((unsigned char)~bmp[i*(real_width>>3)+begin_x]<<shift);
  909. if(bool1) screen[begin_x] &= *p;
  910. if(shift!=8) screen[begin_x+1] &= *(p+1);
  911. for(j=begin_x+1 ; j<end_x ; j++)
  912. {
  913. line = ~((unsigned char)~bmp[i*(real_width>>3)+j]<<shift);
  914. screen[j] &= *p;
  915. if(shift!=8) screen[j+1] &= *(p+1);
  916. }
  917. }
  918. line = (unsigned char)~bmp[i*(real_width>>3)+end_x];
  919. if(bool3) line &= -1<<real_width-width;
  920. line = ~(line << shift);
  921. if(begin_x < end_x || bool1) screen[end_x] &= *p;
  922. if(bool2) screen[end_x+1] &= *(p+1);
  923. screen += 16;
  924. }
  925. }
  926. #endif
  927. #ifdef ML_BMP_XOR_CL
  928. void ML_bmp_xor_cl(const unsigned char *bmp, int x, int y, int width, int height)
  929. {
  930. unsigned short line;
  931. char shift, *screen, *p;
  932. int i, j, real_width, begin_x, end_x, begin_y, end_y;
  933. char bool1=1, bool2=1, bool3;
  934. if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
  935. p = (char*)&line;
  936. real_width = (width-1>>3<<3)+8;
  937. if(y < 0) begin_y = -y;
  938. else begin_y = 0;
  939. if(y+height > 64) end_y = 64-y;
  940. else end_y = height;
  941. shift = 8-(x&7);
  942. if(x<0)
  943. {
  944. begin_x = -x>>3;
  945. if(shift != 8) bool1 = 0;
  946. } else begin_x = 0;
  947. if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
  948. else end_x = real_width-1>>3;
  949. bool3 = (end_x == real_width-1>>3);
  950. screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
  951. for(i=begin_y ; i<end_y ; i++)
  952. {
  953. if(begin_x < end_x)
  954. {
  955. line = bmp[i*(real_width>>3)+begin_x] << shift;
  956. if(bool1) screen[begin_x] ^= *p;
  957. if(shift!=8) screen[begin_x+1] ^= *(p+1);
  958. for(j=begin_x+1 ; j<end_x ; j++)
  959. {
  960. line = bmp[i*(real_width>>3)+j] << shift;
  961. screen[j] ^= *p;
  962. if(shift!=8) screen[j+1] ^= *(p+1);
  963. }
  964. }
  965. line = bmp[i*(real_width>>3)+end_x];
  966. if(bool3) line &= -1<<real_width-width;
  967. line <<= shift;
  968. if(begin_x < end_x || bool1) screen[end_x] ^= *p;
  969. if(bool2) screen[end_x+1] ^= *(p+1);
  970. screen += 16;
  971. }
  972. }
  973. #endif
  974. #ifdef ML_BMP_8_OR
  975. void ML_bmp_8_or(const unsigned char *bmp, int x, int y)
  976. {
  977. unsigned short line;
  978. char i, shift, begin=0, end=8, *screen, *p=(char*)&line;
  979. if(!bmp || x<0 || x>120 || y<-7 || y>63) return;
  980. if(y < 0) begin = -y;
  981. if(y > 56) end = 64-y;
  982. shift = 8-(x&7);
  983. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  984. for(i=begin ; i<end ; i++)
  985. {
  986. line = bmp[i]<<shift;
  987. screen[0] |= *p;
  988. if(shift!=8) screen[1] |= *(p+1);
  989. screen += 16;
  990. }
  991. }
  992. #endif
  993. #ifdef ML_BMP_8_AND
  994. void ML_bmp_8_and(const unsigned char *bmp, int x, int y)
  995. {
  996. unsigned short line;
  997. char i, shift, begin=0, end=8, *screen, *p=(char*)&line;
  998. if(!bmp || x<0 || x>120 || y<-7 || y>63) return;
  999. if(y < 0) begin = -y;
  1000. if(y > 56) end = 64-y;
  1001. shift = 8-(x&7);
  1002. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1003. for(i=begin ; i<end ; i++)
  1004. {
  1005. line = ~((unsigned char)~bmp[i]<<shift);
  1006. screen[0] &= *p;
  1007. if(shift!=8) screen[1] &= *(p+1);
  1008. screen += 16;
  1009. }
  1010. }
  1011. #endif
  1012. #ifdef ML_BMP_8_XOR
  1013. void ML_bmp_8_xor(const unsigned char *bmp, int x, int y)
  1014. {
  1015. unsigned short line;
  1016. char i, shift, begin=0, end=8, *screen, *p=(char*)&line;
  1017. if(!bmp || x<0 || x>120 || y<-7 || y>63) return;
  1018. if(y < 0) begin = -y;
  1019. if(y > 56) end = 64-y;
  1020. shift = 8-(x&7);
  1021. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1022. for(i=begin ; i<end ; i++)
  1023. {
  1024. line = bmp[i]<<shift;
  1025. screen[0] ^= *p;
  1026. if(shift<8) screen[1] ^= *(p+1);
  1027. screen += 16;
  1028. }
  1029. }
  1030. #endif
  1031. #ifdef ML_BMP_8_OR_CL
  1032. void ML_bmp_8_or_cl(const unsigned char *bmp, int x, int y)
  1033. {
  1034. unsigned short line;
  1035. char i, shift, begin=0, end=8, bool1=1, bool2=1, *screen, *p=(char*)&line;
  1036. if(!bmp || x<-7 || x>127 || y<-7 || y>63) return;
  1037. if(y < 0) begin = -y;
  1038. if(y > 56) end = 64-y;
  1039. shift = 8-(x&7);
  1040. if(x < 0) bool1 = 0;
  1041. if(x>120 || shift==8) bool2 = 0;
  1042. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1043. for(i=begin ; i<end ; i++)
  1044. {
  1045. line = bmp[i]<<shift;
  1046. if(bool1) screen[0] |= *p;
  1047. if(bool2) screen[1] |= *(p+1);
  1048. screen += 16;
  1049. }
  1050. }
  1051. #endif
  1052. #ifdef ML_BMP_8_AND_CL
  1053. void ML_bmp_8_and_cl(const unsigned char *bmp, int x, int y)
  1054. {
  1055. unsigned short line;
  1056. char i, shift, begin=0, end=8, bool1=1, bool2=1, *screen, *p=(char*)&line;
  1057. if(!bmp || x<-7 || x>127 || y<-7 || y>63) return;
  1058. if(y < 0) begin = -y;
  1059. if(y > 56) end = 64-y;
  1060. shift = 8-(x&7);
  1061. if(x < 0) bool1 = 0;
  1062. if(x>120 || shift==8) bool2 = 0;
  1063. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1064. for(i=begin ; i<end ; i++)
  1065. {
  1066. line = ~((unsigned char)~bmp[i]<<shift);
  1067. if(bool1) screen[0] &= *p;
  1068. if(bool2) screen[1] &= *(p+1);
  1069. screen += 16;
  1070. }
  1071. }
  1072. #endif
  1073. #ifdef ML_BMP_8_XOR_CL
  1074. void ML_bmp_8_xor_cl(const unsigned char *bmp, int x, int y)
  1075. {
  1076. unsigned short line;
  1077. char i, shift, begin=0, end=8, bool1=1, bool2=1, *screen, *p=(char*)&line;
  1078. if(!bmp || x<-7 || x>127 || y<-7 || y>63) return;
  1079. if(y < 0) begin = -y;
  1080. if(y > 56) end = 64-y;
  1081. shift = 8-(x&7);
  1082. if(x < 0) bool1 = 0;
  1083. if(x>120 || shift==8) bool2 = 0;
  1084. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1085. for(i=begin ; i<end ; i++)
  1086. {
  1087. line = bmp[i]<<shift;
  1088. if(bool1) screen[0] ^= *p;
  1089. if(bool2) screen[1] ^= *(p+1);
  1090. screen += 16;
  1091. }
  1092. }
  1093. #endif
  1094. #ifdef ML_BMP_16_OR
  1095. void ML_bmp_16_or(const unsigned short *bmp, int x, int y)
  1096. {
  1097. unsigned long line;
  1098. char i, shift, begin=0, end=16, *screen, *p=(char*)&line+1;
  1099. if(!bmp || x<0 || x>112 || y<-15 || y>63) return;
  1100. if(y < 0) begin = -y;
  1101. if(y > 48) end = 64-y;
  1102. shift = 8-(x&7);
  1103. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1104. for(i=begin ; i<end ; i++)
  1105. {
  1106. line = bmp[i]<<shift;
  1107. screen[0] |= *p;
  1108. screen[1] |= *(p+1);
  1109. if(shift!=8) screen[2] |= *(p+2);
  1110. screen += 16;
  1111. }
  1112. }
  1113. #endif
  1114. #ifdef ML_BMP_16_AND
  1115. void ML_bmp_16_and(const unsigned short *bmp, int x, int y)
  1116. {
  1117. unsigned long line;
  1118. char i, shift, begin=0, end=16, *screen, *p=(char*)&line+1;
  1119. if(!bmp || x<0 || x>112 || y<-15 || y>63) return;
  1120. if(y < 0) begin = -y;
  1121. if(y > 48) end = 64-y;
  1122. shift = 8-(x&7);
  1123. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1124. for(i=begin ; i<end ; i++)
  1125. {
  1126. line = ~((unsigned short)~bmp[i]<<shift);
  1127. screen[0] &= *p;
  1128. screen[1] &= *(p+1);
  1129. if(shift!=8) screen[2] &= *(p+2);
  1130. screen += 16;
  1131. }
  1132. }
  1133. #endif
  1134. #ifdef ML_BMP_16_XOR
  1135. void ML_bmp_16_xor(const unsigned short *bmp, int x, int y)
  1136. {
  1137. unsigned long line;
  1138. char i, shift, begin=0, end=16, *screen, *p=(char*)&line+1;
  1139. if(!bmp || x<0 || x>112 || y<-15 || y>63) return;
  1140. if(y < 0) begin = -y;
  1141. if(y > 48) end = 64-y;
  1142. shift = 8-(x&7);
  1143. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1144. for(i=begin ; i<end ; i++)
  1145. {
  1146. line = bmp[i]<<shift;
  1147. screen[0] ^= *p;
  1148. screen[1] ^= *(p+1);
  1149. if(shift!=8) screen[2] ^= *(p+2);
  1150. screen += 16;
  1151. }
  1152. }
  1153. #endif
  1154. #ifdef ML_BMP_16_OR_CL
  1155. void ML_bmp_16_or_cl(const unsigned short *bmp, int x, int y)
  1156. {
  1157. unsigned long line;
  1158. char i, shift, begin=0, end=16, bool1=1, bool2=1, bool3=1, *screen, *p=(char*)&line+1;
  1159. if(!bmp || x<-15 || x>127 || y<-15 || y>63) return;
  1160. if(y < 0) begin = -y;
  1161. if(y > 48) end = 64-y;
  1162. shift = 8-(x&7);
  1163. if(x < 0) bool1 = 0;
  1164. if(x<-8 || x>119) bool2 = 0;
  1165. if(x>111 || shift==8) bool3 = 0;
  1166. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1167. for(i=begin ; i<end ; i++)
  1168. {
  1169. line = bmp[i]<<shift;
  1170. if(bool1) screen[0] |= *p;
  1171. if(bool2) screen[1] |= *(p+1);
  1172. if(bool3) screen[2] |= *(p+2);
  1173. screen += 16;
  1174. }
  1175. }
  1176. #endif
  1177. #ifdef ML_BMP_16_AND_CL
  1178. void ML_bmp_16_and_cl(const unsigned short *bmp, int x, int y)
  1179. {
  1180. unsigned long line;
  1181. char i, shift, begin=0, end=16, bool1=1, bool2=1, bool3=1, *screen, *p=(char*)&line+1;
  1182. if(!bmp || x<-15 || x>127 || y<-15 || y>63) return;
  1183. if(y < 0) begin = -y;
  1184. if(y > 48) end = 64-y;
  1185. shift = 8-(x&7);
  1186. if(x < 0) bool1 = 0;
  1187. if(x<-8 || x>119) bool2 = 0;
  1188. if(x>111 || shift==8) bool3 = 0;
  1189. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1190. for(i=begin ; i<end ; i++)
  1191. {
  1192. line = ~((unsigned short)~bmp[i]<<shift);
  1193. if(bool1) screen[0] &= *p;
  1194. if(bool2) screen[1] &= *(p+1);
  1195. if(bool3) screen[2] &= *(p+2);
  1196. screen += 16;
  1197. }
  1198. }
  1199. #endif
  1200. #ifdef ML_BMP_16_XOR_CL
  1201. void ML_bmp_16_xor_cl(const unsigned short *bmp, int x, int y)
  1202. {
  1203. unsigned long line;
  1204. char i, shift, begin=0, end=16, bool1=1, bool2=1, bool3=1, *screen, *p=(char*)&line+1;
  1205. if(!bmp || x<-15 || x>127 || y<-15 || y>63) return;
  1206. if(y < 0) begin = -y;
  1207. if(y > 48) end = 64-y;
  1208. shift = 8-(x&7);
  1209. if(x < 0) bool1 = 0;
  1210. if(x<-8 || x>119) bool2 = 0;
  1211. if(x>111 || shift==8) bool3 = 0;
  1212. screen = ML_vram_adress()+(y+begin<<4)+(x>>3);
  1213. for(i=begin ; i<end ; i++)
  1214. {
  1215. line = bmp[i]<<shift;
  1216. if(bool1) screen[0] ^= *p;
  1217. if(bool2) screen[1] ^= *(p+1);
  1218. if(bool3) screen[2] ^= *(p+2);
  1219. screen += 16;
  1220. }
  1221. }
  1222. #endif
  1223. #ifdef ML_BMP_OR_ZOOM
  1224. void ML_bmp_or_zoom(const unsigned char *bmp, int x, int y, int width, int height, float zoom_w, float zoom_h)
  1225. {
  1226. int i, j, iz, jz, width_z, height_z, nb_width, i3, bit, x_screen, pixel;
  1227. int zoom_w14, zoom_h14;
  1228. int begin_x, end_x, begin_y, end_y;
  1229. char* vram = ML_vram_adress();
  1230. if (!bmp) return;
  1231. if (zoom_h < 0) zoom_h = 0;
  1232. if (zoom_w < 0) zoom_w = 0;
  1233. zoom_w14 = zoom_w * 16384;
  1234. zoom_h14 = zoom_h * 16384;
  1235. width_z = width * zoom_w14 >> 14 ;
  1236. height_z = height * zoom_h14 >> 14;
  1237. nb_width = width + 7 >> 3;
  1238. if (x < 0) begin_x = -x;
  1239. else begin_x = 0;
  1240. if (x+width_z > 128) end_x = 128-x;
  1241. else end_x = width_z;
  1242. if (y < 0) begin_y = -y;
  1243. else begin_y = 0;
  1244. if (y+height_z > 64) end_y = 64-y;
  1245. else end_y = height_z;
  1246. for (iz=begin_x; iz<end_x; iz++)
  1247. {
  1248. i = (iz << 14) / zoom_w14;
  1249. i3 = i >> 3;
  1250. bit = 0x80 >> (i & 7);
  1251. x_screen = x+iz;
  1252. for (jz=begin_y; jz<end_y; jz++)
  1253. {
  1254. j = (jz << 14) / zoom_h14;
  1255. pixel = bmp[i3 + nb_width * j] & bit;
  1256. if (pixel != 0) vram[(y+jz<<4)+(x_screen>>3)] |= 128>>(x_screen&7);
  1257. }
  1258. }
  1259. }
  1260. #endif
  1261. #ifdef ML_BMP_AND_ZOOM
  1262. void ML_bmp_and_zoom(const unsigned char *bmp, int x, int y, int width, int height, float zoom_w, float zoom_h)
  1263. {
  1264. int i, j, iz, jz, width_z, height_z, nb_width, i3, bit, x_screen, pixel;
  1265. int zoom_w14, zoom_h14;
  1266. int begin_x, end_x, begin_y, end_y;
  1267. char* vram = ML_vram_adress();
  1268. if (!bmp) return;
  1269. if (zoom_h < 0) zoom_h = 0;
  1270. if (zoom_w < 0) zoom_w = 0;
  1271. zoom_w14 = zoom_w * 16384;
  1272. zoom_h14 = zoom_h * 16384;
  1273. width_z = width * zoom_w14 >> 14 ;
  1274. height_z = height * zoom_h14 >> 14;
  1275. nb_width = width + 7 >> 3;
  1276. if (x < 0) begin_x = -x;
  1277. else begin_x = 0;
  1278. if (x+width_z > 128) end_x = 128-x;
  1279. else end_x = width_z;
  1280. if (y < 0) begin_y = -y;
  1281. else begin_y = 0;
  1282. if (y+height_z > 64) end_y = 64-y;
  1283. else end_y = height_z;
  1284. for (iz=begin_x; iz<end_x; iz++)
  1285. {
  1286. i = (iz << 14) / zoom_w14;
  1287. i3 = i >> 3;
  1288. bit = 0x80 >> (i & 7);
  1289. x_screen = x+iz;
  1290. for (jz=begin_y; jz<end_y; jz++)
  1291. {
  1292. j = (jz << 14) / zoom_h14;
  1293. pixel = bmp[i3 + nb_width * j] & bit;
  1294. if (pixel == 0) vram[(y+jz<<4)+(x_screen>>3)] &= ~(128>>(x_screen&7));
  1295. }
  1296. }
  1297. }
  1298. #endif
  1299. #ifdef ML_BMP_XOR_ZOOM
  1300. void ML_bmp_xor_zoom(const unsigned char *bmp, int x, int y, int width, int height, float zoom_w, float zoom_h)
  1301. {
  1302. int i, j, iz, jz, width_z, height_z, nb_width, i3, bit, x_screen, pixel;
  1303. int zoom_w14, zoom_h14;
  1304. int begin_x, end_x, begin_y, end_y;
  1305. char* vram = ML_vram_adress();
  1306. if (!bmp) return;
  1307. if (zoom_h < 0) zoom_h = 0;
  1308. if (zoom_w < 0) zoom_w = 0;
  1309. zoom_w14 = zoom_w * 16384;
  1310. zoom_h14 = zoom_h * 16384;
  1311. width_z = width * zoom_w14 >> 14 ;
  1312. height_z = height * zoom_h14 >> 14;
  1313. nb_width = width + 7 >> 3;
  1314. if (x < 0) begin_x = -x;
  1315. else begin_x = 0;
  1316. if (x+width_z > 128) end_x = 128-x;
  1317. else end_x = width_z;
  1318. if (y < 0) begin_y = -y;
  1319. else begin_y = 0;
  1320. if (y+height_z > 64) end_y = 64-y;
  1321. else end_y = height_z;
  1322. for (iz=begin_x; iz<end_x; iz++)
  1323. {
  1324. i = (iz << 14) / zoom_w14;
  1325. i3 = i >> 3;
  1326. bit = 0x80 >> (i & 7);
  1327. x_screen = x+iz;
  1328. for (jz=begin_y; jz<end_y; jz++)
  1329. {
  1330. j = (jz << 14) / zoom_h14;
  1331. pixel = bmp[i3 + nb_width * j] & bit;
  1332. if (pixel != 0) vram[(y+jz<<4)+(x_screen>>3)] ^= 128>>(x_screen&7);
  1333. }
  1334. }
  1335. }
  1336. #endif
  1337. #ifdef ML_BMP_OR_ROTATE
  1338. void ML_bmp_or_rotate(const unsigned char *bmp, int x, int y, int width, int height, int angle)
  1339. {
  1340. int i, j, i3, dx, dy, ox, oy, xr, yr, nb_width, pixel, bit;
  1341. int cosinus, sinus;
  1342. char* vram = ML_vram_adress();
  1343. if (!bmp) return;
  1344. ox = x + width / 2;
  1345. oy = y + height / 2;
  1346. angle %= 360;
  1347. if (angle < 0) angle += 360;
  1348. if (angle == 0) {cosinus = 16384; sinus = 0;}
  1349. else if (angle == 90) {cosinus = 0; sinus = -16384;}
  1350. else if (angle == 180) {cosinus = -16384; sinus = 0;}
  1351. else if (angle == 270) {cosinus = 0; sinus = 16384;}
  1352. else
  1353. {
  1354. cosinus = cosf(-3.14 * angle / 180.0) * 16384;
  1355. sinus = sinf(-3.14 * angle / 180.0) * 16384;
  1356. }
  1357. nb_width = width + 7 >> 3;
  1358. for (i=0; i<width; i++)
  1359. {
  1360. bit = 0x80 >> (i & 7);
  1361. i3 = i >> 3;
  1362. dx = x + i - ox;
  1363. for (j=0; j<height; j++)
  1364. {
  1365. dy = y + j - oy;
  1366. xr = ox + (dx * cosinus - dy * sinus >> 14);
  1367. yr = oy + (dx * sinus + dy * cosinus >> 14);
  1368. if (!(xr < 0 || xr > 127 || yr < 0 || yr > 63))
  1369. {
  1370. pixel = bmp[i3 + nb_width * j] & bit;
  1371. if (pixel != 0) vram[(yr<<4)+(xr>>3)] |= 128>>(xr&7);
  1372. }
  1373. }
  1374. }
  1375. }
  1376. #endif
  1377. #ifdef ML_BMP_AND_ROTATE
  1378. void ML_bmp_and_rotate(const unsigned char *bmp, int x, int y, int width, int height, int angle)
  1379. {
  1380. int i, j, i3, dx, dy, ox, oy, xr, yr, nb_width, pixel, bit;
  1381. int cosinus, sinus;
  1382. char* vram = ML_vram_adress();
  1383. if (!bmp) return;
  1384. ox = x + width / 2;
  1385. oy = y + height / 2;
  1386. angle %= 360;
  1387. if (angle < 0) angle += 360;
  1388. if (angle == 0) {cosinus = 16384; sinus = 0;}
  1389. else if (angle == 90) {cosinus = 0; sinus = -16384;}
  1390. else if (angle == 180) {cosinus = -16384; sinus = 0;}
  1391. else if (angle == 270) {cosinus = 0; sinus = 16384;}
  1392. else
  1393. {
  1394. cosinus = cosf(-3.14 * angle / 180.0) * 16384;
  1395. sinus = sinf(-3.14 * angle / 180.0) * 16384;
  1396. }
  1397. nb_width = width + 7 >> 3;
  1398. for (i=0; i<width; i++)
  1399. {
  1400. bit = 0x80 >> (i & 7);
  1401. i3 = i >> 3;
  1402. dx = x + i - ox;
  1403. for (j=0; j<height; j++)
  1404. {
  1405. dy = y + j - oy;
  1406. xr = ox + (dx * cosinus - dy * sinus >> 14);
  1407. yr = oy + (dx * sinus + dy * cosinus >> 14);
  1408. if (!(xr < 0 || xr > 127 || yr < 0 || yr > 63))
  1409. {
  1410. pixel = bmp[i3 + nb_width * j] & bit;
  1411. if (pixel == 0) vram[(yr<<4)+(xr>>3)] &= ~(128>>(xr&7));
  1412. }
  1413. }
  1414. }
  1415. }
  1416. #endif
  1417. #ifdef ML_BMP_XOR_ROTATE
  1418. void ML_bmp_xor_rotate(const unsigned char *bmp, int x, int y, int width, int height, int angle)
  1419. {
  1420. int i, j, i3, dx, dy, ox, oy, xr, yr, nb_width, pixel, bit;
  1421. int cosinus, sinus;
  1422. char* vram = ML_vram_adress();
  1423. if (!bmp) return;
  1424. ox = x + width / 2;
  1425. oy = y + height / 2;
  1426. angle %= 360;
  1427. if (angle < 0) angle += 360;
  1428. if (angle == 0) {cosinus = 16384; sinus = 0;}
  1429. else if (angle == 90) {cosinus = 0; sinus = -16384;}
  1430. else if (angle == 180) {cosinus = -16384; sinus = 0;}
  1431. else if (angle == 270) {cosinus = 0; sinus = 16384;}
  1432. else
  1433. {
  1434. cosinus = cosf(-3.14 * angle / 180.0) * 16384;
  1435. sinus = sinf(-3.14 * angle / 180.0) * 16384;
  1436. }
  1437. nb_width = width + 7 >> 3;
  1438. for (i=0; i<width; i++)
  1439. {
  1440. bit = 0x80 >> (i & 7);
  1441. i3 = i >> 3;
  1442. dx = x + i - ox;
  1443. for (j=0; j<height; j++)
  1444. {
  1445. dy = y + j - oy;
  1446. xr = ox + (dx * cosinus - dy * sinus >> 14);
  1447. yr = oy + (dx * sinus + dy * cosinus >> 14);
  1448. if (!(xr < 0 || xr > 127 || yr < 0 || yr > 63))
  1449. {
  1450. pixel = bmp[i3 + nb_width * j] & bit;
  1451. if (pixel != 0) vram[(yr<<4)+(xr>>3)] ^= 128>>(xr&7);
  1452. }
  1453. }
  1454. }
  1455. }
  1456. #endif