GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 GammelTid = QueryPerformanceTimer while(hurra) { NyTid = QueryPerformanceCounter DeltaTid = NyTid - GammelTid GammelTid = NyTid LesInput Logikk DispatchDataSett // Valgfritt avhengig av kravene til applikasjonen SignalRender Yield } Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Her er tråden som tar seg av tastetrykk. Problemet med tastetrykk er: 1. Brukeren skal ha mulighet for å forandre retning på ormen. 2. Om ormen ikke har beveget seg enda så skal brukeren ha ENDA en mulighet for å forandre den FØR ormen beveger seg. 3. Det er ikke lov å flytte ormen i motsatt retning av den retningen den har. Altså VK_UP så blir VK_DOWN motsatt retning. VK_LEFT så blir VK_RIGHT motsatt retning. 4. Jeg bufrer keyboard pollingen i 2 tastetrykk. Bufferen inneholder 2 tastetrykk's historie, mer enn det er ikke nødvendig som jeg kan se. 5. Problemet når brukeren har registrert 2 tastetrykk i historien og brukeren om bestemmer retningen så må den sjekke ulovlig retning i det første tastetrykket, ikke den siste som ble registrert i bufferen, da må tastebufferen slettes. Ulovlige retninger skal kun registreres hvis den første retningen i bufferen er lovlig. Osv. he-he. For hvis en ny retning er lovlig i første tastetrykk så betyr det at nåværende ulovlige retninger vil være lovlig i neste key i bufferen. proc KeyPoller lpParameter local Buf[4]:DWORD ; Save all registers push ebx push edi ; Set items in Buf to not keypressed (0) cld lea edi,[buf] mov ecx,4 xor eax,eax mov esi,edi rep stosd ; Set up registers mov ebx,$8000 ; Test bit 15.. (if bit is set, key is down) mov edi,1 xor ebp,ebp ; always zero ; ebx=$8000 esi=Buf edi=1 ebp=always zero ;------------------------------------------------------------------------------- align 16 .main: invoke WaitForSingleObject,[DirMutex],-1 invoke GetAsyncKeyState,VK_LEFT test eax,ebx jnz @F mov [esi],ebp ; Allow this key next time since its released now jmp .right ; All keys must be parsed every time, we can't jump back to main until all keys are processed @@: cmp [esi],ebp ; if already DOWN, skip this key jnz .right ; skip key since its already down and not allowed this time mov dword [esi],edi ; key allowed this time, set status to keydown cmp [NibbleDir],VK_LEFT ; if same dir, skip it je .bad1 cmp [NibbleDir],VK_RIGHT; if opposite dir, skip it je .bad1 mov [NibbleDirNext],VK_LEFT ; save this new key mov [illegalDir],VK_LEFT jmp .right .bad1: mov ecx,[NibbleDir] mov edx,[NibbleDirNext] cmp ecx,edx je .right mov [illegalDir],VK_LEFT .right: invoke GetAsyncKeyState,VK_RIGHT test eax,ebx jnz @F mov [esi+4],ebp ; Allow this key next time since its released now jmp .up ; All keys must be parsed every time, we can't jump back to main until all keys are processed @@: cmp [esi+4],ebp ; if already DOWN, skip this key jnz .up ; skip key since its already down and not allowed this time mov dword [esi+4],edi ; key allowed this time, set status to keydown cmp [NibbleDir],VK_RIGHT ; if same dir, skip it je .bad2 cmp [NibbleDir],VK_LEFT ; if opposite dir, skip it je .bad2 mov [NibbleDirNext],VK_RIGHT ; save this new key mov [illegalDir],VK_RIGHT jmp .up .bad2: mov ecx,[NibbleDir] mov edx,[NibbleDirNext] cmp ecx,edx je .up mov [illegalDir],VK_RIGHT .up: invoke GetAsyncKeyState,VK_UP test eax,ebx jnz @F mov [esi+8],ebp ; Allow this key next time since its released now jmp .down ; All keys must be parsed every time, we can't jump back to main until all keys are processed @@: cmp [esi+8],ebp ; if already DOWN, skip this key jnz .down ; skip key since its already down and not allowed this time mov dword [esi+8],edi ; key allowed this time, set status to keydown cmp [NibbleDir],VK_UP ; if same dir, skip it je .bad3 cmp [NibbleDir],VK_DOWN ; if opposite dir, skip it je .bad3 mov [NibbleDirNext],VK_UP ; save this new key mov [illegalDir],VK_UP jmp .down .bad3: mov ecx,[NibbleDir] mov edx,[NibbleDirNext] cmp ecx,edx je .down mov [illegalDir],VK_UP .down: invoke GetAsyncKeyState,VK_DOWN test eax,ebx jnz @F mov [esi+12],ebp ; Allow this key next time since its released now jmp .done ; All keys must be parsed every time, we can't jump back to main until all keys are processed @@: cmp [esi+12],ebp ; if already DOWN, skip this key jnz .done ; skip key since its already down and not allowed this time mov dword [esi+12],edi ; key allowed this time, set status to keydown cmp [NibbleDir],VK_DOWN ; if same dir, skip it je .bad4 cmp [NibbleDir],VK_UP ; if opposite dir, skip it je .bad4 mov [NibbleDirNext],VK_DOWN ; save this new key mov [illegalDir],VK_DOWN jmp .done .bad4: mov ecx,[NibbleDir] mov edx,[NibbleDirNext] cmp ecx,edx je .done mov [illegalDir],VK_DOWN .done: invoke ReleaseMutex,[DirMutex] jmp .main ; pop registers pop edi pop ebx ; return ret endp Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) GammelTid = QueryPerformanceTimer while(hurra) { NyTid = QueryPerformanceCounter DeltaTid = NyTid - GammelTid GammelTid = NyTid LesInput Logikk DispatchDataSett // Valgfritt avhengig av kravene til applikasjonen SignalRender Yield } Problemet her er at Logikken tar tid å kjøre og et mikrosekund eller noen hundre nanosekund utgjør uhell som mister tastetrykk. Rendertråden burde heller la polle tråden kontinuerlig lagre tastetrykk og om polletråden IKKE er ferdig akkurat idet den rendererer så kan den vente på en mutex eller gjøre noe forberedningsarbeid, på den måten vil man spare tid og unngå uhell og samtidig få raskere kjøring. Når du har de ferskeste tastetrykk tilgjengelig nøyaktig idet du har beveget ormen og er klar for å tegne den, så vil du få god tasterespons. Og om du putter denne polle logikken direkte i rendertråden så vil rendertråden få mer å gjøre. Det er bedre at rendertråden forbereder rendereringen og samtidig lar keytråden gjøre jobben sin, og nøyaktig idet du skal tegne ormen, så henter du tastetrykket som polletråden har lagret og som er ferskest. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Det er helt vanlig for folk å tro at "Datamaskinen er så rask, kan bare polle tastene i game loopen, det har ingen verdens effekt i det hele tatt"... Og det er riktig at datamaskinen er rask, men det ligger mer forståelse i det. Det de ikke tar med i kalkuleringen er at selv om det bare er snakk om nanosekunder, så vil du ved jevne mellomrom treffe akkurat disse nanosekundene som et slags vakum og miste tastetrykkene ved rene uhell, uansett hvor rask datamaskinen er, så spiller de siste nanosekundene en rolle og det er om å gjøre å minimere denne bieffekten. Dette er en vanlig misforståelse blant programmerere. You see Tastetrykk er som lotto. Hver gang du treffer nanosekundene som ikke registrerer keys, så mister du et tastetrykk. Og denne "lottogevinsten" får du ved jevne mellomrom, ikke ved hensikt, men ved uhell. Forskjellen mellom lotto og keypolling er at i dette tilfellet håper man på å ikke vinne en lottogevinst og lottogevinstene får man ved sekunders mellomrom. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 Den mutexen dreper 99% av poenget med at den koden kjører asynkront. Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Det er det den ikke gjør. I rendertråden har den mutexen bare 1% av tiden like etter den har forberedt alt som må gjøres, tiden som spares er enorm hvis du skalerer det opp. Du mangler litt innsikt i akkurat dette som jeg kan se. Men hvis jeg skulle kritisert meg selv så ville jeg implementert en critical section med spin count og en pause instruksjon. Det skylder jeg på at spillet ikke er ferdig enda. Det er ekstremt komplekst helhetlig, det du ser på overflaten er ikke hva som skjer under. Det er nøye gjennomtenkt, om du skal skumme gjennom det med dine c++ øyne i skrivende øyeblikk vil du ikke se en eneste ting. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Det er det den ikke gjør. I rendertråden har den mutexen bare 1% av tiden like etter den har forberedt alt som må gjøres, tiden som spares er enorm hvis du skalerer det opp. Du mangler litt innsikt i akkurat dette som jeg kan se. What? Du har et helt skada design. Du bruker 4 tråder, hvor to av dem går i 100% CPU-tid for noe som ikke burde tatt 1% engang, og selv blitt opplevd helt naturlig. Du trenger ikke mutexer, du trenger ikke polle, du trenger ikke buffre keyboard input. Du kaster bort CPU-tid på noe du umulig kan ha tenkt godt igjennom. Du har forresten feilimplementert GetAsyncKeyState. Endret 2. oktober 2012 av GeirGrusom Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Det er det som er så flott med flere kjerner er at en av de kan dedikeres til 100% og polle taster kontinuerlig og raskt uten at det påvirker de andre kjernene. Om det hadde vært 100% på en kjerne hadde det vært et problem. Det er ikke skada, det er en prioritering for å få god tasterespons. Det er bare du som ikke liker tallene, du liker ikke at det står 50 foran nesa di og et lavt tall på de andre, det "føles ikke riktig" for en c++ programmerer. Men for de som er teknisk anlagt så har det betydning. For deg er det en kosmetisk ting, for meg er det en teknisk ting. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 Du har forresten feilimplementert GetAsyncKeyState. Du hopper fra det ene dårlige poenget til det andre. Hva er det nå du forsøker å si? Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Du har forresten feilimplementert GetAsyncKeyState. Du hopper fra det ene dårlige poenget til det andre. Hva er det nå du forsøker å si? At Nibbles implementasjonen din er rævva. If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks. (...) Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon. Og det er ikke greit at en kjerne bruker 100% cpu. Endret 2. oktober 2012 av GeirGrusom Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Det var ikke det du nevnte, du nevnte GetASyncKeyState. Du vet bare ikke hva du snakker om i det hele tatt. Programmering er ikke en kosmetisk ting. Oppgavebehandlingen og prosent tall er bare kosmetikk Geirern. Hvis du overser kosmetikken og den stimuleringen det gir og fokuserer på det tekniske, så ser du at implementeringen er veldig god. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 Det var ikke det du nevnte, du nevnte GetASyncKeyState. Du vet bare ikke hva du snakker om i det hele tatt. Programmering er ikke en kosmetisk ting. Oppgavebehandlingen og prosent tall er bare kosmetikk Geirern. Hvis du overser kosmetikken og den stimuleringen det gir og fokuserer på det tekniske, så ser du at implementeringen er veldig god. Overhode ikke. Hvis du kjører programmet ditt på en tokjerneprosessor, så kan du drepe ytelsen på rendering. Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) ..og som jeg sa, spillet er designet utelukket for 4 kjerner, jeg skrev det ganske tydelig. Dvs, det er ikke et teknisk problem for formålet, men et spill som jeg hensiktsmessig designet for 4 kjerner. Og det er primært fordi jeg selv har 4 kjerner. Det er bare et leketøy for meg selv egentlig. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) ..og som jeg sa, spillet er designet utelukket for 4 kjerner, jeg skrev det ganske tydelig. Dvs, det er ikke et teknisk problem for formålet, men et spill som jeg hensiktsmessig designet for 4 kjerner. Da har du fokus helt feil, fordi du implementerer noe som i praksis er verdiløst. har du forsøkt å lage det med bare én kjerne? Nibbles i FastTracker 2 klarte det helt fint, og det var skrevet i Pascal. Endret 2. oktober 2012 av GeirGrusom Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Det er ikke noe problem å endre koden til å støtte en, to, fire, seks eller åtte kjerner. Det kan gjøres ganske fort. Men hvis jeg gjør det så tror jeg at jeg vil bruke rawinput istedet. Bufret rawinput. Geir, jeg bruker heller ingen form for hardware rendering, grafikken rendereres i kode, i ren assembler kode og dib sections. Geir så er det også viktig å forstå at i dos dagene hadde du tilgang til hardwaren direkte, i windows må du bruke api. Svakheten til keypolling i windows api'et tvinger meg til å tenke litt annerledes der i forhold til fasttracker. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 Det er ikke noe problem å endre koden til å støtte en, to, fire, seks eller åtte kjerner. Det kan gjøres ganske fort. Men hvis jeg gjør det så tror jeg at jeg vil bruke rawinput istedet. Bufret rawinput. RawInput er nok et bedre valg. Prøv også å legg inn en Sleep(0) i tastaturpolling. Jeg er temmelig sikker på at du ikke vil merke noe som helst bortsett fra at CPU-tiden faller dramatisk. A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution. Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 Geir, det eksemplet du la øverst i tråden, det var faktisk den metoden jeg brukte da ormen hakket. Og det med sleep har jeg også prøvd, det hjelper enormt på cpu aktivitet, men det gjør at tastene får en liten økning i failrate og det liker jeg ikke Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Geir, det eksemplet du la øverst i tråden, det var faktisk den metoden jeg brukte da ormen hakket. Og det med sleep har jeg også prøvd, det hjelper enormt på cpu aktivitet, men det gjør at tastene får en liten økning i failrate og det liker jeg ikke Egentlig mener jeg du skal kunne ha dette rett før ormen blir flyttet, men da må du AND eax, 0x80000000 som fjerner bitet som forteller om knappen var trykket tidligere eller ikke. edit: altså rett etter GetAsyncKeyState Endret 2. oktober 2012 av GeirGrusom Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Egentlig mener jeg du skal kunne ha dette rett før ormen blir flyttet, men da må du AND eax, 0x80000000 som fjerner bitet som forteller om knappen var trykket tidligere eller ikke. edit: altså rett etter GetAsyncKeyState 0x8000 det er en short, men antar det var en typo. Tsja, kanskje kanskje. Jeg har ikke prøvd det. Men nå er spillet ikke ferdig og jeg holder ennå på å lage det ferdig, håper jeg får det ferdig til i kveld, jeg laget en rutine for å omgjøre paint bilder til maps. Altså, du kan bare tegne røde linjer over et grid system og så har jeg et program som omgjør det til digitale maps. Det fine med det er at man bare kan bruke linjer og rektangler direkte i ms paint. Som du ser har jeg designet gridsystemet med oddetall, slik at det alltid er en midtlinje horisontalt og vertikalt. Her er malen for gridsystemet. Jeg har markert viktige tall med tjukke linjer. så tegner du bare over med røde linjer, behøver ikke være nøyaktig, sålenge det er innenfor gridboksene. Så konverteres det til et digitalt map av et verktøy som jeg holder på å lage nå. Endret 2. oktober 2012 av LonelyMan Lenke til kommentar
Gjest Slettet+9871234 Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Hva med assembly på iPhone? Er det en mulighet? Hadde vært kult, ja ... Tviler litt, dog, da Apple trolig ikke vil slippe folk inn på for nært. Er det ikke slik at man ikke engang vet specs på den nyeste prosessoren de bruker? Det kan være riktig og Apple er svært strenge, men flere og flere plattformer kan tvinge frem mer åpenhet. Du og jeg har som forbrukere sterk makt. Ikke som enkeltpersoner, men som summen av alle forbrukere. Våre penger og kjøp snakker. Jeg blir liit overrasket om de ulike selskapene ikke publiserer manualer for prosessorens assembler instruksjoner. Intel gjorde alltid det den gangen jeg drev med assembly. Jeg har vurdert å se litt på assembly igjen. Jeg er spesielt interessert i 64 bits assembly, men assembly på en smart telefon hadde selvsagt også vært interessant. En time i uken kan være nok til å følge med på kode og etter hvert beherske assembly for 64 bist prosessoren. Er det noen som kjenner en god assemly bok / kild på Intel 64 bits prosessorer? Andre moderne prosessorer som litteratur om assembly på mobile plattformer er selvsagt også interessant. Følgende Amazon bok søk: assembly gir jo en god del treff på eldre literatur. Den nyeste The Art of Assembly Language er fra 2010. Endret 2. oktober 2012 av Slettet+9871234 Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå