Request: Tutorial on Greyscales
#1
Posted 19 September 2007 - 02:38 PM
Thanks in advance,
SebHoll
#2
Posted 19 September 2007 - 11:55 PM
char checker_pattern[8] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 };(A checkered box)
Well ok, if you know how to organize and store bitmaps then let's move on. Grayscales in fx-9860 work by "flipping" buffers. If you every played with those flip books, they create some sort of animation when you're flipping through the pages. Well, in the fx-9860, either two buffers or three are "flipped" through. If you don't know what buffers are, just pretend they're like sheets of paper. One buffer = 1 sheet of paper. 2 buffers = 2 sheets of paper. And just like paper, you can draw whatever you want onto a buffer. One each buffer, only black or white can be drawn. These two buffers are "flipped through" really fast that it makes your brain think your seeing gray.
With two buffers (with a, let's say for example a 40% first buffer and 60% second buffer):
- Black + White = Light gray
- White + Black = Dark gray
- Black + Black = Black
Now let's apply this to code. Let's say we already got our sprites:
unsigned char box_one[8] = { 0xFF, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0xFF }; unsigned char box_two[8] = { 0xFF, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0xFF };
We also need to declare our buffers (or our "sheets of paper" to draw on):
unsigned char buffer1[1024]; unsigned char buffer2[1024];
Initialize the grayscale engine and tell it which buffers you are using:
GrayInit(3273, 1454); GrayLinkBuffers(buffer1, buffer2);
And draw our sprites onto our buffers (or "sheets of paper"):
while (IsKeyDown(KEY_CTRL_EXIT) != 1) { DrawSprite8(60, 28, buffer1, box_one, 0); DrawSprite8(60, 28, buffer2, box_two, 0); }
For the whole program:
#include "fxlib.h" #include "stdio.h" #include "revolution.h" int AddIn_main(int isAppli, unsigned short OptionNum) { unsigned char buffer1[1024]; unsigned char buffer2[1024]; unsigned char box_one[8] = { 0xFF, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0xFF }; unsigned char box_two[8] = { 0xFF, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0xFF }; memset(&buffer1, 0, 1024); memset(&buffer2, 0, 1024); GrayInit(3273, 1454); GrayLinkBuffers(buffer1, buffer2); while (IsKeyDown(KEY_CTRL_EXIT) != 1) { DrawSprite8(60, 28, buffer1, box_one, 0); DrawSprite8(60, 28, buffer2, box_two, 0); } Reset_Calc(); return 0; } #pragma section _BR_Size unsigned long BR_Size; #pragma section #pragma section _TOP int InitializeSystem(int isAppli, unsigned short OptionNum) { return INIT_ADDIN_APPLICATION(isAppli, OptionNum); } #pragma section
#3
Posted 20 September 2007 - 08:29 AM
- Does the constant flipping of these buffers cause a significant loss of speed?
- Why do you have to keep drawing the sprites to the buffers in the main loop? Surely when they are drawn once, they stay there, right?
- How do you use more buffers to obtain more shades of grey, and is there a limit to how many buffers can be used?
- Do you have to be careful about drawing while a buffer is being shown or not? (I have used Double-Buffering in game programming before, and am all to aware of these types of problems).
Cheers
SebHoll
#4
Posted 20 September 2007 - 01:18 PM
The magic numbers specify how long each buffer is to be displayed. These values are found by error and trial by searching which values look good. If one number is larger than the other, than that buffer gets displayed longer than the other. If both values are the same, than you get a 1 shade of gray,What are the 'magic numbers' in the GreyInit() function, and how do you choose them?
I don't know it's a significant loss, but there is some loss to do the flipping of buffers. If you look in MLC and tried out it's games, you still have some pretty fast games that use grayscales.Does the constant flipping of these buffers cause a significant loss of speed?
Having more buffers let's you have more combinations like:How do you use more buffers to obtain more shades of grey, and is there a limit to how many buffers can be used?
Black + Black + White = Very dark gray
Black + White + Black = Dark gray
Black + White + White = Light gray
....
The Revolution-FX engine only allows up to 3 buffers. Using 3 buffers will be a bit more tricky though.
No, not really. The chances that the buffer you are drawing onto is being drawn to the screen, is very very minimal.Do you have to be careful about drawing while a buffer is being shown or not?
Yes, they stay there. They don't have to be in the main loop, I just did that because I don't want a empty loop as there is nothing else to do.Why do you have to keep drawing the sprites to the buffers in the main loop? Surely when they are drawn once, they stay there, right?
#5
Posted 20 September 2007 - 02:42 PM
Edit: I've just tried you code example above by copying and pasting it into a new project in the official Casio SDK, and although it builds OK, the emulator throws an unspecified exception error when you select the add-in from the main-menu. :|
#6
Posted 20 September 2007 - 07:22 PM
Yes.OK, thanks. Just to clarify, if the flipping of the buffers done automatically, behind the scenes. All we have to do is draw to them?
If I have understood it correctly: An interrupt a piece of code that is run whenever the processor is 'interrupted' . It could be interrupted by a change on its IO ports or a change in its internal components, like the timer. The timer can interrupt the processor whenever the timer you set has expired, and runs the code you tells it to run. In RevFX's case, this code displays 'the other buffer' and sets an appropriate timeout for the next interrupt to happen.
#7
Posted 20 September 2007 - 08:19 PM
Now, can anyone point out why kucalc's greyscale code example above won't run?
#8
Posted 20 September 2007 - 11:16 PM
#9
Posted 21 September 2007 - 08:24 AM
#10
Posted 21 September 2007 - 12:52 PM
#11
Posted 21 September 2007 - 08:32 PM
:shock: Although I could probably "emulate in my head" in my native BASIC programming languages, C is completely new to me and it's hit and miss whether I've remembered to comply to it's strict (and sometimes pedantic ) syntax rules. I'm just thankful whether it will build, as usually if I get it to that stage, the logic is fine... I suppose therefore it could be feasible to create an add-in thins way, but I think I'm quite a way off being able to develop a serious application under those conditions...I guess it depends on your level of programming. MLC is I say is a pretty complex program, though it only took me 3 day to write a functioning build, I didn't need to use a emulator to write MLC. One way to bypass the emulator is to emulate and run the program in your head. That's what I do, the CASIO emulator is often just way too slow. Another alternative is to write our own emulator, a community emulator.
:shock: :shock: :shock: I wouldn't even know where to start with something like that! I would imagine it would be really complicated though...Another alternative is to write our own emulator, a community emulator.
#12
Posted 22 September 2007 - 04:31 PM
#13
Posted 12 November 2007 - 12:28 AM
int AddIn_main(int isAppli, unsigned short OptionNum) { const unsigned char Rifleone[] = {0x00, 0x00,0x00,0x00,0x07,0xE0,0x04,0x20,0x04,0x20,0x04,0x20,0x0F,0xF0,0x08,0x10,0x38, 0x1C,0x28,0x14,0x28,0x14,0x28,0x14,0x28, 0x14,0x28,0x14,0x28,0x14,0x28,0x14}; const unsigned char Rifletwo[] = {0x00, 0x00,0x00,0x00,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x0F,0xF0,0x0F,0xF0,0x3F, 0xFC,0x3F,0xFC,0x3F,0xFC,0x3F,0xFC,0x3F, 0xFC,0x3F,0xFC,0x3F,0xFC,0x3F,0xFC}; unsigned long buffer1[256] = { 0 }; unsigned long buffer2[256] = { 0 }; memset(&buffer1,0,256); memset(&buffer2,0,256); GrayLinkBuffers(&buffer1,&buffer2); GrayInit(3273,1454); while(IsKeyDown(KEY_CTRL_MENU)==0){ DrawSprite16(20,20,buffer1,Rifleone,0); DrawSprite16(20,20,buffer2,Rifletwo,0); } }I tried my hand at grayscales so I could draw a sprite for the 3D game. It's a rifle but this comes up with an error.
' ** L2310 (E) Undefined external symbol "_sgn" referenced in "graphics" '
But the thing is, _sgn is no where is this code.
#14
Posted 12 November 2007 - 04:09 AM
You'll have to switch back to v0.3 for now when using graphics. This should be fixed really soon.
#15
Posted 12 November 2007 - 04:14 AM
#16
Posted 12 November 2007 - 04:27 AM
#17
Posted 12 November 2007 - 09:06 PM
Umm, NO!I guess it depends on your level of programming. MLC is I say is a pretty complex program, though it only took me 3 day to write a functioning build, I didn't need to use a emulator to write MLC. One way to bypass the emulator is to emulate and run the program in your head. That's what I do, the CASIO emulator is often just way too slow. Another alternative is to write our own emulator, a community emulator.
You already have too many projects in your head! :shock:
#18
Posted 14 November 2007 - 04:51 AM
#19
Posted 14 November 2007 - 06:26 AM
#20
Posted 28 November 2007 - 07:49 AM
I tried with draw all but the calc froze. I think it might be something to do with my code. ill see what i can do but I just wanna know. can i do it with the Drawall?
#21
Posted 29 November 2007 - 12:40 AM
unsigned char splash_buffer1[1024]; unsigned char splash_buffer2[1024]; unsigned char buffer1[1024]; unsigned char buffer2[1024]; GrayLinkBuffers(buffer1, buffer2); GrayInit(3280, 3280); memcpy(buffer1, splash_buffer1, 1024); memcpy(buffer2, splash_buffer2, 1024);
#22
Posted 29 November 2007 - 02:23 AM
#23
Posted 02 December 2007 - 02:59 AM
I have
void drawintro(){ const unsigned char main1[]; const unsigned char main2[]; char buffer1[1024]; char buffer2[1024]; memset(buffer1,0,1024); memset(buffer2,0,1024); GrayInit(3280,3280); GrayLinkBuffers(buffer1,buffer2); while(IsKeyDown(KEY_CTRL_AC)==0){ memcpy(buffer1,main1,1024); memcpy(buffer2,main2,1024); } GrayEnd(); memset(buffer1,0,1024); memset(buffer2,0,1024); } int AddIn_main(int isAppli, unsigned short OptionNum) { drawintro(); Bdisp_AllClr_DDVRAM(); drawmain(0,0,1); SaveDisp(1); cursorx=1; cursory=1; while(1){ RestoreDisp(1); if(cursorx==1&cursory==1){ Bdisp_AreaReverseVRAM(2,17,63,26); } if(cursorx==1&cursory==2){ Bdisp_AreaReverseVRAM(2,29,63,39); } if(cursorx==1&cursory==3){ Bdisp_AreaReverseVRAM(2,42,63,52); } if(cursorx==2&cursory==1){ Bdisp_AreaReverseVRAM(66,17,125,26); } if(cursorx==2&cursory==2){ Bdisp_AreaReverseVRAM(66,29,125,39); } if(cursorx==2&cursory==3){ Bdisp_AreaReverseVRAM(66,42,125,52); } Bdisp_PutDisp_DD(); GetKey(&getkey); if(getkey==KEY_CTRL_DOWN){ cursory++; } if(getkey==KEY_CTRL_UP){ cursory--; } if(cursory3){ cursory=1; } if(getkey==KEY_CTRL_RIGHT){ cursorx++; } if(getkey==KEY_CTRL_LEFT){ cursorx--; } if(cursorx2){ cursorx=1; } } Reset_Calc(); }
I left out the global variables XD. it builds fine but just freezes XD
#24
Posted 02 December 2007 - 04:25 PM
#25
Posted 03 December 2007 - 12:03 AM
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users