bfg.gamepassion Posted December 8, 2011 Share Posted December 8, 2011 (edited) Hi, i really need BIG help. In the Newcoleco coding library is a superb fonction called put_frame. Here is the source code : ; gpfram0.s .module put_frame ; global from this code .globl _put_frame ; put_frame (void *table, byte x, byte y, byte width, byte height) .area _CODE _put_frame: exx pop hl exx pop hl pop de pop bc push bc push de push hl exx push hl exx push ix push iy call 0x080b pop iy pop ix ret It take a memory zone (*table) of characters of widht and height, an display it at position x,y. If it's out of the screen, it's okay, it don't crash anything. I really can't read assembly. But What i'd like to to, is if this routine want to put a char at a position x > 24, then, it don't do put the char. Can somebody change easily this assembly routine to do that ?! Or is it not possible because it call a bios routine at 0X080b ??? By the way, there is the put_frame0 routine, who don't check "boundary" ... Maybe it's possible to modify ... ; gp9fram0.s .module put_frame0 .globl calc_offset ; global from this code .globl _put_frame0 ; put_frame0 (void *table, byte x, byte y, byte width, byte height) .area _CODE _put_frame0: exx pop hl exx pop hl pop de call calc_offset pop bc push bc push de push hl exx push hl exx loop: push bc push de push hl ld b,#0 xor a call 0x1fdf pop hl pop de pop bc push bc ld b,#0 add hl,bc ex de,hl ld bc,#0x0020 add hl,bc ex de,hl pop bc dec b ld a,b jr nz,loop ret Edited December 8, 2011 by bfg.gamepassion Quote Link to comment Share on other sites More sharing options...
youki Posted December 9, 2011 Share Posted December 9, 2011 <ul> <li>Hi Michel,</li> </ul> <p>The put_frame , as you stated, make call to coleco bios routine put_frame , so you won't be able to modify the routine . (Or do you want create your own bios on chip and patch your coleco???)</p> <p> </p> <p>concerning the put_frame0 , i have to check . But i didn't not understand what you want do exactly? I think put_frame don't put the char if x is > at 24 already no?</p> <p> </p> <p>Contact me per mail ou on my forums , to explain me your problem. </p> <p> </p> <p> </p> Quote Link to comment Share on other sites More sharing options...
hardhat Posted December 20, 2011 Share Posted December 20, 2011 That first routine just puts the parameters in the correct registers and calls the OS7 function to do the work. The second function just calls write_vram() for each line. So it could be modified to do the clipping I suppose. The best way to do this, is to do the clipping at column 24 in C (I call it maxx), or use double buffering, and draw to the off screen buffer where ever you like, then draw your menu or whatever at column 24 and beyond, then show the whole screen at once. To do the clipping in C you'd say: void put_frame_clipped(void *table, byte maxx, byte x, byte y, byte width, byte height) { byte j; byte w=width; if( x>=maxx) return; /* off screen. */ if( x+w>maxx) w=maxx-x; for( j=y; j<y+height && j<24; j++) { put_frame( table, x, j, w, 1); table+=width; } } This could use write_vram even more efficiently, if speed is an issue. For double buffering, you set it up with: void setup() { screen( name_table1, name_table2); } Then draw what you like, then redraw the menu at column 24 and beyond, and your drawing will only be visible when you call: swap_screen(); Quote Link to comment Share on other sites More sharing options...
bfg.gamepassion Posted December 20, 2011 Author Share Posted December 20, 2011 Thanks for advices !! Here's the routine i've decided to use : void put_frameS(byte *tile,char x,char y,char w,char h) { char i; char cw; // calculated weight //char px; int offset_deplacement; char tmp; if (x>23) return; if (y>23) return; tmp = x+w; if (tmp<24) // Il n'y aura pas de clipping à droite { if ( (x>=0) && ((y+h)<24) && (y>=0) ) // Et il n'y aura pas de clipping tout court { put_frame0(tile,x,y,w,h); } else // Il y aura un clipping à gauche { put_frame(tile,x,y,w,h); } return; } offset_deplacement = 0; // Si on dépasse du crop // Il faut calculer la nouvelle largeur if ((tmp) > 24) cw = 24-x; else cw = w; for (i=0;i<h;i++) { tmp = y+i; // Ligne courant de l'écran à écrire if ((tmp)>24) return; if ((tmp)>=0) { put_vram(chrtab+((tmp)<<5)+x,tile+offset_deplacement,cw); } offset_deplacement += w; } } It mixed 3 "techniques" to have the more optimized speed possible i think. Quote Link to comment Share on other sites More sharing options...
hardhat Posted December 22, 2011 Share Posted December 22, 2011 Looks good. That should work well. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.