[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] modules: reparieren von Pong



+ Mit dem Programm Pong kann man jetzt wirklich Pong spielen!
---
 src/modules/c/pong/main.c | 362 ++++++++++++++++++++++++++++++++------
 1 file changed, 304 insertions(+), 58 deletions(-)

diff --git a/src/modules/c/pong/main.c b/src/modules/c/pong/main.c
index 0773dc21..9d2c42fb 100644
--- a/src/modules/c/pong/main.c
+++ b/src/modules/c/pong/main.c
@@ -33,15 +33,304 @@
 #include <syscall.h>
 #include <types.h>
 #include <unistd.h>
+#include <kbd.h>
+#include <init.h>
 
-int main(int argc, char** argv)
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+
+
+
+
+typedef struct Vector2 {
+    int x;
+    int y;
+} Vector2;
+
+typedef struct Player {
+    Vector2 position;
+    Vector2 size;
+    int life;
+} Player;
+
+typedef struct Ball {
+    Vector2 position;
+    Vector2 speed;
+    Vector2 size;
+    bool active;
+} Ball;
+
+typedef struct Key {
+    bool down;
+    bool pressed;
+} Key;
+
+typedef struct Keyboard {
+    pid_t kbc_pid;
+    Key arrow_up;
+    Key arrow_down;
+    Key start;
+    Key pause;
+} Keyboard;
+
+//------------------------------------------------------------------------------------
+// Global Variables Declaration
+//------------------------------------------------------------------------------------
+
+static const int screen_width = 640;
+static const int screen_height = 480;
+static const int time_per_frame = 20*1000; /* 20ms */
+static const int player_max_life = 5;
+
+static bool game_over = false;
+static bool pause = false;
+
+static Player player = {0};
+static Ball ball = {0};
+static Keyboard keyboard = {0};
+
+static video_bitmap_t *front;
+
+//------------------------------------------------------------------------------------
+// Module Functions Declaration (local)
+//------------------------------------------------------------------------------------
+
+static void rpc_kbd_callback(pid_t pid, uint32_t cid, size_t data_size, void* data);
+
+static bool init_screen(void);
+static bool init_keyboard(void);
+static bool init_game(void);
+
+
+static void update_player(void);
+static void update_ball(void);
+static void run(void);
+static void render(void);
+
+static void update_key(Key* key, bool down);
+static bool is_key_pressed(Key *key);
+
+//------------------------------------------------------------------------------------
+// Funktion Definitions
+//------------------------------------------------------------------------------------
+
+
+static void update_key(Key* key, bool down)
+{
+    if (!down && key->down)
+    {
+        key->pressed = true;
+    }
+
+    key->down = down;
+}
+
+static bool is_key_pressed(Key *key)
+{
+    if (key->pressed)
+    {
+        key->pressed = false;
+        return true;
+    }
+
+    return false;
+}
+
+static void run()
+{
+    uint64_t time_last_update = get_tick_count();
+    uint64_t delta_time = 0;
+
+    while (true)
+    {
+        delta_time += get_tick_count() - time_last_update;
+        time_last_update = get_tick_count();
+
+        while (delta_time >= time_per_frame)
+        {
+            delta_time -= time_per_frame;
+            update_player();
+            update_ball();
+        }
+        render();
+    }
+}
+
+static void update_player()
+{
+    if (!pause && !game_over)
+    {
+        if (player.life <= 0)
+        {
+            game_over = true;
+        }
+
+        if (keyboard.arrow_up.down)
+        {
+            player.position.y -= 5;
+        }
+
+        if (keyboard.arrow_down.down)
+        {
+            player.position.y += 5;
+        }
+
+        if ((player.position.y + player.size.y) >= screen_height)
+        {
+            player.position.y = screen_height - player.size.y;
+        }
+        else if (player.position.y <= 0)
+        {
+            player.position.y = 0;
+        }
+    }
+}
+
+static void update_ball()
+{
+
+    if (!pause && !game_over)
+    {
+        if (is_key_pressed(&keyboard.start) && !ball.active)
+        {
+            ball.speed = (Vector2){5,0};
+            ball.active = true;
+        }
+
+        if (ball.active)
+        {
+            ball.position.x += ball.speed.x;
+            ball.position.y += ball.speed.y;
+        }
+
+        if ((ball.position.y + ball.size.y) >= screen_height ||
+            (ball.position.y) <= 0)
+        {
+            ball.speed.y = -ball.speed.y;
+        }
+
+        if ((ball.position.x + ball.size.x) >= screen_width)
+        {
+            ball.speed.x = -ball.speed.x;
+        }
+
+        // gooaaal!
+        if (ball.position.x <= 0)
+        {
+            ball.position = (Vector2){screen_width/2, screen_height/2};
+            ball.speed = (Vector2){0, 0};
+            ball.active = false;
+            player.life--;
+        }
+
+        // collision with player
+        if (player.position.x - ball.size.x <= ball.position.x &&
+            player.position.x + player.size.x >= ball.position.x &&
+            player.position.y - ball.size.y <= ball.position.y &&
+            player.position.y + player.size.y >= ball.position.y)
+        {
+
+            if (ball.speed.x < 0)
+            {
+                ball.speed.x = -ball.speed.x;
+                ball.speed.y = (ball.position.x - (player.position.y + player.size.x/2))/30;
+            }
+        }
+    }
+}
+
+static void render(void)
+{
+    /* Male background */
+    libvideo_change_color(0,0,0,0);
+    libvideo_draw_rectangle(0,0,screen_width, screen_height);
+
+    /* Male Brett */
+    libvideo_change_color(0, 255, 0, 0);
+    libvideo_draw_rectangle(player.position.x, player.position.y, player.size.x, player.size.y);
+
+    /* Male Ball */
+    libvideo_change_color(0, 0xab, 0xcd, 0xef);
+    libvideo_draw_rectangle(ball.position.x, ball.position.y, ball.size.x, ball.size.y);
+
+
+    libvideo_do_command_buffer();
+    libvideo_flip_buffers(front);
+}
+
+
+static bool init_game(void)
+{
+
+    /* Initialize player */
+    player.position = (Vector2){screen_width*1/10, screen_height/2};
+    player.size = (Vector2){20, screen_height/5};
+    player.life = player_max_life;
+
+    /* Initialize ball */
+    ball.position = (Vector2){screen_width/2, screen_height/2};
+    ball.speed = (Vector2){0, 0};
+    ball.size = (Vector2){20, 20};
+    ball.active = false;
+
+
+    return true;
+}
+
+static bool init_keyboard(void)
+{
+    // RPC-Handler fuer die Callbacks von KBD einrichten
+    register_message_handler(KBD_RPC_CALLBACK, rpc_kbd_callback);
+
+    keyboard.kbc_pid = init_service_get("kbc");
+    if (!keyboard.kbc_pid) {
+        return false;
+    }
+
+    // Callback registrtrieren bei KBC
+    return rpc_get_dword(keyboard.kbc_pid, KBD_RPC_REGISTER_CALLBACK, 0, NULL);
+   
+}
+
+static void rpc_kbd_callback(pid_t pid, uint32_t cid, size_t data_size,
+    void* data)
+{
+    uint8_t* kbd_data = data;
+
+
+    if ((pid != keyboard.kbc_pid) || (data_size != 2)) {
+        return;
+    }
+
+    p();
+
+    if (kbd_data[0] == KEYCODE_ARROW_UP)
+    {
+        update_key(&keyboard.arrow_up, !kbd_data[1]);
+    }
+    else if (kbd_data[0] == KEYCODE_ARROW_DOWN)
+    {
+        update_key(&keyboard.arrow_down, !kbd_data[1]);
+    }
+    else if (kbd_data[0] == KEYCODE_ALTGR)
+    {
+        update_key(&keyboard.start, !kbd_data[1]);
+    }
+
+    v();
+}
+
+
+static bool init_screen()
 {
     stdout = 0;
     driver_context_t* main_context;
     main_context = libvideo_create_driver_context("vesa");
     if (!main_context) {
         fprintf(stderr, "Konnte Grafiktreiberkontext nicht erstellen\n");
-        return EXIT_FAILURE;
+        return false;
     }
     libvideo_use_driver_context(main_context);
     libvideo_get_command_buffer(1024);
@@ -85,75 +374,32 @@ int main(int argc, char** argv)
 
     printf("Farbe gesetzt.\n");
 
-    if (libvideo_change_display_resolution(0, 640, 480, 24) != 0) {
+    if (libvideo_change_display_resolution(0, screen_width, screen_height, 24) != 0) {
         printf("Modus setzen fehlgeschlagen\n");
-        return -1;
+        return false;
     }
 
     printf("Modus gesetzt.\n");
 
-    video_bitmap_t *front;
+
     front = libvideo_get_frontbuffer_bitmap(0);
     int buffers = libvideo_request_backbuffers(front, 2);
 
     printf("Got frontbuffer. %d Backbuffer.\n", buffers);
 
-    int angle = 0;
-    int speed = 100;
-
-    int x = 1024/2;
-    int y = 768/2;
-
-    int dx, dy;
-
-    int frames = 0;
+    libvideo_change_target(front);
+    
+    return true;
+}
 
-    uint64_t start = get_tick_count();
+int main(int argc, char** argv)
+{
 
-    int oldsec = 0;
+    init_screen();
+    init_keyboard();
+    init_game();
 
-    libvideo_change_target(front);
+    run();
 
-    while (1) {
-//        libvideo_change_target(back);
-        libvideo_change_color(0,0,0,0);
-        libvideo_draw_rectangle(0,0,1024,768);
-
-        libvideo_change_color(0, 255, 0, 0);
-        libvideo_draw_rectangle(0,0,1024,20);
-        libvideo_draw_rectangle(0, 748, 1024, 20);
-        libvideo_draw_rectangle(1004, 0, 20, 768);
-
-        dx = sin(angle * M_PI / 180) * speed;
-        dy = cos(angle * M_PI / 180) * speed;
-
-        angle += 1;
-        if (angle >= 360) angle=0;
-
-        libvideo_change_color(0, 0xab, 0xcd, 0xef);
-        libvideo_draw_rectangle(x-10+dx, y-10+dy, 20, 20);
-
-        dx <<= 1;
-        dy <<= 1;
-        libvideo_change_color(0, 0, 255, 255);
-        libvideo_draw_rectangle(x+dx, y+dy, 3, 3);
-
-//        libvideo_change_target(front);
-//        libvideo_draw_bitmap(back, 0,0 );
-        libvideo_do_command_buffer();
-        libvideo_flip_buffers(front);
-
-        frames = frames + 1;
-        uint64_t now = get_tick_count();
-        uint64_t diff = now - start;
-        // In Sek
-        diff /= 1000000;
-        if (diff > oldsec) {
-            oldsec = diff;
-            int fps = frames / diff;
-            printf("Sek %d : %d Frames so far, Overall %d FPS\n", diff, fps, frames);
-        }
-    }
     return 0;
-
 }
-- 
2.29.2