why can't I setf a char in a string containing nulls?

Started by ant, November 05, 2011, 04:27:00 PM

Previous topic - Next topic

ant

I'm trying to set a character value in a string containing zeros. Is the following behaviour correct?



newLISP v.10.3.3 on OSX IPv4/6 UTF-8, execute 'newlisp -h' for more info.



> > (set 's "abc")

"abc"

> (setf (s 1) "X")

"X"

> s

"aXc"

> (set 's "000000")

"000000"

> s

"000000"

> (length s)

3

> (setf (s 1) "X")



ERR]

Lutz

On UTF-8 versions of newLISP indexing - either implicit or using 'nth' - works only on ASCII and UTF-8 text strings and on a character- rather than byte- count basis. One UTF-8 character can contain several bytes. The binary 0 marks the end of a text string.



On non-UTF-8 versions indexing will also work on binary string buffers containing invalid ASCII or UTF-8 characters. Your example would work, but would not be portable.



But you still can do it on an UTF-8 version using 'cpymem':


(set 's "000000")

(cpymem "A" (+ (address s) 1) 1)

s => "00A00"


The 'cpymem' function can crash newLISP when supplying wrong addresses, or copying beyond the end of a string buffer.

ant

Hi Lutz, thank you for the suggestion.



In view of what you say can you suggest the most appropriate data type to use to pass to glDrawPixels? I want to create a contiguous array of RGB binary byte values to pass to this function and I want to manipulate the contents of this buffer in LISP, to display bitmapped images. If I use strings should I be able to read and write arbitrary values to arbitrary locations in the string buffer?



In C I might use an array of unsigned chars. In newLISP what would be the equivalent of this?



    rgbbuf[index] = byte_value;

Lutz

Yes, I would use a string buffer to pass the RGB values. Prepare the array using a LISP list then use 'pack' with the appropriate format characters to generate the buffer to pass to the C-function:


(set 'buffer (pack (dup "b" no-of-byte-values-in-list) the-list-of-rgb-values))

ant

Lutz, I appreciate you taking the time to answer my newbie questions.



I found this worked for me:


(define (set-pixel x y r g b)
(let (i (* (+ x (* y WIDTH)) 3))
(cpymem (pack "bbb" r g b) (+ (address rgb-buf) i) 3)))


Your suggestion meant rewriting the entire bitmap to change one pixel, which seemed inefficient. Also, for even a tiny 100 x 100 pixel bitmap I think you were suggesting I'd need a list of 30,000 cons cells. Wouldn't it be quite inefficient to access an arbitrary cell to change its value?



I'm attempting to implement a 2D game in newLISP, so performance will be important. It's probably a silly idea. But I'm hoping to learn more about LISP than I know now, which isn't much.



Ant

Lutz

Only when creating the whole bitmap in one shot, you need many Lisp cells. When you do it in smaller portions, you only need 3 cells per pixel, as in your example.



But perhaps it is better to work on a higher level of graphics generation, i.e. vector graphics instead of pixel graphics. The OpenGL demo here:



http://www.newlisp.org/syntax.cgi?downloads/OpenGL/opengl-demo-lsp.txt">http://www.newlisp.org/syntax.cgi?downl ... mo-lsp.txt">http://www.newlisp.org/syntax.cgi?downloads/OpenGL/opengl-demo-lsp.txt



has good performance and works with a pre generated vector image of a teapot.



If you game is only 2D you should also be able to get adequate performance using the  Java based guisererver.jar. Several users have programmed simple arcade style games with good performance. But using OpenGL will probably give faster results.

Lutz

Only when creating the whole bitmap in one shot, you need many Lisp cells. When you do it in smaller portions, you only need 3 cells per pixel, as in your example.



But perhaps it is better to work on a higher level of graphics generation, i.e. vector graphics instead of pixel graphics. The OpenGL demo here:



http://www.newlisp.org/syntax.cgi?downloads/OpenGL/opengl-demo-lsp.txt">http://www.newlisp.org/syntax.cgi?downl ... mo-lsp.txt">http://www.newlisp.org/syntax.cgi?downloads/OpenGL/opengl-demo-lsp.txt



has good performance and works with a pre generated vector image of a teapot.



If you game is only 2D, you should also be able to get adequate performance using the  Java based guiserver.jar. Several users have programmed simple arcade style games with good performance. But using OpenGL will probably give faster results.

ant

Yes, that demo is the point from which I started hacking. I'll pursue my bitmap effort a little further and see what FPS I get. I'll probably have further questions. If I think the end result is likely to be of any interest to anyone else I will make it freely available. Thank you again.