0001                                   Aiwnios.com
0002 
0003   Welcome to Aiwnios.com,the best server on earth. I will show you how  to do 
0004 cool stuff like write compilers and make games. I will write articles time to 
0005 time,but first let me tell you about myself.
0006 
0007   My name is Clayton and I like compilers alot.I wrote Aiwnios which is a  HolyC 
0008 compiler that runs on 64,bit arm and X86_64 and it's Travis Scott lit.I will 
0009 explain it in detail how it works,the first part is the lexer. I'm not a unix 
0010 pro but here are my notes Unix Notes or my Jain Notes.
0011 
0012   Here is a link to the User Guide if you want to know how to use aiwnios. Or 
0013 maybe you are here for the blog
0014 
0015   Checkout My FlashCards app and flash cards for the latest in nroots Greek 
0016 Quest(download the ISO and MountFile it in Aiwnios to use it).
0017 
0018   Irc Server
0019 
0020 aiwnios.com 6667
0021 Turn off SSL before connecting in your client
0022 Dont send anything important over the IRC server
0023 
0024 
0025                            Kralech Compiler Tutorial
0026 
0027   I dont know where my life will end up but I have a compiler. This is certian. 
0028 I did it. I will show others how to do it. This is a good way when you are 
0029 right. A compiler turns source code into action that your computer understands. 
0030 Knowing how to compile is a good way to milk a computer to the max
0031 
0032 
0033 <1>
0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 Lesson 1: The Lexer 0056 Lexers turn raw data (such as source code ) into tokens a motherfucking 0057 compiler can use. Dont make a compiler without a lexer or you will have to 0058 juggle lots of meaningless symbols 0059 0060 Lesson 2: The Parser 0061 A compiler must turn tokens into meaningful constructs that the compiler will 0062 use. Representing the reality of the source data is key (representation) when 0063 generating machine code. 0064 0065 0066 Lesson 3: Register Allocation Pt.1 0067 Registers are values that live in your computer. Values in in registers,and 0068 sometimes they die. Here we see which values are living and dead at what points 0069 in time 0070 0071 0072 Lesson 4: Reg Allocation Pt.2: Graph Coloring 0073 0074 Compilers have a finite number of registers. We must use the registers in a good 0075 fashion to generate good machine code. 0076 -] Registers Poem 0077 0078 I hate the scare-registered program 0079 For it lacks a wham. 0080 As the heated graph... 0081 One cant help but laugh, 0082 For one is too poor,the other too dumb 0083 0084 0085 Lesson 5: Reg Allocation Pt.3: Using Less Registers 0086 Registers are finite,forms are not. A value may be in register R10 at one 0087 point,RDI at another 0088 0089 Lesson 6: Reg Allocation Pt.4: Assigning temporary registers 0090 0091 Lesson 7: Reg GENERATING MOTHERFUCKIN MACHINE CODE 0092 0093 Shitpit Pt.3 0094 0095 5-27-24 Pt.1 0096 0097 Im Pushin' P putting Quake2 from steam on a flash drive to play on the RISC-V 0098 machine. I once said I am a living legend. This is simply not the case. A 0099 educated person in kindegarden looks like a genius(by comparasion). I need to 0100 find the rest of the compiler clan.Im not sure where they are 0101 0102 In my life I used to play with transitors as a kid. I wanted to build robots. 0103 I guess you could say I was a genius,but in reality I simply had access to more 0104 imformation than other kids. Its not that hard to build and AND gate,or a NOT 0105 gate. Alternating Current was secrectly above my head. I never understood 0106 inductors. 0107 0108 Math is the real star of the show. Do you ever wonder how people come up with 0109 operational amplifiers and filters; It's through math. Ill give an example of a 0110 simple amplifier and how math is responsible for it 0111 <2>
0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 Edit: I have no idea how I worked the math of an operational amplififier at like 0130 12/13. I have become dumbers over the years. Time to stop pretending to be 0131 smart 0132 0133 5-26-24 Pt.2 0134 0135 Some people suffer for fame. I am not famous and even if I was I would not 0136 care. If you have seen the qualities of seeking attention you have seen whatever 0137 the fuck this is: 0138 <3>
0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 Detioration of the senses and substance will occur. You will no longer be able 0160 to drink the Gamer Girl piss and bathwater. Dont carelessly misuse yourself 0161 while you are sensible. God will misuse you once your senses start to disappear 0162 and you will be unable to construct reality. I dont know if the target 0163 demographic for retarded Gamer Girl piss is old men or young men. I really dont 0164 know. 0165 0166 5-26-24 Pt.1 0167 0168 I heard autistic people cannot think abstractly easier. If I look at my notes 0169 they are not glued togheter or make any sense when viewed as a whole. They are 0170 not concrete(abstract). I am diagnosed with autism but I dont have it too bad. 0171 0172 You may be wondering about socialization. I have wrote before that beings are 0173 capable of receiving and giving love. This could apply to humanity at large as 0174 opposed to a small group of individuals. I do not care about anyone enough to 0175 marry them. I don't even care about them enough to serious talk to them,but I 0176 care enough to offer tea to homeless people and volenteer/work at food pantry 0177 for homeless people. I dont do this for money because I only get paid half of 0178 what I "work"(I volenteer the rest of the days). 0179 0180 See this section for why I am not Schitzophrenic. 0181 0182 5-25-24 Pt.2 0183 0184 Have you seen internal conflict. No? I have(self control). There are few if 0185 any outside oppressors. A room with a sexy RISC-V machine or other programmable 0186 machine is sexy is the same as the world to me. I wonder about the mentality of 0187 insane people. I used to belive God wanted me to wash myself alot but I was not 0188 insane becuase the Quran said so,therefore my "insane" OCD was based in a sort 0189 of reality. I was operating on bad info. I am not actually insane because I was 0190 operating on bad information as opposed to pure insanity. 0191 0192 Actually insne people(I imagine) are unable to different reality from 0193 thoughts. Insane people and "insane" people only appear the same on the outside. 0194 Hueristics are illrevelant here. 0195 0196 0197 5-25-24 Pt.1 0198 0199 Biases obscure reality. Try looking in the mirror and seeing an evil person. 0200 Morality seems to be used to justify sins more than it is used to condemn them. 0201 People eat food then it comes back out. This is self morality. True morality is 0202 not a by-product. 0203 0204 A facts is different than the reason is it being presented to you 0205 0206 5-23-24 Pt.1 0207 0208 People going full smart mode must not eat beans. There was a crow 2(?) days 0209 ago that wanted to enter my workplace,he flew into the window multiple and 0210 squaked and left his claw-marks on the window. Mr Crow tried to enter again at 0211 the front door. 0212 0213 What belongs to humans is in my hands,and what is the crow's is in his(?) 0214 claws. It is improper to take what belongs to the crow,and improper for the bird 0215 to enter my workplace,even though he is cute. 0216 0217 5-22-24 Pt.1 0218 0219 Things not to think about: 0220 <4>
0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238 0239 0240 0241 0242 0243 0244 0245 Im not sure why this sounds like a good idea to me. They say sharing sins is a 0246 first step. Just as jucie has less taste when mixed with lots of water,sins 0247 become reduced when confessed. I asked StableDefusion to make a picture of a 0248 hedgehog made out of shit and cheetos but I didnt get a good result 0249 0250 5-21-24 Pt.4 0251 0252 I will reload the Smalltalk compiler. I wil use goto's instead of switch 0253 statements 0254 0255 5-21-24 Pt.3 0256 0257 We loose life when we loose senses(by death),to live we must remain sensible 0258 to live. I think of a severly retarded frog individual that has no snese of 0259 reality and does everthing that comes to mind. He looks like a meth addict. 0260 0261 I should make a archive of sexy content that demonstrates the in-sensibity of 0262 humans,like a "best of" list of crazyshit.com. I saw a guy smoking meth out of 0263 some fine plumbing dressed up like Super Mario. I swear the shit was fuckin lit. 0264 0265 5-21-24 Pt.2 0266 The Tirhankaras would not approve of deporting people but I cannot censor 0267 myself. The best person to deport to Africa is yourself sometimes. 0268 0269 5-21-24 Pt.1 0270 0271 Systematic deportation of mastrubators to Africa is a good way to solve the 0272 world's problems. Ill do research on how to run for President. I need to be 35 0273 years old. We need to assemble a Pornhub to Africa pipeline to fuel economic 0274 growth. Africa will benefit because they will have people to help fix poverty 0275 <5>
0276 0277 0278 0279 0280 0281 0282 0283 0284 0285 0286 0287 0288 0289 0290 0291 0292 0293 0294 0295 0296 0297 0298 0299 0300 0301 0302 0303 0304 0305 0306 0307 0308 0309 0310 0311 0312 0313 0314 0315 5-20-24 Pt.5 0316 0317 It is improper to romanicize anything out of reach. Security is a virtue. If I 0318 lost everythng and I accept the situation I will have security. Hypothetical 0319 gains from "just try it" are no match for security. A hyptohetical gain is 0320 lesser than the actuall loss in aquiring such a gain. Doing what suites you and 0321 makes you happy is perfecty fine and doesnt need to be fixed 0322 0323 5-20-24 Pt.4 0324 0325 Delusion could be defined as holding a gun to someone's head and claiming 0326 victimhood for the victim disobeying him. If the victim obeys it is still 0327 delusion. They say forced non-murder isnt true peace. This is the socitey 0328 delusion 0329 0330 Societies are defined by sets of morals. A Society without morals is an 0331 oxymoron. 0332 0333 Good people sell cures.Bad people create problems then sell cures. It is 0334 common for people to advocate freedom then condemn the liberties of others. 0335 Religious freedoom is no more of an oxymoron than society liberty. No values == 0336 no morals. The only super power you get from morality is self control 0337 0338 It seems to me that people dont have true morals and are just pretending. If I 0339 say the n word then everyone will condemn me but I am literally on a literal 0340 level harming no one. Sweet words("dont say the n word") can motivate people to 0341 do good. Does evil brew in silence or numbers. 0342 0343 Religion is good at reminding people to have morals. Home and security guards 0344 evils. Its like visiting house that you no longer live in. 0345 0346 5-20-24 Pt.3 0347 0348 If you have even seen words,you probably dont remember the paper they were 0349 written on. Thats becuase it is way too easy to read words. You could even 0350 transliterate greek if I told you what the letters sounded like. Reading isnt 0351 the true virtue,understanding is. Why am I writing the things I write 0352 0353 Compasion comes in 2 forms,Self-helping and Self-Obstructing. Somtimes helping 0354 others helps you or hurts you. Rejecting compassion is garenteed to deny the 0355 possibly of benefit but accepting compasion can give you either or 0356 0357 5-20-24 Pt.2 0358 0359 I am not a f*g,maybe I am a fig so I might be plantsexual but I dont know how 0360 sexy lettuce is. I dont know if it is possible that plants have genderes 0361 0362 5-20-24 Pt.1 0363 0364 Members of the Heavens Gate cult dressed up as star trek charactors before 0365 pwning themselves. Sometimes reality is strange we have to do strange things to 0366 express reality. It is less narcasistic to accept a loss than to deny it. I am 0367 reflecting on my reality.It is an serious act,the only people seeing 0368 trajedy/confusion are outsiders 0369 0370 5-19-24 Pt.2 0371 0372 Abstracting the dying out of death is bad. Everyone wants what they lust for 0373 until they have it. Vice versa. The problem with good people isnt good people 0374 dying,rather its when death becomes an abstract and trajedy becomes just. 0375 0376 5-19-24 Pt.1 0377 0378 I am a creatin with little sense of direction,but with a Compiler and loads of 0379 time. Despite being true I will refuse to hear it from other. Just in the same 0380 way it is useless to reason with a wall,it is useless to explain compilers with 0381 outsiders. Likewise it is useless to reason with me about direction; This is not 0382 a choise made in ignorance though 0383 0384 A Goldfish does what is best for him,witihin his capacity. Whatever 0385 hypothetical gain will go over it's goofy goldfish brain. He is soley concerned 0386 with reality. Anyone thinking of hyptheticals alone isnt thinking about 0387 reality. Goldfish poo poo brains are good at reality studies. 0388 0389 My misadventures are focosed with reality and not hyptoheticals. A 0390 hyptohetical evil is lesser than the actuall evil in combaring a hypothetical 0391 evil. 0392 0393 Morality is over my head. It is not for me to decide. 0394 0395 5-13-24 Pt.1 0396 0397 It is a strange occurance to read something to complex to understand,it is 0398 stranger to understand it. Aquisition and understanding is a 2 fold activity 0399 0400 5-10-24 Pt.2 0401 0402 Dillo 3.1 is out,grab your bros 0403 0404 5-10-24 Pt.1 0405 0406 I will say that humility is knowling your place as the asker of questions. 0407 Gods I think have a degree of humility in awnsering questions. The planter 0408 doesnt ask the Sun God for rain and the Althete doesnt ask the Rain God for 0409 sun. I suppose the Gods know their place and we ought to know our place too 0410 The 1 God cannot awnser the prayers of both the farmer and the athlete. 0411 0412 You see,knowledge is reduction ,and reality consitutes knowledge. You cannot 0413 attain liberation without reduction and restaint from evil 0414 0415 Clayton 0416 0417 <nrootconauto@gmail.com>
0418 0419 0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 0450 0451 0452 0453 0454 0455 WIP DOOM port 0456 I am working on a port of Doom that runs on Aiwnios(TOOM). 0457
0458 0459 0460 0461 0462 0463 0464 0465 0466 0467 0468 0469 0470 0471 0472 0473 0474 0475 0476 0477 0478 0479 0480 0481 0482 0483 0484 0485 0486 0487 0488 0489 0490 0491 0492 0493 0494 0495 0496 0497 0498 0499 0500 0501 0502 0503 0504 0505 Compiler Part 1,The Lexer 0506 0507 The first part of the compiler is the lex. It turned the text from the source 0508 code into words(tokens) that the compiler understands. For example, 0509 "123" gets turned into a TK_I64. 0510 0511 In our lexer,we have CLexFile's which are blocks of text we read,this can we 0512 any piece of text,like a macro's definition or an #exe block or a file. We get 0513 the charactors out of the Lexer via LexGetChar,which will do things like free 0514 the old CLexFile if we reach the end of the stream. 0515 0516 Sometimes we want to put a charactor back into the stream. You can use CCF_USE 0517 _LAST_U16 to reuse the last charactor. For example,if we are looking for digits 0518 in the expression 123; and we hit the semicolon,we dont want to discard the 0519 semicolon that we just got,so we put it back into the lexer by setting CCF_USE_L 0520 AST_U16 0521 0522 0523 <8>
0524 0525 0526 0527 0528 0529 0530 0531 0532 0533 0534 0535 0536 0537 0538 0539 0540 0541 0542 0543 Compiler Part 2,The Parser 0544 0545 The second part of the compiler is the the parser. At the heart of this parser 0546 (in AIWNIOS_PrsExp.HC) is the shunting yard algorithm. This uses Reverse Polish 0547 Notation. This is a form of stack notation that looks like this: 0548 0549 0550 1 2 + 3 4 + * 0551 0552 The operators come is the order that they are used,lets see again with some 0553 parenthesis 0554 0555 ((1 2 +) (3 4 +) *) 0556 0557 Pretty epic isn't it. 0558 0559 To generate this,I use a stack called CCmpCtrl->ps with a class of CPrsStk. 0560 There are 3 stacks in a CPrsStk. The first is the precedence stack,the second is 0561 pointers to the generated CRPN's. The final is tree nodes. 0562 0563 The algorithm works by immediately pushing numbers to the stack first. 0564 Operators are pushed to the Shunting yard stack. It looks like this 0565 0566 <9>
0567 0568 0569 0570 0571 0572 0573 0574 0575 0576 0577 0578 0579 0580 0581 0582 0583 0584 0585 0586 The first thing to do here is put the '+' operator on the stack. 0587 0588 <10>
0589 0590 0591 0592 0593 0594 0595 0596 0597 0598 0599 0600 0601 0602 0603 0604 0605 0606 0607 0608 The next thing to do(after we push 2 to the output) is to check if + comes 0609 after *. + comes after the * so we push it to the output,then push * to the 0610 stack for later. We end up with something like this 0611 0612 <11>
0613 0614 0615 0616 0617 0618 0619 0620 0621 0622 0623 0624 0625 0626 0627 0628 0629 0630 0631 0632 0633 0634 Once we are at the end of input(after we add 3). We add all the operators to 0635 the output 0636 0637 <12>
0638 0639 0640 0641 0642 0643 0644 0645 0646 0647 0648 0649 0650 0651 0652 0653 0654 0655 0656 0657 Compiler Part 2,The Parser II 0658 0659 UNDER CONSTRUCTION 0660 0661 Compiler Part 3,The Code Generator 0662 0663 0664 The code generator in aiwnios is platform dependant and is written in C to 0665 make porting to new platforms easier(bootstrapping is done in C). There is an 0666 interface in AIWNIOS_CodeGen.HC to use the turn the Intermediate Codes from the 0667 HolyC parser into the C intermediate codes. 0668 0669 There are multiple phases to turning the intermeidate codes into machine code. 0670 The first phases are in optpass.c. This file is pretty simple and does things 0671 like constant folding(OptPassConstFold) and merging communitive operations(OptPa 0672 ssMergeCommunitives). This is boring stuff ,but the epic part is in x86_64_backe 0673 nd.c(or arm_backend.c for AARCH64). 0674 0675 The most important thing this file does is generate machine code,at the top of 0676 the file you will see functions that generate voluptuous X86 instructions for 0677 you. The second most important part is generating the temporary registers for 0678 the intermediate codes. 0679 0680 To do this,I imagine the CRPN's as a tree. Beacuse temporary registers are 0681 scare,we need to make good use of them. A good way to do this is to assign them 0682 to the leafs of the tree,and when we are done using them,we Pop them from our 0683 imaginary stack(computers loves stacks). 0684 0685 0686 <13>
0687 0688 0689 0690 0691 0692 0693 0694 0695 0696 0697 0698 0699 0700 0701 0702 0703 0704 The heavy lifting for this is done in PushTmpDepthFirst. This we recuse into 0705 the parse "Tree" and Push items once it's children are done. Items are popped 0706 when we are done with them. The PushTmp/PushTmpSpilled functions will 0707 automatically choose a temporary register based on how many temporary registers 0708 are used,or if none are availble a stack location will be choosed. 0709 0710 The fun part is at the __OptPassFinal function. This is basically a gaint 0711 switch statement that will generate the machine code from the intermediate 0712 codes. 0713 0714 This is done in 2 passes,the first pass is done to see how big the resulting 0715 source code is,and the second part is to actually generator the source code. In 0716 my code generator,I have code_misc's on some of the intermedaite codes like 0717 IC_GOTO. 0718 0719 Sometimes we want the address of a label,but we dont know it untill all the 0720 machine code is generated. You can have the compiler fill in the label at an 0721 offset in the machine code with CodeMiscAddRef(CCodeMisc*,I64 offset). At the 0722 end of our OptPassFinal function I fill in the holes with the label pointers. 0723 0724 0725 User-Guide 0726 0727 Runtime Part 1:Graphics I 0728 0729 Use the Fs->draw_it callback to draw something to the current window 0730 0731 0732 U0 DrawIt(CTask *,CDC *dc) { 0733 dc->color=BLUE; 0734 GrRect(dc,0,0,100,100); 0735 } 0736 Fs->draw_it=&DrawIt; 0737 0738 0739 0740 The first argument is a pointer to the CTask being drawn,and the second 0741 argument is a CDC drawing context,use some primitives to draw to the screen. 0742 0743 -] GrRect 0744 0745 GrRect(dc,200,200,100,100); 0746 0747 -] GrPlot(single pixel) 0748 0749 GrPlot(dc,200,200); 0750 0751 -] GrFillCircle 0752 0753 GrFillCircle(dc,100,100,50); 0754 0755 -] GrCircle 0756 0757 GrCircle(dc,100,100,50); 0758 0759 -] GrLine 0760 0761 GrLine(dc,100,100,0,0); 0762 0763 -] GrPrint 0764 0765 GrPrint(dc,100,100,"Hello World"); 0766 0767 -] GrBlot(copy dc to other dc) 0768 0769 GrBlot(dc,100,100,new); 0770 0771 -] DCClear 0772 0773 DCClear(dc); //Resets Z buffer 0774 0775 -] DCFill 0776 0777 DCFill(dc,COLOR); 0778 0779 0780 Runtime Part 1:Graphics Transformations and 3D graphics 0781 0782 TempleOS lets you do sexy stuff with the graphics like 3D graphics. At the 0783 heart of this is a transformation matrix. Im not a math genius but luckily for 0784 me there are functions for managing the math for me. Before we can use a 0785 transformation matrix,we need to set the DCF_TRANSFORMATION flag in CDC->flags. 0786 After wards you can use matrix functions to rotate your drawing things 0787 cordanates 0788 0789 0790 CDC *dc=DCNew(100,100); 0791 Mat4x4IdentEqu(dc->r); //Assign a identity matrix(No transformation) 0792 DCFill; 0793 dc->flags|=DCF_TRANSFORMATION; 0794 F64 rotx=0; 0795 for(;rotx<=2*pi;rotx+=(2*pi/100.)) { 0796 DCFill(dc); 0797 Mat4x4IdentEqu(dc->r); //Reset our transformation 0798 Mat4x4RotZ(dc->r,rotx); 0799 Mat4x4TranslationEqu(dc->r,50,50,0); 0800 dc->color=YELLOW; 0801 GrRect3(dc,0,0,0,50,50); 0802 DCFill; 0803 GrBlot(,100,100,dc); 0804 Sleep(33); 0805 } 0806 DCDel(dc); 0807 DCFill; 0808 0809 0810 Here are a list of (transformation) matrix goodies: 0811 -] Mat4x4RotX 0812 0813 //Rotates around the X axis,used for Y-flipping 0814 0815 -] Mat4x4RotY 0816 0817 //Rotates around the Y axis,used for X-flipping 0818 0819 -] Mat4x4RotZ 0820 0821 //Rotates around the Z axis,use general 2D rotations 0822 0823 -] Mat4x4Scale 0824 0825 //Zooms a matrix 0826 0827 -] Mat4x4TranslationEqu 0828 0829 Mat4x4TranslationEqu(mat,x,y,z); //Sets the cordantes of a matrix 0830 0831 -] Mat4x4TranslationAdd 0832 0833 Mat4x4TranslationAdd(mat,x,y,z); //Add to the cordantes of a matrix 0834 0835 -] Mat4x4MulXYZ 0836 0837 Mat4x4MulXYZ(mat,&x,&y,&z); //THIS WILL TRANSFORM THE CORDANTES BY THE MATRIX 0838 0839 0840 You may want to do general math on matricies too: 0841 -] Mat4x4IdentEqu 0842 0843 Mat4x4IdentEqu(mat); //This makes a normal matrix that doesnt do 0844 transofrmations 0845 0846 -] Mat4x4IdentNew 0847 0848 I64 *malloced=Mat4x4IdentNew; //This makes a normal matrix that doesnt do 0849 transofrmations 0850 0851 -] Mat4x4MulMat4x4Equ 0852 0853 Mat4x4MulMat4x4Equ(dst,a,b); //Multiplies a matrix to another matrix,ask a 0854 genius what this actually does 0855 0856 -] Mat4x4MulMat4x4New 0857 0858 I64 *malloced=Mat4x4MulMat4x4Nw(a,b); //Same as above but MAlloced 0859 0860 0861 Sometimes in your 3D adventures you may want to make sure you draw things in 0862 the distacne behind the things in the front. This is called Z-buffering. In 0863 TempleOS this is easy-peasy. Just call DCDepthBufAlloc(dc). This will handle 0864 your depths for you. 0865 0866 Here is a cube thing for you: 0867 0868 0869 CD3I32 poly[4]= 0870 {{-100,-100,-100},{100,-100,-100},{100,100,-100},{-100,100,-100}}; 0871 I64 colors[4]= {BLUE,YELLOW,GREEN,CYAN}; 0872 CDC *dc=DCNew(200,200); 0873 dc->r=Mat4x4IdentNew; 0874 DCDepthBufAlloc(dc); 0875 DCFill; 0876 dc->flags|=DCF_TRANSFORMATION; 0877 F64 rotx=0,roty; 0878 CD3I32 cube[6][6]; 0879 I64 i=0,i2=0; 0880 I64 *trans=Mat4x4IdentNew; 0881 for(rotx=0.; rotx<=(2.*pi)-1.; rotx+=2*pi/4.) { 0882 Mat4x4IdentEqu(trans); 0883 Mat4x4RotX(trans,rotx); 0884 Mat4x4RotY(trans,roty); 0885 for(i2=0; i2!=4; i2++) { 0886 MemCpy(&cube[i][i2],&poly[i2],sizeof(CD3I32)); 0887 Mat4x4MulXYZ(trans,&cube[i][i2].x,&cube[i][i2].y,&cube[i][i2].z); 0888 } 0889 i++; 0890 } 0891 for(rotx=0; rotx<=2*pi; rotx+=(2*pi/100.)) { 0892 DCFill(dc); 0893 DCDepthBufRst(dc); 0894 Mat4x4IdentEqu(dc->r); 0895 Mat4x4RotX(dc->r,rotx); 0896 Mat4x4RotY(dc->r,rotx); 0897 Mat4x4RotZ(dc->r,rotx); 0898 Mat4x4Scale(dc->r,.5); 0899 Mat4x4TranslationEqu(dc->r,0,0,3000); 0900 for(i2=0; i2!=6; i2++) { 0901 dc->color=colors[i2]; 0902 GrFillPoly3(dc,4,cube[i2]); 0903 } 0904 DCFill; 0905 GrBlot(,100,100,dc); 0906 Sleep(33); 0907 } 0908 DCDel(dc); 0909 DCFill; 0910 0911 0912 If you ran the above example,the cube looks flat,THIS IS BECUASE YOU NEED TO 0913 MAKE THINGS SHRINK IN THE DISTANCE 0914 0915 Let me introduce the CDC->transform callback: This callback will be called for 0916 every point that is rendered when DCF_TRANSFORMATION is enabled. To acheive the 0917 epic "shrinking effect",divide the X/Y coordinates by the Z coordanate times a 0918 scale distance Let's see an example: 0919 Heres an example: 0920 0921 0922 #define SCRN_SCALE 512 0923 U0 Transform(CDC *dc,I64 *x,I64 *y,I64 *z) 0924 { 0925 I64 zz; 0926 Mat4x4MulXYZ(dc->r,x,y,z); 0927 zz=SCRN_SCALE/3+*z; 0928 if (zz<1) zz=1; 0929 *x=SCRN_SCALE/2* *x/zz; 0930 *y=SCRN_SCALE/2* (*y)/zz; 0931 *x+=dc->x; 0932 *y+=dc->y; 0933 *z+=dc->z; 0934 } 0935 CDC *dc=DCAlias; 0936 dc->transform=&Transform; 0937 dc->flags|=DCF_TRANSFORMATION; 0938 I64 dist=0; 0939 dc->z=-60; 0940 for(dist=0;dist!=100;dist++) { 0941 Mat4x4TranslationEqu(dc->r,0,0,dist); 0942 dc->color=LTRED; 0943 GrRect3(dc,0,0,0,100,100); 0944 Refresh; 0945 DCFill; 0946 } 0947 0948 Runtime Part 1:Graphics Raster Operations 0949 0950 In TempleOS there are 16 colors,but you can mix them to make "new" colors. 0951 This is called dithering. To use dithering to use raster operations. This allows 0952 us to do things like make shading or invert the colors below what your drawing. 0953 Let's get started 0954 0955 0956 CDC *dc=DCAlias; 0957 I64 cnt; 0958 for(cnt=0;cnt!=100;cnt++) { 0959 dc->color=LTRED+YELLOW<<16+ROPF_DITHER; //Mix LTRED+YELLOW for Orange-ish 0960 color 0961 GrRect3(dc,0,0,0,100,100); 0962 Refresh; 0963 DCFill; 0964 } 0965 0966 0967 If you though that was cool,check out probability dithering. This will make a 0968 shading effect. You can change the percentage of what color gets used to make a 0969 shading of your choice.The CDC->dither_probability_u16 is a 16bit percentage of 0970 the the colors being used. If the dither_probability_u16 is 0,it will use 0971 dc->color,otherwise it will use dc->color.u8[2] if the probability is U16_MAX; 0972 0973 Let's rock(.u8[2] is 16 bits over): 0974 0975 CDC *dc=DCAlias; 0976 I64 cnt; 0977 for(cnt=0;cnt!=100;cnt++) { 0978 dc->color=BLACK; 0979 GrRect(dc,0,0,100,100); 0980 dc->color=LTRED+YELLOW<<16+ROPF_PROBABILITY_DITHER; 0981 dc->dither_probability_u16=U16_MAX*ToF64(cnt)/100.; 0982 GrFloodFill(dc,10,10); 0983 Refresh; 0984 DCFill; 0985 } 0986 DCDel(dc); 0987 0988 Runtime Part 2: Making Noises 0989 0990 TempleOS makes sounds that will bring you back to the days of Atari games. The 0991 simplest way to make a tone is Snd(23);(This higher the number the higher the 0992 pitch). Call "Snd;" to cancel the sound. 0993 0994 If you want to go the extra mile and make a bodacious explosioon sound,use No 0995 ise(milliseconds,min_pitch,max_pitch);. Or if you want a jumping sound,use Sweep 0996 . 0997 0998 Runtime Part 3: Making Music 0999 1000 TempleOS let's you make some epic jams. To do this,we use the Music 1001 1002 A simple song looks like this: 1003 1004 Play("wChDqEeFwGwAwB"); 1005 1006 1007 There are special charactors that change the duration/properties of the 1008 notes,so without further ado,here is a list 1009 -] # 1010 1011 Make a note sharp(comes after the note) 1012 1013 -] w 1014 1015 When before a note,it makes it a whole note 1016 1017 -] h 1018 1019 Makes a half note 1020 1021 -] q 1022 1023 Makes a 1/4 note 1024 1025 -] e 1026 1027 Makes a tiny eigth note 1028 1029 1030 You can change the tempo of the music via the global vairable music.tempo(Be 1031 sure to reset the music's settings via MusicSettingsRst) 1032 1033 Try this: 1034 1035 1036 music.tempo=8; 1037 Play( 1038 "hEhEwEhChEwGqG" 1039 "wCqGqEqAqBqA#qAqGhEhGwAhFhGwEhChDqB" 1040 "wCqGqEqAqBqA#qAqGhEhGwAhFhGwEhChDqB" 1041 "hGhF#hFhD#wEqG#qAhCqAhChD" 1042 "hGhF#hFhD#wE.wC.wC.wC" 1043 "hGhF#hFhD#wEqG#qAhCqAhChDwD#wDwC" 1044 "hGhF#hFhD#wEqG#qAhCqAhChD" 1045 "hGhF#hFhD#wE.wC.wC.wC" 1046 "hGhF#hFhD#wEqG#qAhCqAhChDwD#wDwC" 1047 ); 1048 MusicSettingsRst; 1049 1050 Runtime Part 4: Meta-data and Reflection 1051 1052 HolyC is a mainly just in time language. This means when the code gets 1053 compiled,the information about the code is still in memory. This is great for 1054 having the code reflect on itself and saves a lot of time doing meanial things 1055 like serializing a class. The primary way to do this is via MetaData. This means 1056 data about the self. 1057 1058 To get the metadata of a class out of the compiler,we must use the CTask's 1059 hash table and do these steps 1060 1061 -] Step 1 1062 1063 Lookup the class by it's name CHashClass 1064 *findc=HashFind(cls,Fs->hash_table,HTT_CLASS); 1065 1066 -] Step 2 1067 1068 Lookup the class by it's name CMemberLst 1069 *member=MemberFind("member_name",findc); 1070 1071 -] Step 3 1072 1073 Lookup the meta data I64 meta_data=MemberMeta("META_DATA",member); 1074 1075 1076 1077 Perhaps an example will help: 1078 1079 class CMeta { 1080 I64 a fmt "A:%d\n"; 1081 I64 b fmt "B:%d\n"; 1082 F64 c fmt "C:%n\n"; 1083 }; 1084 CMeta abc={1,2,3}; 1085 U0 Main(U8 *ptr,U8 *cls=lastclass) { 1086 CHashClass *findc=HashFind(cls,Fs->hash_table,HTT_CLASS); 1087 CMemberLst *ml; 1088 U64 sf; 1089 if(!findc) return; 1090 ml=MemberFind("a",findc); 1091 sf=(ptr+ml->offset)[0](U64); 1092 if(MemberMetaFind("fmt",ml)) { 1093 Print(MemberMetaData("fmt",ml),sf); 1094 } 1095 } 1096 Main(&abc); //Here we use lastclass to get the class of abc 1097 1098 1099 If you want to make a form using meta data,you can use PopUpForm 1100 1101 1102 class CInput { 1103 //Be sure to use -P with strings 1104 U8 name[STR_LEN] format "\n"; 1105 I64 age format "\n"; 1106 Bool is_tall format "\n"; 1107 }; 1108 CInput inp; 1109 PopUpForm(&inp); 1110 "%s is %d years old\n",inp.name,inp.age; 1111 if(inp.is_tall) 1112 "Tall!\n"; 1113 1114 1115 Runtime Part 5: Filesystem 1116 1117 If you are used to using TempleOS,use the Cd("Folder"); to move into a folder. 1118 You can list the contents of the directory via Dir(".");("." is the current 1119 folder). Sometimes you want your programs to be aware of the folders. Luckily 1120 for you,you have come to the right place 1121 1122 In TempleOS,each task has a current directory path in Fs->cur_dir(this doesnt 1123 include the drive letter). If you want the full path,use DirCur. 1124 1125 To make a file,use FileWrite("filename","text",4 /*text length*/);. When you 1126 want to read it use FilleRead("filename",&len); FileRead will always put a NULL 1127 terminator at the end of the file for your,so you can use it like a string. 1128 1129 Like C,in TempleOS you can read files in a stream,But in TempleOS,all file 1130 reads/writes act directly on the Hard-Disks sectors(Which are BLK_SIZE bytes 1131 big). You FOpen("filename","w") for writing FOpen("filename","r") for reading. 1132 To open a file for adding more data to it,use FOpen("filename","w+"). Lets see 1133 an example 1134 1135 1136 // 1137 // Files opened with FOpen MUST WRITE BLK_SIZE bytes at once 1138 // A BLK is the size of a hard-disk sector 1139 // 1140 CFile *file=FOpen("Database.BIN","w"); 1141 class CFileEnt { 1142 U8 name[STR_LEN]; 1143 U8 password[STR_LEN]; 1144 }; 1145 #assert sizeof(CFileEnt)<=BLK_SIZE 1146 CFileEnt clayton={"Clayton","123"}; 1147 CFileEnt root={"Root","toor"}; 1148 U8 buffer[BLK_SIZE]; 1149 MemCpy(buffer,&root,sizeof(CFileEnt)); 1150 FBlkWrite(file,buffer,0,1); //Write 1 blk at the first block(blk 0) 1151 MemCpy(buffer,&clayton,sizeof(CFileEnt)); 1152 FBlkWrite(file,buffer,1,1); //Write 1 blk at the second block(blk 1) 1153 FClose(file); 1154 // 1155 // Now we read 1156 // 1157 file=FOpen("Database.BIN","r"); 1158 CFileEnt user; 1159 while(FBlkRead(file,buffer,,1)) { 1160 MemCpy(&user,buffer,sizeof(CFileEnt)); 1161 "Got user \"%s\" with password \"%s\"\n",user.name,user.password; 1162 } 1163 FClose(file); 1164 1165 1166 Making and reading files is fun,but first you need to figure out where a file 1167 is. To do this use, . This will return a CDirEntry of the results(which may be 1168 multiple files). Assuming you are familiar with wildcards from Linux,DOS and 1169 CP/M. Look at this example 1170 1171 1172 FileWrite("abc.TXT","abc",3); 1173 FileWrite("def.TXT","def",3); 1174 FileWrite("ghi.TXT","ghi",3); 1175 CDirEntry *cur,*root=FilesFind("*.TXT",FUF_JUST_FILES); 1176 for(cur=root;cur!=NULL;cur=cur->next) { 1177 "I Found %s\n",cur->full_name; 1178 } 1179 DirEntryDel(root); 1180 1181 1182 A CDirEntry has much information about the directory structure. The most 1183 important is full_name which tells you the full name of the file as you may 1184 expect(name is the filename without the path). When you are done with a CDirEntr 1185 y be sure to free the root data with . 1186 1187 To check if a file exists,you can use FileFind("file.HC") to check if a file 1188 exists. 1189 1190 Time to get to the nitty gritty. Has some epic flags you can use.Im not going 1191 to waste time with exposiiton,rather I will give you a table of flags 1192 1193 1194 -] FUF_RECURSE 1195 1196 This will search in the child folders for the pattern too 1197 1198 -] FUF_JUST_DIRS 1199 1200 Chooses only directories(folders) 1201 1202 -] FUF_JUST_FILES 1203 1204 Chooses only files 1205 1206 -] FUF_JUST_TXT 1207 1208 Chooses only text files 1209 1210 -] FUF_JUST_DD 1211 1212 Chooses only DolDoc files 1213 1214 -] FUF_JUST_SRC 1215 1216 Chooses only source files 1217 1218 -] FUF_Z_OR_NOT_Z 1219 1220 This will ignore Ziped named of files and just check as normal 1221 1222 -] FUF_FLATTEN_TREE 1223 1224 This will flatten a FUF_RECURSE tree for you conveince 1225 1226 1227 If you want to delete files,use DelTree("folder/files");,or if you just want 1228 to remove a fule use Del("file"); 1229 1230 There are 2 ways to make a folder,use Cd("a/b/c/d/e",TRUE); to make a path,or 1231 make a folder one at a time via DirMk("folder_name");. Copy your stuff via CopyT 1232 ree("old","new") or just a file via Copy("old","new"). 1233 1234 And by the way you can open a file chooser via PopUpPickFile("T:/"); 1235 1236 Runtime Part 6: Data structures(1 CQue) 1237 1238 TempleOS comes loaded with useful data structures but it may be confusing at 1239 first. The most important one is a CQue. This means a Circular Queue. It's likle 1240 a loop,ill draw a picture for you. 1241 1242 1243 1244 <14>
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 As you can see(poorly drawn) is that each item has 2 pointers( the CQue->last 1255 and the CQue->next).The ->last pointer is the previous item in the chain,not the 1256 "last" one. 1257 1258 To make a new CQue,use QueInit on the item make both pointers point to the 1259 item,which means an empty CQue. You can insert items into the CQue via QueIns(to 1260 _insert,at). Perhaps an example will help you. 1261 1262 In our below example,I start at head and also end at head as the queue is 1263 ciruclar 1264 1265 1266 CQue *head=MAlloc(sizeof CQue),*one=MAlloc(sizeof CQue),*two=MAlloc(sizeof 1267 CQue),*cur; 1268 QueInit(head); 1269 QueIns(one,head); 1270 QueIns(two,one); 1271 for(cur=head->next;cur!=head;cur=cur->next) 1272 "Current element(excuding HEAD):%P\n",cur; 1273 QueDel(head); //Remove all items in the CQue 1274 Free(head); //QueDel doesnt Free the head 1275 1276 1277 To get the count of items in your queue use QueCnt(head). And to remove an 1278 item form the queue(not Free it),use QueRem which will detach the item from a 1279 queue 1280 1281 1282 CQue *head=MAlloc(sizeof CQue),*one=MAlloc(sizeof CQue),*two=MAlloc(sizeof 1283 CQue),*cur; 1284 QueInit(head); 1285 QueIns(one,head); 1286 QueIns(two,one); 1287 QueRem(one); //Detach one from the CQue 1288 Free(one); //Free it's data 1289 for(cur=head->next;cur!=head;cur=cur->next) 1290 "Current element(excuding HEAD):%P\n",cur; 1291 QueDel(head); //Remove all items in the CQue 1292 Free(head); //QueDel doesnt Free the head 1293 1294 1295 You can insert get the item count of the QueCnt(head) 1296 1297 Here is a reference section: 1298 -] QueInit(head) 1299 1300 Intialize the head of a queue 1301 1302 -] QueIns(to_ins,elem) 1303 1304 Insert an item after the elem 1305 1306 -] QueInsRev(to_ins,elem) 1307 1308 Insert an item before the elem 1309 1310 -] QueRem(elem) 1311 1312 Detach an item from the queue(doesnt free it) 1313 1314 -] QueDel(head) 1315 1316 Frees all items in the queue 1317 1318 -] QueCnt(head) 1319 1320 How many items in the queue(excluding the head) 1321 1322 1323 Runtime Part 7: Data structures 2(HashTable) 1324 1325 Hash tables are like dictionary data structures and each task has one in Fs->h 1326 ash_table. Each CHash has a type and a str. 1327 1328 When you look up a hash from a hash-table you will need the type. For 1329 example,if we want to grab a define(HTT_DEFINE_STR) from our current task,we do: 1330 1331 #define FOO 123 1332 CHashDefineStr *def=HashFind("FOO",Fs->hash_table,HTT_DEFINE_STR); 1333 if(def) 1334 "%s\n",def->data; 1335 1336 We looked up foo with type HTT_DEFINE_STR. Sometimes we want to add things to 1337 a CHashTable. To do this we need to use HashAdd. 1338 1339 CHashDefineStr *d=CAlloc(sizeof(CHashDefineStr)); 1340 d->str=StrNew("Hello"); //Must allocate string on heap 1341 d->type=HTT_DEFINE_STR; 1342 d->data=StrNew("10"); 1343 HashAdd(d,Fs->hash_table); 1344 //We added the macro Hello into the hash table 1345 "%d\n",Hello; 1346 1347 1348 Sometimes you want to make your own hashtables. You can do this via HashTableN 1349 ew(size). size MUST BE A POWER OF 2. 1350 1351 Any generic data in the hashtable should use type HTT_FRAME_PTR as HashTableDe 1352 l doesnt try to make assuptions on how to free the data 1353 1354 Perhaps an example will help: 1355 1356 CHashTable *ht=HashTableNew(0x100); 1357 CHashGeneric *ent=CAlloc(sizeof CHashGeneric); 1358 ent->user_data0=1; 1359 ent->user_data1=2; 1360 ent->user_data2=3; 1361 ent->type=HTT_FRAME_PTR; 1362 ent->str=StrNew("look"); 1363 HashAdd(ent,ht); 1364 CHashGeneric *g=HashFind("look",ht,HTT_FRAME_PTR); 1365 "%d,%d,%d\n",g->user_data0,g->user_data1,g->user_data2; 1366 HashTableDel(ht); 1367 1368 1369 Here is a reference of hash table functions 1370 1371 -] HashAdd(item,table) 1372 1373 Adds an item to the hash table 1374 1375 -] HashRemDel(item,table) 1376 1377 Delete an item from the hash table 1378 1379 -] HashFind(str,table,type) 1380 1381 Find an item in the table 1382 1383 -] HashSingleTableFind(str,table) 1384 1385 Find an item in the table,but dont check parent task's thing 1386 1387 -] HashTableNew(sz) 1388 1389 Make new hashtable,sz must be a power of 2 1390 1391 1392 Runtime Part 8: Data structures 3(Fifo) 1393 1394 Fifo's mean "First In First Out" and do things like store key presses. The 1395 first key you press is the the first one you get out. They also have a maximum 1396 size,which means that if you get too many keys,the old ones will be discarded 1397 1398 It looks like this: 1399 <15>
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 First create a FIFO with FifoI64New,Size must be a power of 2 1416 1417 CFifoI64 *fifoI64=FifoI64New(4); 1418 FifoI64Ins(fifoI64,1); 1419 FifoI64Ins(fifoI64,2); 1420 FifoI64Ins(fifoI64,3); 1421 1422 You can remove an item with FifoI64Rem. This takes a pointer and returns TRUE 1423 1424 CFifoI64 *fifoI64=FifoI64New(4); 1425 FifoI64Ins(fifoI64,1); 1426 FifoI64Ins(fifoI64,2); 1427 FifoI64Ins(fifoI64,3); 1428 I64 val; 1429 while(FifoI64Rem(fifoI64,&val)) 1430 "Got a %d\n",val; 1431 1432 1433 Here is a reference section 1434 1435 -] FifoI64New(sz) 1436 1437 Make a new fifo,sz must be a power of 2 1438 1439 -] FifoI64Flush(f) 1440 1441 Remove all the items from the fifo 1442 1443 -] FifoI64Cnt(f) 1444 1445 Get a count of all the items in the fifo 1446 1447 -] FifoI64Peek(f,&val) 1448 1449 Look at the next item in the fifo without removing it 1450 1451 -] FifoI64Del(f) 1452 1453 Free the fifo 1454 1455 -] FifoI64Rem(f,&val) 1456 1457 Remove an item from the fifo 1458 1459 -] FifoI64Ins(f,val) 1460 1461 Insert an item into the fifo 1462 1463 -] FifoU8Flush(f) 1464 1465 Remove all the items from the fifo 1466 1467 -] FifoU8Cnt(f) 1468 1469 Get a count of all the items in the fifo 1470 1471 -] FifoU8Peek(f,&val) 1472 1473 Look at the next item in the fifo without removing it 1474 1475 -] FifoU8Del(f) 1476 1477 Free the fifo 1478 1479 -] FifoU8Rem(f,&val) 1480 1481 Remove an item from the fifo 1482 1483 -] FifoU8Ins(f,val) 1484 1485 Insert an item into the fifo 1486 1487 -] FifoU8New(sz) 1488 1489 Make a new fifo,sz must be a power of 2 1490 1491 1492 Runtime Part 9: User Input 1493 1494 TempleOS lets you do lit stuff like click on things and use the keyboard. 1495 These events are passed through messages. We use GetMsg to get the 1496 messages,along with a message mask. 1497 1498 I64 x,y; 1499 U0 DrawIt(CTask *t,CDC *dc) { 1500 dc->color=RED; 1501 GrRect(dc,x,y,100,100); 1502 } 1503 U0 Run() { 1504 Fs->draw_it=&DrawIt; 1505 I64 m,x2,y2; 1506 while(TRUE) { 1507 m=GetMsg(&x2,&y2,1<<MSG_MS_MOVE+1<<MSG_MS_R_DOWN); 1508 if(m==MSG_MS_R_DOWN) 1509 break; 1510 x=x2; 1511 y=y2; 1512 Refresh; 1513 } 1514 } 1515 Run; 1516 1517 1518 Keyboard messages can be gotten via ScanKey(&ch,&sc). The first argument is 1519 the ASCII charactor,and the second one is the scancode. The scancode is the raw 1520 key being pressed and has flags in it. I'll give an example usage of the 1521 function first before I dive into details. 1522 1523 I64 x,y; 1524 U0 DrawIt(CTask*,CDC*dc) { 1525 dc->color=GREEN; 1526 GrRect(dc,x,y,100,100); 1527 } 1528 U0 Run() { 1529 Fs->draw_it=&DrawIt; 1530 I64 msg,sc,ch; 1531 for(;TRUE;) { 1532 if(ScanKey(&ch,&sc)) { 1533 if(sc&0xff==SC_ESC) break; 1534 if(sc&0xff==SC_CURSOR_UP) { 1535 y-=3; 1536 } else if(sc&0xff==SC_CURSOR_DOWN) { 1537 y+=3; 1538 } else if(sc&0xff==SC_CURSOR_LEFT) { 1539 x-=3; 1540 } else if(sc&0xff==SC_CURSOR_RIGHT) { 1541 x+=3; 1542 } 1543 } else { 1544 Refresh; 1545 } 1546 } 1547 } 1548 Run; 1549 1550 As you can see,I check the first 8 bits(0xff) of the scan code to test what 1551 key it is. There also flags on the scancode that tell you things like if the 1552 shift key is down etc. 1553 1554 The first byte of scancode is the key code,but the other bytes are flags which 1555 can be tested via the "&" operator 1556 1557 1558 I64 x,y; 1559 I64 color=GREEN; 1560 U0 DrawIt(CTask*,CDC*dc) { 1561 dc->color=color; 1562 GrRect(dc,x,y,100,100); 1563 dc->color=RED; 1564 } 1565 U0 Run() { 1566 Fs->draw_it=&DrawIt; 1567 I64 msg,sc,ch; 1568 for(;TRUE;) { 1569 if(ScanMsg(&ch,&sc,1<<MSG_KEY_UP|1<<MSG_KEY_DOWN)) { 1570 if(sc.u8[0]==SC_ESC) break; 1571 if(sc.u8[0]==SC_CURSOR_UP) { 1572 y-=3; 1573 } else if(sc.u8[0]==SC_CURSOR_DOWN) { 1574 y+=3; 1575 } else if(sc.u8[0]==SC_CURSOR_LEFT) { 1576 x-=3; 1577 } else if(sc.u8[0]==SC_CURSOR_RIGHT) { 1578 x+=3; 1579 } 1580 if(sc&SCF_CTRL) 1581 color=RED; 1582 else if(sc&SCF_SHIFT) 1583 color=YELLOW; 1584 else 1585 color=GREEN; 1586 } else { 1587 Refresh; 1588 } 1589 } 1590 } 1591 Run; 1592 1593 1594 Here's a list of scancode flags: 1595 1596 -] SCF_KEY_UP 1597 1598 The key was released 1599 1600 -] SCF_CTRL 1601 1602 The Ctrl key is down 1603 1604 -] SCF_SHIFT 1605 1606 The shift key is down 1607 1608 -] SCF_ALT 1609 1610 The alt key is down 1611 1612 -] SCF_CAPS 1613 1614 The Caps lock key is down 1615 1616 -] SCF_NUM 1617 1618 The NumLock key is kdown 1619 1620 -] SCF_SCROLL 1621 1622 Scroll Lock key is down 1623 1624 -] SCF_MS_L_DOWN 1625 1626 The left mouse is down 1627 1628 -] SCF_MS_R_DOWN 1629 1630 The right mouse is down 1631 1632 -] SCF_NO_SHIFT 1633 1634 There is no shift 1635 1636 1637 Here's a list of scancode keys: 1638 1639 -] SC_ESC 1640 1641 The escape key 1642 1643 -] SC_BACKSPACE 1644 1645 The backspace key 1646 1647 -] SC_TAB 1648 1649 The tab key 1650 1651 -] SC_ENTER 1652 1653 The enter key 1654 1655 -] SC_CTRL 1656 1657 The ctrl key 1658 1659 -] SC_ALT 1660 1661 The alt key 1662 1663 -] SC_CAPS 1664 1665 The caps lock key 1666 1667 -] SC_NUM 1668 1669 The num lock key 1670 1671 -] SC_SCROLL 1672 1673 The scroll lock key 1674 1675 -] SC_CURSOR_UP 1676 1677 The up key 1678 1679 -] SC_CURSOR_DOWN 1680 1681 The down key 1682 1683 -] SC_CURSOR_LEFT 1684 1685 The left key 1686 1687 -] SC_CURSOR_RIGHT 1688 1689 The right key 1690 1691 -] SC_PAGE_DOWN 1692 1693 The page down key 1694 1695 -] SC_PAGE_UP 1696 1697 The page up key 1698 1699 -] SC_HOME 1700 1701 The home key 1702 1703 -] SC_END 1704 1705 The end key 1706 1707 -] SC_INS 1708 1709 The insert key 1710 1711 -] SC_DELETE 1712 1713 The delete key 1714 1715 -] SC_F1-SC_F12 1716 1717 The Fxx keys 1718 1719 -] SC_PAUSE 1720 1721 The pause key 1722 1723 -] SC_GUI 1724 1725 The logo key 1726 1727 -] SC_PRTSCRN1 1728 1729 The print screen key 1730 1731 -] SC_PRTSCRN2 1732 1733 The print screen key 1734 1735 1736 I mentioned eariler about GetMsg,and I used ScanMsg. GetMsg waits for an 1737 event,but ScanMsg doesn't. There are also message codes 1738 1739 -] MSG_KEY_DOWN(ch,scancode) 1740 1741 A Key is put down 1742 1743 -] MSG_KEY_UP(ch,scancode) 1744 1745 A Key is release 1746 1747 -] MSG_MS_MOVE(x,y) 1748 1749 The mouse is moved 1750 1751 -] MSG_MS_L_DOWN(x,y) 1752 1753 The left button is down 1754 1755 -] MSG_MS_L_UP(x,y) 1756 1757 The left button is down 1758 1759 -] MSG_MS_R_DOWN(x,y) 1760 1761 The right button is down 1762 1763 -] MSG_MS_R_UP(x,y) 1764 1765 The right button is down 1766 1767 1768 Runtime Part 9: Multithreading 1769 1770 TempleOS is non-premptive. This means each Task has to manually tell the 1771 computer when to context swap. The way to do this and prevent freezing is to Yie 1772 ld 1773 1774 In TempleOS,spawning task's is easy,use the Spawn function 1775 1776 1777 U0 Foo(U8 *data) { 1778 Beep; 1779 } 1780 Spawn(&Foo,"Some_data","TaskName"); 1781 1782 1783 You can make a user terminal via User. You can talk to that task via XTalk 1784 1785 1786 CTask *u=User; 1787 XTalk(u,"\"Exiting in 5 seconds\\n\";\n"); //Be sure to put a semi-colon at the 1788 end as we are "the-user". 1789 Sleep(5000); 1790 XTalk(u,"Exit;\n"); 1791 1792 1793 Sometimes you want to wait for a task to die,to do this use DeathWait 1794 1795 1796 CTask *t=User; 1797 DeathWait(&t); //Note address of t 1798 Beep; //Will beep when you exit the User task 1799 1800 1801 There is also a BirthWait 1802 1803 1804 CTask *t=User; 1805 BirthWait(&t); //Note address of t 1806 Beep; //Will beep when you exit the User task 1807 1808 1809 To avoid race conditions we use locks. In TempleOS this is acheived through 1810 locked bit instructions with spinlocks. How it works is LBts will set the 1811 bit,and return the old value of the bit. We keep on setting the bit. If the old 1812 value is not set,it means we have access to the lock,otherwise we keep on 1813 looping. Be sure to reset the bit when you are done with LBtr. 1814 1815 1816 I64 beep_lock=0; 1817 U0 OneThread(I64 snd) { 1818 //This will spin until bit 0 is reset(look at the end of the function) 1819 while(LBts(&beep_lock,0)) //LBts has a side effect of setting the bit after it 1820 is checked 1821 Yield; //We are going to be beeping for awhile so Yield out control to other 1822 tasks 1823 Beep(snd); 1824 //We reset bit 0 of beep_lock to signify we are done with it. 1825 LBtr(&beep_lock,0); 1826 } 1827 I64 i; 1828 for(i;i!=10;i++) { 1829 Spawn(&OneThread,i*7+10); 1830 "Spawned a thread!!\n"; 1831 } 1832 1833 Runtime Part 10: Jobs 1834 1835 In TempleOS,each core has a seth_task. This task does lit stuff like run Jobs 1836 which can be created via TaskExe and you get the results via JobResGet 1837 1838 1839 CJob *job=TaskExe(Gs->seth_task,Fs,"1+1;;;",0); 1840 res=JobResGet(job); 1841 Kill(jobber); 1842 "I got %d\n",res; 1843 1844 With cpu_structs,you can spawn jobs on other cores 1845 1846 1847 CTask *parent_task=Fs; 1848 I64 core=0; 1849 //mp_cnt is the number of cpus 1850 CJob *jobs[mp_cnt]; 1851 for(core=0;core!=mp_cnt;core++) { 1852 jobs[core]=TaskExe(cpu_structs[core].seth_task,Fs, 1853 "Sleep(RandI64%1000);" 1854 "Gs->num;;", //Gs is the current CCPU for the core,->num is the cpu number 1855 0); 1856 } 1857 for(core=0;core!=mp_cnt;core++) { 1858 "Core %d return %d\n",core,JobResGet(jobs[core]); 1859 } 1860 1861 1862 If you want to have the parent task wait while a job runs,you can use the JOBf 1863 _WAKE_MASTER flag. 1864 1865 1866 CTask *parent_task=Fs; 1867 //Things ending in a lowecase f as bits(and need to be shifted to be flags) 1868 TaskExe(Gs->seth_task,parent_task,"Play(\"EGBDF\");",(1<<JOBf_WAKE_MASTER)); 1869 1870 Runtime Part 11: DolDoc 1871 1872 Most of the text you see on screen is from the DolDoc layout engine. It uses a 1873 series of dollar signs to set things like the text color and make elements. The 1874 are stored as a circular queue of CDocEntry's. The easyiest way to make a DolDoc 1875 element is to use DocPrint,use DocPut to get the current task's document. 1876 1877 1878 //BT is a button 1879 CDocEntry *de=DocPrint(DocPut,"\n\n$BT,\"Hello\"$\n\n"); 1880 1881 1882 As you can see,the DolDoc entries have a type and argument. They are 1883 surrounded by $'s. They can also have flags too. This let's you do things like 1884 center the text. Lets see an example: 1885 1886 1887 //TX is a text,+CX is the center flag 1888 CDocEntry *de=DocPrint(DocPut,"\n\n$TX+CX,\"Hello\"$\n\n"); 1889 1890 1891 DolDoc entries can also take an argument,Links use this to figure out where to 1892 go when you click them. Arguments for DolDoc entries come after the comma,some 1893 of the arguments are named and have the format "name=value" 1894 1895 1896 CDocEntry 1897 *de=DocPrint(DocPut,"\n\n$LK,\"Text\",A=\"FL:/PersonalMenu.DD\"$\n\n"); 1898 1899 1900 You can interact directly with the generated CDocEntrys. You can put things 1901 like callbacks into them. In our below example I set the left_cb function 1902 pointer to Beep2 and I tell the entry that it has a callback with DOCEF_LEFT_CB. 1903 1904 1905 I64 Beep2(CDoc *,CDocEntry *) { 1906 Beep; 1907 } 1908 CDocEntry *de=DocPrint(DocPut,"\n\n$BT+CX,\"Hello\"$\n\n"); 1909 de->de_flags|=DOCEF_LEFT_CB; 1910 de->left_cb=&Beep2; 1911 1912 1913 You can use the DocMenu function to get a value from your document. I use the 1914 LE for a left-click-expression. 1915 1916 1917 U0 CreateDialog() { 1918 CDocEntry *nums[3]; 1919 I64 i; 1920 DocClear(DocPut); 1921 "$TX+CX,\"Pick a number:\"$\n"; 1922 for(i=0;i!=3;i++) { 1923 nums[i]=DocPrint(DocPut,"\n\n$BT+CX,\"%d\",LE=%d$\n\n",i,i); 1924 } 1925 DocBottom(DocPut); 1926 switch(DocMenu(DocPut)) { 1927 start: 1928 DocClear(DocPut); 1929 case 0: 1930 "You picked nothing lol.\n"; 1931 break; 1932 case 1: 1933 "One is the one\n"; 1934 break; 1935 case 2: 1936 "Two is too good\n"; 1937 break; 1938 end: 1939 } 1940 } 1941 CreateDialog; 1942 1943 1944 You can use PopUpForm to use a class's meta data for making a menu. 1945 1946 1947 U0 CreateDialog() { 1948 class CInput { 1949 //Be sure to use -P with strings 1950 U8 name[STR_LEN] format "\n"; 1951 I64 age format "\n"; 1952 Bool is_tall format "\n"; //CB is a Check box 1953 }; 1954 CInput inp; 1955 PopUpForm(&inp); 1956 "%s is %d years old\n",inp.name,inp.age; 1957 if(inp.is_tall) 1958 "Tall!\n"; 1959 1960 1961 Yeah time for some reference section ehh: 1962 1963 -] TX 1964 1965 Text 1966 1967 -] CR 1968 1969 Newline 1970 1971 -] CU 1972 1973 Cursor pos,normally a ASCII #5 1974 1975 -] TB 1976 1977 Tab 1978 1979 -] CL 1980 1981 Clears all elements without the "+H" flag 1982 1983 -] PB 1984 1985 Page break 1986 1987 -] PL 1988 1989 Page length 1990 1991 -] LM 1992 1993 Left margin 1994 1995 -] RM 1996 1997 Right margin 1998 1999 -] HD 2000 2001 Header margin 2002 2003 -] FO 2004 2005 Footer margin 2006 2007 -] ID 2008 2009 Indent,use wit tree elements,and use with a negative number to un-indent 2010 2011 -] FD 2012 2013 Forground default color 2014 2015 -] BD 2016 2017 Background default color 2018 2019 -] PT 2020 2021 Command Line Prompt 2022 2023 -] WW 2024 2025 Use 1 to enable word wrap,use 0 to disable 2026 2027 -] UL 2028 2029 Use 1/0 to enable/disable underline 2030 2031 -] IV 2032 2033 Disable/enable Inverting of colors 2034 2035 -] BK 2036 2037 Burger Kind,just kidding,it's actually for blinking 2038 2039 -] SX 2040 2041 Shift the text by a amount of pixels 2042 2043 -] SY 2044 2045 Shift the text up/down by an amount of pixels 2046 2047 -] CB 2048 2049 Checkbox 2050 2051 -] LS 2052 2053 Major Lit Alert 2054 Use with the "D" argument to make a list(from a DefineListLoad),do this 2055 $LS,"potato",D="ST_BIBLE_BOOKS"$ 2056 Clicking on this will make a menu to pick an item from the list 2057 2058 -] MA 2059 2060 A macro,clicking on this will insert LM into the command line prompt 2061 2062 -] TR 2063 2064 A Tree wigdet,use this with ID to nest the tree's 2065 2066 -] HL 2067 2068 Turn HolyC syntax highting on/off 2069 2070 2071 Here is a reference section for the flags,they can be added/removed with 2072 +/-(For example you can do "$TX+CX+H,\"I have CX and H flags.\"$\n";) 2073 2074 -] H 2075 2076 Hold,this will prevent CL from deleting this element 2077 2078 -] L 2079 2080 This will make the element act as a link 2081 2082 -] TR 2083 2084 This will make the element act as a tree 2085 2086 -] LS 2087 2088 This will make the element act as a list 2089 2090 -] PU 2091 2092 This will make a macro run in a popup window 2093 2094 -] C 2095 2096 This will collapse a tree,use -C to uncollapse the tree 2097 2098 -] X 2099 2100 This will save and Exit after the macro is done 2101 2102 -] UD 2103 2104 Update data on typing 2105 2106 2107 Here is a reference section for the argument codes,use them like "$TX,T=\"123\"$ 2108 " 2109 2110 -] T 2111 2112 Tag text,this is the text that gets displayed. 2113 2114 -] LEN 2115 2116 Sets the length of the DA element. 2117 2118 -] A 2119 2120 Sets the link location 2121 2122 -] LE 2123 2124 Left expression,runs an expression on left click 2125 2126 -] RE 2127 2128 Right expression,runs an expression on right click 2129 2130 -] LM 2131 2132 Left macro,runs text on left click 2133 2134 -] RM 2135 2136 Right macro,runs text on right click 2137 2138 -] RT 2139 2140 Raw type of DA 2141 2142 -] U 2143 2144 User data 2145 2146 -] SCX 2147 2148 Scroll x columns Makes a amazing scrolling effect 2149 2150 -] SX 2151 2152 Scroll x pixels 2153 2154 -] SY 2155 2156 Scroll y pixels 2157 2158 2159 Making links is easy,to do this we use "$LK,\"text\",A=\"BF:Acts,2:3\"$"; Here 2160 is a reference for the link codes: 2161 2162 -] FI 2163 2164 File index,FI="file" or FI="file,line" 2165 2166 -] FF 2167 2168 File Find,FF="file,text" 2169 2170 -] BF 2171 2172 Bible Find,BF="book,text". "text" can be a chapter/verse 2173 2174 -] HI 2175 2176 Help Index,HI="Help Index". Make help indexes via #help_index 2177 2178 -] A 2179 2180 Symbol address, takes a pointer A="0x11223344" 2181 2182 2183 Now a function reference: 2184 2185 -] DocBottom 2186 2187 Move to the bottom of the document 2188 2189 -] DocCenter 2190 2191 Make ->cur_entry be in the viewport 2192 2193 -] DocClear 2194 2195 Clear all elements except those with the +H flag 2196 2197 -] DocCollapse(collapsed,doc) 2198 2199 Collapse or un-collapse all trees in the document 2200 2201 -] DocDel 2202 2203 Delete a documents memory 2204 2205 -] DocEntryDel(doc,elem) 2206 2207 Deletes a document entry 2208 2209 -] DocEntryCopy(doc,elem) 2210 2211 Copy an element 2212 2213 -] DocInsDoc(to,from) 2214 2215 Insert a document into an other document 2216 2217 -] DocLock 2218 2219 Lock a document 2220 2221 -] DocUnlock 2222 2223 Unlock a document 2224 2225 -] DocRst 2226 2227 Reset the document 2228 2229 -] DocTop 2230 2231 Go to the top of the document 2232 2233 -] DocLineRead(filename,line) 2234 2235 Read a line from a file 2236 2237 -] DocLineWrite(filename,line,text) 2238 2239 Write a line into a file 2240 2241 -] DocRead(filename) 2242 2243 Read a document from a file 2244 2245 -] DocLoad(into_doc,ptr,len) 2246 2247 Read a document from memory into a docuemnt 2248 2249 -] DocSave(doc,len_ptr) 2250 2251 Save a document into memory 2252 2253 -] DocWrite(doc) 2254 2255 Save a document to disk. Filename is detirmnined by DocNew("filename"); 2256 2257 -] DocMenu 2258 2259 Interact with a document until a value is found 2260 2261 -] DocForm 2262 2263 Use a class's meta-data to make a form for you to fill out 2264 2265 -] DocNew(filename) 2266 2267 Make a new document that will be saved to filename 2268 2269 -] DocGR(doc,filename.GR) 2270 2271 Insert a .GR file into a document 2272 2273 -] DocPrint 2274 2275 Print text into a document 2276 2277 -] DocPut 2278 2279 Get the current document for a task 2280 2281 -] DocType(doc,filename) 2282 2283 Type a file into a document