static int rain_connect(struct serio *serio, struct serio_driver *drv) { u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; struct rain *rain; int err = -ENOMEM; struct cec_log_addrs log_addrs = {}; u16 pa = CEC_PHYS_ADDR_INVALID; rain = kzalloc(sizeof(*rain), GFP_KERNEL); if (!rain) return -ENOMEM; rain->serio = serio; rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain, dev_name(&serio->dev), caps, 1); err = PTR_ERR_OR_ZERO(rain->adap); if (err < 0) goto free_device; rain->dev = &serio->dev; serio_set_drvdata(serio, rain); INIT_WORK(&rain->work, rain_irq_work_handler); mutex_init(&rain->write_lock); spin_lock_init(&rain->buf_lock); err = serio_open(serio, drv); if (err) goto delete_adap; err = rain_setup(rain, serio, &log_addrs, &pa); if (err) goto close_serio; err = cec_register_adapter(rain->adap, &serio->dev); if (err < 0) goto close_serio; rain->dev = &rain->adap->devnode.dev; return 0; close_serio: serio_close(serio); delete_adap: cec_delete_adapter(rain->adap); serio_set_drvdata(serio, NULL); free_device: kfree(rain); return err; }
void rain_draw(int tick) { int n,xadd,yadd,zadd,density, slant_add,slant_mult,slant_div; float slant_ang_y; float *vertex_ptr,*col_ptr; rain_draw_type *rain_draw; // is rain on and not under liquid? if (!map.rain.on) return; if (view.render->camera.under_liquid_idx!=-1) return; // reset on? if (map.rain.reset) { map.rain.reset=FALSE; rain_setup(tick,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); } // rain slant slant_add=rain_slant_add; slant_ang_y=rain_slant_ang_y; if (map.rain.slant_time_msec!=0) { // time to change slant? if (tick>rain_slant_next_end_tick) { rain_slant_add=slant_add=rain_slant_next_add; rain_slant_ang_y=slant_ang_y=rain_slant_next_ang_y; rain_setup_next_slant(tick); } else { // slant in the middle of changing if (tick>rain_slant_next_start_tick) { slant_mult=tick-rain_slant_next_start_tick; slant_div=(rain_slant_next_end_tick-rain_slant_next_start_tick); slant_add=rain_slant_add+(((rain_slant_next_add-rain_slant_add)*slant_mult)/slant_div); slant_ang_y=rain_slant_ang_y+((rain_slant_next_ang_y-rain_slant_ang_y)*((float)slant_mult/(float)slant_div)); } } } angle_get_movement(slant_ang_y,slant_add,&xadd,&zadd); // rain change xadd=(tick-rain_last_tick)*xadd; yadd=(tick-rain_last_tick)*map.rain.speed; zadd=(tick-rain_last_tick)*zadd; rain_last_tick=tick; // rain density density=map.rain.density; if (density>max_rain_density) density=max_rain_density; // construct VBO vertex_ptr=view_bind_map_next_vertex_object(((density*2)*(3+4))); if (vertex_ptr==NULL) return; col_ptr=vertex_ptr+((density*2)*3); // create vertexes rain_draw=view.rain_draws; for (n=0;n!=density;n++) { // move rain rain_draw->x+=xadd; rain_draw->y+=yadd; rain_draw->z+=zadd; if (rain_draw->y>rain_draw->by) rain_setup_single_reset(rain_draw,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); // draw rain *vertex_ptr++=(float)rain_draw->x; *vertex_ptr++=(float)rain_draw->y; *vertex_ptr++=(float)rain_draw->z; *col_ptr++=map.rain.start_color.r; *col_ptr++=map.rain.start_color.g; *col_ptr++=map.rain.start_color.b; *col_ptr++=map.rain.alpha; *vertex_ptr++=(float)(rain_draw->x+xadd); *vertex_ptr++=(float)(rain_draw->y+map.rain.line_length); *vertex_ptr++=(float)(rain_draw->z+zadd); *col_ptr++=map.rain.end_color.r; *col_ptr++=map.rain.end_color.g; *col_ptr++=map.rain.end_color.b; *col_ptr++=map.rain.alpha; rain_draw++; } view_unmap_current_vertex_object(); // setup view gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_ALPHA_TEST); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDepthMask(GL_FALSE); // draw the rain glLineWidth((float)map.rain.line_width); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_FLOAT,0,(void*)0); glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4,GL_FLOAT,0,(void*)(((density*2)*3)*sizeof(float))); glDrawArrays(GL_LINES,0,(density*2)); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glLineWidth(1); // unbind the vbo view_unbind_current_vertex_object(); }