-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathfaq.html
2864 lines (2691 loc) · 139 KB
/
faq.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Frequently Asked Questions</TITLE>
<STYLE TYPE="TEXT/CSS">
<!--
.IE3-DUMMY { CONT-SIZE: 100%; }
BODY { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #E0E0E0; }
P { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H1 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H2 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H3 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H4 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H5 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H6 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
UL { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
TD { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #FFFFFF; }
.NOBORDER { BACKGROUND-COLOR: #E0E0E0; PADDING: 0pt; }
.NOBORDER TD { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #E0E0E0; PADDING: 0pt; }
.CODE { FONT-FAMILY: Courier New; }
-->
</STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#E0E0E0">
<FONT SIZE="5"><B>Frequently Asked Questions</B></FONT>
<HR>
<P>The FAQ list is organized into several categories. In each category, you will see a list of
commonly asked questions in short form. Please click on a question that interests you to get the full form
of the question and the related answer. Note, however, that some questions/answers are related to each other, and some
answers are logical consequences of previous ones. So, after reading the answer, it is recommended
to browse through surrounding quesion/answer pairs too, to get some more information.
<BR><BR>
Also, please visit the <A HREF="http://tichessteamhq.yuku.com">TICT & TIGCC/GCC4TI Programming Message Board</A>
and the <A HREF="http://www.yaronet.com/gcc4ti"><B>GCC4TI message board</B></A>.
A lot of interesting topics about TIGCC/GCC4TI programming are discussed there.</P>
<UL>
<LI><B><A HREF="#language">The C Language</A></B>
<LI><B><A HREF="#tibasic">TI-Basic and C</A></B>
<LI><B><A HREF="#graphics">Graphics and Display</A></B>
<LI><B><A HREF="#assembly">Assembly and C</A></B>
<LI><B><A HREF="#strings">Strings</A></B>
<LI><B><A HREF="#events">Event-driven Programming, Menus, and Throwing Errors</A></B>
<LI><B><A HREF="#vat">TI Variables and the Variable Allocation Table (VAT)</A></B>
<LI><B><A HREF="#memory">Memory, C Variables, and Pointers</A></B>
<LI><B><A HREF="#input">Input: Keyboard and Link</A></B>
<LI><B><A HREF="#misc">Miscellaneous</A></B>
</UL>
<HR>
<H2><A NAME="language"><U>The C Language</U></A></H2>
<UL>
<LI><B><A HREF="#1">Where can I learn more about C?</A></B>
<LI><B><A HREF="#5">Will you implement C++?</A></B>
<LI><B><A HREF="#7">I get weird error messages where I don't see errors.</A></B>
<LI><B><A HREF="#10">Why do I get "Undefined Reference to..." errors?</A></B>
<LI><B><A HREF="#20">How can I make a floating point comparison function for use with qsort?</A></B>
<LI><B><A HREF="#41">Why do I get the message "invalid lvalue in unary '&'"?</A></B>
<LI><B><A HREF="#46">Can I use # (indirection) like in TI-Basic?</A></B>
<LI><B><A HREF="#47">I need the C equivalent of the when() function from TI-Basic.</A></B>
<LI><B><A HREF="#81">I tried to use sizeof to get the size of an object, but it returned zero!</A></B>
<LI><B><A HREF="#82">Can I use sizeof to determine the exact size of functions?</A></B>
</UL>
<HR>
<H2><A NAME="tibasic"><U>TI-Basic and C</U></A></H2>
<UL>
<LI><B><A HREF="#4">RETURN_VALUE doesn't work on AMS 2.xx!</A></B>
<LI><B><A HREF="#21">How can I display a PIC variable created in TI-Basic?</A></B>
<LI><B><A HREF="#50">How can I execute TI-Basic programs or statements from C?</A></B>
<LI><B><A HREF="#61">Can I write a program that returns a value to TI-Basic?</A></B>
<LI><B><A HREF="#62">Why is 'a=GetIntArg (top_estack);' wrong?</A></B>
<LI><B><A HREF="#63">How can I get a value from a TI-Basic matrix element?</A></B>
<LI><B><A HREF="#64">How can I make my C function return itself?</A></B>
</UL>
<HR>
<H2><A NAME="graphics"><U>Graphics and Display</U></A></H2>
<UL>
<LI><B><A HREF="#18">How can I display a number variable on the screen (like an int)?</A></B>
<LI><B><A HREF="#101">Do you plan on implementing 7-level grayscale?</A></B>
<LI><B><A HREF="#14">How can I use sprites?</A></B>
<LI><B><A HREF="#15">I don't understand how to define sprites!</A></B>
<LI><B><A HREF="#17">How do you use sprite functions from sprites.h with grayscale?</A></B>
<LI><B><A HREF="#22">How does BitmapGet work?</A></B>
<LI><B><A HREF="#39">How can I create a virtual screen?</A></B>
<LI><B><A HREF="#40">How can I set up a SCR_RECT structure?</A></B>
<LI><B><A HREF="#42">How can I make a WINDOW structure?</A></B>
<LI><B><A HREF="#43">How do I use functions from the wingraph.h file?</A></B>
<LI><B><A HREF="#44">How do you use DrawIcon?</A></B>
<LI><B><A HREF="#45">I need a really fast line-drawing routine...</A></B>
<LI><B><A HREF="#67">I can't reset printf to start at the top of the screen!</A></B>
<LI><B><A HREF="#85">How can you disable the 2nd and alpha indicators at the bottom of the screen?</A></B>
<LI><B><A HREF="#86">When I disable interrupts, grayscale doesn't work!</A></B>
<LI><B><A HREF="#87">While I was fiddling with interrupt handlers...</A></B>
</UL>
<HR>
<H2><A NAME="assembly"><U>Assembly and C</U></A></H2>
<UL>
<LI><B><A HREF="#13">How can I use a kernel-based libraries in C?</A></B>
<LI><B><A HREF="#88">How can I communicate between ASM and C code?</A></B>
</UL>
<HR>
<H2><A NAME="strings"><U>Strings</U></A></H2>
<UL>
<LI><B><A HREF="#35">How do you use strcat properly?</A></B>
<LI><B><A HREF="#19">How can I write an efficient number to string routine?</A></B>
<LI><B><A HREF="#105">Why can't I use a backslash (e.g. "main\var") in my strings?</A></B>
</UL>
<HR>
<H2><A NAME="events"><U>Event-driven Programming, Menus, and Throwing Errors</U></A></H2>
<UL>
<LI><B><A HREF="#23">If my program throws an error, I can't start it again!</A></B>
<LI><B><A HREF="#59">Can dialogs have popup menus with submenus?</A></B>
<LI><B><A HREF="#77">Why does calling the previous event handler in a user event handler result in a crash?</A></B>
<LI><B><A HREF="#78">How can I use functions in textedit.h to edit a text variable?</A></B>
<LI><B><A HREF="#79">I tried to create a new window for the text editor, but it didn't work...</A></B>
<LI><B><A HREF="#80">Can you change the font in the text editor?</A></B>
<LI><B><A HREF="#58">Why isn't it possible to create menus with more than one level of submenu with PopupAddText, and how can I do it anyway?</A></B>
<LI><B><A HREF="#60">How can I use VTI to pick bytes from menu structures like you describe?</A></B>
</UL>
<HR>
<H2><A NAME="vat"><U>TI Variables and the Variable Allocation Table (VAT)</U></A></H2>
<UL>
<LI><B><A HREF="#51">How can I get a list of all the variables/folders on the calculator?</A></B>
<LI><B><A HREF="#52">How can I determine the type and size of a variable?</A></B>
<LI><B><A HREF="#53">How can I copy a variable from one folder to another?</A></B>
<LI><B><A HREF="#54">How can I create a List or Matrix variable to keep highscores or similar information?</A></B>
<LI><B><A HREF="#55">Can I create a variable with a custom type (like HSC for highscores)?</A></B>
<LI><B><A HREF="#56">I want to create a variable without using functions from stdio.h.</A></B>
<LI><B><A HREF="#84">When I use functions from vat.h, the calculator crashes!</A></B>
</UL>
<HR>
<H2><A NAME="memory"><U>Memory, C Variables, and Pointers</U></A></H2>
<UL>
<LI><B><A HREF="#25">I have trouble allocating memory, my program crashes on the second run.</A></B>
<LI><B><A HREF="#26">I can't understand C matrices!</A></B>
<LI><B><A HREF="#28">How do I store variables so they retain their values, like for highscores?</A></B>
<LI><B><A HREF="#29">Global variables retain value?</A></B>
<LI><B><A HREF="#30">How can you control where data is stored in memory and access it?</A></B>
<LI><B><A HREF="#31">What is so horrible about global variables?</A></B>
<LI><B><A HREF="#32">How can you store a number such as 0x4c00 in a pointer?</A></B>
<LI><B><A HREF="#33">Is it possible to add one or two bytes to a longword pointer?</A></B>
<LI><B><A HREF="#34">Why can't you assign values to dereferenced void pointers?</A></B>
<LI><B><A HREF="#36">How can I have large global variables that don't take up space in my program file?</A></B>
<LI><B><A HREF="#37">How can I create a dynamic two-dimensional array?</A></B>
<LI><B><A HREF="#38">How can I create variable-size arrays?</A></B>
<LI><B><A HREF="#99">Why do I get "Value computed is not used" when working with pointers?</A></B>
</UL>
<HR>
<H2><A NAME="input"><U>Input: Keyboard and Link</U></A></H2>
<UL>
<LI><B><A HREF="#68">How can I get input from the keyboard?</A></B>
<LI><B><A HREF="#57">I'm having trouble with the functions from link.h...</A></B>
<LI><B><A HREF="#69">Do you have the function that gets called when you do InputStr in TI-Basic?</A></B>
<LI><B><A HREF="#70">How can I make a keyboard input function that allows you to bring up the CHAR menu (or MATH, etc)?</A></B>
<LI><B><A HREF="#71">I'm having trouble with the OSGetStatKey function.</A></B>
<LI><B><A HREF="#72">How can I read the keyboard faster than ngetchx, but easier than _rowread?</A></B>
<LI><B><A HREF="#73">How can I get the key repetition feature to work using the keyboard queue?</A></B>
<LI><B><A HREF="#74">Why are ngetchx and kbhit so slow?</A></B>
<LI><B><A HREF="#75">Is there a function like the idle_loop function?</A></B>
<LI><B><A HREF="#76">How can I bring up the VAR-LINK dialog and get the name of the selected file?</A></B>
<LI><B><A HREF="#98">I'm having troubles while reading I/O ports!</A></B>
</UL>
<HR>
<H2><A NAME="misc"><U>Miscellaneous</U></A></H2>
<UL>
<LI><B><A HREF="#9">Some of your examples don't compile!</A></B>
<LI><B><A HREF="#12">Why do you use -O2/-Os when -O3 performs better optimization?</A></B>
<LI><B><A HREF="#83">I need to access the FLASH memory.</A></B>
<LI><B><A HREF="#24">Some functions with no arguments (like 'off') don't work for me!</A></B>
<LI><B><A HREF="#48">How can I detect the hardware version of the calculator?</A></B>
<LI><B><A HREF="#65">How can I use very large integers like TIOS?</A></B>
<LI><B><A HREF="#66">I need the gotoxy() function to port PC programs to the calculator...</A></B>
<LI><B><A HREF="#49">How can I create a program that is bigger than 24K and works on AMS 2.xx?</A></B>
<LI><B><A HREF="#102">What might be the reason for my program leaking a small amout of memory?</A></B>
<LI><B><A HREF="#103">What is an "Address Error"?</A></B>
<LI><B><A HREF="#104">Why does my program using dialog boxes crash?</A></B>
</UL>
<HR>
<H3><A NAME="1"><U>Where can I learn more about C?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Is there any examples available on the net from which it is possible to
learn something more...
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
The best solution would be if I wrote a tutorial. Unfortunately, I have
not enough time to write tutorials, small examples, etc. Some examples come
with TIGCC starting from release 0.6, but this is probably not enough. I know that some
people work on making a tutorial, but as far as I know, all of them are
in a very early state. I suggest first learning C language (not C++) on some big
computer (PC, Mac, etc.). A very good list of generic C language tutorials may be found
on the <A HREF="http://tict.ticalc.org">TI-Chess Team Home Page</A>. After learning the basics
of C, reading the documentation of GCC4TILIB will be enough to learn how to apply this
to TI programming. In addition, try looking at my programs like
creversi, cblaster and scott (scott is in the advint.zip archive); all of them are
in the TI-89 assembly games directory on ticalc.org. Note that every day the number of TI
programs written in C increases, so now there are lots of open-source C programs
which can be found on ticalc.org.
</TD></TR></TABLE></P>
<H3><A NAME="5"><U>Will you implement C++?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I learn C++ in a school so it will be good if I can program my TI-89 in C++ (not in
ordinary C). Do you plan to implement C++ on TI-89?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
No. Although C++ is more powerful language than C, it is not a language which is
good for TI calculators. It is not efficient enough to be good for a calculator.
The code generated by C++ is less efficient than code
generated by ordinary C, and it is too bloated. So, even if somebody made C++
compiler for TI, I don't recommend using any C++ extensions (like classes, and
especially streaming), except if you like programs like</P>
<PRE>cout << "Hello world";
</PRE>
<P>which produces 5 Kb long code...
</TD></TR></TABLE></P>
<H3><A NAME="7"><U>I get weird error messages where I don't see errors.</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
The compiler sometimes report strange error messages on places where I really can not see
any errors. For example, the compiler reports the error</P>
<PRE>parse error before 'void'
</PRE>
<P>but the statement on which the error is reported was</P>
<PRE>int cexp;
</PRE>
<P>I am really confused. First, I don't see any errors here, and second, I can't see any 'void'
keywords here!
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Yes, such problems may really be the source of big frustrations. There is nothing wrong with
above statement, but note that <CODE>'cexp'</CODE> is a function defined in
<A HREF="timath.html">timath.h</A> header file, and you can not use this name as a name
of a variable. Now you can say why you got such strange error message? See, the most of
functions in GCC4TILIB are translated by the <A HREF="cpp.html">preprocessor</A> into constructions which perform
indirect function calls through a TIOS jump table. In other words, <CODE>'cexp'</CODE> will
be replaced by the preprocessor into the indirect function call constructor whenever it is
used. So, the innocent statement like</P>
<PRE>int cexp;
</PRE>
<P>will be converted into</P>
<PRE>int (*(void(**)(float,float,float*,float*))(*(long*)0xC8+1316));
</PRE>
<P>which is a syntax error. And the error is just before <CODE>'void'</CODE>.
<BR><BR>
I can not do anything against such hidden errors. Whenever you encounter strange errors without
obvious reasons, check whether you used reserved library name for your identifier. The chance
of making such errors is much smaller if you include only the necessary header files than if you
include the general header file <A HREF="tigcclib.html">tigcclib.h</A>.
</TD></TR></TABLE></P>
<H3><A NAME="10"><U>Why do I get "Undefined Reference to..." errors?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
When I tried to compile my program, the linker reports to me</P>
<PRE>Undefined reference to ...</PRE>
<P>although my program seems correct. What's a problem?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Either something is wrong with your program (more probably you used a function which is not
defined elsewhere, maybe due to typing error), or you used something which is not yet
implemented yet in GCC4TI (which is probably true if you got an undefined reference to a
symbol which begins which the double underscore
<CODE>'__'</CODE>). For example, although
GCC4TI supports very long (64-bit) integers (<CODE>'long long'</CODE> type, which is a
<A HREF="gnuexts.html">GNU C extension</A>), the support for multiplying and dividing double
longs is not supported yet. For example, if you try to divide two double-long numbers, you
will get an undefined reference to <CODE>'__udivdi3'</CODE>. Sorry, there is no simple help
for this. You must live without 64-bit division for now. It may be implemented in
the future.
</TD></TR></TABLE></P>
<H3><A NAME="20"><U>How can I make a floating point comparison function for use with qsort?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
How I can define a comparison function for sorting an array of floats using
<A HREF="stdlib.html#qsort">qsort</A> function:
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Here is a simple example (called "Sort Floats"):</P>
<PRE>// Sort a list of floating point values
#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
// Comparison Function
CALLBACK short flt_comp(const void *a, const void *b)
{
return fcmp (*(const float*)a, *(const float*)b);
}
// Main Function
void _main(void)
{
float list[5] = {2.5, 3.18, 1.42, 4.0, 3.25};
int i;
clrscr ();
qsort (list, 5, sizeof (float), flt_comp);
for (i = 0; i < 5; i++)
printf ("%f\n", list[i]);
ngetchx ();
}
</PRE>
<P></TD></TR></TABLE></P>
<H3><A NAME="41"><U>Why do I get the message "invalid lvalue in unary '&'"?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Well, I need to know more about lvalues and GNU C initializers and cast
constructors. Especially, I need to know why I sometimes get an error
message "invalid lvalue in unary '&'"...
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Click <A HREF="gnuexts.html">here</A> to see everything about GNU C
extensions. But if you are lazy to read too much, I will be more concrete
here. First, in GNU C (GCC4TI is GNU C), initializers may be non-constants.
For example,</P>
<PRE>int a = 3, b = 4, c = 5, d = 6;
int array[4] = {a, b, c, d};
</PRE>
<P>is quite legal. That's why</P>
<PRE>int a = 3, b = 4, c = 5, d = 6;
SCR_RECT myScr = {{b + a, b - a, d + c, d - c}};
</PRE>
<P>is quite legal too. Second, GNU C has one very nice
extension in addition to ordinary C: cast constructors. This is a
method for constructing structures, arrays, unions etc. "on fly" by
using a typecasting of an initializer to an appropriate data type, for
example</P>
<PRE>(SCR_RECT){{10, 10, 50, 50}}
</PRE>
<P>So, you can use</P>
<PRE>SCR_RECT myScr;
...
myScr = (SCR_RECT){{10, 10, 50, 50}};
</PRE>
<P>which is impossible in ordinary C (ANSI C). You can even use</P>
<PRE>myScr = (SCR_RECT){{a, b, c, d}};
</PRE>
<P>where a,b,c,d are expressions. Well, but what is now the problem?
See, C has two type of objects: lvalues and non-lvalues. lvalues
are objects which may appear on the left size of an assignment.
For example, a variable is an lvalue and a constant is not an lvalue,
because <CODE>'x=5'</CODE> is legal and <CODE>'5=x'</CODE>
(or <CODE>'5=3'</CODE>) is not legal. Not only variables are lvalues;
for example, dereferenced pointers are also lvalues, so this is legal
for example (store 100 at address 0x4c00):</P>
<PRE>*(char*)0x4c00 = 100;
</PRE>
<P>So, <CODE>'*(char*)0x4c00'</CODE> is an lvalue. Now, about the problem. In GNU C,
cast constructors are lvalues only if the initializer is completely
constant. I.e. <CODE>'(SCR_RECT){{10,10,50,50}}'</CODE> is an lvalue, but
<CODE>'(SCR_RECT){{a,b,c,d}}'</CODE> is not. As C language accepts unary '&'
operator (i.e. "address of") only on lvalue objects, this means
that, for example,</P>
<PRE>&(SCR_RECT){{10, 10, 50, 50}}
</PRE>
<P>is legal, but</P>
<PRE>&(SCR_RECT){{a, b, c, d}}
</PRE>
<P>is not! This is the real cause of the problem!!!
<BR><BR>
What you can do if you need an address of non-constant cast constructor? You need
to declare an auxilary variable. For example, declare one
<A HREF="graph.html#SCR_RECT">SCR_RECT</A> variable, say myScr,</P>
<PRE>SCR_RECT myScr;
</PRE>
<P>and instead of</P>
<PRE>ScrRectFill (&(SCR_RECT){{a, b, c, d}}, ScrRect, A_XOR);
</PRE>
<P>use:</P>
<PRE>myScr = (SCR_RECT){{a, b, c, d}};
ScrRectFill (&myScr, ScrRect, A_XOR);
</PRE>
<P>Note that <CODE>'&myScr'</CODE> is legal, because <CODE>'myScr'</CODE> is
an lvalue (it is an ordinary variable). I hope that this helps a lot
understanding of cast constructors and lvalues.
</TD></TR></TABLE></P>
<H3><A NAME="46"><U>Can I use # (indirection) like in TI-Basic?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I wonder how I can simulate the indirection operator (<CODE>'#'</CODE>) from
TI-Basic in C programs...
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Nothing equivalent to indirection (<CODE>'#'</CODE>) exists in any compiling
language (like C), since the variable names do not appear in the compiled
program. You need to make up your mind to avoid this operator.
For indirect references to variables in C, you can use
<A HREF="opers.html#asterisk">pointers</A>. However, usually you can
re-express the code using multiple
<CODE><A HREF="keywords.html#if">if</A></CODE>-<CODE><A HREF="keywords.html#if">else</A></CODE>
statements or arrays. Don't be afraid, C will process it 1000 times faster
than TI-Basic processes indirections.
</TD></TR></TABLE></P>
<H3><A NAME="47"><U>I need the C equivalent of the when() function from TI-Basic.</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I need the C equivalent of the <CODE>'when()'</CODE> function from TI-Basic.
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
This is simple:</P>
<PRE>when (<I>condition</I>, <I>true_val</I>, <I>false_val</I>)
</PRE>
<P>is translated to C as</P>
<PRE><I>condition</I> ? <I>true_val</I> : <I>false_val</I>
</PRE>
<P>For example,</P>
<PRE>sign = x >= 0 ? 1 : -1;
</PRE>
<P>Happy?
</TD></TR></TABLE></P>
<H3><A NAME="81"><U>I tried to use sizeof to get the size of an object, but it returned zero!</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
When I tried to use the <A HREF="keywords.html#sizeof">sizeof</A> operator to determine the
exact size of some objects, I got zero as the result. What is wrong?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
You probably tried something like</P>
<PRE>printf ("%d", sizeof (<I>something</I>));
</PRE>
<P>The ANSI standard proposes that the <A HREF="keywords.html#sizeof">sizeof</A> operator returns
a value of type <A HREF="stddef.html#size_t">size_t</A>, which is in fact long integer in
this implementation. So, the result is pushed on the stack as a long integer, but the format
specifier "%d" expects an ordinary integer, so it pulls from the stack just one word, which
is zero in this case. You need to write</P>
<PRE>printf ("%ld", sizeof (<I>something</I>));
</PRE>
<P>Alternatively, you can use a typecast to convert the result to a short integer</P>
<PRE>printf ("%d", (short) sizeof (<I>something</I>));
</PRE>
<P>assuming that no object would be longer that 32767 bytes.
</TD></TR></TABLE></P>
<H3><A NAME="82"><U>Can I use sizeof to determine the exact size of functions?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Is it possible to determine the size of the function using the
<A HREF="keywords.html#sizeof">sizeof</A> operator?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
No. In "normal" programs you should never know this information.
ANSI C even does not propose what is <CODE>'sizeof(<I>function</I>)'</CODE>, and such
construction will be rejected by the most of C compilers.
GNU C (like GCC4TI is) uses <A HREF="gnuexts.html#SEC79">extended pointer arithmetic</A>
on such way that <CODE>'sizeof(<I>function</I>)'</CODE> is always 1. If you are a dirty
hacker (as I am), and if you really need to determine the number of bytes occupied by
function, I used the following method:</P>
<PRE>void MyFunction(void)
{
// <I>The function body...</I>
}
void End_Marker(void);
asm("End_Marker:");
...
...
num_of_bytes = (char*)End_Marker - (char*)MyFunction;
</PRE>
<P>Note however that this method is not absolutely reliable, because it depends of the ordering of
functions in the program. But, the compiler is free to change the order of functions
if such reorganization may lead to a better code.
</TD></TR></TABLE></P>
<HR>
<H3><A NAME="4"><U>RETURN_VALUE doesn't work on AMS 2.xx!</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I have problems with programs which return values to the TI-Basic using
<A HREF="htretval.html">RETURN_VALUE</A> directive!
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Yes, this is a problem with AMS 2.xx. For some strange reasons AMS 2.xx
does not allow ASM programs to be part of expressions any more, i.e. if
<CODE>'xyz'</CODE> is an ASM program, <CODE>'xyz(3,2)+5'</CODE> or
<CODE>'xyz(3,2)->a'</CODE>
is not legal in AMS 2.xx. Fortunately, there is a solution. Read what I wrote about this
problem in the section <A HREF="htretval.html">How to return values to the TI-Basic</A>.
</TD></TR></TABLE></P>
<H3><A NAME="21"><U>How can I display a PIC variable created in TI-Basic?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Is it hard to display a PIC variable created from TI-Basic in C programs?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
No, it is easy. It is enough to locate the variable (using <A HREF="vat.html#SymFind">SymFind</A>
for example), and to display its content using <A HREF="graph.html#BitmapPut">BitmapPut</A> (its
contents are just as expected by <A HREF="graph.html#BitmapPut">BitmapPut</A> function). To be
more concrete, look at the following function:</P>
<PRE>short show_picvar (SYM_STR SymName, short x, short y, short Attr)
{
SYM_ENTRY *sym_entry = SymFindPtr (SymName, 0);
if (!sym_entry) return FALSE;
if (peek (HToESI (sym_entry->handle)) != PIC_TAG) return FALSE;
BitmapPut (x, y, HeapDeref (sym_entry->handle) + 2, ScrRect, Attr);
return TRUE;
}
</PRE>
<P>The usage of this function is straightforward, for example:</P>
<PRE>show_picvar (SYMSTR ("testpic"), 30, 30, A_NORMAL);
</PRE>
<P>assuming that "testpic" is the name of the wanted PIC variable. This function returns
<A HREF="alloc.html#Bool">TRUE</A> if the operation was successful, else returns
<A HREF="alloc.html#Bool">FALSE</A> (i.e. the picvar does not exist, or it is not
a PIC variable).
</TD></TR></TABLE></P>
<H3><A NAME="50"><U>How can I execute TI-Basic programs or statements from C?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Is there any way to execute a file (i.e. another ASM or TI-Basic program) from a C program?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
There are a lot of methods for doing this.
The most obvious method to do this is usage of a function like this one:</P>
<PRE>void progrun(const char *name)
{
char fname[25];
HANDLE h;
strcpy (fname, name);
strcat (fname, "()");
push_parse_text (fname);
h = HS_popEStack ();
TRY
NG_execute (h, FALSE);
FINALLY
HeapFree (h);
ENDFINAL
}
</PRE>
<P>The usage of it is straightforward, for example:</P>
<PRE>progrun ("testprog");
</PRE>
<P>Note that the program you call may throw errors. If you understand this function, you can easily expand it
to accept arguments, etc. Principally, using <A HREF="estack.html#NG_execute">NG_execute</A>
you can execute any particular sequence of TI-Basic statements.
</TD></TR></TABLE></P>
<P>See also: <A HREF="#49">How can I create a program that is bigger than 24K and works on AMS 2.xx?</A></P>
<H3><A NAME="61"><U>Can I write a program that returns a value to TI-Basic?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Is it possible to write a program which will return a value to TI-Basic, i.e. which
acts like functions in TI-Basic?
<BR><BR>
This is easy, was implemented a long time ago, and is described on the
starting page of the documentation.
</TD></TR></TABLE></P>
<H3><A NAME="62"><U>Why is 'a=GetIntArg (top_estack);' wrong?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
What is wrong in doing</P>
<PRE>a = GetIntArg (top_estack);
</PRE>
<P>It seems that it works fine, but you always use an auxilary variable...
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
It works fine sometimes, but not always. See, <A HREF="args.html#GetIntArg">GetIntArg</A>
is a function-looking macro, with <B>changes</B> the value of its actual
argument. So, if you write</P>
<PRE>a = GetIntArg (top_estack);
</PRE>
<P>you will also change the value of TIOS system variable <A HREF="estack.html#top_estack">top_estack</A>,
and I am not sure that you really want this. So, I strictly recommend using an auxilary variable,
like in the following example:</P>
<PRE>ESI argptr = top_estack;
...
a = GetIntArg (argptr);
</PRE>
<P>Using this method, you will avoid unexpected changes of <A HREF="estack.html#top_estack">top_estack</A>.
</TD></TR></TABLE></P>
<H3><A NAME="63"><U>How can I get a value from a TI-Basic matrix element?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I have a matrix on the top of the expression stack which is produced as a
result of calculation, and I don't know how do I put a matrix element located
at [i,j] into result (values of 'i' and 'j' may vary)? I have read infos about
<A HREF="estack.html">estack.h</A>, but I couldn't find the answer...
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
There is a lot of methods. I suggest the following one:</P>
<PRE>ESI ptr;
int result;
int i = 1; // <I>Just an example</I>
int j = 2;
push_parse_text ("[[11,12][21,22]]"); // <I>An example matrix</I>
ptr = locate_element (i,j);
result = GetIntArg (ptr); // <I>(assumed that elements are ints)</I>
</PRE>
<P>where <CODE>'locate_element'</CODE> is an user-written function, which may be
implemented as follows:</P>
<PRE>ESI locate_element (short m, short n)
{
short i;
ESI ptr = top_estack-1;
for (i = 0; i < m-1; i++) ptr = next_expression_index (ptr);
ptr--;
for (i = 0; i < n-1; i++) ptr = next_expression_index (ptr);
return ptr;
}
</PRE>
<P>You can use it as-is, but it will be much better if you can
understand how it works.
</TD></TR></TABLE></P>
<H3><A NAME="64"><U>How can I make my C function return itself?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Suppose I'm writing an ASM function <CODE>'foo(n)'</CODE> which accepts an
argument (a string, for example). I want to make <CODE>'foo(n)'</CODE>
return <CODE>'foo(n)'</CODE> (the call itself) when <CODE>'n'</CODE> is of type
"VAR" (i.e. if nothing has been assigned to <CODE>'n'</CODE> yet)...
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
This is quite easy, if you know in advance the name of the program.
Suppose, that your program name is "example". Here is the demo (called
"Function Returning Itself") which will return <CODE>'example(n)'</CODE> if
you type <CODE>'example(n)'</CODE> if
<CODE>'n'</CODE> is a variable, and which will return the string "blabla"
(for example) if the argument is something else:</P>
<PRE>// A function returning itself
#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define RETURN_VALUE // Return pushed expression
#define MIN_AMS 101 // Compile for AMS 1.01 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
// Main Function
void _main(void)
{
ESI argptr = top_estack;
if (GetArgType (argptr) <= VAR_Q_TAG) // it means that arg is a variable
// see Tags to see why...
push_expr_quantum (SYMSTR ("example"), USERFUNC_TAG);
else
{
while (ESTACK (top_estack) != END_TAG)
top_estack = next_expression_index (top_estack);
top_estack--;
push_string (SYMSTR ("blabla"));
}
}
</PRE>
<P>Note that this solution is not ideal: if you rename the program name to something else,
the function will still return <CODE>'example(n)'</CODE>. It
<I>is</I> possible to determine the real name of the program in the run time, but this
is very awkward.
</TD></TR></TABLE></P>
<HR>
<H3><A NAME="18"><U>How can I display a number variable on the screen (like an int)?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
How can I convert an integer or a float to a string?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
It's easy. Use
<A HREF="stdio.html#sprintf">sprintf</A>. For example:</P>
<PRE>char string1[50];
char string2[50];
short int var1;
float var2;
...
sprintf (string1, "%d", var1);
sprintf (string2, "%f", var2);
</PRE>
<P>That's why there is no need for functions like <B>itoa</B> and <B>ftoa</B>
in opposite to <A HREF="stdlib.html#atoi">atoi</A> and <A HREF="timath.html#atof">atof</A>.
</TD></TR></TABLE></P>
<H3><A NAME="101"><U>Do you plan on implementing 7-level grayscale?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Do you plan to implement 7-level grayscale mode?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
So far no, because nobody yet implemented 7-level grayscale which works stable on both HW1
and HW2 calculators. I don't want to implement features which works only on HW1 calculators.
</TD></TR></TABLE></P>
<H3><A NAME="14"><U>How can I use sprites?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Do you know how I can use sprites with GCC4TI ?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Another common question. The answer depends on the size of the sprite.
If your sprite is not wider than 32 pixels (which is likely),
then you can now use the <A HREF="sprites.html">sprites.h</A>
header file. This header file defines fast functions which work with sprites
(including masked sprites). The only limitation is that the sprite must not be
wider than 32 pixels (the height is not limited).
<BR><BR>
What to do if you want sprites wider than 32 pixels, and don't want to use
kernel-based programming? The answer depends on what the usage of this sprite will be. If you don't
need fast action, the built-in function <A HREF="graph.html#BitmapPut">BitmapPut</A>
may be good enough. If you need a very fast sprite routine, you may be better
off using the ExtGraph library by the
<A HREF="http://tict.ticalc.org/">TI-Chess Team</A>.
</TD></TR></TABLE></P>
<H3><A NAME="15"><U>I don't understand how to define sprites!</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I can't understand how sprites are defined; I looked in many program sources, and every
sprite definition looks for me as an array of random hex numbers!?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Well, suppose that you want to make a sprite which is a
filled circle. Make a grid on the paper, and make a sprite shape by filling
grid squares. Then, replace each filled square with 1 and each blank square
with 0. In above example, it may look like:
<BR><BR>
00111000<BR>
01111100<BR>
11111110<BR>
11111110<BR>
01111100<BR>
00111000
<BR><BR>
Then, produce rows as a set of binary numbers, and convert them
to hex. For example:
<BR><BR>
00111000 binary = 38 hex<BR>
01111100 binary = 7C hex
<BR><BR>
etc. These hex numbers describe the sprite, i.e. the sprite
definition should be</P>
<PRE>unsigned char sprite [] = {0x38, 0x7C, ...};
</PRE>
<P>assuming that <A HREF="sprites.html#Sprite8">Sprite8</A> will be used. That's all...
<BR><BR>
<B>Note:</B> GCC4TI also supports binary numbers (<CODE>0b...</CODE>).
</TD></TR></TABLE></P>
<H3><A NAME="17"><U>How do you use sprite functions from sprites.h with grayscale?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I would like to know if it is possible to use the sprite functions
in <A HREF="sprites.html">sprites.h</A> with grayscale. I have tried
using the <A HREF="sprites.html#Sprite16">Sprite16</A> function with
grayscale, and none of the sprites I intended to be in grayscale appeared.
I tried to use <A HREF="graph.html#DrawIcon">DrawIcon</A> and the grayscale
worked just fine. But <A HREF="graph.html#DrawIcon">DrawIcon</A> is too
slow... Can <A HREF="sprites.html#Sprite16">Sprite16</A> and
<A HREF="sprites.html#Sprite32">Sprite32</A> handle grayscale sprites.
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Very common question in a recent time. See, you probably tried to use
<A HREF="gray.html#GraySetAMSPlane">GraySetAMSPlane</A>.
<A HREF="sprites.html#Sprite16">Sprite16</A> have a parameter for drawing
plane, so it is not sensitive to <A HREF="gray.html#GraySetAMSPlane">GraySetAMSPlane</A>:
you need to give the plane as an explicite parameter. In fact, you need to
have two different sprite planes and to draw a sprite twice, passing two
different planes as a parameter. For example,</P>
<PRE>static unsigned short light_definition [] = {...};
static unsigned short dark_definition [] = {...};
...
Sprite16 (x, y, height, light_definition, GrayGetPlane (LIGHT_PLANE), A_XOR);
Sprite16 (x, y, height, dark_definition, GrayGetPlane (DARK_PLANE), A_XOR);
</PRE>
<P>In other words, sprite routines <I>can</I> handle grayscale
sprites, but not natively, meaning you have to take your grayscale
sprite, split it into two layers, and draw each one separately on its
own plane - the routine does not handle these by itself. As suggested
by Scott Noveck, it is possible to make a function of your own to
handle this. Assume that your grayscale sprites follow the "standard"
format seen in the most of ASM games, with the dark plane data followed
immediately by the light plane data. This routine will call
<A HREF="sprites.html#Sprite16">Sprite16</A> twice - once for each plane:</P>
<PRE>void GraySprite16 (short x, short y, short h, unsigned short *spr, short mode)
{
Sprite16 (x, y, h, *spr, GetPlane (LIGHT_PLANE), mode);
Sprite16 (x, y, h, *spr + h, GetPlane (DARK_PLANE), mode);
}
</PRE>
<P>Don't be afraid about calling <A HREF="gray.html#GrayGetPlane">GrayGetPlane</A> each
time: it is not a waste of time. Its implementation is smart: when the input
is a constant, it will simply evaluate to a memory address that
contains the pointer; when it is variable, it expands to a simple macro.
</TD></TR></TABLE></P>
<H3><A NAME="22"><U>How does BitmapGet work?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
Can you give me info on how <A HREF="graph.html#BitmapGet">BitmapGet</A> works.
I've tried everything that I know and I still get protected memory errors. The
manual just doesn`t give anything solid to base a few lines of code on.
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
You probably didn't allocate enough space to store a bitmap.
The simplest way to do so is given in this example (called "Bitmap Test"):</P>
<PRE>// Retrieve and store a bitmap
#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#include <tigcclib.h> // Include All Header Files
// Main Function
void _main(void)
{
SCR_RECT full_screen = {{0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1}};
char buffer [BITMAP_HDR_SIZE + LCD_WIDTH*LCD_HEIGHT/8]; // or 2004 for a TI-89 and 3844 for a TI-92+/V200 if you like it more
BitmapGet (&full_screen, buffer); // store screen in buffer
clrscr ();
printf ("Press any key to\nrestore screen...");
ngetchx ();
BitmapPut (0, 0, buffer, &full_screen, A_REPLACE);
ngetchx ();
}
</PRE>
<P>Note that this is just an example: for saving/restoring the whole screen,
the functions <A HREF="graph.html#LCD_save">LCD_save</A> and
<A HREF="graph.html#LCD_restore">LCD_restore</A> are much more efficient!
Moreover, <I>buffer</I> will probably be allocated using
<A HREF="alloc.html#malloc">malloc</A> in a more realictic example.
</TD></TR></TABLE></P>
<H3><A NAME="39"><U>How can I create a virtual screen?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
How I can change the port for the screen memory to draw to it, and then copy it
back to the regular address?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
Do this:</P>
<PRE>void *virtual = malloc (LCD_SIZE); // <I>Allocate the buffer</I>
...
if (!virtual) ... // <I>do some error handling - not enough memory!</I>
PortSet (virtual, 239, 127); // <I>redirect drawing routines to buffer</I>
</PRE>
<P>or, even simpler, virtual screen may be simply in any local variable which is
enough long:</P>
<PRE>char virtual[3840];
...
PortSet (virtual, 239, 127);
</PRE>
<P>Note that, in this case, virtual memory will be in fact somewhere on the stack.
There is nothing bad in this, but keep in mind that the total amount of the
stack is 16K, so don't put TOO MANY data (like big arrays etc.) on the stack
(i.e. in local variables). If you really need to handle a lot of data, use
<A HREF="alloc.html#malloc">malloc</A> instead.
<BR><BR>
After this, do any drawing you want - it will be redirected to the virtual
screen. To copy this to the regular screen (i.e. to display it) do this:</P>
<PRE>memcpy (LCD_MEM, virtual, LCD_SIZE);
</PRE>
<P>or even simpler (this is the same):</P>
<PRE>LCD_restore (buffer);
</PRE>
<P>And, don't forget to do <A HREF="graph.html#PortRestore">PortRestore</A> before end of the program, else TIOS will
be fooled after returning to TI-Basic!
</TD></TR></TABLE></P>
<H3><A NAME="40"><U>How can I set up a SCR_RECT structure?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
How I can setup properly a <A HREF="graph.html#SCR_RECT">SCR_RECT</A> structure?
For example, the <A HREF="graph.html#FillTriangle">FillTriangle</A>
function requires the parameter of <A HREF="graph.html#SCR_RECT">SCR_RECT</A> type.
How to put coordinates into it, so that I can change the clipping area for the screen?
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
If all coordinates of clip area are known in advance (for example 5, 5, 90, 70),
do this:</P>
<PRE>FillTriangle (10, 10, 10, 50, 50, 50, &(SCR_RECT){{5, 5, 90, 70}}, A_NORMAL);
</PRE>
<P>or, using "standard" C (i.e. without <A HREF="gnuexts.html">GNU extensions</A>):
</P>
<PRE>SCR_RECT area = {{5, 5, 90, 70}}; // <I>somewhere in the declaration part</I>
...
FillTriangle (10, 10, 10, 50, 50, 50, &area, A_NORMAL);
</PRE>
<P>Note that double braces are necessary because <A HREF="graph.html#SCR_RECT">SCR_RECT</A>
is an union.
<BR><BR>
If coordinates are not known in advance, for examples if they are in
integer variables a, b, c and d, you can do this:</P>
<PRE>SCR_RECT area;
...
area.xy.x0 = a;
area.xy.y0 = b;
area.xy.x1 = c;
area.xy.y1 = d;
FillTriangle (10, 10, 10, 50, 50, 50, &area, A_NORMAL);
</PRE>
<P>or, much simpler, using <A HREF="gnuexts.html">GNU C extensions</A>:</P>
<PRE>FillTriangle (10, 10, 10, 50, 50, 50, &(SCR_RECT){{a, b, c, d}}, A_NORMAL);
</PRE>
<P></TD></TR></TABLE></P>
<H3><A NAME="42"><U>How can I make a WINDOW structure?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I would like to make my own window but I don't understand the lot of fields in
the <A HREF="wingraph.html#WINDOW">WINDOW</A> structure, like <CODE>'TaskID'</CODE>
and others!
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
You do not need to fill up the <A HREF="wingraph.html#WINDOW">WINDOW</A>
structure manually: function <A HREF="wingraph.html#WinOpen">WinOpen</A>
will fill everything automatically. See the next question for examples of usage.
</TD></TR></TABLE></P>
<H3><A NAME="43"><U>How do I use functions from the wingraph.h file?</U></A></H3>
<P><TABLE CELLPADDING="4"><TR><TD VALIGN="TOP"><B>Q:</B></TD><TD>
I need some examples of how to use the functions in the <A HREF="wingraph.html">wingraph.h</A> header file.
Especially, I am confused with static and/or dynamic data allocation.
I tried to use <A HREF="alloc.html">alloc.h</A> to create necessary structures, but something was wrong...
</TD></TR><TR><TD VALIGN="TOP"><B>A:</B></TD><TD>
I will give five very similar examples how to do the same thing. From the first and
fifth example you will see that you need not to use <A HREF="alloc.html">alloc.h</A> at all, and in the
second, third and fourth example, you will see what you need to do if you want
to use dynamic allocation (i.e. <A HREF="alloc.html">alloc.h</A>) anyway. Maybe this is not so obvious
from my documnetation, but flags in <A HREF="wingraph.html#WinOpen">WinOpen</A> must be ORed, so they must be
"separated" by "|", not by commas.
<BR><BR>
Example 1: Using <A HREF="wingraph.html">wingraph.h</A> without dynamic allocation (called "Window 1"):</P>
<PRE>#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
// Main Function
void _main(void)
{
WINDOW wind;
WIN_RECT winr = {20, 20, 80, 50};
WinOpen (&wind, &winr, WF_SAVE_SCR | WF_TTY);
WinActivate (&wind);
WinFont (&wind, F_6x8);
WinStr (&wind, "hello everyone");
ngetchx ();
WinClose (&wind);
}
</PRE>
<P>Example 2: Window is allocated dynamically (called "Window 2"):</P>
<PRE>#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
// Main Function
void _main(void)
{
WINDOW *wind = HeapAllocPtr (sizeof (WINDOW));
WIN_RECT winr = {20, 20, 80, 50};
WinOpen (wind, &winr, WF_SAVE_SCR | WF_TTY);
WinActivate (wind);
WinFont (wind, F_6x8);
WinStr (wind, "hello everyone");
ngetchx ();
WinClose (wind);
HeapFreePtr(wind);
}
</PRE>
<P>Note that synonyms for <A HREF="alloc.html#HeapAllocPtr">HeapAllocPtr</A> and
<A HREF="alloc.html#HeapFreePtr">HeapFreePtr</A> are
<A HREF="alloc.html#malloc">malloc</A> and <A HREF="alloc.html#free">free</A> (like in ANSI C).
<BR><BR>
Example 3: Both "window" and "rect" are allocated dynamically (called "Window 3"):</P>
<PRE>#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
// Main Function
void _main(void)
{
WINDOW *wind = HeapAllocPtr (sizeof (WINDOW));
WIN_RECT *winr = HeapAllocPtr (sizeof (WIN_RECT));
winr->x0 = 20; winr->y0 = 20;
winr->x1 = 80; winr->y1 = 50;
WinOpen (wind, winr, WF_SAVE_SCR | WF_TTY);
WinActivate (wind);
WinFont (wind, F_6x8);
WinStr (wind, "hello everyone");
ngetchx ();
WinClose (wind);
HeapFreePtr (wind);
HeapFreePtr (winr);
}
</PRE>
<P>Example 4: How to use <A HREF="wingraph.html#MakeWinRect">MakeWinRect</A> to avoid "winr" (called "Window 4"):</P>
<PRE>#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
// Main Function
void _main(void)
{
WINDOW *wind = HeapAllocPtr (sizeof (WINDOW));
WinOpen (wind, MakeWinRect (20, 20, 80, 50), WF_SAVE_SCR | WF_TTY);
WinActivate (wind);
WinFont (wind, F_6x8);
WinStr (wind, "hello everyone");
ngetchx ();
WinClose (wind);
HeapFreePtr (wind);
}
</PRE>
<P>Example 5: This is what I do in my programs (called "Window 5"):</P>
<PRE>#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200