C-programmering del 4. Ulf Assarsson. extern, sta.c, Överkurs: const, inline, Gameloop, grafikloop, fraktalt berg

Relevanta dokument
Ulf Assarsson. Grundläggande C-programmering del 5 Applika'onsbyggnad/Spelprogrammering (real'dsstyrsystem) och Avancerad C.

Grundläggande C-programmering del 4 Mer programstruktur samt Dynamisk minnesallokering Ulf Assarsson

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

Repetition C-programmering

Introduktion C-programmering

Ulf Assarsson. Grundläggande C-programmering del 2 Pekare och Arrayer. Läromoment:

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

Programmering av grafisk display

Programmering av grafisk display

Demonstration och konsultation Arbetsbokens avsnitt 5 och 6 LCD Grafisk display Introduktion till laboration 3

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

Ulf Assarsson. Grundläggande C-programmering del 3. Läromoment: Grundläggande C-programmering del 3

TDIU01 - Programmering i C++, grundkurs

Funktionens deklaration

Det finns många flaggor till g++,

Programmering av inbyggda system. Pekare och Arrayer. Ulf Assarsson. Originalslides av Viktor Kämpe

Recap Mera om nya typer Kort Fält. Programmering. Sommarkurs Verónica Gaspes. IDE-sektionen.

Klassdeklaration. Metoddeklaration. Parameteröverföring

Översikt Introduktion DST 1. Nicholas Wickström. IDE, Högskolan i Halmstad. N. Wickström

Grundläggande C-programmering

Typkonvertering. Java versus C

Structs och funktionspekare

Programsystemkonstruktion med C++

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Föreläsning 3: Booleans, if, switch

TDIU01 - Programmering i C++, grundkurs

F4. programmeringsteknik och Matlab

En klass behöver både deklaration och definition. Daniel Aarno Globala funktioner och variabler är OK.

Att använda pekare i. C-kod

TDIU01 Programmering i C++

Ulf Assarsson. Grafisk display + seriekommunika3on (USART) Läromoment: USART Grundläggande C-programmering del 2

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

TDIU01 - Programmering i C++, grundkurs

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

Programbibliotek. Ur innehållet: Olika typer av bibliotek Kompilatorbibliotek C-bibliotek Run-time miljö Så skapar du ett nytt bibliotek

Enkla datatyper minne

Övning från förra gången: readword

grundläggande C++, funktioner m.m.

Föreläsning 10. Pekare (Pointers)

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar

Innehåll. Pekare Exempel

F5: Högnivåprogrammering

Ett enkelt program i C++, hello.cpp. #include <iostream> int main() { std::cout << "Hello World\n"; return 0; } C++, Övning 1

Assemblerprogrammering - fördjupning

C++-programmets beståndsdelar

Objektorienterad programmering. Fält som funktionsresultat. Mer om fält: att uppdatera ett parameterfält. Kontrast: Parametrar av primitiv typ

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Muddy. Funktioner / metoder. Punktnotation. Evalueringsordning

Byggstenar. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Grundläggande datatyper

EDA480/EDA485 - Maskinorienterad programmering, tentamen 2006-xx-xx 1(7)

Arrays (indicerade variabler) Föreläsning 6

Innehåll. Pekare Exempel

Programbibliotek. Ur innehållet: Olika typer av bibliotek Kompilatorbibliotek C-bibliotek Run-time miljö Så skapar du ett nytt bibliotek

Första exemplet. Kompilator & länkare. Projekt. Övning 1, Ögrupp 4, Programsystemkonstruktion med C++, Ronnie Johansson,

F5: Högnivåprogrammering

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursens hemsida:

Objektorientering i liten skala

Programmering av inbyggda system

Tillämpad programmering

Grundläggande C-programmering del 1 - För maskinorienterad programmering

Programmering av inbyggda system. Pekare och Arrayer. Viktor Kämpe

Assemblerprogrammering för ARM del 2

Programsystemkonstruktion med C++: Övning 1. Karl Palmskog september 2010

Programmering B med Visual C

Arrays (indicerade variabler) Föreläsning 4

Grundläggande C-programmering del 1 - För maskinorienterad programmering

TENTAMEN PROGRAMMERING I JAVA, 5P SOMMARUNIVERSITETET

E02 "The Review" Föreläsning 2, HT2013 Grunderna, repetition. Johan Leitet. Kurs: 1dv403 Webbteknik I

Tentamen EDAF30 Programmering i C++

En kort text om programmering i C.

Föreläsning 6: Metoder och fält (arrays)

Föreläsning 4 IS1300 Inbyggda system

Assemblerprogrammering, ARM-Cortex M4 del 3

Kapitel 1. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Kapitel 1 grunderna i C++

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

EDAA20 Programmering och databaser. Mål komprimerat se kursplanen för detaljer. Checklista. Föreläsning 1-2 Innehåll. Programmering.

BMI = (vikt i kg) / (längd i m) 2. Lösningsförslag

Övning 3 i 2D1324. Strukturering h filer deklaration vs definition Debuggning gdb Preprocessorn #define assert(s) FILE LINE Länkning

F4 Klasser och Metoder. ID1004 Objektorienterad programmering Fredrik Kilander

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Grundkurs Programmering

Symboliska konstanter const

Funk%oner. Vad är det och hur definierar vi en Top- down- programmering lokala globala variabler void och flera inparametrar

Exempel ( )

TDDC76 - Programmering och Datastrukturer

Programmering, grundkurs, 8.0 hp HI1024, extra tentamen, TEN1, för TIDAA1. Fredagen den 11 mars 2011,

Poster ( structar ) Postdeklarationer

Skriv i mån av plats dina lösningar direkt i tentamen. Skriv ditt kodnummer längst upp på varje blad.

OOP Objekt-orienterad programmering

TDDI82 - Projekt. Christoffer Holm. Institutionen för datavetenskap (IDA)

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Innehåll. 1 Typdeklarationer och typomvandling 2 Resurshantering. 3 Objektorientering, kort repetition. 4 Klasser

TDDC77 Objektorienterad Programmering

tentamensdags och lab 3

Programmering, grundkurs, 8.0 hp HI1024, HI1900 etc., Tentamen TEN1. Måndagen den 10 januari 2011,

Programmering A. Johan Eliasson

Operativsystem (IS1350) :00-12:00

Välkommen till. Datastrukturer, algoritmer och programkonstruktion. eller DOA

Transkript:

C-programmering del 4 Ulf Assarsson Läromoment: extern, sta.c, Överkurs: const, inline, Gameloop, grafikloop, fraktalt berg Kopplat.ll: Lab 5 - spelprogrammering

Kombinera C och assembler Anropa assembler-ru.ner från C Anropa C-ru.ner från assembler Kodgenerering sker från olika filer, så ihopkopplingen sker i länkningen..o filer Parameteröverföring och returvärden Se Rogers föreläsning MOP-Cortex_M4_assemblerprogrammering_3 2

GCC genererar assembler från C Från C.ll assembler Från assembler.ll maskinkod Symbolerna i assemblern är samma som i C för ARMs gcc. Annars vanligt med eu understreck: myadd() _myadd: i C i assembler T ex för au undvika reserverade ord i assemblerspråket Nu: import / extern Synlighet assembler / C 3

Bonus Import / Export IMPORT i assembler säger au symbolen kommer från en annan fil. IMPORT myfunc... BL myfunc Symbol från annan fil ( t ex.c-fil) Börja exekvera funk.onen myfunc: EXPORT myfunc BX LR Exportera symbolen så den kan importeras av annan fil ( t ex.c-fil eller assemblerfil) I den här kursen använder vi dock asm () för au inline:a assembler direkt i en c-fil. 4

Extern extern i C säger au symbolen kommer från en annan fil. // main.c #include <stdio.h> extern int g_var; void myfunc(); void main() myfunc(); g_var definerad senare t ex i annan.c-fil extern ej nödvändig för funk.oner, prototypen säger: finns vid länkning. // myfunc.c int g_var; void myfunc() printf("hej"); ; Vanligast är dock au ta hjälp av.h-fil 5

Extern Poäng: Om ni kodar eu större program för lab5 så vill ni nog inte ha alla globala objekt/ variabler deklarerade i main-filen. Då måste ni använda extern. extern i C säger au symbolen kommer från en annan fil. // main.c #include "fractalmountain.h POBJECT objects[] = &player, &fmountain; unsigned int nobjects = 2; void main() // fractalmountain.h #ifndef FRACTALMOUNTAIN_H #define FRACTALMOUNTAIN_H #include "object.h" #include "types.h" void somefunc1(); void somefunc2(); extern OBJECT fmountain; #endif //FRACTALMOUNTAIN_H // fractalmountain.c #include fractalmountain.h" OBJECT fmountain = 0, // geometri - ingen 0,0, // riktningsvektor 0,0, // initial startposition drawmountain, // draw method 0, // clear_object unused movemountain, // move method set_object_speed // set-speed method ; extern = declare without defining Utan extern skulle vi skapa en ny variabel. 6

Synlighet av symboler Alla symboler synliga per-default i C för länkaren. Inga symboler synliga per-default i assembler: Gör symboler (i.o filen) synliga med EXPORT Gör symboler från andra filer synliga med IMPORT 7

sta.c static i C kan göra två saker 1. Ta bort synlighet (för andra filer) av symboler. 2. Allokera minne för lokala variabler som om de vore globala variabler (men forfarande med lokal synlighet) istället för på stacken. 8

Sta.c variant 1 static int var; Variabeln var kan ej ses från andra filer, oavseu om man använder extern eller IMPORT. 9

Sta.c variant 2 #include <stdio.h> void testfkt() int var1 = 0; static int var2 = 0; var1++; var2++; printf("var1: %i, var2: %i \n", var1, var2); int main() testfkt(); testfkt(); testfkt(); Utskrij: var1: 1, var2: 1 var1: 1, var2: 2 var1: 1, var2: 3 var2 ini.aliseras.ll noll endast första gången vi anropar funk.onen, men behåller sedan siu värde mellan anrop. var2 är global variabel som endast har lokal synlighet inom siu scope dvs här för testfkt(). 10

Sta.c variant 2 vanligt exempel #include <stdio.h> void testfkt() static int bfirsttime = 1; if(bfirsttime) // T ex allokera minne på heapen // eller förberäkna något. bfirsttime = 0; Gör huvudberäkningarna. int main() testfkt(); T ex: rita gubbe, skriv ut resultat i eu fönster, gör avancerad AI-simulering, skicka data över nätverk. 11

Bonus Några fler qualifiers const inline sta.c extern vola.le (restrict) const double pi = 3.14159265359; // variabeln kan inte ändras x = 90 * pi / 180; // kan förberäknas vid kompileringen // pekaren får nu inte ändra värde till annan adress volatile unsigned char * const inport = (unsigned char*) 0x40021010; static inline int square(int x) return x * x; int main() int a = square(5); 12

Inline och h-filer Bonus Foo kan inte inline:as såhär (< gcc 2010) // main.c #include <stdio.h> #include "foo.h" int main() printf("x is %i", foo(0)); return 0; // foo.h inline int foo(int x); // foo.c #include <stdlib.h> inline int foo(int x) if( x == 0 ) int x = 4; return x; return x; c-fil Inkluderar header-fil header-fil Innehåller funk.onsprototyper c-fil För main.c så syns inte defini.onen av foo() utan bara deklara.onen. Exemplet leder i själva verket oja.ll kompileringsfel. 13

Inline och h-filer Bonus Nu kan foo inline:as // main.c #include <stdio.h> #include "foo.h" int main() printf("x is %i", foo(0)); return 0; // foo.h static inline int foo(int x) if( x == 0 ) int x = 4; return x; return x; c-fil Inkluderar header-fil header-fil För main.c syns nu hela defini.onen av foo() och kan inline:as J. 14

Inline och h-filer Bonus // vecmath.h #ifndef VECMATH_H #define VECMATH_H typedef struct union float v[2]; struct float x,y; ; ; Vec2f; typedef struct Vec2f min; Vec2f max; Box2f; // box inline innebär au man ber kompilatorn au stoppa in koden direkt i anropande funk.on istället för au göra eu funk.onsanrop. Då slipper man overhead för branching och ak.veringspost. För au kunna göra deua får ej inline-funk.onen ligga i en annan.c-fil (ejersom den aldrig syns vid kompileringen utan först vid länkningen. Vissa kompilatorer klarar dock inline även vid länkningssteget. sta.c inline Box2f Add(Box2f * box, Vec2f v) Box2f res; res.min.x = box->min.x + v.x; res.min.y = box->min.y + v.y; res.max.x = box->max.x + v.x; res.max.y = box->max.y + v.y; return res; #endif //VECMATH_H // Adds vector v to min and max of box Vissa kompilatorer kräver sta.c framför inline, ty om inline misslyckas så kan funk.onen Add() bli globalt definierad (dvs får skapad kod som är globalt synlig vid länknigen) för varje.cfil som inkluderar vecmath.h, om det inte stod sta.c. Sta.c betyder au Add() bara får.c-fillokal synlighet. Utan sta.c genereras länkfelet mul.ple defini.on om vecmath.h inkluderas av flera.c-filer. 15

Typer läses läuast från höger -> vänster #define find and replace på textnivå. Typedef funkar inte på samma säu (men oja ingen prak.sk skillnad) typedef int postnr; typedef int gatunummer; postnr x = 41501; Gatunummer y = 3; // Observera au x och y nu har samma typ så man kan skriva x = y; Angående typer: Läs från höger ;ll vänster: (const finns sedan C89/90) unsigned char * const inport = (unsigned char*) 0x400; // inport är en constant pekare.ll en unsigned char unsigned char const * inport2 = (unsigned char*) 0x400; // inport är en pekare.ll en constant unsigned char const unsigned char * inport2 = (unsigned char*) 0x400; // inport är en pekare.ll en constant unsigned char char unsigned const * inport2 = (unsigned char*) 0x400; // inport är en pekare.ll en constant unsigned char char unsigned const * const inport3 = (unsigned char*) 0x400; // inport är en constant pekare.ll en constant unsigned // char MEN (som exempel på au typedef ej motsvarar find and replace) typedef unsigned char* port8ptr; const port8ptr p = (port8ptr)0x400; const unsigned char* p2 = (port8ptr)0x400; p2=0; // OK för p2 är pekare.ll const unsigned char p = 0; // ej OK för p är const-pekare.ll unsigned char port8ptr const p3 är samma som const port8ptr p3 Bonus 16

EU enkelt spel 17

Game loop En typisk game loop. int main(int argc, char **argv) appinit(); // initialize GPIO_E graphic_initalize(); // initialize the lcd-display graphic_clearscreen(); clearbuffers(); // clear front/backbuffer bool gameover = false; while(!gameover ) clearbuffer(0); collisiondetection(); // sets flags on the objects updateplayer(); // user input updateobjects(); // moves and/or kills objects based on the flags drawobjects(); // draws the objects (based on the flags) swapbuffers(); // draw backbuffer and swap back/frontbuffer. delay_milli(40); // ~25 frames/sec 18

Game loop POBJECT objects[] = &player, osv ; unsigned int nobjects = 1; void collisiondetection() ; // insert your own code void updateobjects() for(int i=0; i<nobjects; i++) objects[i]->move(objects[i]); void drawobjects() for(int i=0; i<nobjects; i++) objects[i]->draw(objects[i]); sta.c OBJECT player = &ball_g, // geometri för en boll 0,0, // ini.ala riktningskoordinater 1,1, // ini.al startposi.on draw_object, clear_object, move_object, set_object_speed ; // funk.onspekare void updateplayer() switch( tstchar() ) // tstchar() checkar input via USART-porten case '6': player.set_speed( &player, 2, 0); break; case '4': player.set_speed( &player, -2, 0); break; case '8': player.set_speed( &player, 0, -2); break; case '2': player.set_speed( &player, 0, 2); break; 19

Game loop En realis.sk grafikloop. int main(int argc, char **argv) appinit(); graphic_initalize(); graphic_clearscreen(); clearbuffers(); bool gameover = false; unsigned char framebuffer0[1024], framebuffer1[1024]; unsigned char *frontbuffer = framebuffer0; unsigned char *backbuffer = framebuffer1; void clearbuffer(unsigned char val) for (int i=0; i<1024; i++) backbuffer[i] = val; void clearbuffers() for (int i=0; i<1024; i++) backbuffer[i] = frontbuffer[i] = 0; while(!gameover ) clearbuffer(0); collisiondetection(); updateplayer(); updateobjects(); drawobjects(); swapbuffers(); delay_milli(40); void swapbuffers() graphic_drawscreen(); unsigned char* tmp = frontbuffer; // swap front/backbuffers frontbuffer = backbuffer; backbuffer = tmp; 20

Game loop En realis.sk grafikloop. void graphic_drawscreen(void) unsigned int k = 0; bool bupdateaddr = true; for(uint8 c=0; c<2; c++) // loop over both controllers (the two displays) uint8 controller = (c == 0)? B_CS1 : B_CS2; for(uint8 j = 0; j < 8; j++) // loop over pages graphic_writecommand(lcd_set_page j, controller ); graphic_writecommand(lcd_set_add 0, controller); for(uint8 i = 0; i <= 63; i++, k++) // loop over addresses // update display only where it is different from last frame if( backbuffer[k]!= frontbuffer[k] ) if(bupdateaddr ) graphic_writecommand(lcd_set_add i, controller); graphic_writedata(backbuffer[k], controller); bupdateaddr = false; // Display hardware auto-increments the address per write else bupdateaddr = true; // No write -> we need to update the x-address next write 21

Game loop Vi får då även uppdatera pixel(). void pixel( int x, int y, int set ) if (!set) return; if( (x > 127 ) (x < 0) (y > 63) (y < 0) ) return; unsigned char mask = 1 << (y%8); int index = 0; if(x>=64) x -= 64; index = 512; index += x + (y/8)*64; backbuffer[index] = mask; switch( y%8 ) case 0: mask = 1; break; case 1: mask = 2; break; case 2: mask = 4; break; case 3: mask = 8; break; case 4: mask = 0x10; break; case 5: mask = 0x20; break; case 6: mask = 0x40; break; case 7: mask = 0x80; break; 22

Fractal mountains POBJECT objects[] = &player, &fmountain; unsigned int nobjects = 2; sta.c OBJECT fmountain = 0, // geometri behöver vi ej 0,0, // ini.ala riktningskoordinater 0,0, // ini.al startposi.on drawmountain, // funk.onspekare 0, // unused move_object, // dummy set_object_speed // dummy ; sta.c OBJECT player = &ball_g, // geometri för en boll 0,0, // ini.ala riktningskoordinater 1,1, // ini.al startposi.on draw_object, // funk.onspekare clear_object, move_object, set_object_speed ; 23

Fractal mountains static unsigned char y_values[128]; void drawmountain() static bool bfirsttime = true; if(bfirsttime) bfirsttime = false; for(uint8 x=0; x<128; x++) y_values[x] = fractal(); else // shift mountain to the left for(uint8 x=0; x<127; x++) y_values[x] = y_values[x+1]; y_values[127] = fractal(); // anropa pixel för alla x=[0,127] for(uint8 x=0; x<127; x++) pixel(x, y_values[x], 1); 24

Fractal mountains #define RAND_MAX 32767 static unsigned int next = 1; static unsigned int rand(void) next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768; static void srand(unsigned int seed) next = seed; 25

Fractal mountains static unsigned char fractal() // f = noise(t)*a + noise(0.5t)*2a + noise(0.25t)*4a... static int noise[] = 0,0,0; // room for 3 octaves static int t = 0; static int f = RAND_MAX / 2; const int half_max = RAND_MAX/2; noise[0] = (rand() > half_max)? 1 : -1; // update each time if( (t%2) == 1) noise[1] = (rand() > half_max)? 1 : -1; // update every 2 nd time if( (t%4) == 3) noise[2] = (rand() > half_max)? 1 : -1; // update every 4 th time // sum octaves int val = 0; for(int i=0; i<3; i++) val += noise[i]; f += val; // update our static non-bounced fractal function t = (t+1) % 4; val = f % 64; // return a bounced value between 32 + [0-32] val = (val > 31)? 63-val : val; return val + 32; 26

För au ni ska kunna läsa kod C luriga uuryck (överkurs) for (expr/dekl; expr; expr) statement; if( expr ) Godtyckliga expressions. Examples of statements: if, while, do/while, for, switch, expr Deklara.on av lokala variabler: int a, b; Examples of expressions: x = y + 3; x++; x = y = 0; // Both x and y are initialized to 0 proc( arg1, arg2 );// Function call y = z = f(x) + 3; // A function-call expression expr, expr; // list of expressions. Conditional value // of the expression is the result of the // last expression. 27

För au ni ska kunna läsa kod C luriga uuryck (överkurs) Godtyckligt expression/dekl. Dock typiskt en vanlig deklara.on och ini.ering av loopvariabeln. for(expr/dekl; expr; expr) statement; for (int a=1, b=0; b<5, a++, f(a), a<3; b++, a += (b>a)? 1 : -1) a++, b++; Godtyckligt expression. OBS vilkorets värde endast lika med sista uurycket a<3 (så b<5 har här ingen effekt). if(a=0, b++, a = (b == c) ) Gör inte såhär ejersom det blir svårläst kod! 28

För au ni ska kunna läsa kod C luriga uuryck (överkurs) EU.ll knäppt exempel void f(int b, int c) printf("%d, %d", b, c); void main() int a = 0; f( (++a, ++a, ++a), (++a, ++a)); Expr för 1:a parametern. Vad skrivs ut? Svar: 3, 5 Kommaseparerade expressions evalueras vä -> hö. Så även för inputparametrar hos de flesta C-kompilatorer (men är ospecificerat). Värdet för en lista av expr är värdet av sista uurycket. Expr för 2:a parametern. Värde = värdet hos sista uurycken (++a). Gör inte såhär ejersom det blir svårläst kod! 29

EU spel Exempel på lite större projekt Output i konsolen Denna version kör enbart på Windows + CodeLite men hyfsat läu au porta. Utan externa APIs Objektorienterad s.l Objekt: Anima.on, Object, Enemy, Player, Text h-filerna visar strukturen hup://www.cse.chalmers.se/~uffe/mop/game.zip 30