[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 | 370 +++++++++++++++++++++++++++++++-------
 1 file changed, 310 insertions(+), 60 deletions(-)

diff --git a/src/modules/c/pong/main.c b/src/modules/c/pong/main.c
index 0773dc21..9ced7990 100644
--- a/src/modules/c/pong/main.c
+++ b/src/modules/c/pong/main.c
@@ -33,15 +33,308 @@
 #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 +378,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;
-
-    uint64_t start = get_tick_count();
-
-    int oldsec = 0;
-
     libvideo_change_target(front);
+    
+    return true;
+}
 
-    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;
+int main(int argc, char** argv)
+{
 
+	init_screen();
+	init_keyboard();
+	init_game();
+	
+	run();
+	
+    return 0;
 }
-- 
2.29.2