This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's Your Projects subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. Project Releases => Your Projects
Author Message
Liazon
title goes here


Bandwidth Hog


Joined: 01 Nov 2005
Posts: 2007

Posted: 15 Jan 2008 09:09:46 pm    Post subject:

lemme answer immediate questions first, then double post *gasp* for the rest of the stuff

so ya, basically, it's like the storm said, for 4 level gs, you have to display one layer twice as long as the other, so what ever is just on that layer appears darker than whatever is just on the other layer, while not being black/white. so in other words, timing is critical when it comes to 4 level gs.

for your 3 lvl gs, you don't have to worry since off timings won't screw up how the single gray color looks, since the viewer doesn't have some other gray to compare to to make them realize, "oh flicker", at least generally it won't look as bad as bad 4 lvl.

as for your question about dma, i just realized you're not writing an APP. so $9d95 would be a crappy place to insert some mem ^^ i might need an entire other post to help ya. as to why buffers have to be next to each other, that's because RGP is an INTERLACED gs routine. more on that later, but it's not pretty if Duck originally used shadow registers to achieve this.

and idk about MOS cuz I haven't done shell programming in awhile. I imagine it's in a doc somewhere on Detached Solutions. really on 3 places for a 768 byte buffer and that's plotsscreen, savesscreen, and appbackupscreen. all three are pretty good except for savesscreen and the APD stuff, but that's usually irrelevant if it's used as a a screen buffer i think.

so basically, you've actually got a lot of options when it comes to gs. you could do it your way, which works pretty good. or you could use RGP, which has a higher overhead than some can cope with. or you can do like thestorm said and write your own gs routine to fit your own needs. I guess the basics of it are pretty easy if you like writing interrupts.
but lemme show you some stuff first.
[quote name='"from MaxCoderz"']Hm, I found loads of stuff about grayscale, but they didn't really get into interlacing, they only stated that you should do it.
Do you just mask everything and switch masks every time?

Edit: it doesn't look nearly as bad as on this screeny, but it give some idea as to how it looks, in reality it looks more like the dark area switches to light sometimes, and the light area switches to somewhere in between dark and light
[/quote]
so that's basically no interlacing, just switching between two buffers to achieve 4 lvl gs. i think the only draw back to this is what happens when timings are off. Not to mention, i guess i could call it the "mass effect" of changing the entire screen at a time. the eyes pick up on it and can sometimes notice these changes and the gs effect is slightly lost. that being said, like the guy said, sometimes it's not noticeable on hardware, sometimes it's really obvious. actually, this is one thing I'm annoyed with the calcs, they aren't very consistent, even at best. ^^ I have a thing against those limited edition clear blue, purple, and green 83+BE cuz every one i've encountered has a bad LCD controller and can't handle gs too well ( or at least RGP).

edit: I'm tempted to say that interlacing is "needed" only because of the LCD driver, which the 86 and 68ks don't have. probably why it's rare to see interlacing in gs routines for 86/68ks (i'm pretty sure TIGCC does not use interlacing, which might be why on HW2-4, flicker is more common since they have to manually do a memcpy() to switch buffers, instead of simply redirecting the video hardware to a new buffer like the HW1s), though I'd imagine if you wanted 8 lvl gs, a certain degree of interlacing might help ^^.
[quote name='"from MaxCoderz"']the way I did it, it becomes quite crazy


the dark-gray part is much lighter in reality than on the screeny..

edit: but it's a bit dark, so this time with an other mask that has less dark and more light in it:


edit again: that was crap, 128 cc's between each write omg, now it's 85, looks a bit better:
[/quote]
so these are other examples using bit level interlacing. getting there...


Last edited by Guest on 15 Jan 2008 09:36:21 pm; edited 1 time in total
Back to top
Liazon
title goes here


Bandwidth Hog


Joined: 01 Nov 2005
Posts: 2007

Posted: 15 Jan 2008 09:25:53 pm    Post subject:

and now to quote Jim e for a better explanation.

[quote name='"Jim e"']Well I thought I'd find the guide I wrote in my sentbox but apparently it doesn't save to many messages.  So heres a quick run down of interlacing


Lets say this is the image you want.




It would be composed of 2 layers commonly referred to as a dark layer and a light layer.  The dark layer is generally stored before the light layer.  So that image would look like this.

Dark:


Light:


For 4 level gray scale, the dark layer is displayed 2 times longer than the light.  So if the light layer flashed once than the dark is twice.




This method is generally faster, the biggest reason is because you don't have to perform fastcopy again when the dark layer was shown prior.  So in other words you can skip 1 lcd update.  That save a tremendous amount of time.  This method of updating the entire screen with a layer is also simpler to code and generally lighter.

However, if timing is inaccurate, the screen will look flickery and be quite unpleasant.  If timing is accurate but not tuned properly, you'll end up seeing a line moving across the screen. Which is horribly noticeable.


Rigview came along with accurate controllable timing and a new method of displaying the screen. This was done by interlacing bytes from both layers.

Unlike the last screen you can actually tell even at this low frame rate whats suppose to be dark and whats suppose to be light. Even if the timing is slightly off the noise produced by that is spread out more evenly. So the effect is less painful.  This however gets more bloated because you have to carry pointers to both layers and have a method to decide which layer gets used on what byte.  Thats either by unrolling code or giving up some more registers.

I think it was ~actually Tijl Coosemans (Kalimero), according to tr1p1ea, then Dirk Kingma~ Duck who decided to take it to the bit level, not sure on that. But there was a good deal of benefit from it.  No matter how bad timing was dithering the bits together allowed for a very even image.  The screen, no matter how noisy, was not unpleasant.



Of course with every advantage there is a disadvantage, the code is MUCH more complicated. Duck's code actually used shadow registers, so you can imagine the nightmare of having to work with that code.  Big issue with it is that you have the annoyance of having to work with masks. So lets count the registers.

A 16bit pointer for the dark layer.  How bout HL?
An 8bit mask for the dark layer.    Ummm C?
A 8bit temporary storage place for the masked dark layer. B!
A 16bit pointer for the light layer.  DE then
An 8bit mask for the light layer.    ....uh
A 16bit value to add the offset to the next byte.  oh SP!!!?
An 8bit loop counter.  crap.

So in other words, this code would be register starved.  You want each write to the lcd port to occur within ~70 tstates of the last write.  Self Modifying Code works to an extent but is still not very fast.

Then some bright boy(I forget his name, had letters in it I swear) ~Johan Forslöf (doyanx)~ came up with a method that relied on reversible operations. What this did was get rid of the need of temporary storage and the need to hold both masks. (Kinda plays back into your xor swapping thing).

So this would look like:

Dark_layer ^ Light_layer & Dark_mask ^ Light_layer = result

As opposed to:
(Dark_layer & Dark_mask) | ( Light_layer & Light_mask ) = result

Just comparing the code is noticeable improvement.


Code:
;Old broken code
   ld a,(ix)
   and d
   ld c,a
   ld a,(hl)
   and e
   or c

;New hotness
   ld a,(de)
   xor (hl)
   and c
   xor (hl)
This can really save you from requiring use of slower registers or shadow registers.  Typically you can get WAY below the required lcd delay. So its extremely helpful.


So this is what I ended up using for RGP.  It runs at fastcopy speed so I decided thats enough optimization.  It requires that layers be stored next to each other, but that isn't to much of an issue.

~code goes here~

For the masks, The dark layer should mask out 1/3 of its bits, the light layer should mask out 2/3 of its bits.[/quote]
and then tr1p1ea writes his own for his psuedo 3-D mario game and Super Smash Bros. game that is supposedly faster, but I've never seen it.
so that's the history of 4 lvl gs in a nutshell. any questions?

basically, that's what RGP does. uses an interrupt + interlacing to achieve grayscale. looks pretty good in almost all cases... except on those annoying colored BEs x.x

I'm a bit biased towards RGP cuz I like it, and I have the convenience of writing apps, but it's not for everyone I guess.

slightly offtopic: did you ever get iondetect to work for you? that'd be awesome if you could get a level editor out.


Last edited by Guest on 15 Jan 2008 09:27:41 pm; edited 1 time in total
Back to top
TheStorm


Calc Guru


Joined: 17 Apr 2007
Posts: 1233

Posted: 15 Jan 2008 09:48:52 pm    Post subject:

OK so the RGP does use a dual buffer and fun stuff (bit masking). I would really like to see that code:)
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 15 Jan 2008 11:07:19 pm    Post subject:

hmmm... Ok, i'll see if i can somehow manage to integrate RGP in.

No, I can't seem to get iondetect to work. I've set the parameters correctly, I just can't figure out why it's not finding what I want it to.

The code for RGP is here (download file).

I've looked through the RGP source, and it seems that at the moment:
a. sprite needs to be 8*8
b. sprite needs to be aligned
c. cryptic code (first scan)

I'll try to decode it and maybe modify it so it can suit my needs
Back to top
cjgone
Aw3s0m3


Active Member


Joined: 24 May 2006
Posts: 693

Posted: 15 Jan 2008 11:19:56 pm    Post subject:

RGP is pretty darn perfect except a very unoticable flicker.

When I used rgp, I copied pictures straight to the buffer

gsactivebuf1 and gsactivbebuf2.... No need to disable extra buffers since it won't use them anyway....

So you don't even need to use the greyscale sprite routines...you could use your own as long as you write to those 2 buffers.


Last edited by Guest on 15 Jan 2008 11:22:33 pm; edited 1 time in total
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 15 Jan 2008 11:58:20 pm    Post subject:

cool, that means I don't have to code the hardest part! All I need is a way to get my sprites into those two buffers and RGP handles the rest!

(rushes off to code)
Back to top
TheStorm


Calc Guru


Joined: 17 Apr 2007
Posts: 1233

Posted: 16 Jan 2008 12:34:05 am    Post subject:

Yay rush hour can now have 4 lvl grayscale Smile
Back to top
Liazon
title goes here


Bandwidth Hog


Joined: 01 Nov 2005
Posts: 2007

Posted: 16 Jan 2008 10:50:50 am    Post subject:

glad I could help.

can't wait to see cars w/ different colors in the next release!

and you'll only need to disable the extra buffers if you're using any of the routines included w/ graylib2.inc or graylib.inc, since they're all equated towards the buffers. also if you need more routines to modify, look at graylib.inc since the second release only includes the updated gs routine (that cryptic stuff) and a couple of the routines.

btw, when will external levels be supported?
Back to top
luby
I want to go back to Philmont!!


Calc Guru


Joined: 23 Apr 2006
Posts: 1477

Posted: 16 Jan 2008 05:03:44 pm    Post subject:

MirageOS txt file explaining MOS wrote:
4) You may use all of savesscreen, appbackupscreen, and tempswaparea for variable storage.
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 16 Jan 2008 05:25:30 pm    Post subject:

@liazon: umm... can't figure out why iondetect won't work. This has kind of been put on hold for now until I can basically re-program a lot of the main game. You also mentioned greylib2.inc, is that the one Jim E wrote? Or are they both by the same person (this thing)?

@luby: thanks, maybe it was another buffer or another shell I was thinking of.

edit:
@liazon: oh, haha. yeah. I knew that (the 2nd part). Are the greylib2.inc just complete replacements, as in delete them from greylib.inc? Or not? I'm having a hard time understanding what Jim e said about graylib2.inc and how to use it. The documented one (on TIcalc.org) isn't much easier to understand, either. any help here?


Last edited by Guest on 16 Jan 2008 05:36:14 pm; edited 1 time in total
Back to top
Liazon
title goes here


Bandwidth Hog


Joined: 01 Nov 2005
Posts: 2007

Posted: 16 Jan 2008 06:24:10 pm    Post subject:

graylib2.inc is a "replacement" although graylib.inc (the original) does have some sprite routines if you want to use them. the only difference in the gs code between the 2 is that iirc graylib2 checks for SE or not, and turns it on at some point iirc. that and I think graylib2 is a bit faster.

for what you want to do, you probably only need graylib2.inc.

it's really simple to use though:

call gsenable at the beginning
call gsdisable at the end

are you having trouble allocating buffers?
you just need to define:
gsactivebuffer1:
.block 768
gsactivebuffer2:
.block 768

or something like that in your program. otherwise, make it dynamic space.


Last edited by Guest on 16 Jan 2008 06:24:56 pm; edited 1 time in total
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 16 Jan 2008 06:40:21 pm    Post subject:

haha, At the beginning of the code, apparently you need to define whether it's a TI83 or TI8P or else it won't work. What a stupid thing to miss.

Here's what I think I'll need.

don't know if it's in graylib2.inc in it or not

  • The actual interrupt (whatever is running in the background)
  • enable gs
  • disable gs
  • setfreq (not necessary, but a plus)
  • buffer copy
graylib2.inc does have (among others):

  • largesprite
  • buffer copy

edit:
Ok, I've run into a problem. For some reason the buffer clear command doesn't work while gs is enabled (causes ram-reset). It should, shouldn't it?


Last edited by Guest on 16 Jan 2008 06:59:54 pm; edited 1 time in total
Back to top
Liazon
title goes here


Bandwidth Hog


Joined: 01 Nov 2005
Posts: 2007

Posted: 16 Jan 2008 07:05:26 pm    Post subject:

WikiGuru wrote:
@liazon: umm... can't figure out why iondetect won't work. This has kind of been put on hold for now until I can basically re-program a lot of the main game. You also mentioned greylib2.inc, is that the one Jim E wrote? Or are they both by the same person (this thing)?


that's Duck's grayscale package, which RGP was based of off. Unlike Duck's gs, RGP doesn't need to set a frequency. iirc, it either uses the crystal timers, or defaults to the most frequent interrupt frequency.


also, you should include it at the bottom of your code, and not w/ ti83plus.inc or ion.inc or etc, in case that wasn't clear.

and the buffer clearing routine clears plotsscreen and savesscreen

try #define NODOUBLEBUFFER at the top of your code.
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 16 Jan 2008 07:16:43 pm    Post subject:

I did, and it still crashes. For some reason gsClearBuffer just doesn't want to work when I have gs enabled. It works perfectly fine with gs disabled, but that doesn't help me... for some reason gs enable draws these funny lines on the top and I can't figure out a way to get rid of them (see attached file)

The crash at the end of the screenie is when it runs into gsClearBuffer with gs enabled.


Last edited by Guest on 16 Jan 2008 07:17:12 pm; edited 1 time in total
Back to top
Liazon
title goes here


Bandwidth Hog


Joined: 01 Nov 2005
Posts: 2007

Posted: 16 Jan 2008 08:19:03 pm    Post subject:

you're using the wrong grayscale package.

graylib2.inc

idk the differences between Latenite/Brass so this may not work entirely, not to mention i havent' done shells in awhile xD

Code:
 .nolist
#include "ion.inc"
#include "ti83plus.inc"
#define nodoublebuffer
 .list
;hopefully I'm doing this right
 .org $9d93
 .db $BB,$6D
 xor a
 jr nc,Start
.db "Program",0

start:
 call gsenable
 ld hl,gbuf1
 ld de,gbuf1+1
 ld (hl),$FF
 ld bc,768
 ldir
 call gsgetk
 call gsclearbuffer
 ld hl,gbuf2
 ld de,gbuf2+1
 ld (hl),$FF
 ld bc,768
 ldir
 call gsgetk
 call gsclearbuffer
 call gsdisable

#include "graylib2.inc"
.end
end


probably made a mistake somewhere, but try that.

main thing is, you don't have to set interrupt frequencies w/ RGP, it's just plug and play.


Last edited by Guest on 16 Jan 2008 08:21:19 pm; edited 1 time in total
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 17 Jan 2008 05:18:56 pm    Post subject:

ok, i'll work on that. in the mean time, can anyone give me any headway into external level support?
Back to top
cjgone
Aw3s0m3


Active Member


Joined: 24 May 2006
Posts: 693

Posted: 17 Jan 2008 06:01:05 pm    Post subject:

Use iondetect, assuming you call gsDisable or have the calc in mode 1 while using it.

In fact, I don't know if you need to be in mode 1 :S


Last edited by Guest on 17 Jan 2008 06:02:49 pm; edited 1 time in total
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 17 Jan 2008 09:49:51 pm    Post subject:

ok, i've made significant progress on the greyscale, except there are a few problems. I'll try to iron them out, but I can't seem to figure out what's wrong
Back to top
cjgone
Aw3s0m3


Active Member


Joined: 24 May 2006
Posts: 693

Posted: 17 Jan 2008 11:19:55 pm    Post subject:

What problem are you having (screeshot)?

Is it crashing or giving weird display problems....


NOTE: IF YOU USE NODOUBLEBUFFER things will blur really badly.... making them hard to make out if you are moving an object at a slight speed.
Back to top
WikiGuru
ADOS (Attention deficit... Oh! Shiny!)


Elite


Joined: 15 Sep 2005
Posts: 923

Posted: 18 Jan 2008 05:18:48 pm    Post subject:

no, it's just small checks and typos. A called a memory address instead of jumping to it, typed the wrong register, forgot to change a few things from the old version, etc. It's frustrating with this much code!

edit: i kind of what to take a poll, I've been fiddling around with a different way to move cars. Instead of holding [2nd] down, you would press [2nd] to "select" a car, move with the arrow keys, and then press [Alpha] to deselect it. Is this a better idea? I have a demo if you want to try it.

edit2: i also had another idea about moving cars. Because RGP makes the program coherently slower, what if I made it so that instead of moving one pixel each time the arrow key is pressed, the program move multiple pixels (1,2,5, or 10 pixels)? The screenie demonstrates the current speed (1 pixel).

edit3: sorry for so many edits, but how are the new graphics?

edit4: ok, last edit for this post, promise! Does anyone know how to use iondetect/can show me a working example (all the code for the main program and the "level") so I can work on the level editor?


Last edited by Guest on 18 Jan 2008 06:07:48 pm; edited 1 time in total
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    » Goto page Previous  1, 2, 3, 4  Next
» View previous topic :: View next topic  
Page 2 of 4 » All times are UTC - 5 Hours

 

Advertisement